From b90697486de1ce6ea45091c50a0b6f7bd6b253fe Mon Sep 17 00:00:00 2001 From: r0r-5chach Date: Mon, 1 Jan 2024 14:59:32 +0000 Subject: [PATCH] improved command interface --- Cargo.lock | 60 ++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 5 ++-- config.json | 3 +-- src/bin/collect.rs | 3 --- src/bin/main.rs | 10 ++++++++ src/collect.rs | 19 +++++++-------- src/config.rs | 35 +++++++++++++++++++++------ src/errors.rs | 4 ++++ src/install.rs | 8 +++++-- 9 files changed, 120 insertions(+), 27 deletions(-) delete mode 100644 src/bin/collect.rs create mode 100644 src/bin/main.rs diff --git a/Cargo.lock b/Cargo.lock index 0350b2b..9b0dd42 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -96,6 +96,15 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "copy_dir" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "543d1dd138ef086e2ff05e3a48cf9da045da2033d16f8538fd76b86cd49b2ca3" +dependencies = [ + "walkdir", +] + [[package]] name = "heck" version = "0.4.1" @@ -131,6 +140,7 @@ name = "rusty-dotfiles" version = "0.1.0" dependencies = [ "clap", + "copy_dir", "serde_json", ] @@ -140,6 +150,15 @@ version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "serde" version = "1.0.193" @@ -200,6 +219,47 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-sys" version = "0.52.0" diff --git a/Cargo.toml b/Cargo.toml index 76a6254..18a85a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,8 +8,9 @@ publish = ["gitea"] [dependencies] clap = { version = "4.4.12", features = ["derive"] } +copy_dir = "0.1.3" serde_json = "1.0.108" [[bin]] -name = "dotfiles-collect" -path = "src/bin/collect.rs" +name = "dotfiles" +path = "src/bin/main.rs" diff --git a/config.json b/config.json index c0b364e..1dd3c6f 100644 --- a/config.json +++ b/config.json @@ -51,8 +51,7 @@ {"systemd": [ {"user": ["spotifyd.service"]} ]}, - "nvim", - {".vpn": ["templates"]} + "nvim" ]} ]} ]} diff --git a/src/bin/collect.rs b/src/bin/collect.rs deleted file mode 100644 index 56d008b..0000000 --- a/src/bin/collect.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - rusty_dotfiles::collect::run(); -} diff --git a/src/bin/main.rs b/src/bin/main.rs new file mode 100644 index 0000000..e8916f4 --- /dev/null +++ b/src/bin/main.rs @@ -0,0 +1,10 @@ +fn main() { + use clap::Parser; + use rusty_dotfiles::config; + + let args = config::Args::parse(); + match args.cmd { + config::Commands::Collect => rusty_dotfiles::collect::run(&args), + config::Commands::Install{ .. } => rusty_dotfiles::install::run(&args), + }; +} diff --git a/src/collect.rs b/src/collect.rs index 100d4e7..34ceb8d 100644 --- a/src/collect.rs +++ b/src/collect.rs @@ -1,8 +1,7 @@ -pub fn run() { - use clap::Parser; - - let args = super::Args::parse(); - let mut config = super::Config::new(args); +use crate::config; +///TODO: Docs +pub fn run(args: &config::Args) { + let mut config = config::Config::new(args); config.run(); @@ -11,13 +10,13 @@ pub fn run() { destination.push_str(path.as_str()); match path.chars().last() { - Some('/') => create_dir(&config.destination_path), + Some('/') => create_dir(&destination), Some(_) => copy_file(path.as_str(), &destination), None => super::errors::empty_path_error(), } }); } - +///TODO: Docs fn create_dir(destination: &str) { use std::fs; @@ -26,11 +25,9 @@ fn create_dir(destination: &str) { Err(_) => super::errors::create_dir_error(&destination), } } - +///TODO: Docs fn copy_file(path: &str, destination: &str) { - use std::fs; - - match fs::copy(path, &destination) { + match copy_dir::copy_dir(path, &destination) { Ok(_) => (), Err(_) => super::errors::copy_file_error(path), } diff --git a/src/config.rs b/src/config.rs index 8493097..8dda5b6 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,6 @@ -use clap::Parser; -/// Defines the arguments passed to the program. +use crate::errors; +use clap::{Parser, Subcommand}; +/// CLI utility to help with managing user dotfiles. /// /// # Examples /// @@ -13,14 +14,31 @@ use clap::Parser; #[command(author, version, about, long_about = None)] pub struct Args { /// The file path to the config file - #[arg(short, long, default_value = "config.json")] + #[arg(short, long = "config", default_value = "config.json")] pub config_file_path: String, /// The path to the directory to do work in - #[arg(short, long, default_value = "~/dotfiles")] + #[arg(short, long = "destination", default_value = "~/dotfiles")] pub destination_dir_path: String, /// Whether to treat the user's home folder as their username or "$USER" #[arg(short, long, default_value_t = false)] pub use_username: bool, + /// The command to be ran + #[command(subcommand)] + pub cmd: Commands, +} +#[derive(Subcommand, Debug)] +pub enum Commands { + /// Collect files into a destination file + Collect, + /// Installs dotfiles from a git url. + /// + /// The repo either needs to have: + /// 1)a config contained in the root directory + /// 2)a config written to match the file structure of the repo + Install { + #[arg(required = true)] + url: String, + }, } /// The root of a Linux System const ROOT: &str = "/"; @@ -42,7 +60,7 @@ impl Config { /// /// # Arguments /// - /// * `config_file_path` - The file path to the config file + /// * `args` - The arguments parsed from the command called /// /// # Examples /// @@ -50,7 +68,7 @@ impl Config { /// let config = Config::new("config.json"); /// assert_eq!(ROOT, config.root); /// ``` - pub fn new(args: Args) -> Self { + pub fn new(args: &Args) -> Self { let root = "/"; let paths = vec![root.to_string()]; let config = parse_config(&args.config_file_path); @@ -60,7 +78,7 @@ impl Config { config, root: root.to_string(), use_username: args.use_username, - destination_path: args.destination_dir_path, + destination_path: args.destination_dir_path.to_string(), } } /// Initializes the Config instance @@ -83,6 +101,7 @@ impl Config { /// # Arguments /// /// * `json_file_tree` - The file_tree of paths to generate as a JSON Object + /// * `current_root` - The current operating directory path fn generate_paths(&mut self, json_file_tree: &serde_json::Value, current_root: &mut String) { match json_file_tree { @@ -128,6 +147,7 @@ impl Config { self.generate_paths(dir, &mut current_root) ); } + /// Parses a file from a JSON String /// /// # Arguments @@ -188,6 +208,7 @@ fn read_file_from_path(file_path: &str) -> String { }, } } +///TODO: Docs fn convert_if_user_folder(dirname: &str, want_username: bool) -> String { use std::env; diff --git a/src/errors.rs b/src/errors.rs index 3b36b3d..8d09b17 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,13 +1,17 @@ +///TODO: Docs pub fn json_parsing_error() -> ! { eprintln!("Error parsing JSON String. Check to see if your syntax is valid."); std::process::exit(1) } +///TODO: Docs pub fn create_dir_error(dir: &str) { eprintln!("There was an issue creating the directory {}. It may already exist.", dir); } +///TODO: Docs pub fn copy_file_error(path: &str) { eprintln!("There was an issue copying the path {}", path); } +///TODO: Docs pub fn empty_path_error() { eprintln!("A path seems to be empty"); } diff --git a/src/install.rs b/src/install.rs index 0d53590..3bfb582 100644 --- a/src/install.rs +++ b/src/install.rs @@ -1,4 +1,8 @@ - //TODO: mod install +use crate::config; + +//TODO: mod install //TODO: clone dotfiles //TODO: copy dotfiles to location in config - +pub fn run(args: &config::Args) { + () +}