Skip to content

Commit

Permalink
fix bug where --auto-req option does not accept auto and the scri…
Browse files Browse the repository at this point in the history
…pt path
  • Loading branch information
cat-in-136 committed Jun 1, 2024
1 parent 668918b commit eb7a34b
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 62 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ rpm = { version = "0.13.1", default-features = false }
toml = "0.7"
cargo_toml = "0.15"
clap = { version = "4.3", features = ["derive"] }
color-print = "0.3"
thiserror = "1"
elf = "0.7"

Expand Down
17 changes: 7 additions & 10 deletions src/auto_req/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,14 @@ pub enum AutoReqMode {
BuiltIn,
}

impl From<&Option<cli::AutoReqMode>> for AutoReqMode {
fn from(value: &Option<cli::AutoReqMode>) -> Self {
use cli::AutoReqMode as M;
use AutoReqMode::*;

impl From<cli::AutoReqMode> for AutoReqMode {
fn from(value: cli::AutoReqMode) -> Self {
match value {
None => Auto,
Some(M::Disabled) => Disabled,
Some(M::Builtin) => BuiltIn,
Some(M::Script(path)) => Script(path.into()),
Some(M::FindRequires) => Script(PathBuf::from(RPM_FIND_REQUIRES)),
cli::AutoReqMode::Auto => AutoReqMode::Auto,
cli::AutoReqMode::Disabled => AutoReqMode::Disabled,
cli::AutoReqMode::Builtin => AutoReqMode::BuiltIn,
cli::AutoReqMode::FindRequires => AutoReqMode::Script(PathBuf::from(RPM_FIND_REQUIRES)),
cli::AutoReqMode::Script(path) => AutoReqMode::Script(path),
}
}
}
Expand Down
123 changes: 72 additions & 51 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use clap::{builder::PossibleValue, Parser, ValueEnum};
use clap::{
builder::{PathBufValueParser, PossibleValuesParser, TypedValueParser, ValueParserFactory},
Arg, Command, Parser, ValueEnum,
};
use std::ffi::OsStr;
use std::path::PathBuf;

/// Wrapper used when the application is executed as Cargo plugin
Expand Down Expand Up @@ -29,7 +33,18 @@ pub struct Cli {
pub package: Option<String>,

/// Automatic dependency processing mode.
#[arg(long)]
#[arg(long,
help = "Automatic dependency processing mode. \
[default: auto] \
[possible values: auto, disabled, builtin, find-requires, /path/to/find-requires]",
long_help = color_print::cstr!("Automatic dependency processing mode.\n\n\
[default: auto]\n\
Possible values:\n\
- <bold>auto</bold>: Automatic discovery of dependencies.\n\
- <bold>disabled</bold>: Disable automatic discovery of dependencies. [alias: no]\n\
- <bold>builtin</bold>: Use the builtin procedure based on ldd.\n\
- <bold>find-requires</bold>: Use the external program specified in RPM_FIND_REQUIRES.\n\
- <bold>/path/to/find-requires</bold>: Use the specified external program."))]
pub auto_req: Option<AutoReqMode>,

/// Sub-directory name for all generated artifacts. May be
Expand Down Expand Up @@ -102,54 +117,59 @@ impl From<Compression> for rpm::CompressionWithLevel {
}
}

#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum AutoReqMode {
Auto,
Disabled,
Builtin,
FindRequires,
Script(String),
Script(PathBuf),
}

