diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2018-10-23 15:52:13 +0200 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2019-02-17 11:09:48 +0100 |
commit | 49df7f54a940d40aa000243f8da710412cff27e2 (patch) | |
tree | 6257b79250592dddeaf61966bf9014f89f53f739 /bin/core | |
parent | ac5a3c02987d318a126b4f0823ea42fc27a9c875 (diff) |
Rewrite imag-ref
Diffstat (limited to 'bin/core')
-rw-r--r-- | bin/core/imag-ref/src/main.rs | 112 | ||||
-rw-r--r-- | bin/core/imag-ref/src/ui.rs | 108 |
2 files changed, 159 insertions, 61 deletions
diff --git a/bin/core/imag-ref/src/main.rs b/bin/core/imag-ref/src/main.rs index 9d8e131a..332e9477 100644 --- a/bin/core/imag-ref/src/main.rs +++ b/bin/core/imag-ref/src/main.rs @@ -47,15 +47,17 @@ extern crate libimagutil; mod ui; use ui::build_ui; -use std::path::PathBuf; use std::process::exit; +use std::io::Write; use libimagerror::trace::MapErrTrace; use libimagerror::exit::ExitUnwrap; use libimagrt::setup::generate_runtime_setup; use libimagrt::runtime::Runtime; -use libimagstore::storeid::IntoStoreId; use libimagentryref::reference::Ref; +use libimagentryref::reference::MutRef; +use libimagentryref::reference::RefFassade; +use libimagentryref::hasher::default::DefaultHasher; fn main() { let version = make_imag_version!(); @@ -69,6 +71,7 @@ fn main() { debug!("Call: {}", name); match name { "deref" => deref(&rt), + "create" => create(&rt), "remove" => remove(&rt), other => { debug!("Unknown command"); @@ -82,47 +85,43 @@ fn main() { } fn deref(rt: &Runtime) { - let cmd = rt.cli().subcommand_matches("deref").unwrap(); - let id = cmd.value_of("ID") - .map(String::from) - .map(PathBuf::from) - .unwrap() // saved by clap - .into_storeid() - .map_err_trace_exit_unwrap(); - - match rt.store().get(id.clone()).map_err_trace_exit_unwrap() { - Some(entry) => { - entry - .get_path() - .map_err_trace_exit_unwrap() - .to_str() - .ok_or_else(|| { - error!("Could not transform path into string!"); + let cmd = rt.cli().subcommand_matches("deref").unwrap(); + let ids = rt.ids::<::ui::PathProvider>().map_err_trace_exit_unwrap(); + let out = rt.stdout(); + let mut outlock = out.lock(); + + ids.into_iter() + .for_each(|id| { + match rt.store().get(id.clone()).map_err_trace_exit_unwrap() { + Some(entry) => { + entry + .as_ref_with_hasher::<DefaultHasher>() + .get_path() + .map_err_trace_exit_unwrap() + .to_str() + .ok_or_else(|| { + error!("Could not transform path into string!"); + exit(1) + }) + .map(|s| writeln!(outlock, "{}", s)) + .ok(); // safe here because we exited already in the error case + + let _ = rt.report_touched(&id).unwrap_or_exit(); + }, + None => { + error!("No entry for id '{}' found", id); exit(1) - }) - .map(|s| info!("{}", s)) - .ok(); // safe here because we exited already in the error case - - let _ = rt.report_touched(&id).unwrap_or_exit(); - }, - None => { - error!("No entry for id '{}' found", id); - exit(1) - }, - }; + }, + } + }); } fn remove(rt: &Runtime) { use libimaginteraction::ask::ask_bool; - let cmd = rt.cli().subcommand_matches("remove").unwrap(); - let yes = cmd.is_present("yes"); - let id = cmd.value_of("ID") - .map(String::from) - .map(PathBuf::from) - .unwrap() // saved by clap - .into_storeid() - .map_err_trace_exit_unwrap(); + let cmd = rt.cli().subcommand_matches("remove").unwrap(); + let yes = cmd.is_present("yes"); + let ids = rt.ids::<::ui::PathProvider>().map_err_trace_exit_unwrap(); let mut input = rt.stdin().unwrap_or_else(|| { error!("No input stream. Cannot ask for permission"); @@ -131,21 +130,30 @@ fn remove(rt: &Runtime) { let mut output = rt.stdout(); - match rt.store().get(id.clone()).map_err_trace_exit_unwrap() { - Some(mut entry) => { - if yes || - ask_bool(&format!("Delete ref from entry '{}'", id), None, &mut input, &mut output) - .map_err_trace_exit_unwrap() - { - let _ = entry.remove_ref().map_err_trace_exit_unwrap(); - } else { - info!("Aborted"); + ids.into_iter() + .for_each(|id| { + match rt.store().get(id.clone()).map_err_trace_exit_unwrap() { + Some(mut entry) => { + if yes || + ask_bool(&format!("Delete ref from entry '{}'", id), None, &mut input, &mut output) + .map_err_trace_exit_unwrap() + { + let _ = entry.as_ref_with_hasher_mut::<DefaultHasher>() + .remove_ref() + .map_err_trace_exit_unwrap(); + } else { + info!("Aborted"); + } + }, + None => { + error!("No entry for id '{}' found", id); + exit(1) + }, } - }, - None => { - error!("No entry for id '{}' found", id); - exit(1) - }, - }; + }); +} + +fn create(rt: &Runtime) { + unimplemented!() } diff --git a/bin/core/imag-ref/src/ui.rs b/bin/core/imag-ref/src/ui.rs index e7d714ee..c14eafe2 100644 --- a/bin/core/imag-ref/src/ui.rs +++ b/bin/core/imag-ref/src/ui.rs @@ -17,19 +17,34 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // -use clap::{Arg, App, SubCommand}; +use std::path::PathBuf; + +use clap::{Arg, App, ArgMatches, SubCommand}; + +use libimagstore::storeid::StoreId; +use libimagstore::storeid::IntoStoreId; +use libimagrt::runtime::IdPathProvider; +use libimagerror::trace::MapErrTrace; pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { app .subcommand(SubCommand::with_name("deref") - .about("'Dereference' a ref. This prints the Path of the referenced file") + .about("'Dereference a ref. This prints the Path(es) of the referenced file(s)") .version("0.1") .arg(Arg::with_name("ID") .index(1) .takes_value(true) - .required(true) - .help("The id of the store entry to dereference") + .required(false) + .multiple(true) + .help("The id of the store entry to dereference.") .value_name("ID")) + + .arg(Arg::with_name("ignore-noref") + .long("ignore-noref") + .takes_value(false) + .required(false) + .multiple(false) + .help("Ignore store entries which are not refs and do not print error message")) ) .subcommand(SubCommand::with_name("remove") @@ -38,14 +53,89 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .arg(Arg::with_name("ID") .index(1) .takes_value(true) - .required(true) + .required(false) .multiple(true) .help("Remove the reference from this store entry") .value_name("ENTRIES")) - .arg(Arg::with_name("yes") - .long("yes") - .short("y") - .help("Don't ask whether this really should be done")) + .arg(Arg::with_name("ignore-noref") + .long("ignore-noref") + .takes_value(false) + .required(false) + .multiple(false) + .help("Ignore store entries which are not refs and do not print error message")) ) + + .subcommand(SubCommand::with_name("create") + .about("Create a reference to a file") + .version("0.1") + .arg(Arg::with_name("ID") + .index(1) + .takes_value(true) + .required(true) + .multiple(false) + .help("Create a reference with that ID in the store. If the store id exists, it will be made into a reference.") + .value_name("ID")) + + .arg(Arg::with_name("path") + .index(2) + .takes_value(true) + .required(true) + .multiple(false) + .help("The path to refer to. If there is no basepath configuration in the config file for the path this file is located at, the operation will error.") + .value_name("ID")) + + .arg(Arg::with_name("force") + .long("force") + .takes_value(false) + .required(false) + .multiple(false) + .help("Use force to override existing references")) + ) +} + +pub struct PathProvider; +impl IdPathProvider for PathProvider { + fn get_ids(matches: &ArgMatches) -> Vec<StoreId> { + match matches.subcommand() { + ("deref", Some(subm)) => { + subm.values_of("ID") + .ok_or_else(|| { + error!("No StoreId found"); + ::std::process::exit(1) + }) + .unwrap() + .into_iter() + .map(PathBuf::from) + .map(|pb| pb.into_storeid()) + .collect::<Result<Vec<_>, _>>() + .map_err_trace_exit_unwrap() + }, + + ("remove", Some(subm)) => { + subm.values_of("ID") + .ok_or_else(|| { + error!("No StoreId found"); + ::std::process::exit(1) + }) + .unwrap() + .into_iter() + .map(PathBuf::from) + .map(|pb| pb.into_storeid()) + .collect::<Result<Vec<_>, _>>() + .map_err_trace_exit_unwrap() + }, + + ("create", _) => { + error!("Command does not get IDs as input"); + ::std::process::exit(1) + }, + + + (other, _) => { + error!("Not a known command: {}", other); + ::std::process::exit(1) + } + } + } } |