From d5abd94c24a6d4542bbdddc8a8d43a7de6f4eed5 Mon Sep 17 00:00:00 2001 From: diogo464 Date: Tue, 15 Feb 2022 18:54:09 +0000 Subject: allow linking multiples files at once --- src/dotup.rs | 28 ++++++++++++++++++---------- src/main.rs | 28 +++++++++++++++------------- 2 files changed, 33 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/dotup.rs b/src/dotup.rs index 296b182..5f1287f 100644 --- a/src/dotup.rs +++ b/src/dotup.rs @@ -131,8 +131,8 @@ impl Dotup { pub fn link(&mut self, origin: impl AsRef, destination: impl AsRef) { let link_result: anyhow::Result<()> = try { - let origin = self.prepare_relative_path(origin.as_ref())?; - let destination = destination.as_ref(); + let origin = self.prepare_relative_origin(origin.as_ref())?; + let destination = self.prepare_relative_destination(destination.as_ref())?; self.depot.link_create(origin, destination)?; }; match link_result { @@ -144,7 +144,7 @@ impl Dotup { pub fn unlink(&mut self, paths: impl Iterator>, uninstall: bool) { for origin in paths { let unlink_result: anyhow::Result<()> = try { - let origin = self.prepare_relative_path(origin.as_ref())?; + let origin = self.prepare_relative_origin(origin.as_ref())?; let links_under: Vec<_> = self.depot.links_under(&origin)?.collect(); for link_id in links_under { if uninstall && self.symlink_is_installed_by_link_id(link_id)? { @@ -233,8 +233,8 @@ impl Dotup { fn mv_one(&mut self, origin: &Path, destination: &Path) -> anyhow::Result<()> { log::debug!("mv_one : {} to {}", origin.display(), destination.display()); - let relative_origin = self.prepare_relative_path(origin)?; - let relative_destination = self.prepare_relative_path(destination)?; + let relative_origin = self.prepare_relative_origin(origin)?; + let relative_destination = self.prepare_relative_origin(destination)?; match self.depot.link_find(&relative_origin)? { Some(link_id) => { let is_installed = self.symlink_is_installed_by_link_id(link_id)?; @@ -307,7 +307,7 @@ impl Dotup { fn status_path_to_item(&self, canonical_path: &Path) -> anyhow::Result { debug_assert!(canonical_path.is_absolute()); debug_assert!(canonical_path.exists()); - let relative_path = self.prepare_relative_path(canonical_path)?; + let relative_path = self.prepare_relative_origin(canonical_path)?; let item = if canonical_path.is_dir() { if let Some(link_id) = self.depot.link_find(&relative_path)? { @@ -442,21 +442,29 @@ impl Dotup { .unwrap_or_default() } - fn prepare_relative_path(&self, origin: &Path) -> anyhow::Result { - let canonical = utils::weakly_canonical(origin); + fn prepare_relative_path(path: &Path, base: &Path) -> anyhow::Result { + let canonical = utils::weakly_canonical(path); let relative = canonical - .strip_prefix(&self.depot_dir) + .strip_prefix(base) .context("Invalid origin path, not under depot directory")?; Ok(relative.to_owned()) } + fn prepare_relative_origin(&self, path: &Path) -> anyhow::Result { + Self::prepare_relative_path(path, &self.depot_dir) + } + + fn prepare_relative_destination(&self, path: &Path) -> anyhow::Result { + Self::prepare_relative_path(path, &self.install_base) + } + fn link_ids_from_paths_iter( &self, paths: impl Iterator>, ) -> anyhow::Result> { let mut link_ids = HashSet::::default(); for path in paths { - let path = self.prepare_relative_path(path.as_ref())?; + let path = self.prepare_relative_origin(path.as_ref())?; link_ids.extend(self.depot.links_under(&path)?); } Ok(Vec::from_iter(link_ids.into_iter())) diff --git a/src/main.rs b/src/main.rs index acd0e38..8c8e9dc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -116,25 +116,27 @@ struct LinkArgs { #[clap(long)] directory: bool, - origin: PathBuf, + origins: Vec, destination: PathBuf, } fn command_link(global_flags: Flags, args: LinkArgs) -> anyhow::Result<()> { let mut dotup = utils::read_dotup(&global_flags)?; - if !args.directory && args.origin.is_dir() { - let directory = args.origin; - let origins = utils::collect_files_in_dir_recursive(&directory)?; - for origin in origins { - // unwrap: origin is under directory so stripping should not fail - let path_extra = origin.strip_prefix(&directory).unwrap(); - let destination = args.destination.join(path_extra); - dotup.link(&origin, &destination); - } - } else { - dotup.link(&args.origin, &args.destination); - }; + for origin in args.origins { + if !args.directory && origin.is_dir() { + let directory = origin; + let origins = utils::collect_files_in_dir_recursive(&directory)?; + for origin in origins { + // unwrap: origin is under directory so stripping should not fail + let path_extra = origin.strip_prefix(&directory).unwrap(); + let destination = args.destination.join(path_extra); + dotup.link(&origin, &destination); + } + } else { + dotup.link(&origin, &args.destination); + }; + } utils::write_dotup(&dotup)?; Ok(()) } -- cgit