static AUTO_REQ_VARIANTS: &[AutoReqMode] = &[
AutoReqMode::Disabled,
AutoReqMode::Builtin,
AutoReqMode::FindRequires,
AutoReqMode::Script(String::new()),
];
impl ValueParserFactory for AutoReqMode {
type Parser = AutoReqModeParser;

impl ValueEnum for AutoReqMode {
fn value_variants<'a>() -> &'a [Self] {
AUTO_REQ_VARIANTS
fn value_parser() -> Self::Parser {
AutoReqModeParser
}
}

fn to_possible_value(&self) -> Option<PossibleValue> {
use AutoReqMode::*;

let val = match self {
Disabled => PossibleValue::new("disabled")
.help("Disable automatic discovery of dependencies")
.alias("no"),
Builtin => {
PossibleValue::new("builtin").help("Use the builtin procedure based on ldd.")
#[derive(Clone, Debug)]
pub struct AutoReqModeParser;

impl TypedValueParser for AutoReqModeParser {
type Value = AutoReqMode;
fn parse_ref(
&self,
cmd: &Command,
arg: Option<&Arg>,
value: &OsStr,
) -> Result<Self::Value, clap::Error> {
const VALUES: [(&str, AutoReqMode); 5] = [
("auto", AutoReqMode::Auto),
("disabled", AutoReqMode::Disabled),
("no", AutoReqMode::Disabled),
("builtin", AutoReqMode::Builtin),
("find-requires", AutoReqMode::FindRequires),
];

let inner = PossibleValuesParser::new(VALUES.iter().map(|(k, _v)| k));
match inner.parse_ref(cmd, arg, value) {
Ok(name) => Ok(VALUES
.iter()
.find(|(k, _v)| name.as_str() == (k.as_ref() as &str))
.unwrap()
.1
.clone()),
Err(e) if e.kind() == clap::error::ErrorKind::InvalidValue => {
let inner = PathBufValueParser::new();
match inner.parse_ref(cmd, arg, value) {
Ok(v) => Ok(AutoReqMode::Script(v)),
Err(e) => Err(e),
}
}
FindRequires => PossibleValue::new("find-requires")
.help("Use the external program specified in RPM_FIND_REQUIRES."),
_ => PossibleValue::new("/path/to/find-requires")
.help("Use the specified external program."),
};
Some(val)
}

// Provided method
fn from_str(input: &str, ignore_case: bool) -> Result<Self, String> {
let lowercase = String::from(input).to_lowercase();
let val = if ignore_case { &lowercase } else { input };
Ok(match val {
"disabled" => Self::Disabled,
"builtin" => Self::Builtin,
"find-requires" => Self::FindRequires,
_ => Self::Script(input.into()),
})
Err(e) => Err(e),
}
}
}

Expand Down Expand Up @@ -188,23 +208,24 @@ mod tests {
"toml \"text2\"",
])
.unwrap();
assert_eq!(
args.set_metadata,
vec!["TOML_FILE.toml", "TOML_FILE.toml#TOML.PATH"]
);
assert_eq!(args.set_metadata, vec!["toml \"text1\"", "toml \"text2\""]);
}

#[test]
fn test_auto_req() {
//let args = Cli::try_parse_from(["", "--auto-req", "auto"]).unwrap();
//assert!(matches!(args.auto_req, Some(AutoReqMode::Auto)));
let args = Cli::try_parse_from([""]).unwrap();
assert_eq!(args.auto_req, None);
let args = Cli::try_parse_from(["", "--auto-req", "auto"]).unwrap();
assert_eq!(args.auto_req, Some(AutoReqMode::Auto));
let args = Cli::try_parse_from(["", "--auto-req", "builtin"]).unwrap();
assert!(matches!(args.auto_req, Some(AutoReqMode::Builtin)));
assert_eq!(args.auto_req, Some(AutoReqMode::Builtin));
let args = Cli::try_parse_from(["", "--auto-req", "find-requires"]).unwrap();
assert!(matches!(args.auto_req, Some(AutoReqMode::FindRequires)));
//let args = Cli::try_parse_from(["", "--auto-req", "/usr/lib/rpm/find-requires"]).unwrap();
//assert!(matches!(args.auto_req, Some(AutoReqMode::Script(v)) if v.eq("/usr/lib/rpm/find-requires")));
assert_eq!(args.auto_req, Some(AutoReqMode::FindRequires));
let args = Cli::try_parse_from(["", "--auto-req", "/usr/lib/rpm/find-requires"]).unwrap();
assert!(
matches!(args.auto_req, Some(AutoReqMode::Script(v)) if v == PathBuf::from("/usr/lib/rpm/find-requires"))
);
let args = Cli::try_parse_from(["", "--auto-req", "no"]).unwrap();
assert!(matches!(args.auto_req, Some(AutoReqMode::Disabled)));
assert_eq!(args.auto_req, Some(AutoReqMode::Disabled));
}
}
3 changes: 2 additions & 1 deletion src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,8 @@ impl Config {
let meta_aut_req = metadata.get_str("auto-req")?;
let auto_req = match (&cfg.args.auto_req, meta_aut_req) {
(None, Some("no" | "disabled")) => AutoReqMode::Disabled,
(r, _) => r.into(),
(None, _) => AutoReqMode::Auto,
(Some(v), _) => AutoReqMode::from(v.clone()),
};

for requires in find_requires(expanded_file_paths, auto_req)? {
Expand Down

0 comments on commit eb7a34b

Please sign in to comment.