diff --git a/gen/cmd/Cargo.toml b/gen/cmd/Cargo.toml index b7e9e6c95..1abe5396f 100644 --- a/gen/cmd/Cargo.toml +++ b/gen/cmd/Cargo.toml @@ -21,7 +21,7 @@ path = "src/main.rs" experimental-async-fn = [] [dependencies] -clap = { version = "3.2", default-features = false, features = ["std", "suggestions"] } +clap = { version = "4", default-features = false, features = ["error-context", "help", "std", "suggestions", "usage"] } codespan-reporting = "0.11" proc-macro2 = { version = "1.0.39", default-features = false, features = ["span-locations"] } quote = { version = "1.0", default-features = false } diff --git a/gen/cmd/src/app.rs b/gen/cmd/src/app.rs index 7388db518..bfad85626 100644 --- a/gen/cmd/src/app.rs +++ b/gen/cmd/src/app.rs @@ -10,6 +10,7 @@ use clap::builder::{ArgAction, ValueParser}; use clap::{Arg, Command}; use std::collections::{BTreeMap as Map, BTreeSet as Set}; use std::path::PathBuf; +use std::process; use std::sync::{Arc, Mutex, PoisonError}; use syn::parse::Parser; @@ -24,32 +25,28 @@ const TEMPLATE: &str = "\ David Tolnay https://github.com/dtolnay/cxx -USAGE: +{usage-heading} {usage} -ARGS: -{positionals} - -OPTIONS: -{options}\ +{all-args}\ "; -fn app() -> Command<'static> { +fn app() -> Command { let mut app = Command::new("cxxbridge") .override_usage(USAGE) .help_template(TEMPLATE) .next_line_help(true) + .disable_help_flag(true) + .disable_version_flag(true) .arg(arg_input()) .arg(arg_cfg()) .arg(arg_cxx_impl_annotations()) .arg(arg_header()) + .arg(arg_help()) .arg(arg_include()) - .arg(arg_output()) - .mut_arg("help", |a| a.help("Print help information.")); + .arg(arg_output()); if let Some(version) = option_env!("CARGO_PKG_VERSION") { - app = app - .version(version) - .mut_arg("version", |a| a.help("Print version information.")); + app = app.arg(arg_version()).version(version); } app } @@ -57,18 +54,25 @@ fn app() -> Command<'static> { const INPUT: &str = "input"; const CFG: &str = "cfg"; const CXX_IMPL_ANNOTATIONS: &str = "cxx-impl-annotations"; +const HELP: &str = "help"; const HEADER: &str = "header"; const INCLUDE: &str = "include"; const OUTPUT: &str = "output"; +const VERSION: &str = "version"; pub(super) fn from_args() -> Opt { let matches = app().get_matches(); + if matches.get_flag(HELP) { + let _ = app().print_long_help(); + process::exit(0); + } + let input = matches.get_one::(INPUT).cloned(); let cxx_impl_annotations = matches .get_one::(CXX_IMPL_ANNOTATIONS) .map(String::clone); - let header = matches.contains_id(HEADER); + let header = matches.get_flag(HEADER); let include = matches .get_many::(INCLUDE) .unwrap_or_default() @@ -115,21 +119,21 @@ pub(super) fn from_args() -> Opt { } } -fn arg_input() -> Arg<'static> { +fn arg_input() -> Arg { Arg::new(INPUT) .help("Input Rust source file containing #[cxx::bridge].") - .required_unless_present(HEADER) + .required_unless_present_any(&[HEADER, HELP]) .value_parser(ValueParser::path_buf()) } -fn arg_cfg() -> Arg<'static> { +fn arg_cfg() -> Arg { const HELP: &str = "\ Compilation configuration matching what will be used to build the Rust side of the bridge."; let bool_cfgs = Arc::new(Mutex::new(Map::::new())); Arg::new(CFG) .long(CFG) - .takes_value(true) + .num_args(1) .value_name("name=\"value\" | name[=true] | name=false") .action(ArgAction::Append) .value_parser(move |arg: &str| match cfg::parse.parse_str(arg) { @@ -149,7 +153,7 @@ the Rust side of the bridge."; .help(HELP) } -fn arg_cxx_impl_annotations() -> Arg<'static> { +fn arg_cxx_impl_annotations() -> Arg { const HELP: &str = "\ Optional annotation for implementations of C++ function wrappers that may be exposed to Rust. You may for example need to provide @@ -158,20 +162,27 @@ if Rust code from one shared object or executable depends on these C++ functions in another."; Arg::new(CXX_IMPL_ANNOTATIONS) .long(CXX_IMPL_ANNOTATIONS) - .takes_value(true) + .num_args(1) .value_name("annotation") .value_parser(ValueParser::string()) .help(HELP) } -fn arg_header() -> Arg<'static> { +fn arg_header() -> Arg { const HELP: &str = "\ Emit header with declarations only. Optional if using `-o` with a path ending in `.h`."; - Arg::new(HEADER).long(HEADER).help(HELP) + Arg::new(HEADER).long(HEADER).num_args(0).help(HELP) } -fn arg_include() -> Arg<'static> { +fn arg_help() -> Arg { + Arg::new(HELP) + .long(HELP) + .help("Print help information.") + .num_args(0) +} + +fn arg_include() -> Arg { const HELP: &str = "\ Any additional headers to #include. The cxxbridge tool does not parse or even require the given paths to exist; they simply go @@ -179,21 +190,28 @@ into the generated C++ code as #include lines."; Arg::new(INCLUDE) .long(INCLUDE) .short('i') - .takes_value(true) + .num_args(1) .action(ArgAction::Append) .value_parser(ValueParser::string()) .help(HELP) } -fn arg_output() -> Arg<'static> { +fn arg_output() -> Arg { const HELP: &str = "\ Path of file to write as output. Output goes to stdout if -o is not specified."; Arg::new(OUTPUT) .long(OUTPUT) .short('o') - .takes_value(true) + .num_args(1) .action(ArgAction::Append) .value_parser(ValueParser::path_buf()) .help(HELP) } + +fn arg_version() -> Arg { + Arg::new(VERSION) + .long(VERSION) + .help("Print version information.") + .action(ArgAction::Version) +} diff --git a/gen/cmd/src/test.rs b/gen/cmd/src/test.rs index 33a61fdf6..c04c28e8b 100644 --- a/gen/cmd/src/test.rs +++ b/gen/cmd/src/test.rs @@ -3,45 +3,45 @@ cxxbridge $VERSION David Tolnay https://github.com/dtolnay/cxx -USAGE: +Usage: cxxbridge .rs Emit .cc file for bridge to stdout cxxbridge .rs --header Emit .h file for bridge to stdout cxxbridge --header Emit \"rust/cxx.h\" header to stdout -ARGS: - - Input Rust source file containing #[cxx::bridge]. +Arguments: + [input] + Input Rust source file containing #[cxx::bridge]. -OPTIONS: - --cfg - Compilation configuration matching what will be used to build - the Rust side of the bridge. +Options: + --cfg + Compilation configuration matching what will be used to build + the Rust side of the bridge. - --cxx-impl-annotations - Optional annotation for implementations of C++ function wrappers - that may be exposed to Rust. You may for example need to provide - __declspec(dllexport) or __attribute__((visibility(\"default\"))) - if Rust code from one shared object or executable depends on - these C++ functions in another. + --cxx-impl-annotations + Optional annotation for implementations of C++ function wrappers + that may be exposed to Rust. You may for example need to provide + __declspec(dllexport) or __attribute__((visibility(\"default\"))) + if Rust code from one shared object or executable depends on + these C++ functions in another. - -h, --help - Print help information. + --header + Emit header with declarations only. Optional if using `-o` with + a path ending in `.h`. - --header - Emit header with declarations only. Optional if using `-o` with - a path ending in `.h`. + --help + Print help information. - -i, --include - Any additional headers to #include. The cxxbridge tool does not - parse or even require the given paths to exist; they simply go - into the generated C++ code as #include lines. + -i, --include + Any additional headers to #include. The cxxbridge tool does not + parse or even require the given paths to exist; they simply go + into the generated C++ code as #include lines. - -o, --output - Path of file to write as output. Output goes to stdout if -o is - not specified. + -o, --output + Path of file to write as output. Output goes to stdout if -o is + not specified. - -V, --version - Print version information. + --version + Print version information. "; #[test] diff --git a/third-party/BUCK b/third-party/BUCK index bbdf07373..7c522e69f 100644 --- a/third-party/BUCK +++ b/third-party/BUCK @@ -17,24 +17,27 @@ rust_library( rust_library( name = "clap", - srcs = glob(["vendor/clap-3.2.22/src/**/*.rs"]) + [ - "vendor/clap-3.2.22/examples/demo.md", - "vendor/clap-3.2.22/examples/demo.rs", + srcs = glob(["vendor/clap-4.0.2/src/**/*.rs"]) + [ + "vendor/clap-4.0.2/examples/demo.md", + "vendor/clap-4.0.2/examples/demo.rs", ], edition = "2021", - features = ["std"], + features = [ + "error-context", + "help", + "std", + "usage", + ], visibility = ["PUBLIC"], deps = [ ":bitflags", ":clap_lex", - ":indexmap", - ":textwrap", ], ) rust_library( name = "clap_lex", - srcs = glob(["vendor/clap_lex-0.2.4/src/**/*.rs"]), + srcs = glob(["vendor/clap_lex-0.3.0/src/**/*.rs"]), edition = "2021", deps = [ ":os_str_bytes", @@ -52,22 +55,6 @@ rust_library( ], ) -rust_library( - name = "hashbrown", - srcs = glob(["vendor/hashbrown-0.12.3/src/**/*.rs"]), - edition = "2021", - features = ["raw"], -) - -rust_library( - name = "indexmap", - srcs = glob(["vendor/indexmap-1.9.1/src/**/*.rs"]), - edition = "2021", - features = ["std"], - rustc_flags = ["--cfg=has_std"], - deps = [":hashbrown"], -) - rust_library( name = "once_cell", srcs = glob(["vendor/once_cell-1.15.0/src/**/*.rs"]), @@ -146,13 +133,6 @@ rust_library( edition = "2018", ) -rust_library( - name = "textwrap", - srcs = glob(["vendor/textwrap-0.15.1/src/**/*.rs"]), - edition = "2018", - deps = [":unicode-width"], -) - rust_library( name = "unicode-ident", srcs = glob(["vendor/unicode-ident-1.0.4/src/**/*.rs"]), diff --git a/third-party/BUILD b/third-party/BUILD index c812656bc..f68b4b659 100644 --- a/third-party/BUILD +++ b/third-party/BUILD @@ -20,22 +20,25 @@ rust_library( rust_library( name = "clap", - srcs = glob(["vendor/clap-3.2.22/src/**/*.rs"]) + ["vendor/clap-3.2.22/examples/demo.rs"], - crate_features = ["std"], - data = ["vendor/clap-3.2.22/examples/demo.md"], + srcs = glob(["vendor/clap-4.0.2/src/**/*.rs"]) + ["vendor/clap-4.0.2/examples/demo.rs"], + crate_features = [ + "error-context", + "help", + "std", + "usage", + ], + data = ["vendor/clap-4.0.2/examples/demo.md"], edition = "2021", visibility = ["//visibility:public"], deps = [ ":bitflags", ":clap_lex", - ":indexmap", - ":textwrap", ], ) rust_library( name = "clap_lex", - srcs = glob(["vendor/clap_lex-0.2.4/src/**/*.rs"]), + srcs = glob(["vendor/clap_lex-0.3.0/src/**/*.rs"]), edition = "2021", deps = [ ":os_str_bytes", @@ -53,22 +56,6 @@ rust_library( ], ) -rust_library( - name = "hashbrown", - srcs = glob(["vendor/hashbrown-0.12.3/src/**/*.rs"]), - crate_features = ["raw"], - edition = "2021", -) - -rust_library( - name = "indexmap", - srcs = glob(["vendor/indexmap-1.9.1/src/**/*.rs"]), - crate_features = ["std"], - edition = "2021", - rustc_flags = ["--cfg=has_std"], - deps = [":hashbrown"], -) - rust_library( name = "once_cell", srcs = glob(["vendor/once_cell-1.15.0/src/**/*.rs"]), @@ -185,13 +172,6 @@ rust_library( edition = "2018", ) -rust_library( - name = "textwrap", - srcs = glob(["vendor/textwrap-0.15.1/src/**/*.rs"]), - edition = "2018", - deps = [":unicode-width"], -) - rust_library( name = "unicode-ident", srcs = glob(["vendor/unicode-ident-1.0.4/src/**/*.rs"]), diff --git a/third-party/Cargo.lock b/third-party/Cargo.lock index f3c4f2a66..0daa94594 100644 --- a/third-party/Cargo.lock +++ b/third-party/Cargo.lock @@ -8,12 +8,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - [[package]] name = "bitflags" version = "1.3.2" @@ -46,22 +40,20 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.22" +version = "4.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750" +checksum = "31c9484ccdc4cb8e7b117cbd0eb150c7c0f04464854e4679aeb50ef03b32d003" dependencies = [ "bitflags", "clap_lex", - "indexmap", "strsim", - "textwrap", ] [[package]] name = "clap_lex" -version = "0.2.4" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" dependencies = [ "os_str_bytes", ] @@ -194,22 +186,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "indexmap" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" -dependencies = [ - "autocfg", - "hashbrown", -] - [[package]] name = "itoa" version = "1.0.3" @@ -370,12 +346,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "textwrap" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "949517c0cf1bf4ee812e2e07e08ab448e3ae0d23472aee8a06c985f0c8815b16" - [[package]] name = "toml" version = "0.5.9"