From 608cd3983765502eaf2ec6aaeb62f32332796ca1 Mon Sep 17 00:00:00 2001 From: Simmer505 Date: Tue, 30 Jan 2024 21:50:04 -0600 Subject: [PATCH] Started adding error handling, fixed directories not being created if they do not exist, added config file --- Cargo.toml | 1 + src/args/mod.rs | 18 ++++++++ src/config_file/mod.rs | 47 +++++++++++++++++++ src/lib.rs | 96 ++++++++------------------------------- src/main.rs | 13 ++++-- src/program_config/mod.rs | 57 +++++++++++++++++++++++ 6 files changed, 153 insertions(+), 79 deletions(-) create mode 100644 src/args/mod.rs create mode 100644 src/config_file/mod.rs create mode 100644 src/program_config/mod.rs diff --git a/Cargo.toml b/Cargo.toml index 3270a89..48e67b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,4 @@ edition = "2021" [dependencies] clap='4.4.*' +toml='0.8.*' diff --git a/src/args/mod.rs b/src/args/mod.rs new file mode 100644 index 0000000..e5cffcd --- /dev/null +++ b/src/args/mod.rs @@ -0,0 +1,18 @@ +use clap::{Arg, Command, ArgAction, ArgMatches}; + + +pub fn parse_args() -> ArgMatches { + + let matches = Command::new("dotfiles") + .version("0.1") + .author("Ethan Simmons") + .about("Manages dotfiles") + .arg(Arg::new("from-git") + .short('f') + .long("from-git") + .action(ArgAction::SetTrue) + ) + .get_matches(); + + matches +} diff --git a/src/config_file/mod.rs b/src/config_file/mod.rs new file mode 100644 index 0000000..4ecf44b --- /dev/null +++ b/src/config_file/mod.rs @@ -0,0 +1,47 @@ +use std::path::PathBuf; +use std::error::Error; +use std::env; +use std::fs; + +use crate::copy_directory; + +pub struct ConfigFile { + pub manager_path: PathBuf, + pub system_path: PathBuf, + is_dir: bool, +} + + +impl ConfigFile { + pub fn new(rel_git_location: PathBuf, sys_location: PathBuf) -> Result> { + + let home_dir = PathBuf::from(env::var("HOME").expect("$HOME not set")); + let manager_dir = home_dir.join(".dotfiles/"); + + let manager_path = manager_dir.join(rel_git_location); + let system_path = sys_location; + + let is_dir = fs::metadata(&manager_path)?.is_dir(); + + Ok(Self { manager_path, system_path, is_dir }) + } + + pub fn copy_config(&self, to_sys: bool) -> Result<(), Box> { + + let (curr, dest) = if to_sys { + (&self.manager_path, &self.system_path) + } else { + (&self.system_path, &self.manager_path) + }; + + if !self.is_dir { + println!("Copying file"); + fs::copy(curr, dest)?; + Ok(()) + } else { + println!("Starting Copy Dir"); + copy_directory(curr, dest)?; + Ok(()) + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 1d4ddfa..a61b0bf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,74 +1,17 @@ use std::fs; -use std::path::PathBuf; -use std::env; +use std::path::{self, PathBuf}; use std::error::Error; -use clap::{Arg, Command, ArgAction, ArgMatches}; +use clap::ArgMatches; -pub struct Config { - git_location: PathBuf, - sys_location: PathBuf, - is_dir: bool, -} - -impl Config { - pub fn new(rel_git_location: &str, sys_location: &str) -> Result> { - - let home_dir = PathBuf::from(env::var("HOME").expect("$HOME not set")); - let manager_dir = home_dir.join(".dotfiles/"); - - let git_location = manager_dir.join(rel_git_location); - let sys_location = PathBuf::from(sys_location); - - let is_dir = fs::metadata(&git_location)?.is_dir(); - - Ok(Self { git_location, sys_location, is_dir }) - } - -} - - -pub fn parse_args() -> ArgMatches { - - let matches = Command::new("dotfiles") - .version("0.1") - .author("Ethan Simmons") - .about("Manages dotfiles") - .arg(Arg::new("from-git") - .short('g') - .long("from-git") - .action(ArgAction::SetTrue) - ) - .get_matches(); - - matches -} - - - fn copy_config(config: &Config, to_sys: bool) -> Result<(), Box> { - if !config.is_dir { - if to_sys { - let _ = fs::copy(&config.git_location, &config.sys_location)?; - Ok(()) - } else { - let _ = fs::copy(&config.sys_location, &config.git_location)?; - Ok(()) - } - } else { - let (dir, dest) = if to_sys { - (&config.git_location, &config.sys_location) - } else { - (&config.sys_location, &config.git_location) - }; - - println!("Starting Copy Dir"); - copy_directory(&dir, &dest) - } -} +pub mod config_file; +pub mod program_config; +pub mod args; +use program_config::ProgramConfig; fn copy_directory(dir_path: &PathBuf, dest_path: &PathBuf) -> Result<(), Box> { - let dir = fs::read_dir(&dir_path).unwrap(); + let dir = fs::read_dir(&dir_path)?; let entries: Vec<_> = dir.map(|entry| entry.unwrap()).collect(); @@ -86,8 +29,14 @@ fn copy_directory(dir_path: &PathBuf, dest_path: &PathBuf) -> Result<(), Box Result<(), Box Result<(), Box>{ - let configs = vec![ - Config::new("desktop/sway/config", "/home/eesim/.config/sway/config")?, - Config::new("desktop/nvim/init.lua", "/home/eesim/.config/nvim/init.lua")?, - Config::new("desktop/nvim/lua/config", "/home/eesim/.config/nvim/lua/config")?, - Config::new("desktop/alacritty/alacritty.toml", "/home/eesim/.config/alacritty/alacritty.toml")?, - Config::new("desktop/rofi/config.rasi", "/home/eesim/.config/rofi/config.rasi")?, - ]; + + +pub fn run(args: ArgMatches, program_config: ProgramConfig) -> Result<(), Box> { + + let configs = program_config.configs; let copy_to_sys = args.get_flag("from-git"); - let copy_results = configs.iter().map(|config| (copy_config(&config, copy_to_sys), config)); + let copy_results = configs.iter().map(|config| (config.copy_config(copy_to_sys), config)); copy_results.for_each(|result| { if let Err(e) = result.0 { let failed_config = result.1; if copy_to_sys { - println!("Faled to copy {}, with error: {}", failed_config.git_location.to_str().unwrap(), e); + println!("Faled to copy {}, with error: {}", failed_config.manager_path.to_str().expect("Error printing error"), e); } } }); - Ok(()) - } diff --git a/src/main.rs b/src/main.rs index 56f7a4b..a95b2fc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,17 @@ -use dotfiles_manager; +use std::path::PathBuf; + +use dotfiles_manager::args; +use dotfiles_manager::program_config::ProgramConfig; fn main() { - let args = dotfiles_manager::parse_args(); + let args = args::parse_args(); - let _ = dotfiles_manager::run(args); + let program_config = ProgramConfig::parse(PathBuf::from("/home/eesim/.config/dotfiles/config")); + + if let Err(e) = dotfiles_manager::run(args, program_config.unwrap()) { + panic!("Error: {}", e) + }; } diff --git a/src/program_config/mod.rs b/src/program_config/mod.rs new file mode 100644 index 0000000..12117a1 --- /dev/null +++ b/src/program_config/mod.rs @@ -0,0 +1,57 @@ +use std::fs; +use std::str; +use std::path::PathBuf; +use std::error::Error; +use toml::Table; + +use crate::config_file::ConfigFile; + + +pub struct ProgramConfig { + pub manager_dir: PathBuf, + pub configs: Vec, +} + + +impl ProgramConfig { + pub fn parse(config: PathBuf) -> Result> { + + let config_file: Table = str::from_utf8(&fs::read(config)?)?.parse()?; + + let configs = { + let read_configs = config_file.get("configs").unwrap(); + + let configs = read_configs.as_array().unwrap().iter(); + + configs.map(|config| { + + let table = config.as_table().unwrap(); + let manager_path = PathBuf::from(table.get("manager_path").unwrap().as_str().unwrap()); + let system_path = PathBuf::from(table.get("system_path").unwrap().as_str().unwrap()); + + println!("Manager Path: {}", table.get("manager_path").unwrap().as_str().unwrap()); + println!("System Path: {}", table.get("system_path").unwrap().as_str().unwrap()); + + Some(ConfigFile::new(manager_path, system_path).unwrap()) + }) + + + }; + + let valid_configs: Vec = configs.filter_map(|config| match config { + Some(config) => Some(config), + None => { + println!("Failed to parse config"); + None + }, + }).collect(); + + let manager_dir = if config_file.contains_key("manager_directory") { + PathBuf::from(config_file.get("manager_directory").unwrap().as_str().unwrap()) + } else { + PathBuf::from("$HOME/.dotfiles") + }; + + Ok(ProgramConfig{manager_dir, configs: valid_configs}) + } +}