use crate::poem::{read::Readable, recite::Reciteable, Poem}; pub mod environment; pub use environment::Environment; use std::env; use std::fs; use std::path::PathBuf; /// Setup the global shell environment /// /// Sets up the shell's environment via configuration files. In order: /// * `/etc/dwvshrc` /// * `~/.dwvshrc` /// /// For debug builds, all files will instead be sourced from /// `./dist/...` with the exception of `~/.dwvshrc`. pub fn env() -> Environment { // Create a new Environment object, to store some extra shell info let mut env = Environment::new(); // Use local repo path if running the debug target let global_rc = if cfg!(debug_assertions) { let mut base = PathBuf::from(env!("CARGO_MANIFEST_DIR")); base.push("dist/etc/dwvshrc"); base } else { PathBuf::from("/etc/dwvshrc") }; // User defined rc file in ~ let local_rc = match env::var("HOME") { Ok(val) => { let mut rc = PathBuf::from(val); rc.push(".dwvshrc"); rc } Err(_) => { eprintln!("dwvsh: unknown home, falling back to /etc"); PathBuf::from(&global_rc) } }; // Read, read, and recite rrr(global_rc, &mut env); rrr(local_rc, &mut env); // Return the new environment env } /// Read, read, and recite /// /// Small, reusable function used to do the heavy lifting in regards to /// sourcing configuration files. [Read][fs::read_to_string]s a file /// from disk, then [read][crate::poem::read]s (parses) a [Poem], /// then [recite][crate::poem::recite]s that [Poem]. /// Configuration files are just shell scripts. fn rrr(path: PathBuf, env: &mut Environment) { let poetry = match fs::read_to_string(&path) { Ok(poetry) => poetry, Err(e) => { if path.to_string_lossy().contains("etc/dwvshrc") { eprintln!( "dwvsh: unable to read global dwvshrc file: {}", e.to_string().to_lowercase() ); } return; } }; let poem = match Poem::read(poetry, &mut Environment::new()) { Ok(poem) => poem, Err(e) => { eprintln!( "dwvsh: error in {}: {}", path.display(), e.to_string().to_lowercase() ); return; } }; match poem.recite(env) { Ok(_) => {} Err(e) => { eprintln!("dwvsh: {}", e.to_string().to_lowercase()); return; } } }