From 2d6a5b3069706f6f82d3812b949f31e58a97a1d2 Mon Sep 17 00:00:00 2001 From: Ethan Simmons Date: Sat, 3 Feb 2024 20:51:20 -0600 Subject: [PATCH] Completely reworked copying and added more error handling --- src/args/args.rs | 18 ++++ src/args/mod.rs | 19 +--- src/config/config.rs | 162 ++++++++++++++++++++++++++++++++++ src/config/mod.rs | 163 +--------------------------------- src/dotfile/dir.rs | 195 +++++++++++++++++++++++++++++++++++++++++ src/dotfile/dotfile.rs | 170 +++++++++++++++++++++++++++++++++++ src/dotfile/file.rs | 71 +++++++++++++++ src/dotfile/mod.rs | 73 +-------------- src/lib.rs | 54 ++---------- src/main.rs | 4 +- 10 files changed, 630 insertions(+), 299 deletions(-) create mode 100644 src/args/args.rs create mode 100644 src/config/config.rs create mode 100644 src/dotfile/dir.rs create mode 100644 src/dotfile/dotfile.rs create mode 100644 src/dotfile/file.rs diff --git a/src/args/args.rs b/src/args/args.rs new file mode 100644 index 0000000..e5cffcd --- /dev/null +++ b/src/args/args.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/args/mod.rs b/src/args/mod.rs index e5cffcd..6e10f4a 100644 --- a/src/args/mod.rs +++ b/src/args/mod.rs @@ -1,18 +1 @@ -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 -} +pub mod args; diff --git a/src/config/config.rs b/src/config/config.rs new file mode 100644 index 0000000..2145758 --- /dev/null +++ b/src/config/config.rs @@ -0,0 +1,162 @@ +use std::fs; +use std::path::PathBuf; +use std::error::Error; +use std::fmt; + +use toml::Table; + +use crate::dotfile::dotfile::{self, ManagedDotfile}; + + + + +pub struct Config { + pub manager_dir: PathBuf, + pub dotfiles: Vec>, +} + +impl Config { + pub fn parse(path: PathBuf) -> Result { + + let config_file = Config::read_config(path).unwrap(); + + let dotfiles = Config::get_dotfiles(&config_file).unwrap(); + + let manager_dir = Config::get_manager_dir(&config_file); + + Ok(Config{manager_dir, dotfiles}) + } + + + fn read_config(path: PathBuf) -> Result { + + let file = fs::read(path)?; + + let read_file = String::from_utf8(file)?; + + let config: Table = read_file.parse()?; + + Ok(config) + + } + + + fn get_dotfiles(config: &Table) -> Result>, ConfigParseError> { + + let read_dotfiles = config.get("dotfiles"); + + let dotfiles = match read_dotfiles { + Some(dotfiles) => dotfiles, + None => return Err(ConfigParseError::DotfilesParseError), + }; + + let dotfile_iter = match dotfiles.as_array() { + Some(dotfiles) => dotfiles.iter(), + None => return Err(ConfigParseError::DotfilesArrayParseError), + }; + + + let dotfiles = dotfile_iter.map(|dotfile| { + + let dotfile_table = dotfile.as_table().unwrap(); + + let manager_path = PathBuf::from( + match dotfile_table.get("manager_path") { + Some(path) => path.as_str().expect("Invalid character in dotfile path"), + None => return Err(ConfigParseError::DotfilesTableParseError), + } + ); + + let system_path = PathBuf::from( + match dotfile_table.get("system_path") { + Some(path) => path.as_str().expect("Invalid character in dotfile path"), + None => return Err(ConfigParseError::DotfilesTableParseError), + } + ); + + Ok(ManagedDotfile::new(manager_path, system_path)?) + }); + + Ok(dotfiles.collect()) + } + + + fn get_manager_dir(config: &Table) -> PathBuf { + + let manager_dir = if config.contains_key("manager_directory") { + PathBuf::from(config.get("manager_directory").unwrap().as_str().unwrap()) + } else { + PathBuf::from("$HOME/.dotfiles") + }; + + manager_dir + } + +} + + + +#[derive(Debug)] +pub enum ConfigParseError { + FileReadError(std::io::Error), + FromUtfError(std::string::FromUtf8Error), + TomlParseError(toml::de::Error), + DotfilesParseError, + DotfilesArrayParseError, + DotfilesTableParseError, + DotfilesCreateError(dotfile::DotfileError), +} + +impl Error for ConfigParseError {} + +impl fmt::Display for ConfigParseError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + ConfigParseError::FileReadError(io_error) => { + write!(f, "{}", io_error) + }, + ConfigParseError::FromUtfError(utf_error) => { + write!(f, "{}", utf_error) + }, + ConfigParseError::TomlParseError(parse_error) => { + write!(f, "{}", parse_error) + }, + ConfigParseError::DotfilesCreateError(create_error) => { + write!(f, "{}", create_error) + }, + ConfigParseError::DotfilesParseError => { + write!(f, "Dotfiles section not found in config file") + }, + ConfigParseError::DotfilesArrayParseError => { + write!(f, "Dotfiles is not a valid array, Hint: use [[dotfiles]]") + }, + ConfigParseError::DotfilesTableParseError => { + write!(f, "Dotfile table is not valid") + }, + } + } +} + +impl From for ConfigParseError { + fn from(error: std::io::Error) -> ConfigParseError { + ConfigParseError::FileReadError(error) + } +} + +impl From for ConfigParseError { + fn from(error: std::string::FromUtf8Error) -> ConfigParseError { + ConfigParseError::FromUtfError(error) + } +} + +impl From for ConfigParseError { + fn from(error: toml::de::Error) -> ConfigParseError { + ConfigParseError::TomlParseError(error) + } +} + +impl From for ConfigParseError { + fn from(error: dotfile::DotfileError) -> ConfigParseError { + ConfigParseError::DotfilesCreateError(error) + } +} diff --git a/src/config/mod.rs b/src/config/mod.rs index 293be8d..ef68c36 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,162 +1 @@ -use std::fs; -use std::path::PathBuf; -use std::error::Error; -use std::fmt; - -use toml::Table; - -use crate::dotfile::Dotfile; - - -pub struct Config { - pub manager_dir: PathBuf, - pub dotfiles: Vec>, -} - - -impl Config { - pub fn parse(path: PathBuf) -> Result { - - let config_file = Config::read_config(path).unwrap(); - - let dotfiles = Config::get_dotfiles(&config_file).unwrap(); - - let manager_dir = Config::get_manager_dir(&config_file); - - Ok(Config{manager_dir, dotfiles}) - } - - - fn read_config(path: PathBuf) -> Result { - - let file = fs::read(path)?; - - let read_file = String::from_utf8(file)?; - - let config: Table = read_file.parse()?; - - Ok(config) - - } - - - fn get_dotfiles(config: &Table) -> Result>, ConfigParseError> { - - let read_dotfiles = config.get("dotfiles"); - - let dotfiles = match read_dotfiles { - Some(dotfiles) => dotfiles, - None => return Err(ConfigParseError::DotfilesParseError), - }; - - let dotfile_iter = match dotfiles.as_array() { - Some(dotfiles) => dotfiles.iter(), - None => return Err(ConfigParseError::DotfilesArrayParseError), - }; - - - let dotfiles = dotfile_iter.map(|dotfile| { - - let dotfile_table = dotfile.as_table().unwrap(); - - let manager_path = PathBuf::from( - match dotfile_table.get("manager_path") { - Some(path) => path.as_str().expect("Invalid character in dotfile path"), - None => return Err(ConfigParseError::DotfilesTableParseError), - } - ); - - let system_path = PathBuf::from( - match dotfile_table.get("system_path") { - Some(path) => path.as_str().expect("Invalid character in dotfile path"), - None => return Err(ConfigParseError::DotfilesTableParseError), - } - ); - - Ok(Dotfile::new(manager_path, system_path)?) - }); - - Ok(dotfiles.collect()) - - } - - - fn get_manager_dir(config: &Table) -> PathBuf { - - let manager_dir = if config.contains_key("manager_directory") { - PathBuf::from(config.get("manager_directory").unwrap().as_str().unwrap()) - } else { - PathBuf::from("$HOME/.dotfiles") - }; - - manager_dir - } - -} - - - -#[derive(Debug)] -pub enum ConfigParseError { - FileReadError(std::io::Error), - FromUtfError(std::string::FromUtf8Error), - TomlParseError(toml::de::Error), - DotfilesParseError, - DotfilesArrayParseError, - DotfilesTableParseError, - DotfilesCreateError(Box), -} - -impl Error for ConfigParseError {} - -impl fmt::Display for ConfigParseError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - ConfigParseError::FileReadError(io_error) => { - write!(f, "{}", io_error) - }, - ConfigParseError::FromUtfError(utf_error) => { - write!(f, "{}", utf_error) - }, - ConfigParseError::TomlParseError(parse_error) => { - write!(f, "{}", parse_error) - }, - ConfigParseError::DotfilesParseError => { - write!(f, "Dotfiles section not found in config file") - }, - ConfigParseError::DotfilesArrayParseError => { - write!(f, "Dotfiles is not a valid array, Hint: use [[dotfiles]]") - }, - ConfigParseError::DotfilesTableParseError => { - write!(f, "Dotfile table is not valid") - }, - ConfigParseError::DotfilesCreateError(create_error) => { - write!(f, "Failed to create dotfile {}", *create_error) - } - } - } -} - -impl From for ConfigParseError { - fn from(error: std::io::Error) -> Self { - ConfigParseError::FileReadError(error) - } -} - -impl From for ConfigParseError { - fn from(error: std::string::FromUtf8Error) -> Self { - ConfigParseError::FromUtfError(error) - } -} - -impl From for ConfigParseError { - fn from(error: toml::de::Error) -> Self { - ConfigParseError::TomlParseError(error) - } -} - -impl From> for ConfigParseError { - fn from(error: Box) -> Self { - ConfigParseError::DotfilesCreateError(error) - } -} +pub mod config; diff --git a/src/dotfile/dir.rs b/src/dotfile/dir.rs new file mode 100644 index 0000000..84bec29 --- /dev/null +++ b/src/dotfile/dir.rs @@ -0,0 +1,195 @@ +use std::fs; +use std::path::PathBuf; +use std::fmt; +use std::error::Error; + +use crate::dotfile::file::{self, File}; + + + + +pub struct Directory { + files: Vec, + directories: Vec, + pub path: PathBuf, + pub errors: Vec, +} + +impl Directory { + pub fn new(path: &PathBuf) -> Result { + + if !path.exists() { + fs::create_dir_all(path)?; + } + + let dir: Vec<_> = fs::read_dir(path)?.collect(); + + // Find a better way to do this sometime + let mut read_errors: Vec = Vec::new(); + let mut metadata_errors: Vec = Vec::new(); + let mut create_dir_errors: Vec = Vec::new(); + let mut create_file_errors: Vec = Vec::new(); + + let entries = dir.into_iter().filter_map(|entry| match entry { + Ok(entry) => Some(entry), + Err(e) => { + read_errors.push(DirError::from(e)); + None + } + }); + + + let valid_entries: Vec<_> = entries + .filter_map(|entry| match entry.metadata() { + Ok(_) => Some(entry), + Err(e) => { + metadata_errors.push(DirError::from(e)); + None + } + }) + .collect(); + + + let directories: Vec<_> = valid_entries + .iter() + .filter_map(|entry| + if entry.metadata().unwrap().is_dir() { + match Directory::new(&entry.path()) { + Ok(dir) => Some(dir), + Err(e) => { + create_dir_errors.push(DirError::from(e)); + None + }, + } + } else { + None + }) + .collect(); + + + let files: Vec = valid_entries + .iter() + .filter_map(|entry| + if entry.metadata().unwrap().is_file() { + match File::new(&entry.path()) { + Ok(file) => Some(file), + Err(e) => { + create_file_errors.push(DirError::from(e)); + None + }, + } + } else { + None + }) + .collect(); + + // Fix sometime + let errors: Vec = read_errors.into_iter().chain(metadata_errors.into_iter().chain(create_dir_errors.into_iter().chain(create_file_errors.into_iter()))).collect(); + + + Ok(Directory{ files, directories, path: path.to_path_buf(), errors }) + } + + + pub fn copy(&self, dest_path: &PathBuf) -> Result, DirError> { + + let file_copy_results: Vec<_> = self.files + .iter() + .map(|file| { + file.copy( &dest_path.join( PathBuf::from(&file.filename) ) ) + }) + .collect(); + + + let dir_copy_results = { + let dirs = self.directories.iter(); + + let result = dirs.map(|dir| { + let dir_name = match dir.path.file_name() { + Some(filename) => filename, + None => return Err(DirError::NoDirNameError), + }; + + let new_dest_path = dest_path.join(PathBuf::from(dir_name)); + + if !new_dest_path.exists() { + fs::create_dir(&new_dest_path)?; + } + + dir.copy(&new_dest_path) + }).collect::>(); + + result + }; + + let mut copy_errors = Vec::new(); + + file_copy_results.into_iter().for_each(|result| if result.is_err() { + copy_errors.push(DirError::from(result.err().unwrap())) + }); + + dir_copy_results.into_iter().for_each(|result| match result { + Err(e) => { + copy_errors.push(DirError::from(e)); + }, + Ok(copy_results) => { + copy_results.into_iter().for_each(|error| copy_errors.push(error)); + } + }); + + + Ok(copy_errors) + + } +} + + + + + +#[derive(Debug)] +pub enum DirError { + DirCopyMetadataError(std::env::VarError), + DirIOError(std::io::Error), + DirFileCopyError(file::FileError), + NoDirNameError, +} + +impl Error for DirError {} + +impl fmt::Display for DirError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + DirError::DirCopyMetadataError(var_error) => { + write!(f, "{}", var_error) + }, + DirError::DirIOError(io_error) => { + write!(f, "{}", io_error) + }, + DirError::DirFileCopyError(copy_error) => { + write!(f, "{}", copy_error) + }, + DirError::NoDirNameError => { + write!(f, "Directory does not have a valid name") + } + } + } +} + +impl From for DirError { + fn from(error: std::env::VarError) -> DirError { + DirError::DirCopyMetadataError(error) + } +} + +impl From for DirError { + fn from(error: std::io::Error) -> DirError { + DirError::DirIOError(error) + } +} + +impl From for DirError { + fn from(error: file::FileError) -> DirError { + DirError::DirFileCopyError(error) + } +} diff --git a/src/dotfile/dotfile.rs b/src/dotfile/dotfile.rs new file mode 100644 index 0000000..948f094 --- /dev/null +++ b/src/dotfile/dotfile.rs @@ -0,0 +1,170 @@ +use std::path::PathBuf; +use std::error::Error; +use std::env; +use std::fs; +use std::fmt; + +use crate::dotfile::dir; +use crate::dotfile::file; + + + + + +pub enum Dotfile { + File(file::File), + Dir(dir::Directory) +} + + +pub struct ManagedDotfile { + pub manager_dotfile: Dotfile, + pub system_dotfile: Dotfile, +} + +impl ManagedDotfile { + pub fn new(rel_git_location: PathBuf, sys_location: PathBuf) -> Result { + + let home_dir = PathBuf::from(env::var("HOME")?); + let manager_dir = home_dir.join(PathBuf::from(".dotfiles/")); + + let manager_path = manager_dir.join(rel_git_location); + let system_path = sys_location; + + let manager_path_data = fs::metadata(&manager_path); + let sys_path_data = fs::metadata(&system_path); + + let is_dir = match (manager_path_data, sys_path_data) { + (Ok(manager_data), Ok(sys_data)) => manager_data.is_dir() && sys_data.is_dir(), + + (Ok(manager_data), Err(_)) => { + if manager_data.is_dir() { + let _ = fs::create_dir_all(&system_path); + true + } else { + let _ = fs::create_dir_all(&system_path.parent().unwrap()); + false + } + }, + + (Err(_), Ok(sys_data)) => { + if sys_data.is_dir() { + let _ = fs::create_dir_all(&manager_path); + true + } else { + let _ = fs::create_dir_all(&manager_path.parent().unwrap()); + false + } + }, + + (Err(e1), Err(e2)) => return Err(DotfileError::FilesDontExistError((e1, e2))) + }; + + let manager_dotfile = if is_dir { + Dotfile::Dir(dir::Directory::new(&manager_path)?) + } else { + Dotfile::File(file::File::new(&manager_path)?) + }; + + let system_dotfile = if is_dir { + Dotfile::Dir(dir::Directory::new(&system_path)?) + } else { + Dotfile::File(file::File::new(&system_path)?) + }; + + Ok(Self { manager_dotfile, system_dotfile }) + } + + + pub fn copy_dotfile(&self, to_sys: bool) -> Result<(), DotfileError> { + + let (current, destination) = if to_sys { + (&self.manager_dotfile, &self.system_dotfile) + } else { + (&self.system_dotfile, &self.manager_dotfile) + }; + + + if let (Dotfile::File(current_file), Dotfile::File(dest_file)) = (current, destination) { + current_file.copy(&dest_file.path)?; + }; + + + if let (Dotfile::Dir(current_dir), Dotfile::Dir(dest_dir)) = (current, destination) { + let results = current_dir.copy(&dest_dir.path)?; + + results.into_iter().for_each(|result| { + println!("Error copying directory: {}", result) + }) + }; + + Ok(()) + } +} + + + + + +#[derive(Debug)] +pub enum DotfileError { + DotfileIOError(std::io::Error), + DotfileEnvError(std::env::VarError), + FilesDontExistError((std::io::Error, std::io::Error)), + FileCopyError(file::FileError), + DirectoryCopyError(dir::DirError), +} + +impl Error for DotfileError {} + +impl fmt::Display for DotfileError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + DotfileError::DotfileIOError(io_error) => { + write!(f, "{}", io_error) + }, + DotfileError::DotfileEnvError(env_error) => { + write!(f, "{}", env_error) + } + DotfileError::FilesDontExistError((io_error_1, io_error_2)) => { + write!(f, "Neither file exists: {}, {}", io_error_1, io_error_2) + } + DotfileError::FileCopyError(copy_error) => { + write!(f, "{}", copy_error) + } + DotfileError::DirectoryCopyError(copy_error) => { + write!(f, "{}", copy_error) + } + } + } +} + +impl From for DotfileError { + fn from(error: std::io::Error) -> DotfileError { + DotfileError::DotfileIOError(error) + } +} + +impl From for DotfileError { + fn from(error: std::env::VarError) -> DotfileError { + DotfileError::DotfileEnvError(error) + } +} + +impl From<(std::io::Error, std::io::Error)> for DotfileError { + fn from(error: (std::io::Error, std::io::Error)) -> DotfileError { + DotfileError::FilesDontExistError(error) + } +} + +impl From for DotfileError { + fn from(error: file::FileError) -> DotfileError { + DotfileError::FileCopyError(error) + } +} + +impl From for DotfileError { + fn from(error: dir::DirError) -> DotfileError { + DotfileError::DirectoryCopyError(error) + } +} diff --git a/src/dotfile/file.rs b/src/dotfile/file.rs new file mode 100644 index 0000000..ad1add4 --- /dev/null +++ b/src/dotfile/file.rs @@ -0,0 +1,71 @@ +use std::path::PathBuf; +use std::fs; +use std::error::Error; +use std::fmt; + + + + +pub struct File { + pub path: PathBuf, + pub filename: String, +} + +impl File { + pub fn new(path: &PathBuf) -> Result { + + let filename = match path.file_name() { + Some(filename) => match filename.to_str() { + Some(filename) => String::from(filename), + None => return Err(FileError::InvalidUTFError), + }, + None => return Err(FileError::NoFileNameError), + }; + + Ok(File{ path: path.to_path_buf(), filename }) + } + + + pub fn copy(&self, dest_path: &PathBuf) -> Result<(), FileError> { + + fs::copy(&self.path, dest_path)?; + + Ok(()) + } + +} + + + + + +#[derive(Debug)] +pub enum FileError { + CopyError(std::io::Error), + NoFileNameError, + InvalidUTFError, +} + +impl Error for FileError {} + +impl fmt::Display for FileError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + FileError::CopyError(copy_error) => { + write!(f, "{}", copy_error) + }, + FileError::InvalidUTFError => { + write!(f, "Invalild UTF in filename") + }, + FileError::NoFileNameError => { + write!(f, "File does not have a valid filename") + } + } + } +} + +impl From for FileError { + fn from(error: std::io::Error) -> FileError { + FileError::CopyError(error) + } +} diff --git a/src/dotfile/mod.rs b/src/dotfile/mod.rs index 3e5799d..86e26c2 100644 --- a/src/dotfile/mod.rs +++ b/src/dotfile/mod.rs @@ -1,71 +1,4 @@ -use std::path::PathBuf; -use std::error::Error; -use std::env; -use std::fs; +mod dir; +mod file; -use crate::copy_directory; - -pub struct Dotfile { - pub manager_path: PathBuf, - pub system_path: PathBuf, - is_dir: bool, -} - - -impl Dotfile { - 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(PathBuf::from(".dotfiles/")); - - let manager_path = manager_dir.join(rel_git_location); - let system_path = sys_location; - - let manager_path_data = fs::metadata(&manager_path); - let sys_path_data = fs::metadata(&system_path); - - let is_dir = match (manager_path_data, sys_path_data) { - (Ok(manager_data), Ok(sys_data)) => manager_data.is_dir() && sys_data.is_dir(), - (Ok(manager_data), Err(_)) => { - if manager_data.is_dir() { - let _ = fs::create_dir_all(&system_path); - true - } else { - let _ = fs::create_dir_all(&system_path.parent().unwrap()); - false - } - }, - (Err(_), Ok(sys_data)) => { - if sys_data.is_dir() { - let _ = fs::create_dir_all(&manager_path); - true - } else { - let _ = fs::create_dir_all(&manager_path.parent().unwrap()); - false - } - }, - (Err(e1), Err(e2)) => panic!("Neither {} nor {} exists or is readable: {}, {}", manager_path.to_str().unwrap(), system_path.to_str().unwrap(), e1, e2), - }; - - Ok(Self { manager_path, system_path, is_dir }) - } - - pub fn copy_dotfile(&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(()) - } - } -} +pub mod dotfile; diff --git a/src/lib.rs b/src/lib.rs index a6bfc1b..fc47fda 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,51 +1,12 @@ -use std::fs; -use std::path::{self, PathBuf}; use std::error::Error; use clap::ArgMatches; +use crate::config::config::Config; + pub mod config; pub mod dotfile; pub mod args; -use config::Config; - -fn copy_directory(dir_path: &PathBuf, dest_path: &PathBuf) -> Result<(), Box> { - - let dir = fs::read_dir(&dir_path)?; - - let entries: Vec<_> = dir.map(|entry| entry.unwrap()).collect(); - - let files = entries.iter().filter(|entry| entry.metadata().unwrap().is_file()); - let dirs = entries.iter().filter(|entry| entry.metadata().unwrap().is_dir()); - - files.for_each(|file| { - let file_path = dir_path.join(file.file_name()); - let dest_path = dest_path.join(file.file_name()); - - let _ = fs::copy(file_path, dest_path); - - println!("Copying file"); - }); - - dirs.for_each(|dir| { - let current_dir_path = dir_path.join(dir.file_name()); - - let dest_path = dest_path.join(dir.file_name()); - - if !(path::Path::try_exists(&dest_path).unwrap()) { - let _ = fs::create_dir(&dest_path); - } - - - println!("Copying dir"); - let _ = copy_directory(¤t_dir_path, &dest_path); - - }); - - Ok(()) - -} - pub fn run(args: ArgMatches, config: Config) -> Result<(), Box> { @@ -64,14 +25,13 @@ pub fn run(args: ArgMatches, config: Config) -> Result<(), Box> { let copy_results = valid_dotfiles.iter().map(|dotfile| (dotfile.copy_dotfile(copy_to_sys), dotfile)); copy_results.for_each(|result| { - if let Err(e) = result.0 { - let failed_dotfile = result.1; - - if copy_to_sys { - println!("Faled to copy {}, with error: {}", failed_dotfile.manager_path.to_str().expect("Error printing error"), e); - } + match result.0 { + Err(e) => println!("Failed to copy dotfile: {}", e), + _ => (), } }); + + Ok(()) } diff --git a/src/main.rs b/src/main.rs index bc0f042..400619f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,8 @@ use std::path::PathBuf; use std::error::Error; -use dotfiles_manager::args; -use dotfiles_manager::config::Config; +use dotfiles_manager::args::args; +use dotfiles_manager::config::config::Config; fn main() -> Result<(), Box> {