Started adding error handling, fixed directories not being created if they do not exist, added config file
This commit is contained in:
@@ -7,3 +7,4 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap='4.4.*'
|
clap='4.4.*'
|
||||||
|
toml='0.8.*'
|
||||||
|
|||||||
18
src/args/mod.rs
Normal file
18
src/args/mod.rs
Normal file
@@ -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
|
||||||
|
}
|
||||||
47
src/config_file/mod.rs
Normal file
47
src/config_file/mod.rs
Normal file
@@ -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<Self, Box<dyn Error>> {
|
||||||
|
|
||||||
|
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<dyn Error>> {
|
||||||
|
|
||||||
|
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(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
96
src/lib.rs
96
src/lib.rs
@@ -1,74 +1,17 @@
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::PathBuf;
|
use std::path::{self, PathBuf};
|
||||||
use std::env;
|
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use clap::{Arg, Command, ArgAction, ArgMatches};
|
use clap::ArgMatches;
|
||||||
|
|
||||||
pub struct Config {
|
pub mod config_file;
|
||||||
git_location: PathBuf,
|
pub mod program_config;
|
||||||
sys_location: PathBuf,
|
pub mod args;
|
||||||
is_dir: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Config {
|
|
||||||
pub fn new(rel_git_location: &str, sys_location: &str) -> Result<Self, Box<dyn Error>> {
|
|
||||||
|
|
||||||
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<dyn Error>> {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
use program_config::ProgramConfig;
|
||||||
|
|
||||||
fn copy_directory(dir_path: &PathBuf, dest_path: &PathBuf) -> Result<(), Box<dyn Error>> {
|
fn copy_directory(dir_path: &PathBuf, dest_path: &PathBuf) -> Result<(), Box<dyn Error>> {
|
||||||
|
|
||||||
let dir = fs::read_dir(&dir_path).unwrap();
|
let dir = fs::read_dir(&dir_path)?;
|
||||||
|
|
||||||
let entries: Vec<_> = dir.map(|entry| entry.unwrap()).collect();
|
let entries: Vec<_> = dir.map(|entry| entry.unwrap()).collect();
|
||||||
|
|
||||||
@@ -86,8 +29,14 @@ fn copy_directory(dir_path: &PathBuf, dest_path: &PathBuf) -> Result<(), Box<dyn
|
|||||||
|
|
||||||
dirs.for_each(|dir| {
|
dirs.for_each(|dir| {
|
||||||
let current_dir_path = dir_path.join(dir.file_name());
|
let current_dir_path = dir_path.join(dir.file_name());
|
||||||
|
|
||||||
let dest_path = dest_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");
|
println!("Copying dir");
|
||||||
let _ = copy_directory(¤t_dir_path, &dest_path);
|
let _ = copy_directory(¤t_dir_path, &dest_path);
|
||||||
|
|
||||||
@@ -98,32 +47,27 @@ fn copy_directory(dir_path: &PathBuf, dest_path: &PathBuf) -> Result<(), Box<dyn
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn run(args: ArgMatches) -> Result<(), Box<dyn Error>>{
|
|
||||||
|
|
||||||
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")?,
|
pub fn run(args: ArgMatches, program_config: ProgramConfig) -> Result<(), Box<dyn Error>> {
|
||||||
Config::new("desktop/nvim/lua/config", "/home/eesim/.config/nvim/lua/config")?,
|
|
||||||
Config::new("desktop/alacritty/alacritty.toml", "/home/eesim/.config/alacritty/alacritty.toml")?,
|
let configs = program_config.configs;
|
||||||
Config::new("desktop/rofi/config.rasi", "/home/eesim/.config/rofi/config.rasi")?,
|
|
||||||
];
|
|
||||||
|
|
||||||
let copy_to_sys = args.get_flag("from-git");
|
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| {
|
copy_results.for_each(|result| {
|
||||||
if let Err(e) = result.0 {
|
if let Err(e) = result.0 {
|
||||||
let failed_config = result.1;
|
let failed_config = result.1;
|
||||||
|
|
||||||
if copy_to_sys {
|
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(())
|
Ok(())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
13
src/main.rs
13
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() {
|
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)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
57
src/program_config/mod.rs
Normal file
57
src/program_config/mod.rs
Normal file
@@ -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<ConfigFile>,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl ProgramConfig {
|
||||||
|
pub fn parse(config: PathBuf) -> Result<Self, Box<dyn Error>> {
|
||||||
|
|
||||||
|
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<ConfigFile> = 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})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user