diff --git a/CHANGELOG.md b/CHANGELOG.md index f0c0861..7581689 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Default page size to config [#96] +- Custom config path [#86] ## [0.2.6] - 2021-04-17 @@ -182,6 +183,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#79]: https://github.com/soywod/himalaya/issues/79 [#83]: https://github.com/soywod/himalaya/issues/83 [#84]: https://github.com/soywod/himalaya/issues/84 +[#86]: https://github.com/soywod/himalaya/issues/86 [#87]: https://github.com/soywod/himalaya/issues/87 [#89]: https://github.com/soywod/himalaya/issues/89 [#96]: https://github.com/soywod/himalaya/issues/96 diff --git a/src/completion/cli.rs b/src/comp/cli.rs similarity index 69% rename from src/completion/cli.rs rename to src/comp/cli.rs index 0679b67..6646fb5 100644 --- a/src/completion/cli.rs +++ b/src/comp/cli.rs @@ -5,7 +5,7 @@ use std::io; error_chain! {} -pub fn completion_subcmds<'c>() -> Vec> { +pub fn comp_subcmds<'s>() -> Vec> { vec![SubCommand::with_name("completion") .about("Generates the completion script for the given shell") .args(&[Arg::with_name("shell") @@ -13,19 +13,19 @@ pub fn completion_subcmds<'c>() -> Vec> { .required(true)])] } -pub fn completion_matches(mut app: App, matches: &ArgMatches) -> Result { +pub fn comp_matches(mut app: App, matches: &ArgMatches) -> Result { if let Some(matches) = matches.subcommand_matches("completion") { - debug!("[completion::cli::matches] completion command matched"); + debug!("[comp::cli::matches] completion command matched"); let shell = match matches.value_of("shell").unwrap() { "fish" => Shell::Fish, "zsh" => Shell::Zsh, "bash" | _ => Shell::Bash, }; - debug!("[completion::cli::matches] shell: {}", shell); + debug!("[comp::cli::matches] shell: {}", shell); app.gen_completions_to("himalaya", shell, &mut io::stdout()); return Ok(true); }; - debug!("[completion::cli::matches] nothing matched"); + debug!("[comp::cli::matches] nothing matched"); Ok(false) } diff --git a/src/config/cli.rs b/src/config/cli.rs index c7b797c..edc2d2d 100644 --- a/src/config/cli.rs +++ b/src/config/cli.rs @@ -1,9 +1,16 @@ use clap::Arg; -pub fn account_arg<'a>() -> Arg<'a, 'a> { - Arg::with_name("account") - .long("account") - .short("a") - .help("Selects a specific account") - .value_name("STRING") +pub fn config_args<'a>() -> Vec> { + vec![ + Arg::with_name("config") + .long("config") + .short("c") + .help("Forces a specific config path") + .value_name("PATH"), + Arg::with_name("account") + .long("account") + .short("a") + .help("Selects a specific account") + .value_name("NAME"), + ] } diff --git a/src/config/model.rs b/src/config/model.rs index 0843a5b..65d8f58 100644 --- a/src/config/model.rs +++ b/src/config/model.rs @@ -132,15 +132,16 @@ impl Config { Ok(path) } - pub fn new_from_file() -> Result { - let mut file = File::open( - Self::path_from_xdg() + pub fn new(path: Option) -> Result { + let path = match path { + Some(path) => path, + None => Self::path_from_xdg() .or_else(|_| Self::path_from_xdg_alt()) .or_else(|_| Self::path_from_home()) .chain_err(|| "Cannot find config path")?, - ) - .chain_err(|| "Cannot open config file")?; + }; + let mut file = File::open(path).chain_err(|| "Cannot open config file")?; let mut content = vec![]; file.read_to_end(&mut content) .chain_err(|| "Cannot read config file")?; diff --git a/src/flag/cli.rs b/src/flag/cli.rs index 543e56b..21e921f 100644 --- a/src/flag/cli.rs +++ b/src/flag/cli.rs @@ -11,7 +11,7 @@ error_chain! { } } -fn flags_arg<'f>() -> Arg<'f, 'f> { +fn flags_arg<'a>() -> Arg<'a, 'a> { Arg::with_name("flags") .help("IMAP flags (see https://tools.ietf.org/html/rfc3501#page-11)") .value_name("FLAGSā€¦") @@ -19,7 +19,7 @@ fn flags_arg<'f>() -> Arg<'f, 'f> { .required(true) } -pub fn flag_subcmds<'f>() -> Vec> { +pub fn flag_subcmds<'s>() -> Vec> { vec![SubCommand::with_name("flags") .aliases(&["flag"]) .about("Handles flags") diff --git a/src/imap/cli.rs b/src/imap/cli.rs index 0f675ea..6ba8ed4 100644 --- a/src/imap/cli.rs +++ b/src/imap/cli.rs @@ -14,7 +14,7 @@ error_chain! { } } -pub fn imap_subcmds<'a>() -> Vec> { +pub fn imap_subcmds<'s>() -> Vec> { vec![SubCommand::with_name("idle").about("Spawns a blocking idle daemon")] } diff --git a/src/main.rs b/src/main.rs index cfdb9d7..16e857d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ use clap; use error_chain::error_chain; use log::{debug, error, trace}; -use std::env; +use std::{env, path::PathBuf}; mod input; mod smtp; @@ -32,13 +32,13 @@ mod mbox { pub(crate) mod cli; pub(crate) mod model; } -mod completion { +mod comp { pub(crate) mod cli; } use crate::{ - completion::cli::{completion_matches, completion_subcmds}, - config::{cli::account_arg, model::Config}, + comp::cli::{comp_matches, comp_subcmds}, + config::{cli::config_args, model::Config}, flag::cli::{flag_matches, flag_subcmds}, imap::cli::{imap_matches, imap_subcmds}, mbox::cli::{mbox_matches, mbox_source_arg, mbox_subcmds}, @@ -52,7 +52,7 @@ use crate::{ error_chain! { links { - CompletionCli(crate::completion::cli::Error, crate::completion::cli::ErrorKind); + CompletionCli(crate::comp::cli::Error, crate::comp::cli::ErrorKind); Config(crate::config::model::Error, crate::config::model::ErrorKind); FlagCli(crate::flag::cli::Error, crate::flag::cli::ErrorKind); ImapCli(crate::imap::cli::Error, crate::imap::cli::ErrorKind); @@ -68,13 +68,13 @@ fn build_app<'a>() -> clap::App<'a, 'a> { .about(env!("CARGO_PKG_DESCRIPTION")) .author(env!("CARGO_PKG_AUTHORS")) .args(&output_args()) - .arg(account_arg()) + .args(&config_args()) .arg(mbox_source_arg()) .subcommands(flag_subcmds()) .subcommands(imap_subcmds()) .subcommands(mbox_subcmds()) .subcommands(msg_subcmds()) - .subcommands(completion_subcmds()) + .subcommands(comp_subcmds()) } fn run() -> Result<()> { @@ -83,12 +83,14 @@ fn run() -> Result<()> { let output_fmt: OutputFmt = matches.value_of("output").unwrap().into(); let log_level: LogLevel = matches.value_of("log").unwrap().into(); + let custom_config: Option = matches.value_of("config").map(|s| s.into()); init_logger(&output_fmt, &log_level)?; debug!("[main] output format: {}", output_fmt); debug!("[main] log level: {}", log_level); + debug!("[main] custom config path: {:?}", custom_config); debug!("[main] init config"); - let config = Config::new_from_file()?; + let config = Config::new(custom_config)?; trace!("[main] {:#?}", config); let account_name = matches.value_of("account"); @@ -97,13 +99,13 @@ fn run() -> Result<()> { trace!("[main] {:#?}", account); let mbox = matches.value_of("mailbox").unwrap(); - debug!("[msg::cli::matches] mailbox: {}", mbox); + debug!("[main] mailbox: {}", mbox); debug!("[main] begin matching"); let _matched = mbox_matches(&account, &matches)? || flag_matches(&account, &mbox, &matches)? || imap_matches(&config, &account, &mbox, &matches)? - || completion_matches(build_app(), &matches)? + || comp_matches(build_app(), &matches)? || msg_matches(&config, &account, &mbox, &matches)?; Ok(()) diff --git a/src/mbox/cli.rs b/src/mbox/cli.rs index 04cdd11..e41c9fc 100644 --- a/src/mbox/cli.rs +++ b/src/mbox/cli.rs @@ -28,7 +28,7 @@ pub fn mbox_target_arg<'a>() -> Arg<'a, 'a> { .value_name("TARGET") } -pub fn mbox_subcmds<'a>() -> Vec> { +pub fn mbox_subcmds<'s>() -> Vec> { vec![SubCommand::with_name("mailboxes") .aliases(&["mailbox", "mboxes", "mbox", "m"]) .about("Lists all mailboxes")] diff --git a/src/msg/cli.rs b/src/msg/cli.rs index d14e642..8747dc5 100644 --- a/src/msg/cli.rs +++ b/src/msg/cli.rs @@ -67,7 +67,7 @@ fn attachment_arg<'a>() -> Arg<'a, 'a> { .takes_value(true) } -pub fn msg_subcmds<'a>() -> Vec> { +pub fn msg_subcmds<'s>() -> Vec> { vec![ SubCommand::with_name("list") .aliases(&["lst", "l"]) diff --git a/wiki b/wiki index b5f3d7a..fb38ee9 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit b5f3d7ad36c5a77e37dff9c343b82dcb42d484be +Subproject commit fb38ee9b4ae679a01f73dd7d77f369a83dd888e5