Skip to content

Commit

Permalink
Update argument parser to clap 4
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed Sep 28, 2022
1 parent 00406ec commit 1c9bc3c
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 146 deletions.
2 changes: 1 addition & 1 deletion gen/cmd/Cargo.toml
Expand Up @@ -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 }
Expand Down
67 changes: 43 additions & 24 deletions gen/cmd/src/app.rs
Expand Up @@ -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;

Expand All @@ -24,51 +25,55 @@ const TEMPLATE: &str = "\
David Tolnay <dtolnay@gmail.com>
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_version());
if let Some(version) = option_env!("CARGO_PKG_VERSION") {
app = app
.version(version)
.mut_arg("version", |a| a.help("Print version information."));
app = app.version(version);
}
app
}

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::<PathBuf>(INPUT).cloned();
let cxx_impl_annotations = matches
.get_one::<String>(CXX_IMPL_ANNOTATIONS)
.map(String::clone);
let header = matches.contains_id(HEADER);
let header = matches.get_flag(HEADER);
let include = matches
.get_many::<String>(INCLUDE)
.unwrap_or_default()
Expand Down Expand Up @@ -115,21 +120,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::<String, bool>::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) {
Expand All @@ -149,7 +154,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
Expand All @@ -158,42 +163,56 @@ 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
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)
}
56 changes: 28 additions & 28 deletions gen/cmd/src/test.rs
Expand Up @@ -3,45 +3,45 @@ cxxbridge $VERSION
David Tolnay <dtolnay@gmail.com>
https://github.com/dtolnay/cxx
USAGE:
Usage:
cxxbridge <input>.rs Emit .cc file for bridge to stdout
cxxbridge <input>.rs --header Emit .h file for bridge to stdout
cxxbridge --header Emit \"rust/cxx.h\" header to stdout
ARGS:
<input>
Input Rust source file containing #[cxx::bridge].
Arguments:
[input]
Input Rust source file containing #[cxx::bridge].
OPTIONS:
--cfg <name=\"value\" | name[=true] | name=false>
Compilation configuration matching what will be used to build
the Rust side of the bridge.
Options:
--cfg <name=\"value\" | name[=true] | name=false>
Compilation configuration matching what will be used to build
the Rust side of the bridge.
--cxx-impl-annotations <annotation>
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 <annotation>
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 <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 <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 <output>
Path of file to write as output. Output goes to stdout if -o is
not specified.
-o, --output <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]
Expand Down
40 changes: 10 additions & 30 deletions third-party/BUCK
Expand Up @@ -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",
Expand All @@ -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"]),
Expand Down Expand Up @@ -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"]),
Expand Down
38 changes: 9 additions & 29 deletions third-party/BUILD
Expand Up @@ -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",
Expand All @@ -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"]),
Expand Down Expand Up @@ -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"]),
Expand Down

0 comments on commit 1c9bc3c

Please sign in to comment.