From 406a3e662b3fafd73ab72a6f7bd4e22131654dfb Mon Sep 17 00:00:00 2001 From: diogo464 Date: Mon, 7 Feb 2022 15:45:21 +0000 Subject: snapshot --- Cargo.lock | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 2 + src/main.rs | 77 ++++++++++++++++++++++++++----------- 3 files changed, 181 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 835a197..c005523 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + [[package]] name = "ansi_term" version = "0.12.1" @@ -40,6 +49,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "clap" version = "3.0.14" @@ -77,11 +92,36 @@ dependencies = [ "ansi_term", "anyhow", "clap", + "flexi_logger", + "log", "serde", "slotmap", "toml", ] +[[package]] +name = "flexi_logger" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "969940c39bc718475391e53a3a59b0157e64929c80cf83ad5dde5f770ecdc423" +dependencies = [ + "ansi_term", + "atty", + "glob", + "lazy_static", + "log", + "regex", + "rustversion", + "thiserror", + "time", +] + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + [[package]] name = "hashbrown" version = "0.11.2" @@ -113,6 +153,12 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + [[package]] name = "lazy_static" version = "1.4.0" @@ -125,12 +171,30 @@ version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + [[package]] name = "memchr" version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +[[package]] +name = "num_threads" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97ba99ba6393e2c3734791401b66902d981cb03bf190af674ca69949b6d5fb15" +dependencies = [ + "libc", +] + [[package]] name = "os_str_bytes" version = "6.0.0" @@ -182,6 +246,29 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "rustversion" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" + [[package]] name = "serde" version = "1.0.136" @@ -243,6 +330,44 @@ version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" +[[package]] +name = "thiserror" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "time" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "004cbc98f30fa233c61a38bc77e96a9106e65c88f2d3bef182ae952027e5753d" +dependencies = [ + "itoa", + "libc", + "num_threads", + "time-macros", +] + +[[package]] +name = "time-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25eb0ca3468fc0acc11828786797f6ef9aa1555e4a211a60d64cc8e4d1be47d6" + [[package]] name = "toml" version = "0.5.8" diff --git a/Cargo.toml b/Cargo.toml index ea24a57..b7a73a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,8 @@ edition = "2021" ansi_term = "0.12.1" anyhow = "1.0.53" clap = { version = "3.0.14", features = ["derive"] } +flexi_logger = "0.22.3" +log = "0.4.14" serde = { version = "1.0.136", features = ["derive"] } slotmap = "1.0.6" toml = "0.5.8" diff --git a/src/main.rs b/src/main.rs index 1cb68d4..f623450 100644 --- a/src/main.rs +++ b/src/main.rs @@ -923,7 +923,7 @@ pub mod dotup { pub fn link(&mut self, origin: impl AsRef, destination: impl AsRef) { let link_result: anyhow::Result<()> = try { - let origin = self.prepare_origin_path(origin.as_ref())?; + let origin = self.prepare_relative_path(origin.as_ref())?; let destination = destination.as_ref(); self.depot.link_create(origin, destination)?; }; @@ -936,7 +936,7 @@ pub mod dotup { pub fn unlink(&mut self, paths: impl Iterator>) { for origin in paths { let unlink_result: anyhow::Result<()> = try { - let origin = self.prepare_origin_path(origin.as_ref())?; + let origin = self.prepare_relative_path(origin.as_ref())?; let search_results = self.depot.link_search(&origin)?; match search_results { depot::SearchResult::Found(link_id) => { @@ -959,7 +959,7 @@ pub mod dotup { let mut already_linked: HashSet = Default::default(); for origin in paths { let install_result: anyhow::Result<()> = try { - let origin = self.prepare_origin_path(origin.as_ref())?; + let origin = self.prepare_relative_path(origin.as_ref())?; let canonical_pairs = self.canonical_pairs_under(&origin)?; for pair in canonical_pairs { if already_linked.contains(&pair.link_id) { @@ -978,7 +978,7 @@ pub mod dotup { pub fn uninstall(&self, paths: impl Iterator>) { for origin in paths { let uninstall_result: anyhow::Result<()> = try { - let origin = self.prepare_origin_path(origin.as_ref())?; + let origin = self.prepare_relative_path(origin.as_ref())?; let canonical_pairs = self.canonical_pairs_under(&origin)?; for pair in canonical_pairs { self.symlink_uninstall(&pair.origin, &pair.destination)?; @@ -1001,7 +1001,7 @@ pub mod dotup { let origins = { let mut v = Vec::new(); for origin in origins { - match self.prepare_origin_path(origin.as_ref()) { + match self.prepare_relative_path(origin.as_ref()) { Ok(origin) => v.push(origin), Err(e) => { println!("invalid link {} : {e}", origin.as_ref().display()); @@ -1066,7 +1066,7 @@ pub mod 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_origin_path(&canonical_path)?; + let relative_path = self.prepare_relative_path(&canonical_path)?; let item = if canonical_path.is_dir() { if let Some(link_id) = self.depot.link_find(&relative_path)? { @@ -1204,7 +1204,7 @@ pub mod dotup { .unwrap_or_default() } - fn prepare_origin_path(&self, origin: &Path) -> anyhow::Result { + fn prepare_relative_path(&self, origin: &Path) -> anyhow::Result { let canonical = utils::weakly_canonical(origin); let relative = canonical .strip_prefix(&self.depot_dir) @@ -1214,7 +1214,7 @@ pub mod dotup { // returns the canonical pairs for all links under `path`. fn canonical_pairs_under(&self, path: &Path) -> anyhow::Result> { - let origin = self.prepare_origin_path(path)?; + let origin = self.prepare_relative_path(path)?; let mut canonical_pairs = Vec::new(); for link_id in self.depot.links_under(origin)? { canonical_pairs.push(self.canonical_pair_from_link_id(link_id)); @@ -1250,11 +1250,19 @@ pub mod dotup { fn symlink_install(&self, origin: &Path, destination: &Path) -> anyhow::Result<()> { debug_assert!(origin.is_absolute()); debug_assert!(destination.is_absolute()); + log::debug!( + "symlink_install : {} -> {}", + origin.display(), + destination.display() + ); - if let Some(destination_parent) = destination.parent() { - std::fs::create_dir_all(destination_parent) - .context("Failed to create directories")?; - } + let destination_parent = destination + .parent() + .ok_or_else(|| anyhow::anyhow!("destination has no parent component"))?; + std::fs::create_dir_all(destination_parent).context("Failed to create directories")?; + // need to do this beacause if the destination path ends in '/' because the symlink + // functions will treat it as a directory but we want a file with that name. + let destination = destination.with_file_name(destination.file_name().unwrap()); let destination_exists = destination.exists(); let destination_is_symlink = destination.is_symlink(); @@ -1264,9 +1272,16 @@ pub mod dotup { } if destination_is_symlink { + log::debug!("symlink already exists, removing before recreating"); std::fs::remove_file(&destination)?; } - std::os::unix::fs::symlink(origin, destination).context("Failed to create symlink")?; + + log::debug!( + "creating filesystem symlink {} -> {}", + origin.display(), + destination.display() + ); + std::os::unix::fs::symlink(origin, destination).context("failed to create symlink")?; Ok(()) } @@ -1274,6 +1289,7 @@ pub mod dotup { fn symlink_uninstall(&self, origin: &Path, destination: &Path) -> anyhow::Result<()> { debug_assert!(origin.is_absolute()); debug_assert!(destination.is_absolute()); + let destination = destination.with_file_name(destination.file_name().unwrap()); if destination.is_symlink() { let symlink_destination = destination.read_link()?.canonicalize()?; @@ -1329,16 +1345,6 @@ mod utils { pub const DEFAULT_DEPOT_FILE_NAME: &str = ".depot"; - /// 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(collect_paths_in_dir(dir)? - .into_iter() - .partition(|p| p.is_dir())) - } - pub fn collect_paths_in_dir(dir: impl AsRef) -> anyhow::Result> { Ok(std::fs::read_dir(dir)? .filter_map(|e| e.ok()) @@ -1465,6 +1471,7 @@ mod utils { use std::path::PathBuf; use clap::Parser; +use flexi_logger::Logger; use utils::DEFAULT_DEPOT_FILE_NAME; #[derive(Parser, Debug)] @@ -1478,8 +1485,19 @@ pub struct Flags { #[derive(Parser, Debug)] #[clap(author, version, about, long_about = None)] struct Args { + /// 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, + #[clap(flatten)] flags: Flags, + #[clap(subcommand)] command: SubCommand, } @@ -1497,6 +1515,19 @@ enum SubCommand { fn main() -> anyhow::Result<()> { let args = Args::parse(); + + let log_level = match args.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()?; + match args.command { SubCommand::Init(cmd_args) => command_init(args.flags, cmd_args), SubCommand::Link(cmd_args) => command_link(args.flags, cmd_args), -- cgit