From dc6094211136e4e4aabe4dce6f0636e17e46395c Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 22 Apr 2019 14:44:33 +0200 Subject: [PATCH 1/3] Add CLI interface for listing dead refs Signed-off-by: Matthias Beyer --- bin/core/imag-ref/src/ui.rs | 43 +++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/bin/core/imag-ref/src/ui.rs b/bin/core/imag-ref/src/ui.rs index 1a264ea5..21b5bb13 100644 --- a/bin/core/imag-ref/src/ui.rs +++ b/bin/core/imag-ref/src/ui.rs @@ -100,6 +100,35 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .multiple(false) .help("Use force to override existing references")) ) + + .subcommand(SubCommand::with_name("list-dead") + .about("List all dead references") + .version("0.1") + .arg(Arg::with_name("ID") + .index(1) + .takes_value(true) + .required(false) + .multiple(true) + .help("Filter these IDs for dead ones") + .value_name("ID")) + + .arg(Arg::with_name("list-dead-pathes") + .long("pathes") + .takes_value(false) + .required(false) + .multiple(false) + .conflicts_with("list-dead-ids") + .help("List pathes which do not exist anymore but are referenced from imag entries")) + + .arg(Arg::with_name("list-dead-ids") + .long("ids") + .takes_value(false) + .required(false) + .multiple(false) + .conflicts_with("list-dead-pathes") + .help("List ids of entries which refer to a path that does not exist")) + ) + } pub struct PathProvider; @@ -134,6 +163,20 @@ impl IdPathProvider for PathProvider { .map_err_trace_exit_unwrap() }, + ("list-dead", 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::, _>>() + .map_err_trace_exit_unwrap() + }, + ("create", _) => { error!("Command does not get IDs as input"); ::std::process::exit(1) From 485779a17660597a04f897cd949b87117c7895f5 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 22 Apr 2019 14:57:10 +0200 Subject: [PATCH 2/3] Implement list-dead subcommand MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch implements a helper in imag-ref to list all dead references either by store id or by path which is referenced. Suggested-by: Leon Schürmann Signed-off-by: Matthias Beyer --- bin/core/imag-ref/src/main.rs | 48 ++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/bin/core/imag-ref/src/main.rs b/bin/core/imag-ref/src/main.rs index adb8d1e2..e1973a30 100644 --- a/bin/core/imag-ref/src/main.rs +++ b/bin/core/imag-ref/src/main.rs @@ -74,9 +74,10 @@ fn main() { .map(|name| { debug!("Call: {}", name); match name { - "deref" => deref(&rt), - "create" => create(&rt), - "remove" => remove(&rt), + "deref" => deref(&rt), + "create" => create(&rt), + "remove" => remove(&rt), + "list-dead" => list_dead(&rt), other => { debug!("Unknown command"); let _ = rt.handle_unknown_subcommand("imag-ref", other, rt.cli()) @@ -161,6 +162,47 @@ fn remove(rt: &Runtime) { }); } +fn list_dead(rt: &Runtime) { + let cfg = get_ref_config(&rt, "imag-ref").map_err_trace_exit_unwrap(); + let cmd = rt.cli().subcommand_matches("list-dead").unwrap(); // safe by main() + let list_path = cmd.is_present("list-dead-pathes"); + let list_id = cmd.is_present("list-dead-ids"); + let mut output = rt.stdout(); + + rt.ids::<::ui::PathProvider>() + .map_err_trace_exit_unwrap() + .into_iter() + .for_each(|id| { + match rt.store().get(id.clone()).map_err_trace_exit_unwrap() { + Some(entry) => { + let entry_path = entry + .as_ref_with_hasher::() + .get_path(&cfg) + .map_err_trace_exit_unwrap(); + + if !entry_path.exists() { + if list_id { + writeln!(output, "{}", entry.get_location().local().display()) + } else if list_path { + writeln!(output, "{}", entry_path.display()) + } else { + unimplemented!() + } + .map_err(Error::from) + .map_err_trace_exit_unwrap(); + + let _ = rt.report_touched(entry.get_location()).unwrap_or_exit(); + } + } + + None => { + error!("Does not exist: {}", id.local().display()); + exit(1) + } + } + }); +} + fn create(rt: &Runtime) { unimplemented!() } From a7f2826bb92d3bc63bfe71dd42ab70559980b4e4 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 27 Apr 2019 01:57:40 +0200 Subject: [PATCH 3/3] Fix: Do only check entries which are a ref We should not try to check entries that are not refs because this will always fail. And because we fail _hard_, the execution of the command fails on the first non-ref-entry and exits the program. Not good for a filter... :-) Signed-off-by: Matthias Beyer --- bin/core/imag-ref/src/main.rs | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/bin/core/imag-ref/src/main.rs b/bin/core/imag-ref/src/main.rs index e1973a30..bd9f6ed6 100644 --- a/bin/core/imag-ref/src/main.rs +++ b/bin/core/imag-ref/src/main.rs @@ -175,23 +175,24 @@ fn list_dead(rt: &Runtime) { .for_each(|id| { match rt.store().get(id.clone()).map_err_trace_exit_unwrap() { Some(entry) => { - let entry_path = entry - .as_ref_with_hasher::() - .get_path(&cfg) - .map_err_trace_exit_unwrap(); + let entry_ref = entry.as_ref_with_hasher::(); - if !entry_path.exists() { - if list_id { - writeln!(output, "{}", entry.get_location().local().display()) - } else if list_path { - writeln!(output, "{}", entry_path.display()) - } else { - unimplemented!() + if entry_ref.is_ref().map_err_trace_exit_unwrap() { // we only care if the entry is a ref + let entry_path = entry_ref.get_path(&cfg).map_err_trace_exit_unwrap(); + + if !entry_path.exists() { + if list_id { + writeln!(output, "{}", entry.get_location().local().display()) + } else if list_path { + writeln!(output, "{}", entry_path.display()) + } else { + unimplemented!() + } + .map_err(Error::from) + .map_err_trace_exit_unwrap(); + + let _ = rt.report_touched(entry.get_location()).unwrap_or_exit(); } - .map_err(Error::from) - .map_err_trace_exit_unwrap(); - - let _ = rt.report_touched(entry.get_location()).unwrap_or_exit(); } }