diff options
| -rw-r--r-- | src/dotup.rs | 28 | ||||
| -rw-r--r-- | src/main.rs | 28 |
2 files changed, 33 insertions, 23 deletions
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 { | |||
| 131 | 131 | ||
| 132 | pub fn link(&mut self, origin: impl AsRef<Path>, destination: impl AsRef<Path>) { | 132 | pub fn link(&mut self, origin: impl AsRef<Path>, destination: impl AsRef<Path>) { |
| 133 | let link_result: anyhow::Result<()> = try { | 133 | let link_result: anyhow::Result<()> = try { |
| 134 | let origin = self.prepare_relative_path(origin.as_ref())?; | 134 | let origin = self.prepare_relative_origin(origin.as_ref())?; |
| 135 | let destination = destination.as_ref(); | 135 | let destination = self.prepare_relative_destination(destination.as_ref())?; |
| 136 | self.depot.link_create(origin, destination)?; | 136 | self.depot.link_create(origin, destination)?; |
| 137 | }; | 137 | }; |
| 138 | match link_result { | 138 | match link_result { |
| @@ -144,7 +144,7 @@ impl Dotup { | |||
| 144 | pub fn unlink(&mut self, paths: impl Iterator<Item = impl AsRef<Path>>, uninstall: bool) { | 144 | pub fn unlink(&mut self, paths: impl Iterator<Item = impl AsRef<Path>>, uninstall: bool) { |
| 145 | for origin in paths { | 145 | for origin in paths { |
| 146 | let unlink_result: anyhow::Result<()> = try { | 146 | let unlink_result: anyhow::Result<()> = try { |
| 147 | let origin = self.prepare_relative_path(origin.as_ref())?; | 147 | let origin = self.prepare_relative_origin(origin.as_ref())?; |
| 148 | let links_under: Vec<_> = self.depot.links_under(&origin)?.collect(); | 148 | let links_under: Vec<_> = self.depot.links_under(&origin)?.collect(); |
| 149 | for link_id in links_under { | 149 | for link_id in links_under { |
| 150 | if uninstall && self.symlink_is_installed_by_link_id(link_id)? { | 150 | if uninstall && self.symlink_is_installed_by_link_id(link_id)? { |
| @@ -233,8 +233,8 @@ impl Dotup { | |||
| 233 | fn mv_one(&mut self, origin: &Path, destination: &Path) -> anyhow::Result<()> { | 233 | fn mv_one(&mut self, origin: &Path, destination: &Path) -> anyhow::Result<()> { |
| 234 | log::debug!("mv_one : {} to {}", origin.display(), destination.display()); | 234 | log::debug!("mv_one : {} to {}", origin.display(), destination.display()); |
| 235 | 235 | ||
| 236 | let relative_origin = self.prepare_relative_path(origin)?; | 236 | let relative_origin = self.prepare_relative_origin(origin)?; |
| 237 | let relative_destination = self.prepare_relative_path(destination)?; | 237 | let relative_destination = self.prepare_relative_origin(destination)?; |
| 238 | match self.depot.link_find(&relative_origin)? { | 238 | match self.depot.link_find(&relative_origin)? { |
| 239 | Some(link_id) => { | 239 | Some(link_id) => { |
| 240 | let is_installed = self.symlink_is_installed_by_link_id(link_id)?; | 240 | let is_installed = self.symlink_is_installed_by_link_id(link_id)?; |
| @@ -307,7 +307,7 @@ impl Dotup { | |||
| 307 | fn status_path_to_item(&self, canonical_path: &Path) -> anyhow::Result<StatusItem> { | 307 | fn status_path_to_item(&self, canonical_path: &Path) -> anyhow::Result<StatusItem> { |
| 308 | debug_assert!(canonical_path.is_absolute()); | 308 | debug_assert!(canonical_path.is_absolute()); |
| 309 | debug_assert!(canonical_path.exists()); | 309 | debug_assert!(canonical_path.exists()); |
| 310 | let relative_path = self.prepare_relative_path(canonical_path)?; | 310 | let relative_path = self.prepare_relative_origin(canonical_path)?; |
| 311 | 311 | ||
| 312 | let item = if canonical_path.is_dir() { | 312 | let item = if canonical_path.is_dir() { |
| 313 | if let Some(link_id) = self.depot.link_find(&relative_path)? { | 313 | if let Some(link_id) = self.depot.link_find(&relative_path)? { |
| @@ -442,21 +442,29 @@ impl Dotup { | |||
| 442 | .unwrap_or_default() | 442 | .unwrap_or_default() |
| 443 | } | 443 | } |
| 444 | 444 | ||
| 445 | fn prepare_relative_path(&self, origin: &Path) -> anyhow::Result<PathBuf> { | 445 | fn prepare_relative_path(path: &Path, base: &Path) -> anyhow::Result<PathBuf> { |
| 446 | let canonical = utils::weakly_canonical(origin); | 446 | let canonical = utils::weakly_canonical(path); |
| 447 | let relative = canonical | 447 | let relative = canonical |
| 448 | .strip_prefix(&self.depot_dir) | 448 | .strip_prefix(base) |
| 449 | .context("Invalid origin path, not under depot directory")?; | 449 | .context("Invalid origin path, not under depot directory")?; |
| 450 | Ok(relative.to_owned()) | 450 | Ok(relative.to_owned()) |
| 451 | } | 451 | } |
| 452 | 452 | ||
| 453 | fn prepare_relative_origin(&self, path: &Path) -> anyhow::Result<PathBuf> { | ||
| 454 | Self::prepare_relative_path(path, &self.depot_dir) | ||
| 455 | } | ||
| 456 | |||
| 457 | fn prepare_relative_destination(&self, path: &Path) -> anyhow::Result<PathBuf> { | ||
| 458 | Self::prepare_relative_path(path, &self.install_base) | ||
| 459 | } | ||
| 460 | |||
| 453 | fn link_ids_from_paths_iter( | 461 | fn link_ids_from_paths_iter( |
| 454 | &self, | 462 | &self, |
| 455 | paths: impl Iterator<Item = impl AsRef<Path>>, | 463 | paths: impl Iterator<Item = impl AsRef<Path>>, |
| 456 | ) -> anyhow::Result<Vec<LinkID>> { | 464 | ) -> anyhow::Result<Vec<LinkID>> { |
| 457 | let mut link_ids = HashSet::<LinkID>::default(); | 465 | let mut link_ids = HashSet::<LinkID>::default(); |
| 458 | for path in paths { | 466 | for path in paths { |
| 459 | let path = self.prepare_relative_path(path.as_ref())?; | 467 | let path = self.prepare_relative_origin(path.as_ref())?; |
| 460 | link_ids.extend(self.depot.links_under(&path)?); | 468 | link_ids.extend(self.depot.links_under(&path)?); |
| 461 | } | 469 | } |
| 462 | Ok(Vec::from_iter(link_ids.into_iter())) | 470 | 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 { | |||
| 116 | #[clap(long)] | 116 | #[clap(long)] |
| 117 | directory: bool, | 117 | directory: bool, |
| 118 | 118 | ||
| 119 | origin: PathBuf, | 119 | origins: Vec<PathBuf>, |
| 120 | 120 | ||
| 121 | destination: PathBuf, | 121 | destination: PathBuf, |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | fn command_link(global_flags: Flags, args: LinkArgs) -> anyhow::Result<()> { | 124 | fn command_link(global_flags: Flags, args: LinkArgs) -> anyhow::Result<()> { |
| 125 | let mut dotup = utils::read_dotup(&global_flags)?; | 125 | let mut dotup = utils::read_dotup(&global_flags)?; |
| 126 | if !args.directory && args.origin.is_dir() { | 126 | for origin in args.origins { |
| 127 | let directory = args.origin; | 127 | if !args.directory && origin.is_dir() { |
| 128 | let origins = utils::collect_files_in_dir_recursive(&directory)?; | 128 | let directory = origin; |
| 129 | for origin in origins { | 129 | let origins = utils::collect_files_in_dir_recursive(&directory)?; |
| 130 | // unwrap: origin is under directory so stripping should not fail | 130 | for origin in origins { |
| 131 | let path_extra = origin.strip_prefix(&directory).unwrap(); | 131 | // unwrap: origin is under directory so stripping should not fail |
| 132 | let destination = args.destination.join(path_extra); | 132 | let path_extra = origin.strip_prefix(&directory).unwrap(); |
| 133 | dotup.link(&origin, &destination); | 133 | let destination = args.destination.join(path_extra); |
| 134 | } | 134 | dotup.link(&origin, &destination); |
| 135 | } else { | 135 | } |
| 136 | dotup.link(&args.origin, &args.destination); | 136 | } else { |
| 137 | }; | 137 | dotup.link(&origin, &args.destination); |
| 138 | }; | ||
| 139 | } | ||
| 138 | utils::write_dotup(&dotup)?; | 140 | utils::write_dotup(&dotup)?; |
| 139 | Ok(()) | 141 | Ok(()) |
| 140 | } | 142 | } |
