From 527734c9cfdf3175369d67916c47590055f5b8a6 Mon Sep 17 00:00:00 2001 From: Fabio Valentini Date: Mon, 30 Sep 2024 15:00:56 +0200 Subject: [PATCH] Port to clap v4, bump to heck v0.5 and serial_test v3.1 --- 0001-backport-support-for-clap-v4.patch | 378 ++++++++++++++++++++++++ cbindgen-fix-metadata.diff | 25 ++ rust-cbindgen.spec | 20 +- rust2rpm.toml | 7 + 4 files changed, 424 insertions(+), 6 deletions(-) create mode 100644 0001-backport-support-for-clap-v4.patch create mode 100644 cbindgen-fix-metadata.diff diff --git a/0001-backport-support-for-clap-v4.patch b/0001-backport-support-for-clap-v4.patch new file mode 100644 index 0000000..1aa02fc --- /dev/null +++ b/0001-backport-support-for-clap-v4.patch @@ -0,0 +1,378 @@ +From 3c866c32ec9135731d29066a980ca4edb692201d Mon Sep 17 00:00:00 2001 +From: Fabio Valentini +Date: Mon, 30 Sep 2024 14:55:09 +0200 +Subject: [PATCH] backport support for clap v4 + +--- + src/bindgen/builder.rs | 2 +- + src/bindgen/cargo/cargo.rs | 2 +- + src/main.rs | 120 ++++++++++++++++++++----------------- + tests/depfile.rs | 12 +++- + 4 files changed, 76 insertions(+), 60 deletions(-) + +diff --git a/src/bindgen/builder.rs b/src/bindgen/builder.rs +index a0328b4..4d2eee1 100644 +--- a/src/bindgen/builder.rs ++++ b/src/bindgen/builder.rs +@@ -375,7 +375,7 @@ impl Builder { + } + + if let Some((lib_dir, binding_lib_name)) = self.lib.clone() { +- let lockfile = self.lockfile.as_ref().and_then(|p| p.to_str()); ++ let lockfile = self.lockfile.as_deref(); + + let cargo = Cargo::load( + &lib_dir, +diff --git a/src/bindgen/cargo/cargo.rs b/src/bindgen/cargo/cargo.rs +index 69cf938..542f8e3 100644 +--- a/src/bindgen/cargo/cargo.rs ++++ b/src/bindgen/cargo/cargo.rs +@@ -36,7 +36,7 @@ impl Cargo { + /// need to be parsed. + pub(crate) fn load( + crate_dir: &Path, +- lock_file: Option<&str>, ++ lock_file: Option<&Path>, + binding_crate_name: Option<&str>, + use_cargo_lock: bool, + clean: bool, +diff --git a/src/main.rs b/src/main.rs +index eb78a08..cd4f271 100644 +--- a/src/main.rs ++++ b/src/main.rs +@@ -20,60 +20,58 @@ extern crate quote; + extern crate syn; + extern crate toml; + +-use clap::{Arg, ArgMatches, Command}; ++use clap::{value_parser, Arg, ArgAction, ArgMatches, Command}; + + mod bindgen; + mod logging; + +-use crate::bindgen::{Bindings, Builder, Cargo, Config, Error, Profile, Style}; ++use bindgen::{Bindings, Builder, Cargo, Config, Error}; + + fn apply_config_overrides(config: &mut Config, matches: &ArgMatches) { + // We allow specifying a language to override the config default. This is + // used by compile-tests. +- if let Some(lang) = matches.value_of("lang") { +- config.language = match lang.parse() { +- Ok(lang) => lang, +- Err(reason) => { +- error!("{}", reason); +- return; +- } ++ match matches.try_get_one::("lang") { ++ Ok(Some(lang)) => { ++ config.language = bindgen::Language::from_str(lang).unwrap(); ++ } ++ Err(reason) => { ++ error!("{}", reason); ++ return; + } ++ _ => (), + } + +- if matches.is_present("cpp-compat") { ++ if matches.get_flag("cpp-compat") { + config.cpp_compat = true; + } + +- if matches.is_present("only-target-dependencies") { ++ if matches.get_flag("only-target-dependencies") { + config.only_target_dependencies = true; + } + +- if let Some(style) = matches.value_of("style") { +- config.style = match style { +- "Both" => Style::Both, +- "both" => Style::Both, +- "Tag" => Style::Tag, +- "tag" => Style::Tag, +- "Type" => Style::Type, +- "type" => Style::Type, +- _ => { +- error!("Unknown style specified."); +- return; +- } ++ match matches.try_get_one::("style") { ++ Ok(Some(style)) => { ++ config.style = bindgen::Style::from_str(style).unwrap(); ++ } ++ Err(_) => { ++ error!("Unknown style specified."); ++ return; + } ++ _ => (), + } + +- if let Some(profile) = matches.value_of("profile") { +- config.parse.expand.profile = match Profile::from_str(profile) { +- Ok(p) => p, +- Err(e) => { +- error!("{}", e); +- return; +- } ++ match matches.try_get_one::("profile") { ++ Ok(Some(profile)) => { ++ config.parse.expand.profile = bindgen::Profile::from_str(profile).unwrap(); ++ } ++ Err(e) => { ++ error!("{}", e); ++ return; + } ++ _ => (), + } + +- if matches.is_present("d") { ++ if matches.get_flag("d") { + config.parse.parse_deps = true; + } + } +@@ -82,7 +80,7 @@ fn load_bindings(input: &Path, matches: &ArgMatches) -> Result + // If a file is specified then we load it as a single source + if !input.is_dir() { + // Load any config specified or search in the input directory +- let mut config = match matches.value_of("config") { ++ let mut config = match matches.get_one::("config") { + Some(c) => Config::from_file(c).unwrap(), + None => Config::from_root_or_default( + input +@@ -102,16 +100,16 @@ fn load_bindings(input: &Path, matches: &ArgMatches) -> Result + // We have to load a whole crate, so we use cargo to gather metadata + let lib = Cargo::load( + input, +- matches.value_of("lockfile"), +- matches.value_of("crate"), ++ matches.get_one::("lockfile").map(|s| s.as_path()), ++ matches.get_one::("crate").map(|s| s.as_str()), + true, +- matches.is_present("clean"), +- matches.is_present("only-target-dependencies"), +- matches.value_of("metadata").map(Path::new), ++ matches.get_flag("clean"), ++ matches.get_flag("only-target-dependencies"), ++ matches.get_one::("metadata").map(Path::new), + )?; + + // Load any config specified or search in the binding crate directory +- let mut config = match matches.value_of("config") { ++ let mut config = match matches.get_one::("config") { + Some(c) => Config::from_file(c).unwrap(), + None => { + let binding_crate_dir = lib.find_crate_dir(&lib.binding_crate_ref()); +@@ -140,12 +138,13 @@ fn main() { + .arg( + Arg::new("v") + .short('v') +- .multiple_occurrences(true) ++ .action(ArgAction::Count) + .help("Enable verbose logging"), + ) + .arg( + Arg::new("verify") + .long("verify") ++ .action(ArgAction::SetTrue) + .help("Generate bindings and compare it to the existing bindings file and error if they are different"), + ) + .arg( +@@ -153,6 +152,7 @@ fn main() { + .short('c') + .long("config") + .value_name("PATH") ++ .value_parser(value_parser!(PathBuf)) + .help("Specify path to a `cbindgen.toml` config to use"), + ) + .arg( +@@ -161,16 +161,18 @@ fn main() { + .long("lang") + .value_name("LANGUAGE") + .help("Specify the language to output bindings in") +- .possible_values(["c++", "C++", "c", "C", "cython", "Cython"]), ++ .value_parser(["c++", "C++", "c", "C", "cython", "Cython"]), + ) + .arg( + Arg::new("cpp-compat") + .long("cpp-compat") ++ .action(ArgAction::SetTrue) + .help("Whether to add C++ compatibility to generated C bindings") + ) + .arg( + Arg::new("only-target-dependencies") + .long("only-target-dependencies") ++ .action(ArgAction::SetTrue) + .help("Only fetch dependencies needed by the target platform. \ + The target platform defaults to the host platform; set TARGET to override.") + ) +@@ -180,17 +182,19 @@ fn main() { + .long("style") + .value_name("STYLE") + .help("Specify the declaration style to use for bindings") +- .possible_values(["Both", "both", "Tag", "tag", "Type", "type"]), ++ .value_parser(["Both", "both", "Tag", "tag", "Type", "type"]), + ) + .arg( + Arg::new("d") + .short('d') + .long("parse-dependencies") ++ .action(ArgAction::SetTrue) + .help("Whether to parse dependencies when generating bindings"), + ) + .arg( + Arg::new("clean") + .long("clean") ++ .action(ArgAction::SetTrue) + .help( + "Whether to use a new temporary directory for expanding macros. \ + Affects performance, but might be required in certain build processes.") +@@ -203,6 +207,7 @@ fn main() { + In general this is the folder where the Cargo.toml file of \ + source Rust library resides.") + .required(false) ++ .value_parser(value_parser!(PathBuf)) + .index(1), + ) + .arg( +@@ -221,6 +226,7 @@ fn main() { + .long("output") + .value_name("PATH") + .help("The file to output the bindings to") ++ .value_parser(value_parser!(PathBuf)) + .required(false), + ) + .arg( +@@ -232,6 +238,7 @@ fn main() { + is not specified, the Cargo.lock file is searched for in the \ + same folder as the Cargo.toml file. This option is useful for \ + projects that use workspaces.") ++ .value_parser(value_parser!(PathBuf)) + .required(false), + ) + .arg( +@@ -247,6 +254,7 @@ fn main() { + `cargo metadata --all-features --format-version 1 \ + --manifest-path " + ) ++ .value_parser(value_parser!(PathBuf)) + .required(false), + ) + .arg( +@@ -257,12 +265,13 @@ fn main() { + "Specify the profile to use when expanding macros. \ + Has no effect otherwise." + ) +- .possible_values(["Debug", "debug", "Release", "release"]), ++ .value_parser(["Debug", "debug", "Release", "release"]), + ) + .arg( + Arg::new("quiet") + .short('q') + .long("quiet") ++ .action(ArgAction::SetTrue) + .help("Report errors only (overrides verbosity options).") + .required(false), + ) +@@ -270,10 +279,9 @@ fn main() { + Arg::new("depfile") + .value_name("PATH") + .long("depfile") +- .takes_value(true) +- .min_values(1) +- .max_values(1) ++ .num_args(1) + .required(false) ++ .value_parser(value_parser!(PathBuf)) + .help("Generate a depfile at the given Path listing the source files \ + cbindgen traversed when generating the bindings. Useful when \ + integrating cbindgen into 3rd party build-systems. \ +@@ -282,7 +290,7 @@ fn main() { + ) + .get_matches(); + +- if !matches.is_present("out") && matches.is_present("verify") { ++ if matches.get_flag("verify") && !matches.contains_id("out") { + error!( + "Cannot verify bindings against `stdout`, please specify a file to compare against." + ); +@@ -290,10 +298,10 @@ fn main() { + } + + // Initialize logging +- if matches.is_present("quiet") { ++ if matches.get_flag("quiet") { + logging::ErrorLogger::init().unwrap(); + } else { +- match matches.occurrences_of("v") { ++ match matches.get_count("v") { + 0 => logging::WarnLogger::init().unwrap(), + 1 => logging::InfoLogger::init().unwrap(), + _ => logging::TraceLogger::init().unwrap(), +@@ -301,10 +309,10 @@ fn main() { + } + + // Find the input directory +- let input = match matches.value_of("INPUT") { +- Some(input) => PathBuf::from(input), +- None => env::current_dir().unwrap(), +- }; ++ let input: PathBuf = matches ++ .get_one("INPUT") ++ .cloned() ++ .unwrap_or_else(|| env::current_dir().unwrap()); + + let bindings = match load_bindings(&input, &matches) { + Ok(bindings) => bindings, +@@ -316,15 +324,15 @@ fn main() { + }; + + // Write the bindings file +- match matches.value_of("out") { ++ match matches.get_one::("out") { + Some(file) => { + let changed = bindings.write_to_file(file); + +- if matches.is_present("verify") && changed { +- error!("Bindings changed: {}", file); ++ if matches.get_flag("verify") && changed { ++ error!("Bindings changed: {}", file.display()); + std::process::exit(2); + } +- if let Some(depfile) = matches.value_of("depfile") { ++ if let Some(depfile) = matches.get_one("depfile") { + bindings.generate_depfile(file, depfile) + } + } +diff --git a/tests/depfile.rs b/tests/depfile.rs +index 7d629f3..512f69b 100644 +--- a/tests/depfile.rs ++++ b/tests/depfile.rs +@@ -44,7 +44,11 @@ fn test_project(project_path: &str) { + let mut cmake_build = Command::new("cmake"); + cmake_build.arg("--build").arg(&build_dir); + let output = cmake_build.output().expect("Failed to execute process"); +- assert!(output.status.success(), "Building test project failed"); ++ assert!( ++ output.status.success(), ++ "Building test project failed: {:?}", ++ output ++ ); + let out_str = String::from_utf8(output.stdout).unwrap(); + assert!( + out_str.contains("Running cbindgen"), +@@ -85,7 +89,11 @@ fn test_project(project_path: &str) { + assert_eq!(dep_list, expected_dep_list); + + let output = cmake_build.output().expect("Failed to execute process"); +- assert!(output.status.success(), "Building test project failed"); ++ assert!( ++ output.status.success(), ++ "Building test project failed: {:?}", ++ output ++ ); + let out_str = String::from_utf8(output.stdout).unwrap(); + assert!( + !out_str.contains("Running cbindgen"), +-- +2.46.2 + diff --git a/cbindgen-fix-metadata.diff b/cbindgen-fix-metadata.diff new file mode 100644 index 0000000..67e8afd --- /dev/null +++ b/cbindgen-fix-metadata.diff @@ -0,0 +1,25 @@ +--- cbindgen-0.26.0/Cargo.toml 1970-01-01T00:00:01+00:00 ++++ cbindgen-0.26.0/Cargo.toml 2024-09-30T12:12:30.660048+00:00 +@@ -46,11 +46,11 @@ + required-features = ["clap"] + + [dependencies.clap] +-version = "3.1" ++version = "4" + optional = true + + [dependencies.heck] +-version = "0.4" ++version = "0.5" + + [dependencies.indexmap] + version = "1" +@@ -91,7 +91,7 @@ + version = "0.5" + + [dev-dependencies.serial_test] +-version = "0.5.0" ++version = "3.1" + + [features] + default = ["clap"] diff --git a/rust-cbindgen.spec b/rust-cbindgen.spec index 67a0d2c..865b4b6 100644 --- a/rust-cbindgen.spec +++ b/rust-cbindgen.spec @@ -1,4 +1,4 @@ -# Generated by rust2rpm 25 +# Generated by rust2rpm 26 %bcond_without check %global crate cbindgen @@ -11,8 +11,21 @@ Summary: Tool for generating C bindings to Rust code License: MPL-2.0 URL: https://crates.io/crates/cbindgen Source: %{crates_source} +# Manually created patch for downstream crate metadata changes +# * bump clap dependency from 3.1 to 4 +# * bump heck dependency from 0.4 to 0.5 +# * bump serial_test dev-dependency from 0.5 to 3.1 +Patch: cbindgen-fix-metadata.diff +# * https://github.com/mozilla/cbindgen/commit/d490485 +# * https://github.com/mozilla/cbindgen/commit/61d4112 +Patch: 0001-backport-support-for-clap-v4.patch BuildRequires: cargo-rpm-macros >= 24 +%if %{with check} +BuildRequires: /usr/bin/cython +BuildRequires: /usr/bin/gcc +BuildRequires: /usr/bin/g++ +%endif %global _description %{expand: A tool for generating C bindings to Rust code.} @@ -90,11 +103,6 @@ use the "clap" feature of the "%{crate}" crate. %generate_buildrequires %cargo_generate_buildrequires -%if %{with check} -echo '/usr/bin/cython' -echo '/usr/bin/gcc' -echo '/usr/bin/g++' -%endif %build %cargo_build diff --git a/rust2rpm.toml b/rust2rpm.toml index 7a10ce9..3145167 100644 --- a/rust2rpm.toml +++ b/rust2rpm.toml @@ -1,3 +1,10 @@ +[package] +cargo-toml-patch-comments = [ + "bump clap dependency from 3.1 to 4", + "bump heck dependency from 0.4 to 0.5", + "bump serial_test dev-dependency from 0.5 to 3.1", +] + [requires] test = [ "/usr/bin/cython",