From dc3de04afdde457dade00652980c217163a80569 Mon Sep 17 00:00:00 2001 From: Vincent de Phily Date: Fri, 22 Sep 2023 19:55:09 +0100 Subject: [PATCH] cli: Allow multiple --tmpdir values Each folder will be tried in turn. --- CHANGELOG.md | 1 + src/cli.rs | 48 +++++++++++++++++++++++++++++++------------- src/commands.rs | 4 ++-- src/parse/current.rs | 14 ++++++++----- 4 files changed, 46 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe5d4e8..1c77117 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ * Support searching by multiple terms - eg `emlop s -e gcc clang llvm rust` +* Support multiple `--tmpdir`s * Upgraded clap dependency - Inline help styling/content changed a bit diff --git a/src/cli.rs b/src/cli.rs index bd47b3a..b3b94b5 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -11,6 +11,7 @@ pub fn build_cli_nocomplete() -> Command { // Workaround bad alignment, might be fixed in clap 4 .help(" Show only packages/repos matching ") .long_help("Show only packages/repos matching \n\ + Multiple terms can be provided\n\ Matches using a regex unless `--exact` is specified\n\ See https://docs.rs/regex/*/regex/#syntax\n \ rust: Matches `dev-lang/rust`, `dev-util/rustup`, `dev-python/trustme`, etc\n \ @@ -264,9 +265,12 @@ pub fn build_cli_nocomplete() -> Command { let tmpdir = Arg::new("tmpdir").value_name("dir") .long("tmpdir") .num_args(1) + .action(Append) .default_value("/var/tmp") .display_order(2) - .help("Location of portage tmpdir"); + .help("Location of portage tmpdir") + .long_help("Location of portage tmpdir\n\ + Multiple folders can be provided"); let resume = Arg::new("resume").long("resume") .value_name("source") .value_parser(value_parser!(crate::ResumeKind)) @@ -410,22 +414,38 @@ mod test { .clone() } + macro_rules! one { + ($t: ty, $k: expr, $a: expr) => { + matches($a).get_one::<$t>($k) + }; + } + macro_rules! many { + ($t: ty, $k: expr, $a: expr) => { + matches($a).get_many::<$t>($k).map(|v| v.map(AsRef::as_ref).collect::>()) + }; + } + #[test] fn args() { - assert_eq!(matches("l").get_one::>("first"), None); - assert_eq!(matches("l --first").get_one("first"), Some(&1usize)); - assert_eq!(matches("l --first 2").get_one("first"), Some(&2usize)); - assert_eq!(matches("l -N 2").get_one("first"), Some(&2usize)); - assert_eq!(matches("l -N4").get_one("first"), Some(&4usize)); + assert_eq!(one!(usize, "first", "l"), None); + assert_eq!(one!(usize, "first", "l --first"), Some(&1usize)); + assert_eq!(one!(usize, "first", "l --first"), Some(&1usize)); + assert_eq!(one!(usize, "first", "l --first 2"), Some(&2usize)); + assert_eq!(one!(usize, "first", "l -N 2"), Some(&2usize)); + assert_eq!(one!(usize, "first", "l -N4"), Some(&4usize)); + + assert_eq!(one!(usize, "last", "l --last"), Some(&1usize)); + assert_eq!(one!(usize, "last", "l --last 2"), Some(&2usize)); + assert_eq!(one!(usize, "last", "l -n 2"), Some(&2usize)); - assert_eq!(matches("l --last").get_one("last"), Some(&1usize)); - assert_eq!(matches("l --last 2").get_one("last"), Some(&2usize)); - assert_eq!(matches("l -n 2").get_one("last"), Some(&2usize)); + assert_eq!(one!(ColorStyle, "color", "l"), Some(&ColorStyle::Auto)); + assert_eq!(one!(ColorStyle, "color", "l --color"), Some(&ColorStyle::Always)); + assert_eq!(one!(ColorStyle, "color", "l --color=y"), Some(&ColorStyle::Always)); + assert_eq!(one!(ColorStyle, "color", "l --color n"), Some(&ColorStyle::Never)); + assert_eq!(one!(ColorStyle, "color", "l --color never"), Some(&ColorStyle::Never)); - assert_eq!(matches("l").get_one("color"), Some(&ColorStyle::Auto)); - assert_eq!(matches("l --color").get_one("color"), Some(&ColorStyle::Always)); - assert_eq!(matches("l --color=y").get_one("color"), Some(&ColorStyle::Always)); - assert_eq!(matches("l --color n").get_one("color"), Some(&ColorStyle::Never)); - assert_eq!(matches("l --color never").get_one("color"), Some(&ColorStyle::Never)); + assert_eq!(many!(String, "tmpdir", "p"), Some(vec!["/var/tmp"])); + assert_eq!(many!(String, "tmpdir", "p --tmpdir a"), Some(vec!["a"])); + assert_eq!(many!(String, "tmpdir", "p --tmpdir a --tmpdir b"), Some(vec!["a", "b"])); } } diff --git a/src/commands.rs b/src/commands.rs index b894f8e..5f389c4 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -324,7 +324,7 @@ pub fn cmd_predict(args: &ArgMatches) -> Result { let avg = *args.get_one("avg").unwrap(); let resume = *args.get_one("resume").unwrap(); let mut tbl = Table::new(st).align_left(0).align_left(2).margin(2, " ").last(last); - let tmpdir = args.get_one::("tmpdir").unwrap(); + let tmpdirs = args.get_many::("tmpdir").unwrap().cloned().collect(); // Gather and print info about current merge process. let mut cms = std::i64::MAX; @@ -416,7 +416,7 @@ pub fn cmd_predict(args: &ArgMatches) -> Result { // Done if show.merge && totcount <= first { if elapsed > 0 { - let stage = get_buildlog(&p, tmpdir).unwrap_or_default(); + let stage = get_buildlog(&p, &tmpdirs).unwrap_or_default(); tbl.row([&[&st.pkg, &p.ebuild_version()], &[&FmtDur(pred)], &[&st.clr, &"- ", &FmtDur(elapsed), &st.clr, &stage]]); diff --git a/src/parse/current.rs b/src/parse/current.rs index 287b774..37328d6 100644 --- a/src/parse/current.rs +++ b/src/parse/current.rs @@ -91,11 +91,15 @@ fn get_resume_priv(kind: ResumeKind, file: &str) -> Option> { /// Retrieve summary info from the build log -pub fn get_buildlog(pkg: &Pkg, portdir: &str) -> Option { - let name = format!("{}/portage/{}/temp/build.log", portdir, pkg.ebuild_version()); - info!("Build log: {name}"); - let file = File::open(&name).map_err(|e| warn!("Cannot open {name:?}: {e}")).ok()?; - Some(read_buildlog(file, 50)) +pub fn get_buildlog(pkg: &Pkg, portdirs: &Vec) -> Option { + for portdir in portdirs { + let name = format!("{}/portage/{}/temp/build.log", portdir, pkg.ebuild_version()); + if let Ok(file) = File::open(&name).map_err(|e| warn!("Cannot open {name:?}: {e}")) { + info!("Build log: {name}"); + return Some(read_buildlog(file, 50)); + } + } + None } fn read_buildlog(file: File, max: usize) -> String { let mut last = String::new();