aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordiogo464 <[email protected]>2022-02-15 18:54:09 +0000
committerdiogo464 <[email protected]>2022-02-15 18:54:09 +0000
commitd5abd94c24a6d4542bbdddc8a8d43a7de6f4eed5 (patch)
tree0655678b72c93218789dbd430b4e4d5d2636ef53 /src
parent00e94787e0e473f733b15da24ebe64ed0f595a9e (diff)
allow linking multiples files at once
Diffstat (limited to 'src')
-rw-r--r--src/dotup.rs28
-rw-r--r--src/main.rs28
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
124fn command_link(global_flags: Flags, args: LinkArgs) -> anyhow::Result<()> { 124fn 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}