From 73f9f2d36fae06981f0b91c194da70de3a75adda Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 6 Aug 2016 17:43:28 +0200 Subject: [PATCH 01/46] Add dependency: clap --- bin/Cargo.toml | 1 + bin/src/main.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/bin/Cargo.toml b/bin/Cargo.toml index d9aa7856..4514928c 100644 --- a/bin/Cargo.toml +++ b/bin/Cargo.toml @@ -7,4 +7,5 @@ authors = ["Matthias Beyer "] version = "2.0" walkdir = "0.1.5" crossbeam = "0.2.9" +clap = "2.*" diff --git a/bin/src/main.rs b/bin/src/main.rs index 9dc48b5b..dff9ca8d 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -1,4 +1,5 @@ extern crate crossbeam; +extern crate clap; #[macro_use] extern crate version; extern crate walkdir; From 6909410a43fa52a404e81d9173f339171136ad54 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 6 Aug 2016 17:44:28 +0200 Subject: [PATCH 02/46] Add dependency: libimagrt --- bin/Cargo.toml | 3 +++ bin/src/main.rs | 2 ++ 2 files changed, 5 insertions(+) diff --git a/bin/Cargo.toml b/bin/Cargo.toml index 4514928c..9daddb9e 100644 --- a/bin/Cargo.toml +++ b/bin/Cargo.toml @@ -9,3 +9,6 @@ walkdir = "0.1.5" crossbeam = "0.2.9" clap = "2.*" +[dependencies.libimagrt] +path = "../libimagrt" + diff --git a/bin/src/main.rs b/bin/src/main.rs index dff9ca8d..90423c37 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -3,6 +3,8 @@ extern crate clap; #[macro_use] extern crate version; extern crate walkdir; +extern crate libimagrt; + use std::env; use std::process::exit; use std::process::Command; From ecbbc3dfc166f5486cb17c9def17caf964e8fd60 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 6 Aug 2016 17:55:52 +0200 Subject: [PATCH 03/46] Rewrite imag binary --- bin/src/main.rs | 141 ++++++++++++++++++++++++------------------------ 1 file changed, 69 insertions(+), 72 deletions(-) diff --git a/bin/src/main.rs b/bin/src/main.rs index 90423c37..fb6dba6a 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -13,8 +13,9 @@ use std::io::ErrorKind; use walkdir::WalkDir; use crossbeam::*; +use clap::{Arg, SubCommand}; -const DBG_FLAG: &'static str = "--debug"; +use libimagrt::runtime::Runtime; fn help(cmds: Vec) { println!(r#" @@ -100,88 +101,86 @@ fn get_commands() -> Vec { execs } -fn find_command() -> Option { - env::args().skip(1).filter(|x| !x.starts_with("-")).next() -} - -fn find_flag() -> Option { - env::args().skip(1).filter(|x| x.starts_with("-")).next() -} - -fn is_debug_flag>(ref s: &T) -> bool { - s.as_ref() == DBG_FLAG -} - -fn find_args(command: &str) -> Vec { - env::args() - .skip(1) - .position(|e| e == command) - .map(|pos| env::args().skip(pos + 2).collect::>()) - .unwrap_or(vec![]) -} - fn main() { - let commands = get_commands(); - let mut args = env::args(); - let _ = args.next(); - let first_arg = match find_command() { - Some(s) => s, - None => match find_flag() { - Some(s) => s, - None => { - help(commands); - exit(0); - }, - }, - }; - let is_debug = env::args().skip(1).find(is_debug_flag).is_some(); + let appname = "imag"; + let version = &version!(); + let about = "imag - the PIM suite for the commandline"; + let mut app = Runtime::get_default_cli_builder(appname, version, about); - match &first_arg[..] { - "--help" | "-h" => { - help(commands); - exit(0); - }, + let commands = get_commands(); - "--version" => println!("imag {}", &version!()[..]), + for command in commands.iter() { + let s = SubCommand::with_name(&command[..]); + app = app.subcommand(s) + } - "--versions" => { - let mut result = vec![]; - for command in commands.iter() { - result.push(crossbeam::scope(|scope| { - scope.spawn(|| { - let v = Command::new(command).arg("--version").output(); - match v { - Ok(v) => match String::from_utf8(v.stdout) { - Ok(s) => format!("{} -> {}", command, s), - Err(e) => format!("Failed calling {} -> {:?}", command, e), - }, + let app = app.arg(Arg::with_name("version") + .long("version") + .takes_value(false) + .required(false) + .multiple(false) + .help("Get the version of imag")) + .arg(Arg::with_name("versions") + .long("versions") + .takes_value(false) + .required(false) + .multiple(false) + .help("Get the versions of the imag commands")); + + let matches = app.get_matches(); + + if matches.is_present("version") { + println!("imag {}", &version!()[..]); + exit(0); + } + + if matches.is_present("versions") { + let mut result = vec![]; + for command in commands.iter() { + result.push(crossbeam::scope(|scope| { + scope.spawn(|| { + let v = Command::new(command).arg("--version").output(); + match v { + Ok(v) => match String::from_utf8(v.stdout) { + Ok(s) => format!("{} -> {}", command, s), Err(e) => format!("Failed calling {} -> {:?}", command, e), - } - }) - })) + }, + Err(e) => format!("Failed calling {} -> {:?}", command, e), + } + }) + })) + } + + for versionstring in result.into_iter().map(|handle| handle.join()) { + println!("{}", versionstring); + } + } + + matches.subcommand_name() + .map(|subcommand| { + + let mut subcommand_args = vec![]; + + for arg in Runtime::arg_names() { + matches.value_of(arg) + .map(|value| { + subcommand_args.push(arg); + subcommand_args.push(value); + }); } - for versionstring in result.into_iter().map(|handle| handle.join()) { - println!("{}", versionstring); - } - }, - - s => { - let mut subcommand_args = find_args(s); - if is_debug && subcommand_args.iter().find(is_debug_flag).is_none() { - subcommand_args.insert(0, String::from(DBG_FLAG)); - } - match Command::new(format!("imag-{}", s)) + match Command::new(format!("imag-{}", subcommand)) .stdin(Stdio::inherit()) .stdout(Stdio::inherit()) .stderr(Stdio::inherit()) + .arg(subcommand) .args(&subcommand_args[..]) .spawn() .and_then(|mut handle| handle.wait()) { Ok(exit_status) => { if !exit_status.success() { - println!("{} exited with non-zero exit code", s); + println!("{} exited with non-zero exit code", subcommand); exit(exit_status.code().unwrap_or(42)); } }, @@ -189,11 +188,11 @@ fn main() { Err(e) => { match e.kind() { ErrorKind::NotFound => { - println!("No such command: 'imag-{}'", s); + println!("No such command: 'imag-{}'", subcommand); exit(2); }, ErrorKind::PermissionDenied => { - println!("No permission to execute: 'imag-{}'", s); + println!("No permission to execute: 'imag-{}'", subcommand); exit(1); }, _ => { @@ -203,7 +202,5 @@ fn main() { } } } - - }, - } + }); } From cd70c68a01b171ca6098550c9c034c01e826fd16 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 7 Aug 2016 14:31:34 +0200 Subject: [PATCH 04/46] Add support for --help and -h --- bin/src/main.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/bin/src/main.rs b/bin/src/main.rs index fb6dba6a..03cedd72 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -125,10 +125,23 @@ fn main() { .takes_value(false) .required(false) .multiple(false) - .help("Get the versions of the imag commands")); + .help("Get the versions of the imag commands")) + .arg(Arg::with_name("help") + .long("help") + .short("h") + .takes_value(false) + .required(false) + .multiple(false) + .help("Show help")); + let matches = app.get_matches(); + if matches.is_present("help") { + help(get_commands()); + exit(0); + } + if matches.is_present("version") { println!("imag {}", &version!()[..]); exit(0); From fa379a2fa730c495e30d564a95d6a3223b00c5fc Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 7 Aug 2016 15:11:48 +0200 Subject: [PATCH 05/46] Only return subcommand name --- bin/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/src/main.rs b/bin/src/main.rs index 03cedd72..d40a022b 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -84,7 +84,7 @@ fn get_commands() -> Vec { .filter_map(|path| { path.file_name() .to_str() - .and_then(|s| s.splitn(2, "-").nth(1).map(|s| format!("imag {}", s))) + .and_then(|s| s.splitn(2, "-").nth(1).map(String::from)) }) .collect() }) From 58fd2dbfe44f6213b3b9f13dd78063b1cbd0f78e Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 7 Aug 2016 15:19:20 +0200 Subject: [PATCH 06/46] Shrink App setup code --- bin/src/main.rs | 60 ++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/bin/src/main.rs b/bin/src/main.rs index d40a022b..7a2f3d0e 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -102,40 +102,34 @@ fn get_commands() -> Vec { } fn main() { - let appname = "imag"; - let version = &version!(); - let about = "imag - the PIM suite for the commandline"; - let mut app = Runtime::get_default_cli_builder(appname, version, about); - + let appname = "imag"; + let version = &version!(); + let about = "imag - the PIM suite for the commandline"; let commands = get_commands(); - - for command in commands.iter() { - let s = SubCommand::with_name(&command[..]); - app = app.subcommand(s) - } - - let app = app.arg(Arg::with_name("version") - .long("version") - .takes_value(false) - .required(false) - .multiple(false) - .help("Get the version of imag")) - .arg(Arg::with_name("versions") - .long("versions") - .takes_value(false) - .required(false) - .multiple(false) - .help("Get the versions of the imag commands")) - .arg(Arg::with_name("help") - .long("help") - .short("h") - .takes_value(false) - .required(false) - .multiple(false) - .help("Show help")); - - - let matches = app.get_matches(); + let r = Runtime::get_default_cli_builder(appname, version, about); + let matches = commands + .iter() + .fold(r, |app, cmd| app.subcommand(SubCommand::with_name(cmd))) + .arg(Arg::with_name("version") + .long("version") + .takes_value(false) + .required(false) + .multiple(false) + .help("Get the version of imag")) + .arg(Arg::with_name("versions") + .long("versions") + .takes_value(false) + .required(false) + .multiple(false) + .help("Get the versions of the imag commands")) + .arg(Arg::with_name("help") + .long("help") + .short("h") + .takes_value(false) + .required(false) + .multiple(false) + .help("Show help")) + .get_matches(); if matches.is_present("help") { help(get_commands()); From 58b2597bcb0596a7e8531908c71c127eab2ce482 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 26 Aug 2016 16:35:15 +0200 Subject: [PATCH 07/46] Enable forwarding of args and subcommands --- bin/src/main.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bin/src/main.rs b/bin/src/main.rs index 7a2f3d0e..a17c0801 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -13,7 +13,7 @@ use std::io::ErrorKind; use walkdir::WalkDir; use crossbeam::*; -use clap::{Arg, SubCommand}; +use clap::{Arg, AppSettings, SubCommand}; use libimagrt::runtime::Runtime; @@ -129,6 +129,8 @@ fn main() { .required(false) .multiple(false) .help("Show help")) + .subcommand(SubCommand::with_name("help").help("Show help")) + .settings(&[AppSettings::AllowExternalSubcommands]) .get_matches(); if matches.is_present("help") { From c4c726a9834790257c6a6d51cfc92ead66e1bcea Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 1 Sep 2016 11:24:31 +0200 Subject: [PATCH 08/46] Add dep: log = 0.3 --- bin/Cargo.toml | 1 + bin/src/main.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/bin/Cargo.toml b/bin/Cargo.toml index 9daddb9e..e07df830 100644 --- a/bin/Cargo.toml +++ b/bin/Cargo.toml @@ -8,6 +8,7 @@ version = "2.0" walkdir = "0.1.5" crossbeam = "0.2.9" clap = "2.*" +log = "0.3" [dependencies.libimagrt] path = "../libimagrt" diff --git a/bin/src/main.rs b/bin/src/main.rs index a17c0801..9ac30fb5 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -1,6 +1,7 @@ extern crate crossbeam; extern crate clap; #[macro_use] extern crate version; +#[macro_use] extern crate log; extern crate walkdir; extern crate libimagrt; From ac7fb1904053eca82bcc55c44bb0e6d7907dda36 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 1 Sep 2016 11:24:53 +0200 Subject: [PATCH 09/46] Use libimagrt::setup::generate_runtime_setup() helper to build Runtime object --- bin/src/main.rs | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/bin/src/main.rs b/bin/src/main.rs index 9ac30fb5..19c8c319 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -14,9 +14,10 @@ use std::io::ErrorKind; use walkdir::WalkDir; use crossbeam::*; -use clap::{Arg, AppSettings, SubCommand}; +use clap::{Arg, App, AppSettings, SubCommand}; use libimagrt::runtime::Runtime; +use libimagrt::setup::generate_runtime_setup; fn help(cmds: Vec) { println!(r#" @@ -102,15 +103,10 @@ fn get_commands() -> Vec { execs } -fn main() { - let appname = "imag"; - let version = &version!(); - let about = "imag - the PIM suite for the commandline"; - let commands = get_commands(); - let r = Runtime::get_default_cli_builder(appname, version, about); - let matches = commands +pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { + get_commands() .iter() - .fold(r, |app, cmd| app.subcommand(SubCommand::with_name(cmd))) + .fold(app, |app, cmd| app.subcommand(SubCommand::with_name(cmd))) .arg(Arg::with_name("version") .long("version") .takes_value(false) @@ -132,21 +128,32 @@ fn main() { .help("Show help")) .subcommand(SubCommand::with_name("help").help("Show help")) .settings(&[AppSettings::AllowExternalSubcommands]) - .get_matches(); +} +fn main() { + let appname = "imag"; + let version = &version!(); + let about = "imag - the PIM suite for the commandline"; + let rt = generate_runtime_setup(appname, version, about, build_ui); + let matches = rt.cli(); + + debug!("matches: {:?}", matches); if matches.is_present("help") { + debug!("Calling help()"); help(get_commands()); exit(0); } if matches.is_present("version") { + debug!("Showing version"); println!("imag {}", &version!()[..]); exit(0); } if matches.is_present("versions") { + debug!("Showing versions"); let mut result = vec![]; - for command in commands.iter() { + for command in get_commands().iter() { result.push(crossbeam::scope(|scope| { scope.spawn(|| { let v = Command::new(command).arg("--version").output(); From 389c5b9033f74b11f6b365d1d7ed78a6db60c14a Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 2 Sep 2016 09:39:34 +0200 Subject: [PATCH 10/46] We do not need to pass the subcommand as arg here --- bin/src/main.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/bin/src/main.rs b/bin/src/main.rs index 19c8c319..75c0934f 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -190,7 +190,6 @@ fn main() { .stdin(Stdio::inherit()) .stdout(Stdio::inherit()) .stderr(Stdio::inherit()) - .arg(subcommand) .args(&subcommand_args[..]) .spawn() .and_then(|mut handle| handle.wait()) From 352d7e90838623b9ed335ed520231418a881446d Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 2 Sep 2016 09:48:02 +0200 Subject: [PATCH 11/46] Add some debugging output --- bin/src/main.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bin/src/main.rs b/bin/src/main.rs index 75c0934f..7c2b3320 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -186,6 +186,8 @@ fn main() { }); } + debug!("Calling 'imag-{}' with args: {:?}", subcommand, subcommand_args); + match Command::new(format!("imag-{}", subcommand)) .stdin(Stdio::inherit()) .stdout(Stdio::inherit()) @@ -196,12 +198,15 @@ fn main() { { Ok(exit_status) => { if !exit_status.success() { + debug!("{} exited with non-zero exit code: {:?}", subcommand, exit_status); println!("{} exited with non-zero exit code", subcommand); exit(exit_status.code().unwrap_or(42)); } + debug!("Successful exit!"); }, Err(e) => { + debug!("Error calling the subcommand"); match e.kind() { ErrorKind::NotFound => { println!("No such command: 'imag-{}'", subcommand); From a740dcd7ba40a50dccc86be1653e220514da317f Mon Sep 17 00:00:00 2001 From: Mario Krehl Date: Fri, 2 Sep 2016 16:43:31 +0200 Subject: [PATCH 12/46] Change build_ui to use subcommands() --- bin/src/main.rs | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/bin/src/main.rs b/bin/src/main.rs index 7c2b3320..70fd5097 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -104,9 +104,8 @@ fn get_commands() -> Vec { } pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { - get_commands() - .iter() - .fold(app, |app, cmd| app.subcommand(SubCommand::with_name(cmd))) + app + .settings(&[AppSettings::AllowExternalSubcommands]) .arg(Arg::with_name("version") .long("version") .takes_value(false) @@ -127,7 +126,10 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .multiple(false) .help("Show help")) .subcommand(SubCommand::with_name("help").help("Show help")) - .settings(&[AppSettings::AllowExternalSubcommands]) + .subcommands(get_commands() + .iter() + .map(|cmd| SubCommand::with_name(cmd)) + ) } fn main() { @@ -173,19 +175,9 @@ fn main() { } } - matches.subcommand_name() - .map(|subcommand| { - - let mut subcommand_args = vec![]; - - for arg in Runtime::arg_names() { - matches.value_of(arg) - .map(|value| { - subcommand_args.push(arg); - subcommand_args.push(value); - }); - } - + match matches.subcommand() { + (subcommand, Some(scmd)) => { + let subcommand_args : Vec<&str> = scmd.values_of(subcommand).unwrap().collect(); debug!("Calling 'imag-{}' with args: {:?}", subcommand, subcommand_args); match Command::new(format!("imag-{}", subcommand)) @@ -223,5 +215,10 @@ fn main() { } } } - }); + }, + // clap ensures we have valid input by exiting if not. + // The above case is a catch-all for subcommands, + // so nothing else needs to be expexted. + _ => unreachable!(), + } } From 1900d6922c0372aebdc5adce85f4de4cc4637b80 Mon Sep 17 00:00:00 2001 From: mario Date: Sat, 3 Sep 2016 12:39:21 +0200 Subject: [PATCH 13/46] Fix clap for external subcommands --- bin/src/main.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/bin/src/main.rs b/bin/src/main.rs index 70fd5097..f8e0ccc8 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -126,10 +126,6 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .multiple(false) .help("Show help")) .subcommand(SubCommand::with_name("help").help("Show help")) - .subcommands(get_commands() - .iter() - .map(|cmd| SubCommand::with_name(cmd)) - ) } fn main() { @@ -177,7 +173,7 @@ fn main() { match matches.subcommand() { (subcommand, Some(scmd)) => { - let subcommand_args : Vec<&str> = scmd.values_of(subcommand).unwrap().collect(); + let subcommand_args : Vec<&str> = scmd.values_of("").unwrap().collect(); debug!("Calling 'imag-{}' with args: {:?}", subcommand, subcommand_args); match Command::new(format!("imag-{}", subcommand)) @@ -202,6 +198,7 @@ fn main() { match e.kind() { ErrorKind::NotFound => { println!("No such command: 'imag-{}'", subcommand); + println!("See 'imag --help' for available subcommands"); exit(2); }, ErrorKind::PermissionDenied => { From 882b2ef5a75307f9988e2cb9646449bf5ea8f311 Mon Sep 17 00:00:00 2001 From: mario Date: Sat, 3 Sep 2016 14:58:14 +0200 Subject: [PATCH 14/46] Add help_text() Replaces the help() functions with help_text(), which returns the help_text of imag. Use the .help() function of clap::App to overwrite the help text generated by clap Remove unneeded argument '--help', generated by clap now --- bin/src/main.rs | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/bin/src/main.rs b/bin/src/main.rs index f8e0ccc8..7076a2ea 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -19,8 +19,8 @@ use clap::{Arg, App, AppSettings, SubCommand}; use libimagrt::runtime::Runtime; use libimagrt::setup::generate_runtime_setup; -fn help(cmds: Vec) { - println!(r#" +fn help_text(cmds: Vec) -> String { + let text = format!(r#" _ (_)_ __ ___ __ _ __ _ @@ -39,13 +39,8 @@ fn help(cmds: Vec) { modules can be used independently. Available commands: - "#); - for cmd in cmds.iter() { - println!("\t{}", cmd); - } - - println!(r#" + {imagbins} Call a command with 'imag ' Each command can be called with "--help" to get the respective helptext. @@ -55,9 +50,16 @@ fn help(cmds: Vec) { imag is free software. It is released under the terms of LGPLv2.1 - (c) 2016 Matthias Beyer and contributors"#); + (c) 2016 Matthias Beyer and contributors"#, imagbins = cmds.into_iter() + .map(|cmd| format!("\t{}\n", cmd)) + .fold(String::new(), |s, c| { + let s = s + c.as_str(); + s + })); + text } + fn get_commands() -> Vec { let path = env::var("PATH"); if path.is_err() { @@ -118,14 +120,8 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .required(false) .multiple(false) .help("Get the versions of the imag commands")) - .arg(Arg::with_name("help") - .long("help") - .short("h") - .takes_value(false) - .required(false) - .multiple(false) - .help("Show help")) .subcommand(SubCommand::with_name("help").help("Show help")) + .help(help_text(get_commands())) } fn main() { @@ -136,11 +132,6 @@ fn main() { let matches = rt.cli(); debug!("matches: {:?}", matches); - if matches.is_present("help") { - debug!("Calling help()"); - help(get_commands()); - exit(0); - } if matches.is_present("version") { debug!("Showing version"); From d19243e7a8942646e1b3529c61c246862fe31daa Mon Sep 17 00:00:00 2001 From: mario Date: Sat, 3 Sep 2016 17:58:14 +0200 Subject: [PATCH 15/46] Fall back to get_default_cli_builder insert custom help text cleanup not anymore used code --- bin/Cargo.toml | 3 +++ bin/src/main.rs | 32 +++++++++++++++++++------------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/bin/Cargo.toml b/bin/Cargo.toml index e07df830..4befe8dc 100644 --- a/bin/Cargo.toml +++ b/bin/Cargo.toml @@ -13,3 +13,6 @@ log = "0.3" [dependencies.libimagrt] path = "../libimagrt" +[dependencies.libimagerror] +path = "../libimagerror" + diff --git a/bin/src/main.rs b/bin/src/main.rs index 7076a2ea..25d47ce3 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -5,6 +5,7 @@ extern crate clap; extern crate walkdir; extern crate libimagrt; +extern crate libimagerror; use std::env; use std::process::exit; @@ -14,10 +15,10 @@ use std::io::ErrorKind; use walkdir::WalkDir; use crossbeam::*; -use clap::{Arg, App, AppSettings, SubCommand}; +use clap::{Arg, AppSettings, SubCommand}; use libimagrt::runtime::Runtime; -use libimagrt::setup::generate_runtime_setup; +use libimagerror::trace::trace_error; fn help_text(cmds: Vec) -> String { let text = format!(r#" @@ -105,8 +106,14 @@ fn get_commands() -> Vec { execs } -pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { - app + +fn main() { + let appname = "imag"; + let version = &version!(); + let about = "imag - the PIM suite for the commandline"; + let commands = get_commands(); + let helptext = help_text(commands); + let app = Runtime::get_default_cli_builder(appname, version, about) .settings(&[AppSettings::AllowExternalSubcommands]) .arg(Arg::with_name("version") .long("version") @@ -121,15 +128,14 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .multiple(false) .help("Get the versions of the imag commands")) .subcommand(SubCommand::with_name("help").help("Show help")) - .help(help_text(get_commands())) -} - -fn main() { - let appname = "imag"; - let version = &version!(); - let about = "imag - the PIM suite for the commandline"; - let rt = generate_runtime_setup(appname, version, about, build_ui); - let matches = rt.cli(); + .help(helptext.as_str()); + let rt = Runtime::new(app) + .unwrap_or_else(|e| { + println!("Runtime couldn't be setup. Exiting"); + trace_error(&e); + exit(1); + }); + let matches = rt.cli(); debug!("matches: {:?}", matches); From 5ea5f588a964e46fefcac1efabb7f241c719f7ac Mon Sep 17 00:00:00 2001 From: Mario Krehl Date: Wed, 7 Sep 2016 10:12:55 +0200 Subject: [PATCH 16/46] Fix panics due to unwrap on Option::None --- bin/src/main.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bin/src/main.rs b/bin/src/main.rs index 25d47ce3..12af035e 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -170,7 +170,11 @@ fn main() { match matches.subcommand() { (subcommand, Some(scmd)) => { - let subcommand_args : Vec<&str> = scmd.values_of("").unwrap().collect(); + debug!("Calling with subcommand: {}", subcommand); + let subcommand_args : Vec<&str> = match scmd.values_of("") { + Some(values) => values.collect(), + None => Vec::new() + }; debug!("Calling 'imag-{}' with args: {:?}", subcommand, subcommand_args); match Command::new(format!("imag-{}", subcommand)) From e6d48cb31ab6eee22ae5db3e8ace8f882835303f Mon Sep 17 00:00:00 2001 From: Mario Krehl Date: Wed, 7 Sep 2016 10:16:36 +0200 Subject: [PATCH 17/46] Fix exit codes --- bin/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/src/main.rs b/bin/src/main.rs index 12af035e..885f0163 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -189,7 +189,7 @@ fn main() { if !exit_status.success() { debug!("{} exited with non-zero exit code: {:?}", subcommand, exit_status); println!("{} exited with non-zero exit code", subcommand); - exit(exit_status.code().unwrap_or(42)); + exit(exit_status.code().unwrap_or(1)); } debug!("Successful exit!"); }, @@ -208,7 +208,7 @@ fn main() { }, _ => { println!("Error spawning: {:?}", e); - exit(1337); + exit(1); } } } From 7023d1f2027b1402ca837efc626029e2cb1d687f Mon Sep 17 00:00:00 2001 From: Mario Krehl Date: Wed, 7 Sep 2016 10:31:00 +0200 Subject: [PATCH 18/46] Add check if given subcommand is supported --- bin/src/main.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/bin/src/main.rs b/bin/src/main.rs index 885f0163..de383068 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -175,6 +175,13 @@ fn main() { Some(values) => values.collect(), None => Vec::new() }; + + if !get_commands().contains(&String::from(subcommand)) { + println!("No such command: 'imag-{}'", subcommand); + println!("See 'imag --help' for available subcommands"); + exit(2); + } + debug!("Calling 'imag-{}' with args: {:?}", subcommand, subcommand_args); match Command::new(format!("imag-{}", subcommand)) @@ -198,6 +205,8 @@ fn main() { debug!("Error calling the subcommand"); match e.kind() { ErrorKind::NotFound => { + // With the check above, this absolutely should not happen. + // Keeping it to be safe println!("No such command: 'imag-{}'", subcommand); println!("See 'imag --help' for available subcommands"); exit(2); From c828bed0e15cb7b545403c49a1c3b56c53f26488 Mon Sep 17 00:00:00 2001 From: Mario Krehl Date: Wed, 7 Sep 2016 10:37:16 +0200 Subject: [PATCH 19/46] Fix panic! when reaching unreachable!, because imag doesnt do anything without an argument or subcommand --- bin/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/src/main.rs b/bin/src/main.rs index de383068..b708b861 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -114,7 +114,7 @@ fn main() { let commands = get_commands(); let helptext = help_text(commands); let app = Runtime::get_default_cli_builder(appname, version, about) - .settings(&[AppSettings::AllowExternalSubcommands]) + .settings(&[AppSettings::AllowExternalSubcommands, AppSettings::ArgRequiredElseHelp]) .arg(Arg::with_name("version") .long("version") .takes_value(false) From d69b8498e9e82072da70430143b2141f1f85e015 Mon Sep 17 00:00:00 2001 From: Mario Krehl Date: Wed, 7 Sep 2016 11:07:02 +0200 Subject: [PATCH 20/46] Add some comments --- bin/src/main.rs | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/bin/src/main.rs b/bin/src/main.rs index b708b861..4f6f84d7 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -20,6 +20,8 @@ use clap::{Arg, AppSettings, SubCommand}; use libimagrt::runtime::Runtime; use libimagerror::trace::trace_error; +/// Returns the helptext, putting the Strings in cmds as possible +/// subcommands into it fn help_text(cmds: Vec) -> String { let text = format!(r#" @@ -60,7 +62,7 @@ fn help_text(cmds: Vec) -> String { text } - +/// Returns the list of imag-* executables found in $PATH fn get_commands() -> Vec { let path = env::var("PATH"); if path.is_err() { @@ -108,11 +110,12 @@ fn get_commands() -> Vec { fn main() { + // Initialize the Runtime and build the CLI let appname = "imag"; let version = &version!(); let about = "imag - the PIM suite for the commandline"; let commands = get_commands(); - let helptext = help_text(commands); + let helptext = help_text(commands.clone()); let app = Runtime::get_default_cli_builder(appname, version, about) .settings(&[AppSettings::AllowExternalSubcommands, AppSettings::ArgRequiredElseHelp]) .arg(Arg::with_name("version") @@ -139,6 +142,8 @@ fn main() { debug!("matches: {:?}", matches); + // Begin checking for arguments + if matches.is_present("version") { debug!("Showing version"); println!("imag {}", &version!()[..]); @@ -168,15 +173,19 @@ fn main() { } } + // Matches any subcommand given match matches.subcommand() { (subcommand, Some(scmd)) => { - debug!("Calling with subcommand: {}", subcommand); + // Get all given arguments and further subcommands to pass to + // the imag-<> binary + // Providing no arguments is OK, and is therefore ignored here let subcommand_args : Vec<&str> = match scmd.values_of("") { Some(values) => values.collect(), None => Vec::new() }; - if !get_commands().contains(&String::from(subcommand)) { + // Typos happen, so check if the given subcommand is one found in $PATH + if !commands.clone().contains(&String::from(subcommand)) { println!("No such command: 'imag-{}'", subcommand); println!("See 'imag --help' for available subcommands"); exit(2); @@ -184,6 +193,7 @@ fn main() { debug!("Calling 'imag-{}' with args: {:?}", subcommand, subcommand_args); + // Create a Command, and pass it the gathered arguments match Command::new(format!("imag-{}", subcommand)) .stdin(Stdio::inherit()) .stdout(Stdio::inherit()) @@ -223,9 +233,8 @@ fn main() { } } }, - // clap ensures we have valid input by exiting if not. - // The above case is a catch-all for subcommands, - // so nothing else needs to be expexted. - _ => unreachable!(), + // Calling for example 'imag --versions' will lead here, as this option does not exit. + // There's nothing to do in such a case + _ => {}, } } From 12f9175700ce9da71de1c37fa3607b9440bc5828 Mon Sep 17 00:00:00 2001 From: Mario Krehl Date: Wed, 7 Sep 2016 11:14:08 +0200 Subject: [PATCH 21/46] Fix --versions --- bin/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/src/main.rs b/bin/src/main.rs index 4f6f84d7..f8259d52 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -156,7 +156,7 @@ fn main() { for command in get_commands().iter() { result.push(crossbeam::scope(|scope| { scope.spawn(|| { - let v = Command::new(command).arg("--version").output(); + let v = Command::new(format!("imag-{}",command)).arg("--version").output(); match v { Ok(v) => match String::from_utf8(v.stdout) { Ok(s) => format!("{} -> {}", command, s), From e813ab9e3a58c67e7322dd4c74d8b49ac162a569 Mon Sep 17 00:00:00 2001 From: Mario Krehl Date: Wed, 7 Sep 2016 11:24:36 +0200 Subject: [PATCH 22/46] Pretty output of --versions --- bin/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/src/main.rs b/bin/src/main.rs index f8259d52..70aaf5d0 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -159,7 +159,7 @@ fn main() { let v = Command::new(format!("imag-{}",command)).arg("--version").output(); match v { Ok(v) => match String::from_utf8(v.stdout) { - Ok(s) => format!("{} -> {}", command, s), + Ok(s) => format!("{:10} -> {}", command, s), Err(e) => format!("Failed calling {} -> {:?}", command, e), }, Err(e) => format!("Failed calling {} -> {:?}", command, e), @@ -169,7 +169,7 @@ fn main() { } for versionstring in result.into_iter().map(|handle| handle.join()) { - println!("{}", versionstring); + print!("{}", versionstring); } } From e2d3e5597bbfb64b337de207eb0af67922ab62f4 Mon Sep 17 00:00:00 2001 From: Mario Krehl Date: Wed, 7 Sep 2016 12:53:38 +0200 Subject: [PATCH 23/46] Fix differing amount of newlines from subprocesses influences output --- bin/src/main.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bin/src/main.rs b/bin/src/main.rs index 70aaf5d0..afe37cbb 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -169,7 +169,8 @@ fn main() { } for versionstring in result.into_iter().map(|handle| handle.join()) { - print!("{}", versionstring); + // The amount of newlines may differ depending on the subprocess + println!("{}", versionstring.trim()); } } From 6fe440880070e53bc7c1a68d2941cbc108909691 Mon Sep 17 00:00:00 2001 From: Mario Krehl Date: Wed, 7 Sep 2016 12:57:34 +0200 Subject: [PATCH 24/46] Reduce clone()-ing of commands to necessary places --- bin/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/src/main.rs b/bin/src/main.rs index afe37cbb..71d56820 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -153,7 +153,7 @@ fn main() { if matches.is_present("versions") { debug!("Showing versions"); let mut result = vec![]; - for command in get_commands().iter() { + for command in commands.iter() { result.push(crossbeam::scope(|scope| { scope.spawn(|| { let v = Command::new(format!("imag-{}",command)).arg("--version").output(); @@ -186,7 +186,7 @@ fn main() { }; // Typos happen, so check if the given subcommand is one found in $PATH - if !commands.clone().contains(&String::from(subcommand)) { + if !commands.contains(&String::from(subcommand)) { println!("No such command: 'imag-{}'", subcommand); println!("See 'imag --help' for available subcommands"); exit(2); From 46da70070f8d3cecb766cc5d1d8c25220f9fd96e Mon Sep 17 00:00:00 2001 From: Mario Krehl Date: Wed, 7 Sep 2016 17:09:04 +0200 Subject: [PATCH 25/46] Fix imag-bin-install target --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 60826e52..1199a133 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ imag-bin-update: imag-bin-install: @$(ECHO) "\t[IMAG ][INSTALL]" - @$(CARGO) install --path ./bin/Cargo.toml + @$(CARGO) install --force --path ./bin imag-bin-clean: @$(ECHO) "\t[IMAG ][CLEAN ]" From a200031eb1b52fd799c263abf57f9c5a76d09100 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 5 Sep 2016 19:28:08 +0200 Subject: [PATCH 26/46] imag-counter: use util function warn_exit() --- imag-counter/src/interactive.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/imag-counter/src/interactive.rs b/imag-counter/src/interactive.rs index 4dbb810d..d37a0c05 100644 --- a/imag-counter/src/interactive.rs +++ b/imag-counter/src/interactive.rs @@ -10,6 +10,7 @@ use libimagcounter::counter::Counter; use libimagcounter::error::CounterError; use libimagrt::runtime::Runtime; use libimagutil::key_value_split::IntoKeyValue; +use libimagutil::warn_exit::warn_exit; use libimagerror::trace::{trace_error, trace_error_exit}; type Result = RResult; @@ -17,8 +18,7 @@ type Result = RResult; pub fn interactive(rt: &Runtime) { let scmd = rt.cli().subcommand_matches("interactive"); if scmd.is_none() { - debug!("No subcommand"); - exit(1); + warn_exit("No subcommand", 1); } let scmd = scmd.unwrap(); debug!("Found 'interactive' command"); @@ -130,8 +130,7 @@ impl<'a> Display for Binding<'a> { fn compute_pair<'a>(rt: &'a Runtime, spec: &str) -> Result<(char, Binding<'a>)> { let kv = String::from(spec).into_kv(); if kv.is_none() { - debug!("Key-Value parsing failed!"); - exit(1); + warn_exit("Key-Value parsing failed!", 1); } let kv = kv.unwrap(); From ac5ee9fb518562fd52c561e0a2891fc9b975d72e Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 5 Sep 2016 19:29:06 +0200 Subject: [PATCH 27/46] imag-link: Use util function warn_exit() --- imag-link/src/main.rs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/imag-link/src/main.rs b/imag-link/src/main.rs index fd8d9d5d..7f036e6e 100644 --- a/imag-link/src/main.rs +++ b/imag-link/src/main.rs @@ -26,7 +26,6 @@ extern crate libimagstore; extern crate libimagerror; extern crate libimagutil; -use std::process::exit; use std::ops::Deref; use libimagrt::runtime::Runtime; @@ -38,6 +37,7 @@ use libimagstore::store::Store; use libimagerror::trace::{trace_error, trace_error_exit}; use libimagentrylink::external::ExternalLinker; use libimagutil::warn_result::*; +use libimagutil::warn_exit::warn_exit; use clap::ArgMatches; use url::Url; @@ -57,10 +57,7 @@ fn main() { match name { "internal" => handle_internal_linking(&rt), "external" => handle_external_linking(&rt), - _ => { - warn!("No commandline call"); - exit(1); - }, + _ => warn_exit("No commandline call", 1) } }); } @@ -112,8 +109,7 @@ fn handle_internal_linking(rt: &Runtime) { let mut from = { let from = get_from_entry(&rt); if from.is_none() { - warn!("No 'from' entry"); - exit(1); + warn_exit("No 'from' entry", 1); } from.unwrap() }; @@ -122,8 +118,7 @@ fn handle_internal_linking(rt: &Runtime) { let to = { let to = get_to_entries(&rt); if to.is_none() { - warn!("No 'to' entry"); - exit(1); + warn_exit("No 'to' entry", 1); } to.unwrap() }; From 19711219e76a24d7bee0be51d22f5ca012b1e2b9 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 5 Sep 2016 19:30:21 +0200 Subject: [PATCH 28/46] imag-diary: Use util fn warn_exit() --- imag-diary/src/create.rs | 11 +++-------- imag-diary/src/delete.rs | 13 ++++--------- imag-diary/src/edit.rs | 8 ++------ imag-diary/src/list.rs | 9 +++------ imag-diary/src/view.rs | 9 ++------- 5 files changed, 14 insertions(+), 36 deletions(-) diff --git a/imag-diary/src/create.rs b/imag-diary/src/create.rs index 66818527..c715cfaf 100644 --- a/imag-diary/src/create.rs +++ b/imag-diary/src/create.rs @@ -9,15 +9,13 @@ use libimagrt::runtime::Runtime; use libimagerror::trace::trace_error; use libimagdiary::entry::Entry; use libimagdiary::result::Result; +use libimagutil::warn_exit::warn_exit; use util::get_diary_name; pub fn create(rt: &Runtime) { let diaryname = get_diary_name(rt) - .unwrap_or_else(|| { - warn!("No diary selected. Use either the configuration file or the commandline option"); - exit(1) - }); + .unwrap_or_else( || warn_exit("No diary selected. Use either the configuration file or the commandline option", 1)); let prevent_edit = rt.cli().subcommand_matches("create").unwrap().is_present("no-edit"); @@ -78,10 +76,7 @@ pub fn create(rt: &Runtime) { exit(1); }, - None => { - warn!("Unexpected error, cannot continue"); - exit(1); - }, + None => warn_exit("Unexpected error, cannot continue", 1) }; diary.new_entry_by_id(id) diff --git a/imag-diary/src/delete.rs b/imag-diary/src/delete.rs index d5fd75e7..aec5a8eb 100644 --- a/imag-diary/src/delete.rs +++ b/imag-diary/src/delete.rs @@ -1,4 +1,3 @@ -use std::process::exit; use chrono::naive::datetime::NaiveDateTime; use libimagdiary::diary::Diary; @@ -7,16 +6,15 @@ use libimagrt::runtime::Runtime; use libimagerror::trace::trace_error_exit; use libimagtimeui::datetime::DateTime; use libimagtimeui::parse::Parse; +use libimagutil::warn_exit::warn_exit; use util::get_diary_name; pub fn delete(rt: &Runtime) { use libimaginteraction::ask::ask_bool; - let diaryname = get_diary_name(rt).unwrap_or_else(|| { - warn!("No diary selected. Use either the configuration file or the commandline option"); - exit(1); - }); + let diaryname = get_diary_name(rt) + .unwrap_or_else(|| warn_exit("No diary selected. Use either the configuration file or the commandline option", 1)); let diary = Diary::open(rt.store(), &diaryname[..]); debug!("Diary opened: {:?}", diary); @@ -39,10 +37,7 @@ pub fn delete(rt: &Runtime) { Some(Ok(e)) => e, Some(Err(e)) => trace_error_exit(&e, 1), - None => { - warn!("No entry"); - exit(1); - }, + None => warn_exit("No entry", 1) }; if !ask_bool(&format!("Deleting {:?}", to_del.get_location())[..], Some(true)) { diff --git a/imag-diary/src/edit.rs b/imag-diary/src/edit.rs index 7b79aa26..88dd5eef 100644 --- a/imag-diary/src/edit.rs +++ b/imag-diary/src/edit.rs @@ -1,4 +1,3 @@ -use std::process::exit; use chrono::naive::datetime::NaiveDateTime; use libimagdiary::diary::Diary; @@ -11,15 +10,12 @@ use libimagerror::trace::trace_error; use libimagerror::into::IntoError; use libimagtimeui::datetime::DateTime; use libimagtimeui::parse::Parse; +use libimagutil::warn_exit::warn_exit; use util::get_diary_name; pub fn edit(rt: &Runtime) { - let diaryname = get_diary_name(rt).unwrap_or_else(|| { - warn!("No diary name"); - exit(1); - }); - + let diaryname = get_diary_name(rt).unwrap_or_else(|| warn_exit("No diary name", 1)); let diary = Diary::open(rt.store(), &diaryname[..]); let datetime : Option = rt diff --git a/imag-diary/src/list.rs b/imag-diary/src/list.rs index 757cf3a1..72d2d5ab 100644 --- a/imag-diary/src/list.rs +++ b/imag-diary/src/list.rs @@ -1,5 +1,3 @@ -use std::process::exit; - use libimagdiary::diary::Diary; use libimagdiary::error::DiaryErrorKind as DEK; use libimagdiary::error::MapErrInto; @@ -8,14 +6,13 @@ use libimagentrylist::lister::Lister; use libimagrt::runtime::Runtime; use libimagstore::store::Entry; use libimagerror::trace::trace_error; +use libimagutil::warn_exit::warn_exit; use util::get_diary_name; pub fn list(rt: &Runtime) { - let diaryname = get_diary_name(rt).unwrap_or_else(|| { - warn!("No diary selected. Use either the configuration file or the commandline option"); - exit(1); - }); + let diaryname = get_diary_name(rt) + .unwrap_or_else(|| warn_exit("No diary selected. Use either the configuration file or the commandline option", 1)); fn entry_to_location_listing_string(e: &Entry) -> String { e.get_location().clone() diff --git a/imag-diary/src/view.rs b/imag-diary/src/view.rs index c214eafe..742bc262 100644 --- a/imag-diary/src/view.rs +++ b/imag-diary/src/view.rs @@ -1,19 +1,14 @@ -use std::process::exit; - use libimagdiary::diary::Diary; use libimagentryview::viewer::Viewer; use libimagentryview::builtin::plain::PlainViewer; use libimagrt::runtime::Runtime; use libimagerror::trace::trace_error; +use libimagutil::warn_exit::warn_exit; use util::get_diary_name; pub fn view(rt: &Runtime) { - let diaryname = get_diary_name(rt).unwrap_or_else(|| { - warn!("No diary name"); - exit(1); - }); - + let diaryname = get_diary_name(rt).unwrap_or_else(|| warn_exit("No diary name", 1)); let diary = Diary::open(rt.store(), &diaryname[..]); let show_header = rt.cli().subcommand_matches("view").unwrap().is_present("show-header"); From c91de877d018ac11a475d35649504678d41c6fc8 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 5 Sep 2016 19:33:39 +0200 Subject: [PATCH 29/46] imag-tag: Use util fn warn_exit() --- imag-tag/Cargo.toml | 3 +++ imag-tag/src/main.rs | 7 +++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/imag-tag/Cargo.toml b/imag-tag/Cargo.toml index 4028ec62..33a36544 100644 --- a/imag-tag/Cargo.toml +++ b/imag-tag/Cargo.toml @@ -22,3 +22,6 @@ path = "../libimagerror" [dependencies.libimagentrytag] path = "../libimagentrytag" +[dependencies.libimagutil] +path = "../libimagutil" + diff --git a/imag-tag/src/main.rs b/imag-tag/src/main.rs index f7c91dd0..92d3b7f3 100644 --- a/imag-tag/src/main.rs +++ b/imag-tag/src/main.rs @@ -8,6 +8,7 @@ extern crate libimagstore; extern crate libimagrt; extern crate libimagentrytag; extern crate libimagerror; +extern crate libimagutil; use std::process::exit; use std::path::PathBuf; @@ -19,6 +20,7 @@ use libimagentrytag::tag::Tag; use libimagerror::trace::{trace_error, trace_error_exit}; use libimagentrytag::ui::{get_add_tags, get_remove_tags}; use libimagstore::storeid::StoreId; +use libimagutil::warn_exit::warn_exit; mod ui; @@ -103,10 +105,7 @@ fn list(id: PathBuf, rt: &Runtime) { let entry = match rt.store().get(path.clone()) { Ok(Some(e)) => e, - Ok(None) => { - info!("No entry found."); - exit(1); - }, + Ok(None) => warn_exit("No entry found.", 1), Err(e) => { warn!("Could not get entry '{:?}'", path); From 0635bffd789b95fa9ae8b363be65e25329893191 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 5 Sep 2016 19:34:12 +0200 Subject: [PATCH 30/46] imag-store: Use util fn warn_exit() --- imag-store/src/delete.rs | 11 +++-------- imag-store/src/verify.rs | 6 ++---- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/imag-store/src/delete.rs b/imag-store/src/delete.rs index 537b638d..70594e2a 100644 --- a/imag-store/src/delete.rs +++ b/imag-store/src/delete.rs @@ -3,6 +3,7 @@ use std::path::PathBuf; use libimagrt::runtime::Runtime; use libimagerror::trace::trace_error_exit; use libimagstore::storeid::StoreId; +use libimagutil::warn_exit::warn_exit; pub fn delete(rt: &Runtime) { use std::process::exit; @@ -24,14 +25,8 @@ pub fn delete(rt: &Runtime) { exit(1); }) }) - .or_else(|| { - warn!("No ID passed. Will exit now"); - exit(1); - }) + .or_else(|| warn_exit("No ID passed. Will exit now", 1)) }) - .or_else(|| { - warn!("No subcommand 'delete'. Will exit now"); - exit(1); - }); + .or_else(|| warn_exit("No subcommand 'delete'. Will exit now", 1)); } diff --git a/imag-store/src/verify.rs b/imag-store/src/verify.rs index ca836e3f..b22d5909 100644 --- a/imag-store/src/verify.rs +++ b/imag-store/src/verify.rs @@ -1,13 +1,11 @@ -use std::process::exit; - use libimagrt::runtime::Runtime; +use libimagutil::warn_exit::warn_exit; pub fn verify(rt: &Runtime) { if rt.store().verify() { info!("Store seems to be fine"); } else { - warn!("Store seems to be broken somehow"); - exit(1); + warn_exit("Store seems to be broken somehow", 1); } } From d5d83400fab342df1f658ab55cb15ebab4481eee Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 6 Sep 2016 11:03:55 +0200 Subject: [PATCH 31/46] imag-counter: Use utils to map over Err/Ok --- imag-counter/src/list.rs | 6 +++--- imag-counter/src/main.rs | 33 +++++++-------------------------- 2 files changed, 10 insertions(+), 29 deletions(-) diff --git a/imag-counter/src/list.rs b/imag-counter/src/list.rs index 0c16c019..d18ae9b1 100644 --- a/imag-counter/src/list.rs +++ b/imag-counter/src/list.rs @@ -1,5 +1,5 @@ use libimagrt::runtime::Runtime; -use libimagerror::trace::trace_error; +use libimagerror::trace::{MapErrTrace, trace_error}; use libimagcounter::counter::Counter; pub fn list(rt: &Runtime) { @@ -25,11 +25,11 @@ pub fn list(rt: &Runtime) { println!("{} - {} {}", name.unwrap(), value.unwrap(), unit.unwrap()); } }) - .map_err(|e| trace_error(&e)) + .map_err_trace() .ok(); } }) - .map_err(|e| trace_error(&e)) + .map_err_trace() }); } diff --git a/imag-counter/src/main.rs b/imag-counter/src/main.rs index 304bbb5e..c83bba0a 100644 --- a/imag-counter/src/main.rs +++ b/imag-counter/src/main.rs @@ -27,8 +27,9 @@ use std::str::FromStr; use libimagrt::setup::generate_runtime_setup; use libimagcounter::counter::Counter; -use libimagerror::trace::{trace_error, trace_error_exit}; +use libimagerror::trace::MapErrTrace; use libimagutil::key_value_split::IntoKeyValue; +use libimagutil::info_result::*; mod create; mod delete; @@ -73,30 +74,15 @@ fn main() { match action { Action::Inc => { Counter::load(String::from(name), rt.store()) - .map(|mut counter| { - match counter.inc() { - Err(e) => trace_error_exit(&e, 1), - Ok(_) => info!("Ok"), - } - }) + .map(|mut c| c.inc().map_err_trace_exit(1).map_info_str("Ok")) }, Action::Dec => { Counter::load(String::from(name), rt.store()) - .map(|mut counter| { - match counter.dec() { - Err(e) => trace_error_exit(&e, 1), - Ok(_) => info!("Ok"), - } - }) + .map(|mut c| c.dec().map_err_trace_exit(1).map_info_str("Ok")) }, Action::Reset => { Counter::load(String::from(name), rt.store()) - .map(|mut counter| { - match counter.reset() { - Err(e) => trace_error_exit(&e, 1), - Ok(_) => info!("Ok"), - } - }) + .map(|mut c| c.reset().map_err_trace_exit(1).map_info_str("Ok")) }, Action::Set => { let kv = String::from(name).into_kv(); @@ -112,15 +98,10 @@ fn main() { } let value : i64 = value.unwrap(); Counter::load(String::from(key), rt.store()) - .map(|mut counter| { - match counter.set(value) { - Err(e) => trace_error_exit(&e, 1), - Ok(_) => info!("Ok"), - } - }) + .map(|mut c| c.set(value).map_err_trace_exit(1).map_info_str("Ok")) }, } - .map_err(|e| trace_error(&e)) + .map_err_trace() .ok(); }, |name| { From 23a42dcb0d1ccce630b572fb017080992a074a69 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 6 Sep 2016 11:09:42 +0200 Subject: [PATCH 32/46] imag-link: Use Err/Ok map utility functions to refactor code --- imag-link/src/main.rs | 67 +++++++++++++------------------------------ 1 file changed, 20 insertions(+), 47 deletions(-) diff --git a/imag-link/src/main.rs b/imag-link/src/main.rs index 7f036e6e..a30758e5 100644 --- a/imag-link/src/main.rs +++ b/imag-link/src/main.rs @@ -34,10 +34,11 @@ use libimagstore::error::StoreError; use libimagstore::store::Entry; use libimagstore::store::FileLockEntry; use libimagstore::store::Store; -use libimagerror::trace::{trace_error, trace_error_exit}; +use libimagerror::trace::{MapErrTrace, trace_error, trace_error_exit}; use libimagentrylink::external::ExternalLinker; use libimagutil::warn_result::*; use libimagutil::warn_exit::warn_exit; +use libimagutil::info_result::*; use clap::ArgMatches; use url::Url; @@ -89,7 +90,7 @@ fn handle_internal_linking(rt: &Runtime) { println!("{: <3}: {}", i, link); } }) - .map_err(|e| trace_error(&e)) + .map_err_trace() .ok(); }, @@ -236,38 +237,17 @@ fn handle_external_linking(rt: &Runtime) { } fn add_link_to_entry(store: &Store, matches: &ArgMatches, entry: &mut FileLockEntry) { - let link = matches.value_of("add").unwrap(); - - let link = Url::parse(link); - if link.is_err() { - debug!("URL parsing error..."); - trace_error_exit(&link.unwrap_err(), 1); - } - let link = link.unwrap(); - - if let Err(e) = entry.add_external_link(store, link) { - debug!("Error while adding external link..."); - trace_error(&e); - } else { - debug!("Everything worked well"); - info!("Ok"); - } + Url::parse(matches.value_of("add").unwrap()) + .map_err_trace_exit(1) + .map(|link| entry.add_external_link(store, link).map_err_trace().map_info_str("Ok")) + .ok(); } fn remove_link_from_entry(store: &Store, matches: &ArgMatches, entry: &mut FileLockEntry) { - let link = matches.value_of("remove").unwrap(); - - let link = Url::parse(link); - if link.is_err() { - trace_error_exit(&link.unwrap_err(), 1); - } - let link = link.unwrap(); - - if let Err(e) = entry.remove_external_link(store, link) { - trace_error(&e); - } else { - info!("Ok"); - } + Url::parse(matches.value_of("remove").unwrap()) + .map_err_trace_exit(1) + .map(|link| entry.remove_external_link(store, link).map_err_trace().map_info_str("Ok")) + .ok(); } fn set_links_for_entry(store: &Store, matches: &ArgMatches, entry: &mut FileLockEntry) { @@ -289,29 +269,22 @@ fn set_links_for_entry(store: &Store, matches: &ArgMatches, entry: &mut FileLock .filter_map(|x| x) .collect(); - if let Err(e) = entry.set_external_links(store, links) { - trace_error(&e); - } else { - info!("Ok"); - } + entry.set_external_links(store, links) + .map_err_trace() + .map_info_str("Ok") + .ok(); } fn list_links_for_entry(store: &Store, entry: &mut FileLockEntry) { - let res = entry.get_external_links(store) + entry.get_external_links(store) .and_then(|links| { for (i, link) in links.iter().enumerate() { println!("{: <3}: {}", i, link); } Ok(()) - }); - - match res { - Err(e) => { - trace_error(&e); - }, - Ok(_) => { - info!("Ok"); - }, - } + }) + .map_err_trace() + .map_info_str("Ok") + .ok(); } From b9a9fd52c4f529b17a5812e41776e2e8fe4f4744 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 6 Sep 2016 11:13:08 +0200 Subject: [PATCH 33/46] imag-todo: Use Err/Ok utils to map --- imag-todo/src/main.rs | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/imag-todo/src/main.rs b/imag-todo/src/main.rs index 1163fe3c..a5ca650e 100644 --- a/imag-todo/src/main.rs +++ b/imag-todo/src/main.rs @@ -13,7 +13,6 @@ extern crate libimagstore; extern crate libimagerror; extern crate libimagtodo; -use std::process::exit; use std::process::{Command, Stdio}; use std::io::stdin; @@ -22,7 +21,7 @@ use toml::Value; use libimagrt::runtime::Runtime; use libimagrt::setup::generate_runtime_setup; use libimagtodo::task::Task; -use libimagerror::trace::trace_error; +use libimagerror::trace::{MapErrTrace, trace_error, trace_error_exit}; mod ui; @@ -51,18 +50,13 @@ fn tw_hook(rt: &Runtime) { match Task::import(rt.store(), stdin) { Ok((_, line, uuid)) => println!("{}\nTask {} stored in imag", line, uuid), - Err(e) => { - trace_error(&e); - exit(1); - } + Err(e) => trace_error_exit(&e, 1), } } else if subcmd.is_present("delete") { // The used hook is "on-modify". This hook gives two json-objects // per usage und wants one (the second one) back. let stdin = stdin(); - Task::delete_by_imports(rt.store(), stdin.lock()) - .map_err(|e| trace_error(&e)) - .ok(); + Task::delete_by_imports(rt.store(), stdin.lock()).map_err_trace().ok(); } else { // Should not be possible, as one argument is required via // ArgGroup @@ -120,8 +114,6 @@ fn list(rt: &Runtime) { println!("{}", outstring); }); - if let Err(e) = res { - trace_error(&e); - } + res.map_err_trace().ok(); } From 473e6d5b6a9a0cbc94a33426ebc7ddd4af13140b Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 6 Sep 2016 11:21:14 +0200 Subject: [PATCH 34/46] imag-notes: Use Err/Ok utils to map over results and refactor code --- imag-notes/Cargo.toml | 4 +++ imag-notes/src/main.rs | 68 +++++++++++++++++------------------------- 2 files changed, 32 insertions(+), 40 deletions(-) diff --git a/imag-notes/Cargo.toml b/imag-notes/Cargo.toml index 9eff3718..e79b2460 100644 --- a/imag-notes/Cargo.toml +++ b/imag-notes/Cargo.toml @@ -8,6 +8,7 @@ semver = "0.2.1" clap = "2.*" log = "0.3" version = "2.0.1" +itertools = "0.4" [dependencies.libimagrt] path = "../libimagrt" @@ -24,3 +25,6 @@ path = "../libimagentrytag" [dependencies.libimagerror] path = "../libimagerror" +[dependencies.libimagutil] +path = "../libimagutil" + diff --git a/imag-notes/src/main.rs b/imag-notes/src/main.rs index 3e478ca4..475847c0 100644 --- a/imag-notes/src/main.rs +++ b/imag-notes/src/main.rs @@ -2,20 +2,26 @@ extern crate clap; #[macro_use] extern crate log; extern crate semver; #[macro_use] extern crate version; +extern crate itertools; extern crate libimagnotes; extern crate libimagrt; extern crate libimagentryedit; extern crate libimagentrytag; extern crate libimagerror; +extern crate libimagutil; use std::process::exit; +use itertools::Itertools; + use libimagentryedit::edit::Edit; use libimagrt::runtime::Runtime; use libimagrt::setup::generate_runtime_setup; use libimagnotes::note::Note; -use libimagerror::trace::{trace_error, trace_error_exit}; +use libimagerror::trace::{MapErrTrace, trace_error}; +use libimagutil::info_result::*; +use libimagutil::warn_result::WarnResult; mod ui; use ui::build_ui; @@ -48,9 +54,7 @@ fn name_from_cli(rt: &Runtime, subcmd: &str) -> String { fn create(rt: &Runtime) { let name = name_from_cli(rt, "create"); - Note::new(rt.store(), name.clone(), String::new()) - .map_err(|e| trace_error(&e)) - .ok(); + Note::new(rt.store(), name.clone(), String::new()).map_err_trace().ok(); if rt.cli().subcommand_matches("create").unwrap().is_present("edit") && !edit_entry(rt, name) { @@ -60,8 +64,8 @@ fn create(rt: &Runtime) { fn delete(rt: &Runtime) { Note::delete(rt.store(), String::from(name_from_cli(rt, "delete"))) - .map_err(|e| trace_error(&e)) - .map(|_| println!("Ok")) + .map_err_trace() + .map_info_str("Ok") .ok(); } @@ -83,47 +87,31 @@ fn edit_entry(rt: &Runtime, name: String) -> bool { }, }; - if let Err(e) = note.edit_content(rt) { - trace_error(&e); - warn!("Editing failed"); - return false - } - true + note.edit_content(rt).map_err_trace().map_warn_err_str("Editing failed").is_ok() } fn list(rt: &Runtime) { use std::cmp::Ordering; - let iter = Note::all_notes(rt.store()); - if iter.is_err() { - trace_error_exit(&iter.unwrap_err(), 1); - } + Note::all_notes(rt.store()) + .map_err_trace_exit(1) + .map(|iter| { + let notes = iter.filter_map(|note| note.map_err_trace().ok()) + .sort_by(|note_a, note_b| { + if let (Ok(a), Ok(b)) = (note_a.get_name(), note_b.get_name()) { + return a.cmp(&b) + } else { + return Ordering::Greater; + } + }); - let mut iter = iter.unwrap() - .filter_map(|note| { - match note { - Err(e) => { - trace_error(&e); - None - }, - Ok(e) => Some(e) + for note in notes.iter() { + note.get_name() + .map(|name| println!("{}", name)) + .map_err_trace() + .ok(); } }) - .collect::>(); - - iter.sort_by(|note_a, note_b| { - if let (Ok(a), Ok(b)) = (note_a.get_name(), note_b.get_name()) { - return a.cmp(&b) - } else { - return Ordering::Greater; - } - }); - - for note in iter { - note.get_name() - .map(|name| println!("{}", name)) - .map_err(|e| trace_error(&e)) - .ok(); - } + .ok(); } From a39f07f9a56403fab4d0bf361b8fdefb0604077c Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 6 Sep 2016 11:27:30 +0200 Subject: [PATCH 35/46] imag-diary: Use Err/Ok Result map utils to refactor code --- imag-diary/src/edit.rs | 4 ++-- imag-diary/src/list.rs | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/imag-diary/src/edit.rs b/imag-diary/src/edit.rs index 88dd5eef..6c87d130 100644 --- a/imag-diary/src/edit.rs +++ b/imag-diary/src/edit.rs @@ -6,7 +6,7 @@ use libimagdiary::error::DiaryErrorKind as DEK; use libimagdiary::error::MapErrInto; use libimagentryedit::edit::Edit; use libimagrt::runtime::Runtime; -use libimagerror::trace::trace_error; +use libimagerror::trace::MapErrTrace; use libimagerror::into::IntoError; use libimagtimeui::datetime::DateTime; use libimagtimeui::parse::Parse; @@ -37,7 +37,7 @@ pub fn edit(rt: &Runtime) { Some(Err(e)) => Err(e), None => Err(DEK::EntryNotInDiary.into_error()), } - .map_err(|e| trace_error(&e)).ok(); + .map_err_trace().ok(); } diff --git a/imag-diary/src/list.rs b/imag-diary/src/list.rs index 72d2d5ab..bae95ce4 100644 --- a/imag-diary/src/list.rs +++ b/imag-diary/src/list.rs @@ -5,8 +5,9 @@ use libimagentrylist::listers::core::CoreLister; use libimagentrylist::lister::Lister; use libimagrt::runtime::Runtime; use libimagstore::store::Entry; -use libimagerror::trace::trace_error; use libimagutil::warn_exit::warn_exit; +use libimagerror::trace::MapErrTrace; +use libimagutil::debug_result::*; use util::get_diary_name; @@ -18,7 +19,7 @@ pub fn list(rt: &Runtime) { e.get_location().clone() .without_base() .to_str() - .map_err(|e| trace_error(&e)) + .map_err_trace() .unwrap_or(String::from("<>")) } @@ -28,17 +29,16 @@ pub fn list(rt: &Runtime) { .and_then(|es| { debug!("Iterator for listing: {:?}", es); - let es = es.filter_map(|a| { - debug!("Filtering: {:?}", a); - a.ok() - }).map(|e| e.into()); + let es = es + .filter_map(|a| a.map_dbg(|e| format!("Filtering: {:?}", e)).ok()) + .map(|e| e.into()); CoreLister::new(&entry_to_location_listing_string) .list(es) // TODO: Do not ignore non-ok()s .map_err_into(DEK::IOError) }) - .map(|_| debug!("Ok")) - .map_err(|e| trace_error(&e)) + .map_dbg_str("Ok") + .map_err_trace() .ok(); } From daca530dd57065560bb234516ee563047b790474 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 6 Sep 2016 11:27:42 +0200 Subject: [PATCH 36/46] imag-store: Use Err/Ok Result map utils to refactor code --- imag-store/src/delete.rs | 13 +++++-------- imag-store/src/retrieve.rs | 13 ++++++------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/imag-store/src/delete.rs b/imag-store/src/delete.rs index 70594e2a..885a089c 100644 --- a/imag-store/src/delete.rs +++ b/imag-store/src/delete.rs @@ -1,13 +1,12 @@ use std::path::PathBuf; use libimagrt::runtime::Runtime; -use libimagerror::trace::trace_error_exit; +use libimagerror::trace::MapErrTrace; use libimagstore::storeid::StoreId; use libimagutil::warn_exit::warn_exit; +use libimagutil::warn_result::*; pub fn delete(rt: &Runtime) { - use std::process::exit; - rt.cli() .subcommand_matches("delete") .map(|sub| { @@ -15,15 +14,13 @@ pub fn delete(rt: &Runtime) { .map(|id| { let path = PathBuf::from(id); let path = try!(StoreId::new(Some(rt.store().path().clone()), path) - .map_err(|e| trace_error_exit(&e, 1))); + .map_err_trace_exit(1)); debug!("Deleting file at {:?}", id); rt.store() .delete(path) - .map_err(|e| { - warn!("Error: {:?}", e); - exit(1); - }) + .map_warn_err(|e| format!("Error: {:?}", e)) + .map_err_trace_exit(1) }) .or_else(|| warn_exit("No ID passed. Will exit now", 1)) }) diff --git a/imag-store/src/retrieve.rs b/imag-store/src/retrieve.rs index 39b66741..41f8e936 100644 --- a/imag-store/src/retrieve.rs +++ b/imag-store/src/retrieve.rs @@ -6,7 +6,8 @@ use toml::Value; use libimagstore::store::FileLockEntry; use libimagstore::storeid::StoreId; use libimagrt::runtime::Runtime; -use libimagerror::trace::{trace_error, trace_error_exit}; +use libimagerror::trace::MapErrTrace; +use libimagutil::debug_result::*; pub fn retrieve(rt: &Runtime) { rt.cli() @@ -16,18 +17,16 @@ pub fn retrieve(rt: &Runtime) { .map(|id| { let path = PathBuf::from(id); let path = try!(StoreId::new(Some(rt.store().path().clone()), path) - .map_err(|e| trace_error_exit(&e, 1))); + .map_err_trace_exit(1)); debug!("path = {:?}", path); rt.store() // "id" must be present, enforced via clap spec .retrieve(path) .map(|e| print_entry(rt, scmd, e)) - .map_err(|e| { - debug!("No entry."); - debug!("{}:", e); - trace_error(&e); - }) + .map_dbg_str("No entry") + .map_dbg(|e| format!("{:?}", e)) + .map_err_trace() }) }); } From 88ff94fb6d4ddec48f7beb4691bf61df335dbc79 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 8 Sep 2016 15:05:25 +0200 Subject: [PATCH 37/46] Remove StoreId::is_dir() --- libimagstore/src/storeid.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libimagstore/src/storeid.rs b/libimagstore/src/storeid.rs index eaa1ea05..a5c2c11e 100644 --- a/libimagstore/src/storeid.rs +++ b/libimagstore/src/storeid.rs @@ -79,10 +79,6 @@ impl StoreId { true } - pub fn is_dir(&self) -> bool { - false - } - pub fn to_str(&self) -> Result { if self.base.is_some() { let mut base = self.base.as_ref().cloned().unwrap(); From 7b827ff1497e6d7c365b7632b294ef39fcf234a0 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 9 Sep 2016 11:48:10 +0200 Subject: [PATCH 38/46] Add newline before header The lastest release of the `toml-rs` crate (2.1) removes leading spaces before arrays and tables, causing our tests to fail. This fixes it. --- libimagstore/src/store.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libimagstore/src/store.rs b/libimagstore/src/store.rs index 7780c850..ec37470b 100644 --- a/libimagstore/src/store.rs +++ b/libimagstore/src/store.rs @@ -1440,7 +1440,7 @@ impl Entry { } pub fn to_str(&self) -> String { - format!("---{header}---\n{content}", + format!("---\n{header}---\n{content}", header = ::toml::encode_str(&self.header.header), content = self.content) } From ff5a4b46c7ef546a86eaa429bb39c59d8decfaff Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 8 Sep 2016 15:06:56 +0200 Subject: [PATCH 39/46] Remove StoreId::is_file() --- libimagstore/src/storeid.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libimagstore/src/storeid.rs b/libimagstore/src/storeid.rs index a5c2c11e..b2cfc121 100644 --- a/libimagstore/src/storeid.rs +++ b/libimagstore/src/storeid.rs @@ -75,10 +75,6 @@ impl StoreId { self.clone().into_pathbuf().map(|pb| pb.exists()).unwrap_or(false) } - pub fn is_file(&self) -> bool { - true - } - pub fn to_str(&self) -> Result { if self.base.is_some() { let mut base = self.base.as_ref().cloned().unwrap(); From 636674b0592513deef8542bad8fd9272ea90da17 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 8 Sep 2016 16:52:03 +0200 Subject: [PATCH 40/46] All StoreIds point to files, so this check does not make sense here --- libimagstorestdhook/src/linkverify.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/libimagstorestdhook/src/linkverify.rs b/libimagstorestdhook/src/linkverify.rs index 85551999..cf877526 100644 --- a/libimagstorestdhook/src/linkverify.rs +++ b/libimagstorestdhook/src/linkverify.rs @@ -55,8 +55,6 @@ impl NonMutableHookDataAccessor for LinkedEntriesExistHook { for link in links { if !link.exists() { warn!("File link does not exist: {:?} -> {:?}", fle.get_location(), link); - } else if !link.is_file() { - warn!("File link is not a file: {:?} -> {:?}", fle.get_location(), link); } } }) From 501d1f38a2099efcb9580ede596fdb74cb9f23a4 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 8 Sep 2016 17:37:10 +0200 Subject: [PATCH 41/46] Refactor edit_in_tmpfile() To offer variant where we can pass the editor as command. --- libimagentryedit/src/edit.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libimagentryedit/src/edit.rs b/libimagentryedit/src/edit.rs index cdf976a4..cc9bbc64 100644 --- a/libimagentryedit/src/edit.rs +++ b/libimagentryedit/src/edit.rs @@ -39,6 +39,10 @@ impl<'a> Edit for FileLockEntry<'a> { } pub fn edit_in_tmpfile(rt: &Runtime, s: &mut String) -> Result<()> { + edit_in_tmpfile_with_command(rt.editor(), s) +} + +pub fn edit_in_tmpfile_with_command(cmd: Command, s: &mut String) -> Result<()> { use tempfile::NamedTempFile; use std::io::Seek; use std::io::Read; @@ -75,3 +79,4 @@ pub fn edit_in_tmpfile(rt: &Runtime, s: &mut String) -> Result<()> { Err(EditErrorKind::InstantiateError.into()) } } + From 027fffb5b51d9c957741eab07889bc5aed50189b Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 8 Sep 2016 17:44:21 +0200 Subject: [PATCH 42/46] Move edit_entry_with_cmd() to libimagutil --- libimagentryedit/Cargo.toml | 4 ++- libimagentryedit/src/edit.rs | 54 ++++++++++------------------------- libimagentryedit/src/error.rs | 1 + libimagentryedit/src/lib.rs | 2 +- libimagutil/Cargo.toml | 1 + libimagutil/src/edit.rs | 36 +++++++++++++++++++++++ libimagutil/src/lib.rs | 2 ++ 7 files changed, 59 insertions(+), 41 deletions(-) create mode 100644 libimagutil/src/edit.rs diff --git a/libimagentryedit/Cargo.toml b/libimagentryedit/Cargo.toml index 0c79700e..076519fe 100644 --- a/libimagentryedit/Cargo.toml +++ b/libimagentryedit/Cargo.toml @@ -4,7 +4,6 @@ version = "0.2.0" authors = ["Matthias Beyer "] [dependencies] -tempfile = "2.1.1" [dependencies.libimagerror] path = "../libimagerror" @@ -15,3 +14,6 @@ path = "../libimagrt" [dependencies.libimagstore] path = "../libimagstore" +[dependencies.libimagutil] +path = "../libimagutil" + diff --git a/libimagentryedit/src/edit.rs b/libimagentryedit/src/edit.rs index cc9bbc64..08e2bfb4 100644 --- a/libimagentryedit/src/edit.rs +++ b/libimagentryedit/src/edit.rs @@ -39,44 +39,20 @@ impl<'a> Edit for FileLockEntry<'a> { } pub fn edit_in_tmpfile(rt: &Runtime, s: &mut String) -> Result<()> { - edit_in_tmpfile_with_command(rt.editor(), s) -} - -pub fn edit_in_tmpfile_with_command(cmd: Command, s: &mut String) -> Result<()> { - use tempfile::NamedTempFile; - use std::io::Seek; - use std::io::Read; - use std::io::SeekFrom; - use std::io::Write; - - let file = try!(NamedTempFile::new().map_err_into(EditErrorKind::IOError)); - let file_path = file.path(); - let mut file = try!(file.reopen().map_err_into(EditErrorKind::IOError)); - - try!(file.write_all(&s.clone().into_bytes()[..]).map_err_into(EditErrorKind::IOError)); - try!(file.sync_data().map_err_into(EditErrorKind::IOError)); - - if let Some(mut editor) = rt.editor() { - let exit_status = editor.arg(file_path).status(); - - match exit_status.map(|s| s.success()).map_err(Box::new) { - Ok(true) => { - file.sync_data() - .and_then(|_| file.seek(SeekFrom::Start(0))) - .and_then(|_| { - let mut new_s = String::new(); - let res = file.read_to_string(&mut new_s); - *s = new_s; - res - }) - .map(|_| ()) - .map_err_into(EditErrorKind::IOError) - }, - Ok(false) => Err(EditErrorKind::ProcessExitFailure.into()), - Err(e) => Err(EditErrorKind::IOError.into_error_with_cause(e)), - } - } else { - Err(EditErrorKind::InstantiateError.into()) - } + use libimagutil::edit::edit_in_tmpfile_with_command; + + rt.editor() + .ok_or(EditErrorKind::NoEditor.into_error()) + .and_then(|editor| { + edit_in_tmpfile_with_command(editor, s) + .map_err_into(EditErrorKind::IOError) + .and_then(|worked| { + if !worked { + Err(EditErrorKind::ProcessExitFailure.into()) + } else { + Ok(()) + } + }) + }) } diff --git a/libimagentryedit/src/error.rs b/libimagentryedit/src/error.rs index 0cd675e0..776a51fb 100644 --- a/libimagentryedit/src/error.rs +++ b/libimagentryedit/src/error.rs @@ -1,6 +1,7 @@ generate_error_module!( generate_error_types!(EditError, EditErrorKind, IOError => "IO Error", + NoEditor => "No editor set", ProcessExitFailure => "Process did not exit properly", InstantiateError => "Instantation error" ); diff --git a/libimagentryedit/src/lib.rs b/libimagentryedit/src/lib.rs index 62cff1e4..d0a26038 100644 --- a/libimagentryedit/src/lib.rs +++ b/libimagentryedit/src/lib.rs @@ -1,7 +1,7 @@ #[macro_use] extern crate libimagerror; extern crate libimagstore; extern crate libimagrt; -extern crate tempfile; +extern crate libimagutil; pub mod edit; pub mod error; diff --git a/libimagutil/Cargo.toml b/libimagutil/Cargo.toml index 53e0e0ee..87be5306 100644 --- a/libimagutil/Cargo.toml +++ b/libimagutil/Cargo.toml @@ -7,4 +7,5 @@ authors = ["Matthias Beyer "] lazy_static = "0.1.15" log = "0.3" regex = "0.1" +tempfile = "2.1.1" diff --git a/libimagutil/src/edit.rs b/libimagutil/src/edit.rs new file mode 100644 index 00000000..ad23b6ed --- /dev/null +++ b/libimagutil/src/edit.rs @@ -0,0 +1,36 @@ +use std::io::Read; +use std::io::Seek; +use std::io::SeekFrom; +use std::io::Write; +use std::process::Command; +use std::io::Error as IOError; + +use tempfile::NamedTempFile; + +pub fn edit_in_tmpfile_with_command(mut cmd: Command, s: &mut String) -> Result { + let file = try!(NamedTempFile::new()); + let file_path = file.path(); + let mut file = try!(file.reopen()); + + try!(file.write_all(&s.clone().into_bytes()[..])); + try!(file.sync_data()); + + cmd.arg(file_path) + .status() + .and_then(|status| { + if status.success() { + file.sync_data() + .and_then(|_| file.seek(SeekFrom::Start(0))) + .and_then(|_| { + let mut new_s = String::new(); + let res = file.read_to_string(&mut new_s); + *s = new_s; + res + }) + .map(|_| true) + } else { + Ok(false) + } + }) +} + diff --git a/libimagutil/src/lib.rs b/libimagutil/src/lib.rs index 16183e7b..c0026c6f 100644 --- a/libimagutil/src/lib.rs +++ b/libimagutil/src/lib.rs @@ -16,9 +16,11 @@ #[macro_use] extern crate lazy_static; #[macro_use] extern crate log; extern crate regex; +extern crate tempfile; #[macro_use] mod log_result; pub mod debug_result; +pub mod edit; pub mod info_result; pub mod ismatch; pub mod iter; From 797ea9e8526e27f6b79f64275d750cd3e3e60535 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 9 Sep 2016 17:07:29 +0200 Subject: [PATCH 43/46] travis: Use makefile for building things --- .travis.yml | 46 +++++++++++++--------------------------------- 1 file changed, 13 insertions(+), 33 deletions(-) diff --git a/.travis.yml b/.travis.yml index 94325312..77478906 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,49 +20,29 @@ before_script: export PATH=$HOME/.local/bin:$PATH script: - | - travis_cargo_run_in() { - echo ":: Trying to run cargo in $1" - [[ -d "$1" ]] && - cd "$1" && - { - { - if [[ $(echo "$1" | grep lib) ]]; then - travis-cargo -q test - else - travis-cargo -q build - fi - } && - cd - - } || exit 1 - } - - run_sh_test() { - echo "--- Running test script: '$1'" - bash $1 || { echo "--- Test failed. Exiting"; exit 1; } - echo "--- Test script $1 executed successfully" - } - - echo "<< Changes in ./doc are not build by CI >>" - + libs_to_test="$(find . -maxdepth 1 name "libimag*" -printf "test-%f ")" + bins_to_build="$(find . -maxdepth 1 name "imag-*" -printf "%f ")" + make $libs_to_test && \ + make $bins_to_build && \ for d in $(find -name "Cargo.toml" | grep -vE "^./Cargo.toml$"); do - echo ":: Working on $d" dir=$(dirname $d) { \ - echo -e "\n--- Running in $d ---\n" && \ - travis_cargo_run_in $dir && \ - echo "--- Running test scripts ---" && \ - for testsh in $(find $dir -iname "*test.sh"); do - run_sh_test $testsh - done && \ - echo -e "--- Done with test scripts ---\n\n" + echo "--- Running test scripts ---" && \ + for testsh in $(find $dir -iname "*test.sh"); do + echo "--- Running test script: '$1'" + bash $1 || { echo "--- Test failed. Exiting"; exit 1; } + echo "--- Test script $1 executed successfully" + done && \ } || true done + addons: apt: packages: - libcurl4-openssl-dev - - libelf-dev - libdw-dev + - libelf-dev + - make after_success: - | pushd .imag-documentation && From c535e221b914c307803003a9f1bd4700eea00a42 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 9 Sep 2016 17:08:33 +0200 Subject: [PATCH 44/46] Do two matrix builds: one for binaries, one for libraries --- .travis.yml | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 77478906..5982e293 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,21 +20,20 @@ before_script: export PATH=$HOME/.local/bin:$PATH script: - | - libs_to_test="$(find . -maxdepth 1 name "libimag*" -printf "test-%f ")" - bins_to_build="$(find . -maxdepth 1 name "imag-*" -printf "%f ")" - make $libs_to_test && \ - make $bins_to_build && \ - for d in $(find -name "Cargo.toml" | grep -vE "^./Cargo.toml$"); do - dir=$(dirname $d) - { \ - echo "--- Running test scripts ---" && \ + if [[ "$TEST_SUITE" == "binaries" ]]; then + make $(find . -maxdepth 1 -name "imag-*" -type d -printf "%f ") && \ + for d in $(find -name "Cargo.toml" | grep -vE "^./Cargo.toml$"); do + dir=$(dirname $d) + echo "--- Running test scripts ---" for testsh in $(find $dir -iname "*test.sh"); do - echo "--- Running test script: '$1'" - bash $1 || { echo "--- Test failed. Exiting"; exit 1; } - echo "--- Test script $1 executed successfully" - done && \ - } || true - done + echo "--- Running test script: '$testsh'" + bash $testsh || { echo "--- Test failed. Exiting"; exit 1; } + echo "--- Test script $testsh executed successfully" + done + done + else # $TEST_SUITE == "libraries" + make $(find . -maxdepth 1 -name "libimag*" -printf "test-%f ") + fi addons: apt: @@ -58,6 +57,9 @@ notifications: template: - "%{repository_name} (%{branch} @ %{commit} by %{author}): %{result}" env: + matrix: + - TEST_SUITE=binaries + - TEST_SUITE=libraries global: - TRAVIS_CARGO_NIGHTLY_FEATURE=dev - secure: D+3exBnbvzFvk7fvLOxkF7UotCc4gBbvvOW4xGr9u6dDjEjV5y6CdDy/OQAkhfKhvSou+lIC22g5MuCBQXFEf/ua7A1XzwBAFeVLK4cWZSa7+ql6LdHKqOg3oF6pQlh095WeWr8S2PYJFFJFg8RGUPnbjqdu1J4KSXqe/7GoZ3lYS69mx7D5Hb93KEN084/KGfBuvyJtMjO1fK3spltL2zV8oqegFpv0gLG5GY4LsJ/7ij4Mc6wepXSyyQbaiA1eKMMwQZDvoi4V1mCulo/jeC3pucGxvgnMV5DZs8aa8R7votltGvSpHCgU78LW19dg8oZqwShQQ+XUYw27H+QK5V1lz1l1MaJLbwS3ySyZBPGH8qUuOzQ3bLp9xhAIRgCui3kX/UDhmeME7nJI6k3UZydh+/ydNB1BZHTKn76XS/yFj0Gcibxg7f5fcAYA6Ge5Sg+YPozuwbcKnKe6IpN2M7qNgWa+6MCSXJ1v4BgPb7kN74EynJUM8+yWEFN7MZtWEUQ4ZsHdCs8Pub4C/zHpYGV8qGenZwQzosAFq56YwoGCvJezz35yg4BDd3IMKenOzNnXLBrdxxqX8ySgwt5B3zBqwve/64Lx6OXjae2m8wZKlsmeqad/s6K7nx0zG15/qqRIzyvgcLXq3jwBaHkteq49FRFWvHQFpBQcsPZ2uH4= From 12e7544a2a25b4bf590c9081e2a1fb3ab634f264 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 17 Sep 2016 19:25:37 +0200 Subject: [PATCH 45/46] Move code from libimagentryselect to libimaginteraction --- libimagentryselect/Cargo.toml | 16 ------------ libimagentryselect/README.md | 7 ----- libimagentryselect/src/error.rs | 13 ---------- libimagentryselect/src/lib.rs | 26 ------------------- libimagentryselect/src/result.rs | 6 ----- libimaginteraction/Cargo.toml | 9 ++++--- libimaginteraction/src/error.rs | 7 ++++- libimaginteraction/src/lib.rs | 2 ++ .../src/ui.rs | 14 +++++----- 9 files changed, 20 insertions(+), 80 deletions(-) delete mode 100644 libimagentryselect/Cargo.toml delete mode 100644 libimagentryselect/README.md delete mode 100644 libimagentryselect/src/error.rs delete mode 100644 libimagentryselect/src/lib.rs delete mode 100644 libimagentryselect/src/result.rs rename {libimagentryselect => libimaginteraction}/src/ui.rs (81%) diff --git a/libimagentryselect/Cargo.toml b/libimagentryselect/Cargo.toml deleted file mode 100644 index 19424a2c..00000000 --- a/libimagentryselect/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "libimagentryselect" -version = "0.2.0" -authors = ["Matthias Beyer "] - -[dependencies] -clap = "2.*" -log = "0.3" -interactor = "0.1" - -[dependencies.libimagstore] -path = "../libimagstore" - -[dependencies.libimagerror] -path = "../libimagerror" - diff --git a/libimagentryselect/README.md b/libimagentryselect/README.md deleted file mode 100644 index de6c4825..00000000 --- a/libimagentryselect/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# libimagentryselect - -Small library crate for asking the user to _select_ one or more entries out of -a list of entries. - -Not much functionality, yet. - diff --git a/libimagentryselect/src/error.rs b/libimagentryselect/src/error.rs deleted file mode 100644 index 767779e6..00000000 --- a/libimagentryselect/src/error.rs +++ /dev/null @@ -1,13 +0,0 @@ -generate_error_module!( - generate_error_types!(EntrySelectError, EntrySelectErrorKind, - CLIError => "Error on commandline", - IdMissingError => "Commandline: ID missing", - StoreIdParsingError => "Error while parsing StoreId", - IdSelectingError => "Error while selecting id" - ); -); - -pub use self::error::EntrySelectError; -pub use self::error::EntrySelectErrorKind; -pub use self::error::MapErrInto; - diff --git a/libimagentryselect/src/lib.rs b/libimagentryselect/src/lib.rs deleted file mode 100644 index 8f5bcbd3..00000000 --- a/libimagentryselect/src/lib.rs +++ /dev/null @@ -1,26 +0,0 @@ -#![deny( - non_camel_case_types, - non_snake_case, - path_statements, - trivial_numeric_casts, - unstable_features, - unused_allocation, - unused_import_braces, - unused_imports, - unused_mut, - unused_qualifications, - while_true, -)] - -extern crate clap; -extern crate log; -extern crate interactor; - -extern crate libimagstore; -#[macro_use] -extern crate libimagerror; - -pub mod error; -pub mod result; -pub mod ui; - diff --git a/libimagentryselect/src/result.rs b/libimagentryselect/src/result.rs deleted file mode 100644 index db949cf6..00000000 --- a/libimagentryselect/src/result.rs +++ /dev/null @@ -1,6 +0,0 @@ -use std::result::Result as RResult; - -use error::EntrySelectError; - -pub type Result = RResult; - diff --git a/libimaginteraction/Cargo.toml b/libimaginteraction/Cargo.toml index 7a78df33..d13b2823 100644 --- a/libimaginteraction/Cargo.toml +++ b/libimaginteraction/Cargo.toml @@ -4,12 +4,13 @@ version = "0.2.0" authors = ["Matthias Beyer "] [dependencies] -spinner = "0.4" -interactor = "0.1" -log = "0.3" ansi_term = "0.7.2" -regex = "0.1" +clap = "2.*" +interactor = "0.1" lazy_static = "0.1.15" +log = "0.3" +regex = "0.1" +spinner = "0.4" [dependencies.libimagstore] path = "../libimagstore" diff --git a/libimaginteraction/src/error.rs b/libimaginteraction/src/error.rs index 9285f0fd..ff347f1c 100644 --- a/libimaginteraction/src/error.rs +++ b/libimaginteraction/src/error.rs @@ -1,9 +1,14 @@ generate_error_module!( generate_error_types!(InteractionError, InteractionErrorKind, - Unknown => "Unknown Error" + Unknown => "Unknown Error", + CLIError => "Error on commandline", + IdMissingError => "Commandline: ID missing", + StoreIdParsingError => "Error while parsing StoreId", + IdSelectingError => "Error while selecting id" ); ); pub use self::error::InteractionError; pub use self::error::InteractionErrorKind; +pub use self::error::MapErrInto; diff --git a/libimaginteraction/src/lib.rs b/libimaginteraction/src/lib.rs index a608898f..b994ee21 100644 --- a/libimaginteraction/src/lib.rs +++ b/libimaginteraction/src/lib.rs @@ -18,6 +18,7 @@ extern crate interactor; extern crate ansi_term; #[macro_use] extern crate lazy_static; extern crate regex; +extern crate clap; extern crate libimagentryfilter; extern crate libimagstore; @@ -28,4 +29,5 @@ pub mod ask; pub mod error; pub mod filter; pub mod result; +pub mod ui; diff --git a/libimagentryselect/src/ui.rs b/libimaginteraction/src/ui.rs similarity index 81% rename from libimagentryselect/src/ui.rs rename to libimaginteraction/src/ui.rs index e3e41b8a..850a537e 100644 --- a/libimagentryselect/src/ui.rs +++ b/libimaginteraction/src/ui.rs @@ -7,7 +7,7 @@ use libimagerror::into::IntoError; use result::Result; use error::MapErrInto; -use error::EntrySelectErrorKind as ESEK; +use error::InteractionErrorKind as IEK; pub fn id_argument<'a, 'b>() -> Arg<'a, 'b> { Arg::with_name(id_argument_name()) @@ -33,14 +33,14 @@ pub fn id_argument_long() -> &'static str { pub fn get_id(matches: &ArgMatches) -> Result> { matches .values_of(id_argument_name()) - .ok_or(ESEK::IdMissingError.into_error()) - .map_err_into(ESEK::CLIError) + .ok_or(IEK::IdMissingError.into_error()) + .map_err_into(IEK::CLIError) .and_then(|vals| { vals.into_iter() .fold(Ok(vec![]), |acc, elem| { acc.and_then(|mut v| { let elem = StoreId::new_baseless(PathBuf::from(String::from(elem))); - let elem = try!(elem.map_err_into(ESEK::StoreIdParsingError)); + let elem = try!(elem.map_err_into(IEK::StoreIdParsingError)); v.push(elem); Ok(v) }) @@ -51,12 +51,12 @@ pub fn get_id(matches: &ArgMatches) -> Result> { pub fn get_or_select_id(matches: &ArgMatches, store_path: &PathBuf) -> Result> { use interactor::{pick_file, default_menu_cmd}; - match get_id(matches).map_err_into(ESEK::IdSelectingError) { + match get_id(matches).map_err_into(IEK::IdSelectingError) { Ok(v) => Ok(v), Err(_) => { let path = store_path.clone(); - let p = try!(pick_file(default_menu_cmd, path).map_err_into(ESEK::IdSelectingError)); - let id = try!(StoreId::new_baseless(p).map_err_into(ESEK::StoreIdParsingError)); + let p = try!(pick_file(default_menu_cmd, path).map_err_into(IEK::IdSelectingError)); + let id = try!(StoreId::new_baseless(p).map_err_into(IEK::StoreIdParsingError)); Ok(vec![id]) }, } From 23778d407c05bf04084be599a9b419a37c323f66 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 18 Sep 2016 09:48:59 +0200 Subject: [PATCH 46/46] documentation: Remove dependency on libimagentryselect --- .imag-documentation/Cargo.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.imag-documentation/Cargo.toml b/.imag-documentation/Cargo.toml index 0d45f87b..5057179a 100644 --- a/.imag-documentation/Cargo.toml +++ b/.imag-documentation/Cargo.toml @@ -26,9 +26,6 @@ path = "../libimagentrylist" [dependencies.libimagentrymarkdown] path = "../libimagentrymarkdown" -[dependencies.libimagentryselect] -path = "../libimagentryselect" - [dependencies.libimagentrytag] path = "../libimagentrytag"