Skip to content

Commit

Permalink
CHG some general cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
synoet committed Jun 2, 2024
1 parent b1d4642 commit a90a742
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 94 deletions.
24 changes: 17 additions & 7 deletions src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,18 @@ pub struct DirCache {
/// Cache is stored in a json file ussually ~/.cdwe_cache.json
#[derive(Serialize, Deserialize)]
pub struct Cache {
hash: String,
pub shell: String,
pub hash: String,
values: DirCacheMap,
}

impl Cache {
pub fn new(hash: String, values: DirCacheMap) -> Self {
Cache { hash, values }
pub fn new(shell: String, hash: String, values: DirCacheMap) -> Self {
Cache {
shell,
hash,
values,
}
}

pub fn from_config(config: &Config, config_hash: &str) -> Self {
Expand All @@ -33,7 +38,7 @@ impl Cache {
for directory in &config.directories {
let variables: Vec<EnvVariable> = match &directory.vars {
Some(EnvVariableStruct::HashMap(hash_map)) => hash_map
.into_iter()
.iter()
.map(|(name, value)| EnvVariable {
name: name.clone(),
value: value.clone(),
Expand Down Expand Up @@ -65,7 +70,12 @@ impl Cache {
values.insert(directory.path.clone(), dir_cache);
}

return Cache::new(config_hash.to_string(), values);
let shell = match &config.config {
Some(global_config) => global_config.shell.clone().unwrap_or("bash".to_string()),
None => "bash".to_string(),
};

Cache::new(shell, config_hash.to_string(), values)
}

pub fn get(&self, path: &str) -> Option<&DirCache> {
Expand All @@ -89,9 +99,9 @@ pub fn get_or_create_cache(
}
}

let config = Config::from_str(&config_content).context("failed to parse config")?;
let config = Config::from_str(config_content).context("failed to parse config")?;

return Ok((Cache::from_config(&config, &config_hash), true));
Ok((Cache::from_config(&config, config_hash), true))
}

pub fn write_cache(cache: &Cache, home: &str) -> Result<()> {
Expand Down
138 changes: 86 additions & 52 deletions src/cmd/run.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::Shell;
use crate::cache::Cache;
use crate::config::{Config, EnvAlias, EnvVariable, EnvVariableStruct, EnvVariableVec};
use anyhow::{anyhow, Context, Result};
use crate::cache::{Cache, DirCache};
use crate::config::EnvVariable;
use anyhow::{anyhow, Result};
use std::path::Path;

fn trim_quotes(s: &str) -> String {
Expand All @@ -16,7 +16,13 @@ fn trim_quotes(s: &str) -> String {
}
}

// TODO: implement loading from .env file
/// Parses the content of an .env file with the following structure
/// ```
/// SOME_VAR=test
/// ANOTHER_VAR="test"
/// ````
///
/// Supports values with or without quotes
fn parse_env_file(content: &str, file_name: &str) -> Result<Vec<EnvVariable>> {
let lines = content
.lines()
Expand All @@ -41,71 +47,99 @@ fn parse_env_file(content: &str, file_name: &str) -> Result<Vec<EnvVariable>> {
Ok(vars)
}

pub fn run(cache: &Cache, old_path: String, new_path: String) -> Result<()> {
let old_cached_dir = cache.get(&old_path);
let new_cached_dir = cache.get(&new_path);

let to_set = match new_cached_dir {
Some(dir) => dir.variables.clone(),
None => vec![],
};
fn get_vars_from_env_file(base_path: &str, file_path: &str) -> Option<Vec<EnvVariable>> {
let env_path = Path::new(&base_path).join(file_path);
if let Ok(content) = std::fs::read_to_string(&env_path) {
match parse_env_file(&content, &env_path.to_string_lossy()) {
Ok(vars) => Some(vars),
Err(_) => None,
}
} else {
None
}
}

let to_unset = match old_cached_dir {
Some(dir) => dir
.variables
.clone()
.iter()
.map(|var| var.name.clone())
.collect(),
None => vec![],
};
/// Given a cache unsets the environment variables for the old directory
/// variables are taken from the dir and from any .enf files specified in the config
pub fn unset_variables(dir: &DirCache, path: &str) {
for var in dir.variables.iter() {
println!("unset {}", var.name);
}

for var in to_unset {
println!("unset {}", var);
// Unload variables from .env files specified in config
// for the old directory
for file in &dir.load_from {
let vars = get_vars_from_env_file(path, file);
if let Some(vars) = vars {
for var in vars {
println!("unset {}", var.name);
}
}
}
}

for var in to_set {
/// Given a cache sets the environment variables for the new directory
/// variables are taken from the dir and from any .enf files specified in the config
pub fn set_variables(dir: &DirCache, path: &str) {
for var in &dir.variables {
println!("export {}=\"{}\"", var.name, var.value);
}

let commands = match new_cached_dir {
Some(dir) => dir.run.clone(),
None => vec![],
};
// Load variables from .env files specified in config
for file in &dir.load_from {
let vars = get_vars_from_env_file(path, file);
if let Some(vars) = vars {
for var in vars {
println!("export {}=\"{}\"", var.name, var.value);
}
}
}
}

pub fn set_alias(dir: &DirCache, shell: &str) -> Result<()> {
let (start_str, end_str) = Shell::from_string(shell)?.get_alias_command();
for alias in dir.aliases.iter() {
let mut alias_string = start_str.clone().replace("{{{alias_name}}}", &alias.name);
for cmd in &alias.commands {
alias_string.push_str(&format!("{}\n", cmd));
}

for cmd in commands {
println!("{}", cmd);
println!("{}\n{}\n", &alias_string, &end_str);
}

let aliases_to_unset = match old_cached_dir {
Some(dir) => dir
.aliases
.clone()
.iter()
.map(|alias| alias.name.clone())
.collect(),
None => vec![],
};
Ok(())
}

for alias in aliases_to_unset {
println!("unset -f {} &> /dev/null", alias);
pub fn unset_alias(dir: &DirCache) {
for alias in dir.aliases.iter() {
println!("unset -f {} &> /dev/null", alias.name);
}
}

let aliases = match new_cached_dir {
Some(dir) => dir.aliases.clone(),
None => vec![],
};
pub fn run_command(dir: &DirCache) {
for command in dir.run.iter() {
println!("{}", command);
}
}

for alias in aliases {
let (start_str, end_str) = Shell::from_string("zsh")?.get_alias_command();
pub fn run(cache: &Cache, old_path: String, new_path: String) -> Result<()> {
let old_dir: Option<&DirCache> = cache.get(&old_path);
let new_dir: Option<&DirCache> = cache.get(&new_path);

let mut alias_string = start_str.replace("{{{alias_name}}}", &alias.name);
if old_dir.is_none() && new_dir.is_none() {
return Ok(());
}

for cmd in alias.commands {
alias_string.push_str(&format!("{}\n", cmd));
}
// Unset old environment variables
if let Some(old_dir) = old_dir {
unset_variables(old_dir, &old_path);
unset_alias(old_dir);
}

println!("{}\n{}\n", alias_string, end_str);
if let Some(new_dir) = new_dir {
set_variables(new_dir, &new_path);
set_alias(new_dir, &cache.shell)?;
run_command(new_dir);
}

Ok(())
Expand Down
18 changes: 10 additions & 8 deletions src/cmd/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ pub enum Shell {
Zsh,
}

impl ToString for Shell {
fn to_string(&self) -> String {
match self {
Shell::Bash => "bash".to_string(),
Shell::Fish => "fish".to_string(),
Shell::Zsh => "zsh".to_string(),
}
}
}

impl Shell {
pub fn get_config_path(&self) -> Result<String> {
let home_var = std::env::var("HOME").context("no $HOME set")?;
Expand All @@ -29,14 +39,6 @@ impl Shell {
}
}

pub fn to_string(&self) -> String {
match self {
Shell::Bash => "bash".to_string(),
Shell::Fish => "fish".to_string(),
Shell::Zsh => "zsh".to_string(),
}
}

pub fn from_string(s: &str) -> Result<Self> {
match s {
"bash" => Ok(Shell::Bash),
Expand Down
23 changes: 2 additions & 21 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,6 @@ pub enum EnvVariableStruct {
EnvVariableVec(EnvVariableVec),
}

impl Default for EnvVariableStruct {
fn default() -> Self {
EnvVariableStruct::EnvVariableVec(vec![])
}
}

impl From<EnvVariableStruct> for EnvVariableVec {
fn from(env_variable: EnvVariableStruct) -> Self {
match env_variable {
Expand All @@ -29,7 +23,7 @@ impl From<EnvVariableStruct> for EnvVariableVec {
}
}

#[derive(Deserialize, Serialize, Debug, Clone)]
#[derive(Deserialize, Serialize, Debug, Clone, Default)]
pub struct Config {
pub config: Option<GlobalConfig>,
#[serde(rename = "directory")]
Expand All @@ -44,19 +38,6 @@ pub struct Config {
pub aliases: Option<Vec<DirectoryEnvAlias>>,
}

impl Default for Config {
fn default() -> Self {
Config {
config: None,
directories: vec![],
variables: None,
commands: None,
files: None,
aliases: None,
}
}
}

impl Config {
pub fn default_for_shell(shell: Shell) -> Self {
Config {
Expand Down Expand Up @@ -160,7 +141,7 @@ impl Config {

pub fn from_str(content: &str) -> Result<Self> {
let config: Config =
toml::from_str(content).with_context(|| format!("Could not parse config file"))?;
toml::from_str(content).with_context(|| "Could not parse config file")?;

Ok(config)
}
Expand Down
6 changes: 1 addition & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use config::Config;

#[tokio::main]
async fn main() -> Result<()> {
let start_time = std::time::Instant::now();
let matches = Cli::parse();
let home = std::env::var("HOME").context("no $HOME set")?;
let config_path = format!("{}/{}", &home, "cdwe.toml");
Expand All @@ -20,9 +19,8 @@ async fn main() -> Result<()> {
cmd::Commands::Run { old_dir, new_dir } => {
let contents = std::fs::read_to_string(&config_path)
.with_context(|| format!("Could not read config file at {}", &config_path))?;
// let config = Config::from_str(&contents).context("failed to parse config")?;
let config_hash = utils::get_content_hash(&contents);
let cache_contents: Option<String> = std::fs::read_to_string(&cache_path).ok();
let cache_contents: Option<String> = std::fs::read_to_string(cache_path).ok();
let (cache, did_create_cache) =
cache::get_or_create_cache(cache_contents.as_deref(), &contents, &config_hash)?;

Expand All @@ -38,8 +36,6 @@ async fn main() -> Result<()> {
}
cmd::Commands::Remove { shell } => remove_shell(shell.context("no shell passed")?)?,
}
let end_time = std::time::Instant::now();

println!("command took {:?}", end_time - start_time);
Ok(())
}
2 changes: 1 addition & 1 deletion src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ pub fn get_content_hash(content: &str) -> String {
let mut hasher = Sha256::new();
hasher.update(content.as_bytes());

return format!("{:?}", hasher.finalize());
format!("{:?}", hasher.finalize())
}

0 comments on commit a90a742

Please sign in to comment.