From 0992c36733f58750da93921041424fd09f0158ed Mon Sep 17 00:00:00 2001 From: diogo464 Date: Tue, 8 Feb 2022 09:19:19 +0000 Subject: snapshot before removal --- dotup_cli/src/commands/mod.rs | 1 + dotup_cli/src/commands/mv.rs | 53 +++++++++++++++++++++++++++++++++++++++++++ dotup_cli/src/config.rs | 3 +++ dotup_cli/src/main.rs | 4 ++++ dotup_cli/src/utils.rs | 20 ++++++++++++++++ 5 files changed, 81 insertions(+) create mode 100644 dotup_cli/src/commands/mv.rs (limited to 'dotup_cli/src') diff --git a/dotup_cli/src/commands/mod.rs b/dotup_cli/src/commands/mod.rs index 94dc3fd..bd92599 100644 --- a/dotup_cli/src/commands/mod.rs +++ b/dotup_cli/src/commands/mod.rs @@ -1,6 +1,7 @@ pub mod init; pub mod install; pub mod link; +pub mod mv; pub mod status; pub mod uninstall; pub mod unlink; diff --git a/dotup_cli/src/commands/mv.rs b/dotup_cli/src/commands/mv.rs new file mode 100644 index 0000000..aae2715 --- /dev/null +++ b/dotup_cli/src/commands/mv.rs @@ -0,0 +1,53 @@ +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/config.rs b/dotup_cli/src/config.rs index 2046ad5..dabaf74 100644 --- a/dotup_cli/src/config.rs +++ b/dotup_cli/src/config.rs @@ -4,4 +4,7 @@ use std::path::PathBuf; 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 index 6161ca7..0d730da 100644 --- a/dotup_cli/src/main.rs +++ b/dotup_cli/src/main.rs @@ -58,6 +58,7 @@ struct Opts { 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), @@ -89,16 +90,19 @@ fn main() -> anyhow::Result<()> { 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), diff --git a/dotup_cli/src/utils.rs b/dotup_cli/src/utils.rs index be9f3a9..b9a76a7 100644 --- a/dotup_cli/src/utils.rs +++ b/dotup_cli/src/utils.rs @@ -160,3 +160,23 @@ pub fn collect_read_dir_split( .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; + } +} -- cgit