diff options
| -rw-r--r-- | dotup/src/depot.rs | 18 | ||||
| -rw-r--r-- | dotup_cli/src/commands/mod.rs | 1 | ||||
| -rw-r--r-- | dotup_cli/src/commands/mv.rs | 53 | ||||
| -rw-r--r-- | dotup_cli/src/config.rs | 3 | ||||
| -rw-r--r-- | dotup_cli/src/main.rs | 4 | ||||
| -rw-r--r-- | dotup_cli/src/utils.rs | 20 |
6 files changed, 99 insertions, 0 deletions
diff --git a/dotup/src/depot.rs b/dotup/src/depot.rs index c8801b9..658c0f6 100644 --- a/dotup/src/depot.rs +++ b/dotup/src/depot.rs | |||
| @@ -194,6 +194,24 @@ impl Depot { | |||
| 194 | None | 194 | None |
| 195 | } | 195 | } |
| 196 | 196 | ||
| 197 | pub fn rename_link(&mut self, link_id: LinkID, origin: &Path) { | ||
| 198 | // TODO: improve | ||
| 199 | if let Some(id) = self.get_link_id_by_path(origin) { | ||
| 200 | if link_id != id { | ||
| 201 | self.remove_link(id); | ||
| 202 | } | ||
| 203 | } | ||
| 204 | if let Some(link) = self.links.get_mut(link_id) { | ||
| 205 | let origin_canonical = utils::weakly_canonical(origin); | ||
| 206 | if !origin_canonical.starts_with(&self.base_path) { | ||
| 207 | panic!("new origin outside depot"); | ||
| 208 | } | ||
| 209 | |||
| 210 | link.origin = origin_canonical; | ||
| 211 | link.origin_canonical = utils::weakly_canonical(&link.origin); | ||
| 212 | } | ||
| 213 | } | ||
| 214 | |||
| 197 | /// checks if there are any linked files/directories under the path `path` | 215 | /// checks if there are any linked files/directories under the path `path` |
| 198 | /// if `path` is a path to a file and that file is linked then this function returns true | 216 | /// if `path` is a path to a file and that file is linked then this function returns true |
| 199 | pub fn subpath_has_links(&self, path: &Path) -> bool { | 217 | pub fn subpath_has_links(&self, path: &Path) -> bool { |
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 @@ | |||
| 1 | pub mod init; | 1 | pub mod init; |
| 2 | pub mod install; | 2 | pub mod install; |
| 3 | pub mod link; | 3 | pub mod link; |
| 4 | pub mod mv; | ||
| 4 | pub mod status; | 5 | pub mod status; |
| 5 | pub mod uninstall; | 6 | pub mod uninstall; |
| 6 | pub mod unlink; | 7 | 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 @@ | |||
| 1 | use std::path::{Path, PathBuf}; | ||
| 2 | |||
| 3 | use super::prelude::*; | ||
| 4 | |||
| 5 | /// Install links. (Creates symlinks). | ||
| 6 | /// | ||
| 7 | /// Installing a link will create the necessary directories. | ||
| 8 | /// If a file or directory already exists at the location a link would be installed this command will fail. | ||
| 9 | #[derive(Parser)] | ||
| 10 | pub struct Opts { | ||
| 11 | /// The files/directories to move | ||
| 12 | #[clap(min_values = 2)] | ||
| 13 | paths: Vec<PathBuf>, | ||
| 14 | } | ||
| 15 | |||
| 16 | pub fn main(config: Config, opts: Opts) -> anyhow::Result<()> { | ||
| 17 | let mut depot = utils::read_depot(&config.archive_path)?; | ||
| 18 | |||
| 19 | let (sources, destination) = match opts.paths.as_slice() { | ||
| 20 | [source, destination] => {} | ||
| 21 | [sources @ .., destination] => { | ||
| 22 | let mut curr_destination = destination.to_owned(); | ||
| 23 | for source in sources { | ||
| 24 | let filename = match source.file_name() { | ||
| 25 | Some(filename) => filename, | ||
| 26 | None => { | ||
| 27 | log::warn!("Ignoring '{}', unknown file name", source.display()); | ||
| 28 | continue; | ||
| 29 | } | ||
| 30 | }; | ||
| 31 | curr_destination.push(filename); | ||
| 32 | std::fs::rename(source, &curr_destination)?; | ||
| 33 | if let Some(id) = depot.get_link_id_by_path(&source) { | ||
| 34 | depot.rename_link(id, &curr_destination); | ||
| 35 | } | ||
| 36 | curr_destination.pop(); | ||
| 37 | } | ||
| 38 | } | ||
| 39 | _ => unreachable!(), | ||
| 40 | }; | ||
| 41 | |||
| 42 | utils::write_depot(&depot)?; | ||
| 43 | |||
| 44 | Ok(()) | ||
| 45 | } | ||
| 46 | |||
| 47 | fn rename(depot: &mut Depot, source: &Path, destination: &Path) -> anyhow::Result<()> { | ||
| 48 | std::fs::rename(source, &destination)?; | ||
| 49 | if let Some(id) = depot.get_link_id_by_path(&source) { | ||
| 50 | depot.rename_link(id, &destination); | ||
| 51 | } | ||
| 52 | Ok(()) | ||
| 53 | } | ||
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; | |||
| 4 | pub struct Config { | 4 | pub struct Config { |
| 5 | pub archive_path: PathBuf, | 5 | pub archive_path: PathBuf, |
| 6 | pub install_path: PathBuf, | 6 | pub install_path: PathBuf, |
| 7 | pub working_path: PathBuf, | ||
| 7 | } | 8 | } |
| 9 | |||
| 10 | 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 { | |||
| 58 | enum SubCommand { | 58 | enum SubCommand { |
| 59 | Init(commands::init::Opts), | 59 | Init(commands::init::Opts), |
| 60 | Link(commands::link::Opts), | 60 | Link(commands::link::Opts), |
| 61 | Mv(commands::mv::Opts), | ||
| 61 | Status(commands::status::Opts), | 62 | Status(commands::status::Opts), |
| 62 | Unlink(commands::unlink::Opts), | 63 | Unlink(commands::unlink::Opts), |
| 63 | Install(commands::install::Opts), | 64 | Install(commands::install::Opts), |
| @@ -89,16 +90,19 @@ fn main() -> anyhow::Result<()> { | |||
| 89 | Some(path) => path, | 90 | Some(path) => path, |
| 90 | None => utils::home_directory()?, | 91 | None => utils::home_directory()?, |
| 91 | }; | 92 | }; |
| 93 | let working_path = std::env::current_dir().expect("Failed to obtain current working directory"); | ||
| 92 | log::debug!("Archive path : {}", archive_path.display()); | 94 | log::debug!("Archive path : {}", archive_path.display()); |
| 93 | 95 | ||
| 94 | let config = Config { | 96 | let config = Config { |
| 95 | archive_path, | 97 | archive_path, |
| 96 | install_path, | 98 | install_path, |
| 99 | working_path, | ||
| 97 | }; | 100 | }; |
| 98 | 101 | ||
| 99 | match opts.subcmd { | 102 | match opts.subcmd { |
| 100 | SubCommand::Init(opts) => commands::init::main(config, opts), | 103 | SubCommand::Init(opts) => commands::init::main(config, opts), |
| 101 | SubCommand::Link(opts) => commands::link::main(config, opts), | 104 | SubCommand::Link(opts) => commands::link::main(config, opts), |
| 105 | SubCommand::Mv(opts) => commands::mv::main(config, opts), | ||
| 102 | SubCommand::Status(opts) => commands::status::main(config, opts), | 106 | SubCommand::Status(opts) => commands::status::main(config, opts), |
| 103 | SubCommand::Unlink(opts) => commands::unlink::main(config, opts), | 107 | SubCommand::Unlink(opts) => commands::unlink::main(config, opts), |
| 104 | SubCommand::Install(opts) => commands::install::main(config, opts), | 108 | 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( | |||
| 160 | .map(|e| e.path()) | 160 | .map(|e| e.path()) |
| 161 | .partition(|p| p.is_dir())) | 161 | .partition(|p| p.is_dir())) |
| 162 | } | 162 | } |
| 163 | |||
| 164 | /// Checks if `path` is inside a git repository | ||
| 165 | pub fn path_is_in_git_repo(path: &Path) -> bool { | ||
| 166 | let mut path = if !path.is_absolute() { | ||
| 167 | dbg!(dotup::utils::weakly_canonical(path)) | ||
| 168 | } else { | ||
| 169 | path.to_owned() | ||
| 170 | }; | ||
| 171 | let recurse = path.pop(); | ||
| 172 | path.push(".git"); | ||
| 173 | if path.is_dir() { | ||
| 174 | return true; | ||
| 175 | } | ||
| 176 | if recurse { | ||
| 177 | path.pop(); | ||
| 178 | return path_is_in_git_repo(&path); | ||
| 179 | } else { | ||
| 180 | return false; | ||
| 181 | } | ||
| 182 | } | ||
