From 3469dd5ab5b475a96f852b8c2e12a0b2c1c09caf Mon Sep 17 00:00:00 2001 From: diogo464 Date: Fri, 9 Jul 2021 06:40:35 -0400 Subject: Fixed problem with link creation. --- dotup_cli/src/commands/link.rs | 120 ++++++++++++++++++++++++----------------- 1 file changed, 70 insertions(+), 50 deletions(-) (limited to 'dotup_cli/src') diff --git a/dotup_cli/src/commands/link.rs b/dotup_cli/src/commands/link.rs index 81c396b..518bd4a 100644 --- a/dotup_cli/src/commands/link.rs +++ b/dotup_cli/src/commands/link.rs @@ -32,19 +32,25 @@ pub fn main(config: Config, opts: Opts) -> anyhow::Result<()> { }; if let Some(destination) = destination { - let collected_paths = if opts.directory { - origins.to_vec() + let params = if opts.directory { + origins + .iter() + .map(|p| LinkCreateParams { + origin: p.to_path_buf(), + destination: destination.clone(), + }) + .collect() } else { - collect_file_type(origins, FileType::File)? + let mut params = Vec::new(); + for origin in origins { + link(&depot, &origin, &destination, &origin, &mut params)?; + } + params }; - for path in collected_paths { - let link_desc = LinkCreateParams { - origin: path, - destination: destination.clone(), - }; - log::info!("Creating link : {}", link_desc); - depot.create_link(link_desc)?; + for link_params in params { + log::info!("Creating link : {}", link_params); + depot.create_link(link_params)?; } } else { let base_path = match origins { @@ -63,48 +69,62 @@ pub fn main(config: Config, opts: Opts) -> anyhow::Result<()> { Ok(()) } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -enum FileType { - File, - Directory, +fn link( + depot: &Depot, + origin: &Path, + destination: &Path, + base: &Path, + params: &mut Vec, +) -> anyhow::Result<()> { + let metadata = std::fs::metadata(origin)?; + if metadata.is_file() { + link_file(depot, origin, destination, base, params)?; + } else if metadata.is_dir() { + link_directory_recursive(depot, origin, destination, base, params)?; + } + Ok(()) } -/// Collects canonical files of the given type starting from, and including, entry_paths -fn collect_file_type( - entry_paths: impl IntoIterator>, - collect_type: FileType, -) -> anyhow::Result> { - let entry_paths: Vec = entry_paths - .into_iter() - .map(|p| p.as_ref().to_path_buf()) - .collect(); - let mut collected = Vec::new(); - let mut pending: Vec<_> = entry_paths.iter().cloned().filter(|p| p.is_dir()).collect(); - - for path in entry_paths { - let path = path.canonicalize()?; - if (path.is_file() && collect_type == FileType::File) - || (path.is_dir() && collect_type == FileType::Directory) - { - collected.push(path); - } - } +fn link_file( + depot: &Depot, + origin: &Path, + destination: &Path, + base: &Path, + params: &mut Vec, +) -> anyhow::Result<()> { + let origin_canonical = origin + .canonicalize() + .expect("Failed to canonicalize origin path"); + let base_canonical = base + .canonicalize() + .expect("Failed to canonicalize base path"); + + log::debug!("Origin canonical : {}", origin_canonical.display()); + log::debug!("Base : {}", base.display()); + + let partial = origin_canonical + .strip_prefix(base_canonical) + .expect("Failed to remove prefix from origin path"); + let destination = destination.join(partial); + + let link_params = LinkCreateParams { + origin: origin_canonical, + destination, + }; + params.push(link_params); + Ok(()) +} - while let Some(dir_path) = pending.pop() { - for entry in dir_path.read_dir()? { - let entry = entry?; - let filetype = entry.file_type()?; - - if filetype.is_file() && collect_type == FileType::File { - collected.push(entry.path()); - } else if filetype.is_dir() { - if collect_type == FileType::Directory { - collected.push(entry.path()); - } - pending.push(entry.path()); - } - } +fn link_directory_recursive( + depot: &Depot, + dir_path: &Path, + destination: &Path, + base: &Path, + params: &mut Vec, +) -> anyhow::Result<()> { + for origin in dir_path.read_dir()? { + let origin = origin?.path(); + link(depot, &origin, destination, base, params)?; } - - Ok(collected) + Ok(()) } -- cgit