add custom config path (#86)

This commit is contained in:
Clément DOUIN 2021-04-17 23:19:34 +02:00
parent 3e0d1f704d
commit 95b99c25da
No known key found for this signature in database
GPG key ID: 69C9B9CFFDEE2DEF
10 changed files with 44 additions and 32 deletions

View file

@ -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

View file

@ -5,7 +5,7 @@ use std::io;
error_chain! {}
pub fn completion_subcmds<'c>() -> Vec<App<'c, 'c>> {
pub fn comp_subcmds<'s>() -> Vec<App<'s, 's>> {
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<App<'c, 'c>> {
.required(true)])]
}
pub fn completion_matches(mut app: App, matches: &ArgMatches) -> Result<bool> {
pub fn comp_matches(mut app: App, matches: &ArgMatches) -> Result<bool> {
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)
}

View file

@ -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<Arg<'a, 'a>> {
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"),
]
}

View file

@ -132,15 +132,16 @@ impl Config {
Ok(path)
}
pub fn new_from_file() -> Result<Self> {
let mut file = File::open(
Self::path_from_xdg()
pub fn new(path: Option<PathBuf>) -> Result<Self> {
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")?;

View file

@ -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<App<'f, 'f>> {
pub fn flag_subcmds<'s>() -> Vec<App<'s, 's>> {
vec![SubCommand::with_name("flags")
.aliases(&["flag"])
.about("Handles flags")

View file

@ -14,7 +14,7 @@ error_chain! {
}
}
pub fn imap_subcmds<'a>() -> Vec<App<'a, 'a>> {
pub fn imap_subcmds<'s>() -> Vec<App<'s, 's>> {
vec![SubCommand::with_name("idle").about("Spawns a blocking idle daemon")]
}

View file

@ -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<PathBuf> = 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(())

View file

@ -28,7 +28,7 @@ pub fn mbox_target_arg<'a>() -> Arg<'a, 'a> {
.value_name("TARGET")
}
pub fn mbox_subcmds<'a>() -> Vec<App<'a, 'a>> {
pub fn mbox_subcmds<'s>() -> Vec<App<'s, 's>> {
vec![SubCommand::with_name("mailboxes")
.aliases(&["mailbox", "mboxes", "mbox", "m"])
.about("Lists all mailboxes")]

View file

@ -67,7 +67,7 @@ fn attachment_arg<'a>() -> Arg<'a, 'a> {
.takes_value(true)
}
pub fn msg_subcmds<'a>() -> Vec<App<'a, 'a>> {
pub fn msg_subcmds<'s>() -> Vec<App<'s, 's>> {
vec![
SubCommand::with_name("list")
.aliases(&["lst", "l"])

2
wiki

@ -1 +1 @@
Subproject commit b5f3d7ad36c5a77e37dff9c343b82dcb42d484be
Subproject commit fb38ee9b4ae679a01f73dd7d77f369a83dd888e5