From eb21727868c0feb85fe8e79cf0e8d400fbc6a79f Mon Sep 17 00:00:00 2001 From: Ajeet D'Souza <98ajeet@gmail.com> Date: Fri, 13 Mar 2020 14:12:20 +0530 Subject: [PATCH] Use envy to parse environment variables --- Cargo.lock | 10 ++++++++++ Cargo.toml | 1 + src/db.rs | 4 +--- src/dir.rs | 2 +- src/env.rs | 21 ++++++++++++++++++++ src/main.rs | 16 ++++++++++----- src/subcommand/add.rs | 11 +++++++---- src/subcommand/migrate.rs | 5 +++-- src/subcommand/query.rs | 20 +++++++++---------- src/subcommand/remove.rs | 5 +++-- src/util.rs | 41 +++++++-------------------------------- 11 files changed, 75 insertions(+), 61 deletions(-) create mode 100644 src/env.rs diff --git a/Cargo.lock b/Cargo.lock index 7a4d9c8..360011a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -126,6 +126,14 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "envy" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "fs2" version = "0.4.3" @@ -367,6 +375,7 @@ dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "envy 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "structopt 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -390,6 +399,7 @@ dependencies = [ "checksum crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" "checksum dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" "checksum dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" +"checksum envy 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f938a4abd5b75fe3737902dbc2e79ca142cc1526827a9e40b829a086758531a9" "checksum fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" "checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" diff --git a/Cargo.toml b/Cargo.toml index da87615..64df538 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ anyhow = "1.0.26" bincode = "1.2.1" clap = "2.33.0" dirs = "2.0.2" +envy = "0.4.1" fs2 = "0.4.3" serde = { version = "1.0.104", features = ["derive"] } structopt = "0.3.11" diff --git a/src/db.rs b/src/db.rs index 64d26b1..84f3cff 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,6 +1,5 @@ use crate::dir::Dir; use crate::types::{Epoch, Rank}; -use crate::util; use anyhow::{anyhow, bail, Context, Result}; use fs2::FileExt; use std::fs::{self, File, OpenOptions}; @@ -153,7 +152,7 @@ impl DB { Ok(()) } - pub fn add>(&mut self, path: P, now: Epoch) -> Result<()> { + pub fn add>(&mut self, path: P, max_age: Rank, now: Epoch) -> Result<()> { let path_abs = path .as_ref() .canonicalize() @@ -175,7 +174,6 @@ impl DB { } }; - let max_age = util::get_zo_maxage()?; let sum_age = self.dirs.iter().map(|dir| dir.rank).sum::(); if sum_age > max_age { diff --git a/src/dir.rs b/src/dir.rs index 0c62ddb..5a5f97b 100644 --- a/src/dir.rs +++ b/src/dir.rs @@ -1,4 +1,4 @@ -use crate::types::{Rank, Epoch}; +use crate::types::{Epoch, Rank}; use serde::{Deserialize, Serialize}; use std::path::Path; diff --git a/src/env.rs b/src/env.rs new file mode 100644 index 0000000..ec974f8 --- /dev/null +++ b/src/env.rs @@ -0,0 +1,21 @@ +use serde::Deserialize; +use std::path::PathBuf; + +#[derive(Deserialize, Debug)] +pub struct Env { + #[serde(default = "default_maxage")] + pub maxage: i64, + + #[serde(default = "default_data")] + pub data: Option, +} + +fn default_maxage() -> i64 { + 1000 +} + +fn default_data() -> Option { + let mut path = dirs::home_dir()?; + path.push(".zo"); + Some(path) +} diff --git a/src/main.rs b/src/main.rs index d72b82e..d4a9dc7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,12 @@ mod db; mod dir; +mod env; mod subcommand; mod types; mod util; -use anyhow::Result; +use crate::env::Env; +use anyhow::{Context, Result}; use structopt::StructOpt; // TODO: use structopt to parse env variables: @@ -21,12 +23,16 @@ enum Zoxide { pub fn main() -> Result<()> { let opt = Zoxide::from_args(); + let env = envy::prefixed("_ZO_") + .from_env::() + .with_context(|| "Could not parse environment variables")?; + match opt { - Zoxide::Add(add) => add.run()?, + Zoxide::Add(add) => add.run(&env)?, Zoxide::Init(init) => init.run(), - Zoxide::Migrate(migrate) => migrate.run()?, - Zoxide::Query(query) => query.run()?, - Zoxide::Remove(remove) => remove.run()?, + Zoxide::Migrate(migrate) => migrate.run(&env)?, + Zoxide::Query(query) => query.run(&env)?, + Zoxide::Remove(remove) => remove.run(&env)?, }; Ok(()) diff --git a/src/subcommand/add.rs b/src/subcommand/add.rs index 8ea0d53..4904307 100644 --- a/src/subcommand/add.rs +++ b/src/subcommand/add.rs @@ -1,3 +1,5 @@ +use crate::env::Env; +use crate::types::Rank; use crate::util; use anyhow::{anyhow, Context, Result}; use std::env; @@ -10,16 +12,17 @@ pub struct Add { } impl Add { - pub fn run(&self) -> Result<()> { - let mut db = util::get_db()?; + pub fn run(&self, env: &Env) -> Result<()> { + let mut db = util::get_db(env)?; let now = util::get_current_time()?; + let maxage = env.maxage as Rank; match &self.path { - Some(path) => db.add(path, now), + Some(path) => db.add(path, maxage, now), None => { let current_dir = env::current_dir() .with_context(|| anyhow!("unable to fetch current directory"))?; - db.add(current_dir, now) + db.add(current_dir, maxage, now) } } } diff --git a/src/subcommand/migrate.rs b/src/subcommand/migrate.rs index 1c3a69c..3ffd017 100644 --- a/src/subcommand/migrate.rs +++ b/src/subcommand/migrate.rs @@ -1,3 +1,4 @@ +use crate::env::Env; use crate::util; use anyhow::Result; use structopt::StructOpt; @@ -9,7 +10,7 @@ pub struct Migrate { } impl Migrate { - pub fn run(&self) -> Result<()> { - util::get_db()?.migrate(&self.path) + pub fn run(&self, env: &Env) -> Result<()> { + util::get_db(env)?.migrate(&self.path) } } diff --git a/src/subcommand/query.rs b/src/subcommand/query.rs index 0b02c1b..f580677 100644 --- a/src/subcommand/query.rs +++ b/src/subcommand/query.rs @@ -1,3 +1,4 @@ +use crate::env::Env; use crate::util; use anyhow::Result; use std::path::Path; @@ -12,11 +13,11 @@ pub struct Query { } impl Query { - pub fn run(mut self) -> Result<()> { + pub fn run(mut self, env: &Env) -> Result<()> { let path_opt = if self.interactive { - self.query_interactive() + self.query_interactive(env) } else { - self.query() + self.query(env) }?; if let Some(path) = path_opt { @@ -26,10 +27,7 @@ impl Query { Ok(()) } - fn query(&mut self) -> Result> { - let now = util::get_current_time()?; - let mut db = util::get_db()?; - + fn query(&mut self, env: &Env) -> Result> { if let [path] = self.keywords.as_slice() { if Path::new(path).is_dir() { return Ok(Some(path.to_string())); @@ -40,21 +38,23 @@ impl Query { keyword.make_ascii_lowercase(); } - if let Some(dir) = db.query(&self.keywords, now) { + let now = util::get_current_time()?; + + if let Some(dir) = util::get_db(env)?.query(&self.keywords, now) { return Ok(Some(dir.path)); } Ok(None) } - fn query_interactive(&mut self) -> Result> { + fn query_interactive(&mut self, env: &Env) -> Result> { let now = util::get_current_time()?; for keyword in &mut self.keywords { keyword.make_ascii_lowercase(); } - let dirs = util::get_db()?.query_all(&self.keywords); + let dirs = util::get_db(env)?.query_all(&self.keywords); util::fzf_helper(now, dirs) } } diff --git a/src/subcommand/remove.rs b/src/subcommand/remove.rs index ae879ca..7ed4c54 100644 --- a/src/subcommand/remove.rs +++ b/src/subcommand/remove.rs @@ -1,3 +1,4 @@ +use crate::env::Env; use crate::util; use anyhow::Result; use structopt::StructOpt; @@ -9,7 +10,7 @@ pub struct Remove { } impl Remove { - pub fn run(&self) -> Result<()> { - util::get_db()?.remove(&self.path) + pub fn run(&self, env: &Env) -> Result<()> { + util::get_db(env)?.remove(&self.path) } } diff --git a/src/util.rs b/src/util.rs index 959d182..569acea 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,44 +1,17 @@ use crate::db::DB; use crate::dir::Dir; -use crate::types::{Epoch, Rank}; +use crate::env::Env; +use crate::types::Epoch; use anyhow::{anyhow, Context, Result}; -use std::env; use std::io::{Read, Write}; -use std::path::PathBuf; use std::process::{Command, Stdio}; use std::time::SystemTime; -pub fn get_zo_data() -> Result { - const ZO_DATA: &str = "_ZO_DATA"; - - Ok(match env::var_os(ZO_DATA) { - Some(path) => PathBuf::from(path), - None => { - let mut path = - dirs::home_dir().ok_or_else(|| anyhow!("could not locate home directory"))?; - path.push(".zo"); - path - } - }) -} - -pub fn get_zo_maxage() -> Result { - const ZO_MAXAGE: &str = "_ZO_MAXAGE"; - - let maxage = match env::var_os(ZO_MAXAGE) { - Some(maxage_var) => maxage_var - .to_str() - .ok_or_else(|| anyhow!("invalid Unicode in ${}", ZO_MAXAGE))? - .parse::() - .with_context(|| anyhow!("could not parse ${} as integer", ZO_MAXAGE))? - as Rank, - None => 1000.0, - }; - Ok(maxage) -} - -pub fn get_db() -> Result { - let path = get_zo_data()?; +pub fn get_db(env: &Env) -> Result { + let path = env + .data + .as_ref() + .ok_or_else(|| anyhow!("could not locate database file"))?; DB::open(path) }