From 92b05a877eb772985d2f4fc9cd198ca642b69b6a Mon Sep 17 00:00:00 2001 From: diogo464 Date: Tue, 8 Feb 2022 09:21:12 +0000 Subject: removed old code --- dotup_cli/Cargo.toml | 29 ------ dotup_cli/src/commands/init.rs | 22 ----- dotup_cli/src/commands/install.rs | 25 ----- dotup_cli/src/commands/link.rs | 134 -------------------------- dotup_cli/src/commands/mod.rs | 11 --- dotup_cli/src/commands/mv.rs | 53 ----------- dotup_cli/src/commands/status.rs | 175 ---------------------------------- dotup_cli/src/commands/uninstall.rs | 26 ------ dotup_cli/src/commands/unlink.rs | 43 --------- dotup_cli/src/config.rs | 10 -- dotup_cli/src/main.rs | 111 ---------------------- dotup_cli/src/utils.rs | 182 ------------------------------------ dotup_cli/tests/cli.rs | 145 ---------------------------- 13 files changed, 966 deletions(-) delete mode 100644 dotup_cli/Cargo.toml delete mode 100644 dotup_cli/src/commands/init.rs delete mode 100644 dotup_cli/src/commands/install.rs delete mode 100644 dotup_cli/src/commands/link.rs delete mode 100644 dotup_cli/src/commands/mod.rs delete mode 100644 dotup_cli/src/commands/mv.rs delete mode 100644 dotup_cli/src/commands/status.rs delete mode 100644 dotup_cli/src/commands/uninstall.rs delete mode 100644 dotup_cli/src/commands/unlink.rs delete mode 100644 dotup_cli/src/config.rs delete mode 100644 dotup_cli/src/main.rs delete mode 100644 dotup_cli/src/utils.rs delete mode 100644 dotup_cli/tests/cli.rs (limited to 'dotup_cli') diff --git a/dotup_cli/Cargo.toml b/dotup_cli/Cargo.toml deleted file mode 100644 index 89b8c27..0000000 --- a/dotup_cli/Cargo.toml +++ /dev/null @@ -1,29 +0,0 @@ -[package] -edition = "2018" -name = "dotup_cli" -version = "0.1.0" - -[[bin]] -name = "dotup" -path = "src/main.rs" -doc = false - -[dependencies] -anyhow = "1.0" -log = "0.4" -ansi_term = "0.12.1" - -[dependencies.clap] -features = ["derive"] -version = "3.0.0-rc.7" - -[dependencies.dotup] -path = "../dotup" - -[dependencies.flexi_logger] -features = ["colors"] -version = "0.22" - -[dev-dependencies] -tempfile = "3.2" -assert_cmd = "2.0" diff --git a/dotup_cli/src/commands/init.rs b/dotup_cli/src/commands/init.rs deleted file mode 100644 index 45129bf..0000000 --- a/dotup_cli/src/commands/init.rs +++ /dev/null @@ -1,22 +0,0 @@ -use super::prelude::*; - -/// Creates an empty depot file if one doesnt already exist. -/// -/// By default this will create the file in the current directory -/// but the --depot flag can be used to change this path. -#[derive(Parser)] -pub struct Opts {} - -pub fn main(config: Config, opts: Opts) -> anyhow::Result<()> { - if !dotup::utils::is_file(&config.archive_path)? { - let archive = Archive::default(); - log::info!("Creating archive at {}", &config.archive_path.display()); - utils::write_archive(&config.archive_path, &archive)?; - } else { - log::warn!( - "Archive file already exists : '{}'", - config.archive_path.display() - ); - } - Ok(()) -} diff --git a/dotup_cli/src/commands/install.rs b/dotup_cli/src/commands/install.rs deleted file mode 100644 index 6d9fbf7..0000000 --- a/dotup_cli/src/commands/install.rs +++ /dev/null @@ -1,25 +0,0 @@ -use std::path::PathBuf; - -use super::prelude::*; - -/// Install links. (Creates symlinks). -/// -/// Installing a link will create the necessary directories. -/// If a file or directory already exists at the location a link would be installed this command will fail. -#[derive(Parser)] -pub struct Opts { - /// The files/directories to install. - #[clap(min_values = 1, default_value = ".")] - paths: Vec, -} - -pub fn main(config: Config, opts: Opts) -> anyhow::Result<()> { - let depot = utils::read_depot(&config.archive_path)?; - - for link in utils::collect_links_by_base_paths(&depot, &opts.paths) { - log::info!("Installing link {}", link); - depot.install_link(link, &config.install_path)?; - } - - Ok(()) -} diff --git a/dotup_cli/src/commands/link.rs b/dotup_cli/src/commands/link.rs deleted file mode 100644 index d1f61ea..0000000 --- a/dotup_cli/src/commands/link.rs +++ /dev/null @@ -1,134 +0,0 @@ -use std::{ - fs::{DirEntry, Metadata}, - path::{Path, PathBuf}, -}; - -use super::prelude::*; - -/// Creates links -/// -/// If a link is created for a file that already had a link then the old link will be overwritten. -/// By default creating a link to a directory will recursively link all files under that -/// directory, to actually link a directory use the --directory flag. -#[derive(Parser)] -pub struct Opts { - /// Treats the paths as directories. This will create links to the actual directories instead - /// of recursively linking all files under them. - #[clap(long)] - directory: bool, - - /// The paths to link. The last path is the destination. - paths: Vec, -} - -// TODO: require destination -// remove else branch -pub fn main(config: Config, opts: Opts) -> anyhow::Result<()> { - let mut depot = utils::read_depot(&config.archive_path)?; - - let (origins, destination) = match opts.paths.as_slice() { - p @ [] | p @ [_] => (p, None), - [o @ .., dest] => (o, Some(dest)), - _ => unreachable!(), - }; - - if let Some(destination) = destination { - let params = if opts.directory { - origins - .iter() - .map(|p| LinkCreateParams { - origin: p.to_path_buf(), - destination: destination.clone(), - }) - .collect() - } else { - let mut params = Vec::new(); - for origin in origins { - generate_link_params(&depot, origin, destination, origin, &mut params)?; - } - params - }; - - for link_params in params { - log::info!("Creating link : {}", link_params); - depot.create_link(link_params)?; - } - } else { - let base_path = match origins { - [] => std::env::current_dir()?, - [path] => path.clone(), - _ => unreachable!(), - }; - - for link in utils::collect_links_by_base_paths(&depot, std::iter::once(base_path)) { - log::info!("{}", link); - } - } - - utils::write_depot(&depot)?; - - Ok(()) -} - -fn generate_link_params( - depot: &Depot, - origin: &Path, - destination: &Path, - base: &Path, - params: &mut Vec, -) -> anyhow::Result<()> { - let metadata = std::fs::metadata(origin)?; - if metadata.is_file() { - generate_file_link_params(depot, origin, destination, base, params)?; - } else if metadata.is_dir() { - generate_directory_link_params_recursive(depot, origin, destination, base, params)?; - } - Ok(()) -} - -fn generate_file_link_params( - 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 origin = origin_canonical - .strip_prefix(depot.base_path()) - .unwrap_or(&origin_canonical); - - let link_params = LinkCreateParams { - origin: origin.to_path_buf(), - destination, - }; - params.push(link_params); - Ok(()) -} - -fn generate_directory_link_params_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(); - generate_link_params(depot, &origin, destination, base, params)?; - } - Ok(()) -} diff --git a/dotup_cli/src/commands/mod.rs b/dotup_cli/src/commands/mod.rs deleted file mode 100644 index bd92599..0000000 --- a/dotup_cli/src/commands/mod.rs +++ /dev/null @@ -1,11 +0,0 @@ -pub mod init; -pub mod install; -pub mod link; -pub mod mv; -pub mod status; -pub mod uninstall; -pub mod unlink; - -mod prelude { - pub use crate::prelude::*; -} diff --git a/dotup_cli/src/commands/mv.rs b/dotup_cli/src/commands/mv.rs deleted file mode 100644 index aae2715..0000000 --- a/dotup_cli/src/commands/mv.rs +++ /dev/null @@ -1,53 +0,0 @@ -use std::path::{Path, PathBuf}; - -use super::prelude::*; - -/// Install links. (Creates symlinks). -/// -/// Installing a link will create the necessary directories. -/// If a file or directory already exists at the location a link would be installed this command will fail. -#[derive(Parser)] -pub struct Opts { - /// The files/directories to move - #[clap(min_values = 2)] - paths: Vec, -} - -pub fn main(config: Config, opts: Opts) -> anyhow::Result<()> { - let mut depot = utils::read_depot(&config.archive_path)?; - - let (sources, destination) = match opts.paths.as_slice() { - [source, destination] => {} - [sources @ .., destination] => { - let mut curr_destination = destination.to_owned(); - for source in sources { - let filename = match source.file_name() { - Some(filename) => filename, - None => { - log::warn!("Ignoring '{}', unknown file name", source.display()); - continue; - } - }; - curr_destination.push(filename); - std::fs::rename(source, &curr_destination)?; - if let Some(id) = depot.get_link_id_by_path(&source) { - depot.rename_link(id, &curr_destination); - } - curr_destination.pop(); - } - } - _ => unreachable!(), - }; - - utils::write_depot(&depot)?; - - Ok(()) -} - -fn rename(depot: &mut Depot, source: &Path, destination: &Path) -> anyhow::Result<()> { - std::fs::rename(source, &destination)?; - if let Some(id) = depot.get_link_id_by_path(&source) { - depot.rename_link(id, &destination); - } - Ok(()) -} diff --git a/dotup_cli/src/commands/status.rs b/dotup_cli/src/commands/status.rs deleted file mode 100644 index b7221db..0000000 --- a/dotup_cli/src/commands/status.rs +++ /dev/null @@ -1,175 +0,0 @@ -use std::path::{Path, PathBuf}; - -use ansi_term::Colour; -use clap::Parser; -use dotup::{Depot, Link}; - -use crate::{utils, Config}; - -/// Shows information about links -/// -/// If a link is created for a file that already had a link then the old link will be overwritten. -/// By default creating a link to a directory will recursively link all files under that -/// directory, to actually link a directory use the --directory flag. -#[derive(Parser)] -pub struct Opts { - /// The location where links will be installed to. - /// Defaults to the home directory. - #[clap(long)] - install_base: Option, - - /// The paths to show the status of - paths: Vec, -} - -#[derive(Debug)] -struct State { - max_depth: u32, - install_path: PathBuf, -} - -pub fn main(config: Config, opts: Opts) -> anyhow::Result<()> { - let mut depot = utils::read_depot(&config.archive_path)?; - - // walk dir - // if node is file: - // if linked - // print name in green and destination blue - // if invalid - // print name and destination red - // if not linked - // print name in gray - // if node is directory: - // if linked - // print name in green and destination blue - // if invalid - // print name and destination red - // if not linked: - // print name in gray - // if contains files that are linked/invalid: - // recurse into directory - // - - let depot_base = depot.base_path(); - let mut paths = Vec::new(); - for path in opts.paths { - let canonical = dotup::utils::weakly_canonical(&path); - if canonical.starts_with(depot_base) { - paths.push(canonical); - } else { - log::warn!("Path '{}' is outside the depot", path.display()); - } - } - - if paths.is_empty() { - paths.push(PathBuf::from(".")); - } - - let state = State { - max_depth: u32::MAX, - install_path: config.install_path, - }; - - let (directories, files) = utils::collect_read_dir_split(".")?; - for path in directories.into_iter().chain(files.into_iter()) { - display_status_path(&depot, &state, &path, 0); - } - - utils::write_depot(&depot)?; - - Ok(()) -} - -fn display_status_path(depot: &Depot, state: &State, path: &Path, depth: u32) { - if depth == state.max_depth { - return; - } - - if path.is_dir() { - display_status_directory(depot, state, path, depth); - } else { - display_status_file(depot, state, path, depth); - } -} - -fn display_status_directory(depot: &Depot, state: &State, path: &Path, depth: u32) { - assert!(path.is_dir()); - if depth == state.max_depth || !depot.subpath_has_links(path) { - return; - } - - if let Some(link) = depot.get_link_by_path(path) { - print_link(depot, state, link, depth); - } else { - for entry in std::fs::read_dir(path).unwrap() { - let entry = match entry { - Ok(entry) => entry, - Err(_) => continue, - }; - let entry_path = entry.path().canonicalize().unwrap(); - let entry_path_stripped = entry_path - .strip_prefix(std::env::current_dir().unwrap()) - .unwrap(); - - print_identation(depth); - println!( - "{}", - Colour::Yellow.paint(&format!("{}", path.file_name().unwrap().to_string_lossy())) - ); - - display_status_path(depot, state, &entry_path_stripped, depth + 1); - } - } -} - -fn display_status_file(depot: &Depot, state: &State, path: &Path, depth: u32) { - print_identation(depth); - if let Some(link) = depot.get_link_by_path(path) { - print_link(depot, state, link, depth); - } else { - print_unlinked(path, depth); - } -} - -fn print_link(depot: &Depot, state: &State, link: &Link, depth: u32) { - let origin = link.origin(); - let dest = link.destination(); - let filename = match origin.file_name() { - Some(filename) => filename, - None => return, - }; - - print_identation(depth); - if depot.is_link_installed(link, &state.install_path) { - println!( - "{} -> {}", - Colour::Green.paint(&format!("{}", filename.to_string_lossy())), - Colour::Blue.paint(&format!("{}", dest.display())), - ); - } else { - println!( - "{}", - Colour::Red.paint(&format!( - "{} -> {}", - filename.to_string_lossy(), - dest.display() - )) - ); - } -} - -fn print_unlinked(path: &Path, depth: u32) { - let filename = match path.file_name() { - Some(filename) => filename, - None => return, - }; - - print_identation(depth); - println!("{}", filename.to_string_lossy()); -} - -fn print_identation(depth: u32) { - for i in 0..depth { - print!(" "); - } -} diff --git a/dotup_cli/src/commands/uninstall.rs b/dotup_cli/src/commands/uninstall.rs deleted file mode 100644 index fe44bf0..0000000 --- a/dotup_cli/src/commands/uninstall.rs +++ /dev/null @@ -1,26 +0,0 @@ -use std::path::PathBuf; - -use super::prelude::*; - -/// Uninstalls links. (Removes symlinks). -/// -/// Uninstalling a link for a file that didnt have a link will do nothing. -/// Uninstalling a directory will recursively uninstall all files under it. -/// Symlinks are only deleted if they were pointing to the correct file. -#[derive(Parser)] -pub struct Opts { - /// The files/directories to uninstall. - #[clap(min_values = 1, default_value = ".")] - paths: Vec, -} - -pub fn main(config: Config, opts: Opts) -> anyhow::Result<()> { - let depot = utils::read_depot(&config.archive_path)?; - - for link in utils::collect_links_by_base_paths(&depot, &opts.paths) { - log::info!("Uninstalling link : {}", link); - depot.uninstall_link(link, &config.install_path)?; - } - - Ok(()) -} diff --git a/dotup_cli/src/commands/unlink.rs b/dotup_cli/src/commands/unlink.rs deleted file mode 100644 index abe23e3..0000000 --- a/dotup_cli/src/commands/unlink.rs +++ /dev/null @@ -1,43 +0,0 @@ -use std::{ - fs::{DirEntry, Metadata}, - path::{Path, PathBuf}, -}; - -use super::prelude::*; - -/// Unlinks files/directories. -/// -/// This will recursively remove links. If a path is a directory then it will remove all links -/// recursively. -/// The links are not uninstall by default, see the --uninstall parameter. -#[derive(Parser)] -pub struct Opts { - /// Specify the install base if the links are also to be uninstalled. - #[clap(long)] - uninstall: Option, - - /// The paths to unlink. - #[clap(required = true, min_values = 1)] - paths: Vec, -} - -pub fn main(config: Config, opts: Opts) -> anyhow::Result<()> { - let mut depot = utils::read_depot(&config.archive_path)?; - - for link_id in utils::collect_link_ids_by_base_paths(&depot, &opts.paths) { - let link = depot.get_link(link_id).unwrap(); - log::info!( - "Unlinking(uninstall = {}) : {}", - opts.uninstall.is_some(), - link - ); - if let Some(ref install_base) = opts.uninstall { - depot.uninstall_link(link, &install_base)?; - } - depot.remove_link(link_id); - } - - utils::write_depot(&depot)?; - - Ok(()) -} diff --git a/dotup_cli/src/config.rs b/dotup_cli/src/config.rs deleted file mode 100644 index dabaf74..0000000 --- a/dotup_cli/src/config.rs +++ /dev/null @@ -1,10 +0,0 @@ -use std::path::PathBuf; - -#[derive(Debug)] -pub struct Config { - pub archive_path: PathBuf, - pub install_path: PathBuf, - pub working_path: PathBuf, -} - -impl Config {} diff --git a/dotup_cli/src/main.rs b/dotup_cli/src/main.rs deleted file mode 100644 index 0d730da..0000000 --- a/dotup_cli/src/main.rs +++ /dev/null @@ -1,111 +0,0 @@ -#![allow(unused)] - -pub mod commands; -pub mod config; -pub mod utils; - -pub use config::Config; - -pub mod prelude { - pub use super::{utils, Config}; - pub use clap::{AppSettings, Parser}; - pub use dotup::{Archive, Depot, DepotConfig, Link, LinkCreateParams, LinkID}; -} - -use clap::{AppSettings, Parser}; -use flexi_logger::Logger; -use std::{ - collections::HashMap, - iter::FromIterator, - path::{Path, PathBuf}, -}; - -use prelude::*; - -#[derive(Parser)] -struct Opts { - /// Path to the depot file. - /// - /// By default it will try to find a file named "depot.toml" in the current directory or any of - /// the parent directories. - #[clap(long)] - depot: Option, - - /// Disable output to the console - #[clap(short, long)] - quiet: bool, - - /// A level of verbosity, and can be used multiple times - /// - /// Level 1 - Info - /// - /// Level 2 - Debug - /// - /// Level 3 - Trace - #[clap(short, long, parse(from_occurrences))] - verbose: i32, - - /// The location where links will be installed to. - /// Defaults to the home directory. - #[clap(short, long)] - install_path: Option, - - #[clap(subcommand)] - subcmd: SubCommand, -} - -#[derive(Parser)] -enum SubCommand { - Init(commands::init::Opts), - Link(commands::link::Opts), - Mv(commands::mv::Opts), - Status(commands::status::Opts), - Unlink(commands::unlink::Opts), - Install(commands::install::Opts), - Uninstall(commands::uninstall::Opts), -} - -fn main() -> anyhow::Result<()> { - let opts = Opts::parse(); - - if !opts.quiet { - let log_level = match opts.verbose { - 0 => "warn", - 1 => "info", - 2 => "debug", - _ => "trace", - }; - - Logger::try_with_env_or_str(log_level)? - .format(flexi_logger::colored_default_format) - .set_palette("196;208;32;198;15".to_string()) - .start()?; - } - - let archive_path = match opts.depot { - Some(path) => path, - None => utils::find_archive_path()?, - }; - let install_path = match opts.install_path { - Some(path) => path, - None => utils::home_directory()?, - }; - let working_path = std::env::current_dir().expect("Failed to obtain current working directory"); - log::debug!("Archive path : {}", archive_path.display()); - - let config = Config { - archive_path, - install_path, - working_path, - }; - - match opts.subcmd { - SubCommand::Init(opts) => commands::init::main(config, opts), - SubCommand::Link(opts) => commands::link::main(config, opts), - SubCommand::Mv(opts) => commands::mv::main(config, opts), - SubCommand::Status(opts) => commands::status::main(config, opts), - SubCommand::Unlink(opts) => commands::unlink::main(config, opts), - SubCommand::Install(opts) => commands::install::main(config, opts), - SubCommand::Uninstall(opts) => commands::uninstall::main(config, opts), - } -} diff --git a/dotup_cli/src/utils.rs b/dotup_cli/src/utils.rs deleted file mode 100644 index b9a76a7..0000000 --- a/dotup_cli/src/utils.rs +++ /dev/null @@ -1,182 +0,0 @@ -use std::{ - collections::VecDeque, - path::{Path, PathBuf}, -}; - -use crate::prelude::*; - -const DEFAULT_DEPOT_NAME: &str = "depot.toml"; - -pub fn home_directory() -> anyhow::Result { - match std::env::var("HOME") { - Ok(val) => Ok(PathBuf::from(val)), - Err(e) => { - log::error!("Failed to get home directory from enviornment variable"); - Err(e.into()) - } - } -} - -pub fn find_archive_path() -> anyhow::Result { - let cwd = std::env::current_dir()?; - let compn = cwd.components().count(); - let mut start = PathBuf::new(); - for _ in 0..=compn { - start.push(DEFAULT_DEPOT_NAME); - if dotup::archive_exists(&start) { - return Ok(start); - } - start.pop(); - start.push(".."); - } - Ok(PathBuf::from(DEFAULT_DEPOT_NAME)) -} - -pub fn write_archive(path: impl AsRef, archive: &Archive) -> anyhow::Result<()> { - let path = path.as_ref(); - log::debug!("Writing archive to {}", path.display()); - match dotup::archive_write(path, archive) { - Ok(_) => Ok(()), - Err(e) => { - log::error!( - "Failed to write archive to : {}\nError : {}", - path.display(), - e - ); - Err(e.into()) - } - } -} - -pub fn write_depot(depot: &Depot) -> anyhow::Result<()> { - let write_path = depot.archive_path(); - let archive = depot.archive(); - match dotup::archive_write(write_path, &archive) { - Ok(_) => Ok(()), - Err(e) => { - log::error!( - "Failed to write depot archive to : {}\nError : {}", - write_path.display(), - e - ); - Err(e.into()) - } - } -} - -pub fn read_archive(path: impl AsRef) -> anyhow::Result { - let path = path.as_ref(); - match dotup::archive_read(path) { - Ok(archive) => Ok(archive), - Err(e) => { - log::error!( - "Failed to read archive from : {}\nError : {}", - path.display(), - e - ); - Err(e.into()) - } - } -} - -pub fn read_depot(archive_path: impl AsRef) -> anyhow::Result { - let archive_path = archive_path.as_ref().to_path_buf(); - let archive = read_archive(&archive_path)?; - let depot_config = DepotConfig { - archive: Default::default(), - archive_path, - }; - let mut depot = Depot::new(depot_config)?; - - for archive_link in archive.links { - let link_params = LinkCreateParams::from(archive_link); - if let Err(e) = depot.create_link(link_params) { - log::warn!("Error while adding link : {}", e); - } - } - - Ok(depot) -} - -pub fn collect_links_by_base_paths( - depot: &Depot, - paths: impl IntoIterator>, -) -> Vec<&Link> { - let canonical_paths: Vec<_> = paths - .into_iter() - .map(|p| p.as_ref().canonicalize().unwrap()) - .collect(); - - depot - .links() - .filter(|&l| { - canonical_paths - .iter() - .any(|p| l.origin_canonical().starts_with(p)) - }) - .collect() -} - -pub fn collect_link_ids_by_base_paths( - depot: &Depot, - paths: impl IntoIterator>, -) -> Vec { - collect_links_by_base_paths(depot, paths) - .into_iter() - .map(|l| l.id()) - .collect() -} - -/// Returns a list of canonical paths to all the files in `dir`. This includes files in -/// subdirectories. -/// Fails if dir isnt a directory or if there is some other io error. -pub fn collect_files_in_dir(dir: impl Into) -> anyhow::Result> { - let mut paths = Vec::new(); - let mut dirs = VecDeque::new(); - dirs.push_back(dir.into()); - - while let Some(dir) = dirs.pop_front() { - for entry in std::fs::read_dir(dir)? { - let entry = entry?; - let filetype = entry.file_type()?; - if filetype.is_dir() { - dirs.push_back(entry.path()); - } else { - paths.push(entry.path()); - } - } - } - - Ok(paths) -} - -/// Collects the result of std::fs::read_dir into two vecs -/// The first one contains all the directories and the second one all the files -pub fn collect_read_dir_split( - dir: impl AsRef, -) -> anyhow::Result<(Vec, Vec)> { - Ok(std::fs::read_dir(dir)? - .filter_map(|e| e.ok()) - .map(|e| e.path()) - .partition(|p| p.is_dir())) -} - -/// Checks if `path` is inside a git repository -pub fn path_is_in_git_repo(path: &Path) -> bool { - let mut path = if !path.is_absolute() { - dbg!(dotup::utils::weakly_canonical(path)) - } else { - path.to_owned() - }; - let recurse = path.pop(); - path.push(".git"); - if path.is_dir() { - return true; - } - if recurse { - path.pop(); - return path_is_in_git_repo(&path); - } else { - return false; - } -} diff --git a/dotup_cli/tests/cli.rs b/dotup_cli/tests/cli.rs deleted file mode 100644 index c836f63..0000000 --- a/dotup_cli/tests/cli.rs +++ /dev/null @@ -1,145 +0,0 @@ -use assert_cmd::{assert::Assert, prelude::*}; -use dotup::ArchiveLink; -use std::{ - path::{Path, PathBuf}, - process::Command, -}; -use tempfile::TempDir; - -const DEPOT_FILE_NAME: &str = "depot.toml"; -const BIN_NAME: &str = "dotup"; - -fn create_empty_file(path: impl AsRef) { - let path = path.as_ref(); - if let Some(parent) = path.parent() { - std::fs::create_dir_all(parent).unwrap(); - } - std::fs::write(path, "").unwrap(); -} - -fn prepare_command(dir: &TempDir) -> Command { - let mut cmd = Command::cargo_bin(BIN_NAME).unwrap(); - cmd.current_dir(dir.path()); - cmd -} - -fn run_command(dir: &TempDir, cmd: &str) -> Assert { - let mut c = prepare_command(dir); - c.current_dir(dir.path()); - c.args(cmd.split_whitespace()); - c.assert() -} - -fn prepare_dir() -> TempDir { - let dir = TempDir::new().unwrap(); - create_empty_file(dir.path().join("o1/file.txt")); - create_empty_file(dir.path().join("o1/dir/file.txt")); - create_empty_file(dir.path().join("o2/file1.txt")); - create_empty_file(dir.path().join("o2/file2.txt")); - dir -} - -#[test] -fn test_cli_init() { - let dir = prepare_dir(); - let assert = run_command(&dir, "init"); - - assert.success().code(0); - assert!(dir.path().join(DEPOT_FILE_NAME).is_file()); -} - -#[test] -fn test_cli_link() { - let dir = prepare_dir(); - run_command(&dir, "init").success(); - - let assert = run_command(&dir, "link o1 .config"); - assert.success().code(0); - - let assert = run_command(&dir, "link --directory o2 .scripts"); - assert.success().code(0); - - let archive = dotup::archive_read(dir.path().join(DEPOT_FILE_NAME)).unwrap(); - let link1 = ArchiveLink { - origin: PathBuf::from("o1/file.txt"), - destination: PathBuf::from(".config/file.txt"), - }; - let link2 = ArchiveLink { - origin: PathBuf::from("o1/dir/file.txt"), - destination: PathBuf::from(".config/dir/file.txt"), - }; - let link3 = ArchiveLink { - origin: PathBuf::from("o2"), - destination: PathBuf::from(".scripts"), - }; - - assert!(archive.links.contains(&link1)); - assert!(archive.links.contains(&link2)); - assert!(archive.links.contains(&link3)); -} - -#[test] -fn test_cli_install_uninstall_unlink() { - let dir = prepare_dir(); - run_command(&dir, "init").success(); - run_command(&dir, "link o1 .config").success(); - run_command(&dir, "link --directory o2 .scripts").success(); - - let install_dir = TempDir::new().unwrap(); - let install_base = format!("{}", install_dir.path().display()); - run_command( - &dir, - &format!("--install-path {} install o1 o2", install_base), - ) - .success(); - - assert_eq!( - std::fs::read_link(install_dir.path().join(".config/file.txt")).unwrap(), - dir.path().join("o1/file.txt") - ); - assert_eq!( - std::fs::read_link(install_dir.path().join(".config/dir/file.txt")).unwrap(), - dir.path().join("o1/dir/file.txt") - ); - assert_eq!( - std::fs::read_link(install_dir.path().join(".scripts")).unwrap(), - dir.path().join("o2") - ); - - run_command( - &dir, - &format!("--install-path {} uninstall o1/file.txt", install_base), - ) - .success(); - assert!(!install_dir.path().join(".config/file.txt").exists()); - assert!(install_dir.path().join(".config/dir/file.txt").exists()); - assert!(install_dir.path().join(".scripts").exists()); - - run_command( - &dir, - &format!("--install-path {} uninstall o1", install_base), - ) - .success(); - assert!(!install_dir.path().join(".config/file.txt").exists()); - assert!(!install_dir.path().join(".config/dir/file.txt").exists()); - assert!(install_dir.path().join(".scripts").exists()); - - assert_eq!( - 3, - dotup::archive_read(dir.path().join(DEPOT_FILE_NAME)) - .unwrap() - .links - .len() - ); - - run_command(&dir, &format!("unlink --uninstall {} o2", install_base)).success(); - assert!(!install_dir.path().join(".scripts").exists()); - - assert_eq!( - 2, - dotup::archive_read(dir.path().join(DEPOT_FILE_NAME)) - .unwrap() - .links - .len() - ); -} -- cgit