diff --git a/meli.1 b/meli.1 index 7107fcf6..69251907 100644 --- a/meli.1 +++ b/meli.1 @@ -28,6 +28,7 @@ .Op Fl -help | h .Op Fl -version | v .Op Fl -create-config Op Ar path +.Op Fl -test-config Op Ar path .Op Fl -config Ar path .Sh DESCRIPTION Experimental terminal mail client @@ -41,6 +42,8 @@ Create configuration file in .Pa path if given, or at .Pa $XDG_CONFIG_HOME/meli/config +.It Fl -test-config Op Ar path +Test a configuration file for syntax issues or missing options. .It Fl -config Ar path Start meli with given configuration file. .El diff --git a/src/bin.rs b/src/bin.rs index d214c112..b5786013 100644 --- a/src/bin.rs +++ b/src/bin.rs @@ -77,6 +77,7 @@ macro_rules! error_and_exit { #[derive(Debug)] struct CommandLineArguments { create_config: Option, + test_config: Option, config: Option, help: bool, version: bool, @@ -95,12 +96,14 @@ fn main() { fn run_app() -> Result<()> { enum CommandLineFlags { CreateConfig, + TestConfig, Config, } use CommandLineFlags::*; let mut prev: Option = None; let mut args = CommandLineArguments { create_config: None, + test_config: None, config: None, help: false, version: false, @@ -108,9 +111,16 @@ fn run_app() -> Result<()> { for i in std::env::args().skip(1) { match i.as_str() { + "--test-config" => match prev { + None => prev = Some(TestConfig), + Some(CreateConfig) => error_and_exit!("invalid value for flag `--create-config`"), + Some(Config) => error_and_exit!("invalid value for flag `--config`"), + Some(TestConfig) => error_and_exit!("invalid value for flag `--test-config`"), + }, "--create-config" => match prev { None => prev = Some(CreateConfig), Some(CreateConfig) => error_and_exit!("invalid value for flag `--create-config`"), + Some(TestConfig) => error_and_exit!("invalid value for flag `--test-config`"), Some(Config) => error_and_exit!("invalid value for flag `--config`"), }, "--config" | "-c" => match prev { @@ -119,8 +129,9 @@ fn run_app() -> Result<()> { args.config = Some(String::new()); prev = Some(Config); } - Some(CreateConfig) => error_and_exit!("Duplicate value for flag `--create-config`"), + Some(CreateConfig) => error_and_exit!("invalid value for flag `--create-config`"), Some(Config) => error_and_exit!("invalid value for flag `--config`"), + Some(TestConfig) => error_and_exit!("invalid value for flag `--test-config`"), }, "--help" | "-h" => { args.help = true; @@ -138,6 +149,11 @@ fn run_app() -> Result<()> { args.config = Some(i); prev = None; } + Some(TestConfig) if args.test_config.is_none() => { + args.test_config = Some(i); + prev = None; + } + Some(TestConfig) => error_and_exit!("Duplicate value for flag `--test-config`"), Some(CreateConfig) => error_and_exit!("Duplicate value for flag `--create-config`"), Some(Config) => error_and_exit!("Duplicate value for flag `--config`"), }, @@ -152,6 +168,9 @@ fn run_app() -> Result<()> { println!("\t--help, -h\t\tshow this message and exit"); println!("\t--version, -v\t\tprint version and exit"); println!("\t--create-config[ PATH]\tCreate a sample configuration file with available configuration options. If PATH is not specified, meli will try to create it in $XDG_CONFIG_HOME/meli/config"); + println!( + "\t--test-config PATH\tTest a configuration file for syntax issues or missing options." + ); println!("\t--config PATH, -c PATH\tUse specified configuration file"); return Ok(()); } @@ -165,9 +184,15 @@ fn run_app() -> Result<()> { None => {} Some(CreateConfig) if args.create_config.is_none() => args.create_config = Some("".into()), Some(CreateConfig) => error_and_exit!("Duplicate value for flag `--create-config`"), - Some(Config) => error_and_exit!("error: flag without value: --config"), + Some(Config) => error_and_exit!("error: flag without value: `--config`"), + Some(TestConfig) => error_and_exit!("error: flag without value: `--test-config`"), }; + if let Some(config_path) = args.test_config.as_ref() { + ui::conf::FileSettings::validate(config_path)?; + return Ok(()); + } + if let Some(config_path) = args.create_config.as_mut() { let config_path: PathBuf = if config_path.is_empty() { let xdg_dirs = xdg::BaseDirectories::with_prefix("meli").unwrap(); diff --git a/ui/src/conf.rs b/ui/src/conf.rs index 184c706e..feed7906 100644 --- a/ui/src/conf.rs +++ b/ui/src/conf.rs @@ -231,7 +231,7 @@ impl FileAccount { } #[derive(Debug, Clone, Default, Serialize, Deserialize)] -struct FileSettings { +pub struct FileSettings { accounts: HashMap, #[serde(default)] pager: PagerSettings, @@ -342,6 +342,21 @@ impl FileSettings { Ok(s.unwrap()) } + + pub fn validate(path: &str) -> Result<()> { + let mut file = File::open(path)?; + let mut contents = String::new(); + file.read_to_string(&mut contents)?; + let s: std::result::Result = toml::from_str(&contents); + if let Err(e) = s { + return Err(MeliError::new(format!( + "Config file contains errors: {}", + e.to_string() + ))); + } + + Ok(()) + } } impl Settings {