add --help, --config, --create-config arguments

embed
Manos Pitsidianakis 2019-07-11 11:45:09 +03:00
parent 38da6c83b9
commit df5559023d
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
2 changed files with 110 additions and 7 deletions

View File

@ -9,6 +9,7 @@ name = "meli"
path = "src/bin.rs"
[dependencies]
xdg = "2.1.0"
chan = "0.1.21"
chan-signal = "0.3.1"
nix = "*"

View File

@ -25,6 +25,8 @@ The mail handling stuff is done in the `melib` crate which includes all backend
*/
use std::alloc::System;
use std::io::Write;
use std::path::{Path, PathBuf};
#[global_allocator]
static GLOBAL: System = System;
@ -41,15 +43,115 @@ use chan_signal;
use chan_signal::Signal;
use nix;
use xdg;
macro_rules! error_and_exit {
($($err:expr),*) => {{
println!($($err),*);
std::process::exit(1);
}}
}
#[derive(Debug)]
struct CommandLineArguments {
create_config: Option<String>,
config: Option<String>,
help: bool,
}
fn main() {
/* Lock all stdio outs */
//let _stdout = stdout();
//let mut _stdout = _stdout.lock();
/*
let _stderr = stderr();
let mut _stderr = _stderr.lock();
*/
enum CommandLineFlags {
CreateConfig,
Config,
}
use CommandLineFlags::*;
let mut prev: Option<CommandLineFlags> = None;
let mut args = CommandLineArguments {
create_config: None,
config: None,
help: false,
};
for i in std::env::args().skip(1) {
match i.as_str() {
"--create-config" => match prev {
None => prev = Some(CreateConfig),
Some(CreateConfig) => error_and_exit!("invalid value for flag `--create-config`"),
Some(Config) => error_and_exit!("invalid value for flag `--config`"),
},
"--config" | "-c" => match prev {
None => prev = Some(Config),
Some(CreateConfig) if args.create_config.is_none() => {
args.config = Some(String::new());
prev = Some(Config);
}
Some(CreateConfig) => error_and_exit!("Duplicate value for flag `--create-config`"),
Some(Config) => error_and_exit!("invalid value for flag `--config`"),
},
"--help" | "-h" => match prev {
Some(_) => {}
None => args.help = true,
},
e => match prev {
None => error_and_exit!("error: value without command {}", e),
Some(CreateConfig) if args.create_config.is_none() => {
args.create_config = Some(i);
prev = None;
}
Some(Config) if args.config.is_none() => {
args.config = Some(i);
prev = None;
}
Some(CreateConfig) => error_and_exit!("Duplicate value for flag `--create-config`"),
Some(Config) => error_and_exit!("Duplicate value for flag `--config`"),
},
}
}
if args.help {
println!("usage:\tmeli [--create-config[ PATH]] [--config[ PATH]|-c[ PATH]]");
println!("\tmeli --help");
println!("");
println!("\t--help\t\t\tshow this message 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--config PATH, -c PATH\tUse specified configuration file");
std::process::exit(0);
}
match prev {
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"),
};
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();
xdg_dirs.place_config_file("config").unwrap_or_else(|e| {
error_and_exit!("Cannot create configuration directory:\n{}", e)
})
} else {
Path::new(config_path).to_path_buf()
};
if config_path.exists() {
println!("File `{}` already exists.\nMaybe you meant to specify another path with --create-config=PATH", config_path.display());
std::process::exit(1);
}
let mut file = std::fs::OpenOptions::new()
.write(true)
.create_new(true)
.open(config_path.as_path())
.unwrap_or_else(|e| error_and_exit!("Could not create config file:\n{}", e));
file.write_all(include_bytes!("../sample-config"))
.unwrap_or_else(|e| error_and_exit!("Could not write to config file:\n{}", e));
println!("Written example configuration to {}", config_path.display());
std::process::exit(0);
}
if let Some(config_location) = args.config.as_ref() {
std::env::set_var("MELI_CONFIG", config_location);
}
/* Catch SIGWINCH to handle terminal resizing */
let signal = chan_signal::notify(&[Signal::WINCH]);