diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-05-10 07:08:39 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-05-10 07:08:39 +0000 |
commit | 0f74a9e86a58a54e659fa8464c3c3e4a08604484 (patch) | |
tree | 5e9db6a19f0e1fbcb8b1819da7ec93b5055eccfc | |
parent | 23b1aac127c8d9d5acaeb2354f4d6eccbca192f0 (diff) | |
parent | 35041af94f4ebedd5f6f48e62b7e79775d74cfdc (diff) | |
download | structopt-android13-mainline-conscrypt-release.tar.gz |
Snap for 8564071 from 35041af94f4ebedd5f6f48e62b7e79775d74cfdc to mainline-conscrypt-releaseaml_con_331413000aml_con_331411000aml_con_331312000aml_con_331115000aml_con_331011010android13-mainline-conscrypt-release
Change-Id: Ia1785bd2c9f7deddfef6ed63e7408b5418c12cd2
42 files changed, 831 insertions, 92 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 7d10f0d..f72fb65 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,5 +1,6 @@ { "git": { - "sha1": "8bda3b64daf53f0ed6bb6bee2c767a63c7c477fc" - } -} + "sha1": "97e92a3755a65f8ea44c994fd403208e7d97f561" + }, + "path_in_vcs": "" +}
\ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 14f5a6c..7b4fcc9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,7 +22,7 @@ matrix: before_script: rustup component add clippy script: cargo clippy --all -- -D warnings - - rust: 1.36.0 + - rust: 1.46.0 - rust: stable - rust: beta - rust: nightly @@ -41,6 +41,8 @@ rust_library { name: "libstructopt", host_supported: true, crate_name: "structopt", + cargo_env_compat: true, + cargo_pkg_version: "0.3.26", srcs: ["src/lib.rs"], edition: "2018", features: ["default"], @@ -54,25 +56,3 @@ rust_library { "com.android.virt", ], } - -// dependent_library ["feature_list"] -// ansi_term-0.11.0 -// atty-0.2.14 -// bitflags-1.2.1 "default" -// clap-2.33.3 "ansi_term,atty,color,default,strsim,suggestions,vec_map" -// heck-0.3.2 -// lazy_static-1.4.0 -// libc-0.2.94 -// proc-macro-error-1.0.4 "default,syn,syn-error" -// proc-macro-error-attr-1.0.4 -// proc-macro2-1.0.26 "default,proc-macro" -// quote-1.0.9 "default,proc-macro" -// strsim-0.8.0 -// structopt-derive-0.4.14 -// syn-1.0.71 "clone-impls,default,derive,full,parsing,printing,proc-macro,quote" -// textwrap-0.11.0 -// unicode-segmentation-1.7.1 -// unicode-width-0.1.8 "default" -// unicode-xid-0.2.1 "default" -// vec_map-0.8.2 -// version_check-0.9.3 diff --git a/CHANGELOG.md b/CHANGELOG.md index 650afea..30353f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,21 @@ +# v0.3.25 (2021-10-18) + +* Fix duplication of aliases in subcommands [#504](https://github.com/TeXitoi/structopt/pull/504) + +# v0.3.25 (2021-10-18) + +* No changes + +# v0.3.23 (2021-08-30) + +* Update minimal rust version to 1.46 because of bitflags 1.3 +* Fixed [a bug that occurs when the type of `map` becomes ambiguous](https://github.com/TeXitoi/structopt/issues/490). +* Add support for [skip for enum variant subcommands](https://github.com/TeXitoi/structopt/issues/493) + +# v0.3.22 (2021-07-04) + +* Add support for [generics in derive](https://github.com/TeXitoi/structopt/issues/128) + # v0.3.21 (2020-11-30) * Fixed [another breakage](https://github.com/TeXitoi/structopt/issues/447) @@ -3,17 +3,16 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g., crates.io) dependencies +# to registry (e.g., crates.io) dependencies. # -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. [package] edition = "2018" name = "structopt" -version = "0.3.21" +version = "0.3.26" authors = ["Guillaume Pinot <texitoi@texitoi.eu>", "others"] description = "Parse command line argument by defining a struct." documentation = "https://docs.rs/structopt" @@ -35,10 +34,14 @@ optional = true package = "paw" [dependencies.structopt-derive] -version = "=0.4.14" +version = "=0.4.18" [dev-dependencies.rustversion] version = "1" +[dev-dependencies.strum] +version = "0.21" +features = ["derive"] + [dev-dependencies.trybuild] version = "1.0.5" features = ["diff"] diff --git a/Cargo.toml.orig b/Cargo.toml.orig index fdad9ef..fb77ef2 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,6 +1,6 @@ [package] name = "structopt" -version = "0.3.21" +version = "0.3.26" edition = "2018" authors = ["Guillaume Pinot <texitoi@texitoi.eu>", "others"] description = "Parse command line argument by defining a struct." @@ -28,10 +28,11 @@ travis-ci = { repository = "TeXitoi/structopt" } [dependencies] clap = { version = "2.33", default-features = false } -structopt-derive = { path = "structopt-derive", version = "=0.4.14" } +structopt-derive = { path = "structopt-derive", version = "=0.4.18" } lazy_static = "1.4.0" paw_dep = { version = "1", optional = true, package = "paw" } [dev-dependencies] trybuild = { version = "1.0.5", features = ["diff"] } rustversion = "1" +strum = { version = "0.21", features = ["derive"] } @@ -7,13 +7,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/structopt/structopt-0.3.21.crate" + value: "https://static.crates.io/crates/structopt/structopt-0.3.26.crate" } - version: "0.3.21" + version: "0.3.26" license_type: NOTICE last_upgrade_date { - year: 2020 - month: 11 - day: 30 + year: 2022 + month: 3 + day: 1 } } @@ -1,10 +1,16 @@ # StructOpt -[![Build status](https://travis-ci.org/TeXitoi/structopt.svg?branch=master)](https://travis-ci.org/TeXitoi/structopt) [![](https://img.shields.io/crates/v/structopt.svg)](https://crates.io/crates/structopt) [![](https://docs.rs/structopt/badge.svg)](https://docs.rs/structopt) +[![Build status](https://travis-ci.com/TeXitoi/structopt.svg?branch=master)](https://app.travis-ci.com/github/TeXitoi/structopt) [![](https://img.shields.io/crates/v/structopt.svg)](https://crates.io/crates/structopt) [![](https://docs.rs/structopt/badge.svg)](https://docs.rs/structopt) [![unsafe forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance/) Parse command line arguments by defining a struct. It combines [clap](https://crates.io/crates/clap) with custom derive. +## Maintenance + +As clap v3 is now out, and the structopt features are integrated into (almost as-is), structopt is now in maintenance mode: no new feature will be added. + +Bugs will be fixed, and documentation improvements will be accepted. + ## Documentation Find it on [Docs.rs](https://docs.rs/structopt). You can also check the [examples](https://github.com/TeXitoi/structopt/tree/master/examples) and the [changelog](https://github.com/TeXitoi/structopt/blob/master/CHANGELOG.md). diff --git a/TEST_MAPPING b/TEST_MAPPING index 0f4f93c..8029a19 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -1,8 +1,18 @@ // Generated by update_crate_tests.py for tests that depend on this crate. { + "imports": [ + { + "path": "external/rust/crates/base64" + } + ], "presubmit": [ { "name": "authfs_device_test_src_lib" } + ], + "presubmit-rust": [ + { + "name": "authfs_device_test_src_lib" + } ] } diff --git a/examples/README.md b/examples/README.md index b485393..1475e2a 100644 --- a/examples/README.md +++ b/examples/README.md @@ -31,7 +31,7 @@ How to extract subcommands' args into external structs. ### [Environment variables](env.rs) -How to use environment variable fallback an how it interacts with `default_value`. +How to use environment variable fallback and how it interacts with `default_value`. ### [Advanced](example.rs) diff --git a/examples/after_help.rs b/examples/after_help.rs index db2845f..75816c7 100644 --- a/examples/after_help.rs +++ b/examples/after_help.rs @@ -1,4 +1,28 @@ //! How to append a postscript to the help message generated. +//! +//! Running this example with --help prints this message: +//! ----------------------------------------------------- +//! structopt 0.3.25 +//! I am a program and I do things. +//! +//! Sometimes they even work. +//! +//! USAGE: +//! after_help [FLAGS] +//! +//! FLAGS: +//! -d +//! Release the dragon +//! +//! -h, --help +//! Prints help information +//! +//! -V, --version +//! Prints version information +//! +//! +//! Beware `-d`, dragons be here +//! ----------------------------------------------------- use structopt::StructOpt; diff --git a/examples/at_least_two.rs b/examples/at_least_two.rs index 683db50..a4eb002 100644 --- a/examples/at_least_two.rs +++ b/examples/at_least_two.rs @@ -1,5 +1,20 @@ //! How to require presence of at least N values, //! like `val1 val2 ... valN ... valM`. +//! +//! Running this example with --help prints this message: +//! ----------------------------------------------------- +//! structopt 0.3.25 +//! +//! USAGE: +//! at_least_two <foos>... +//! +//! FLAGS: +//! -h, --help Prints help information +//! -V, --version Prints version information +//! +//! ARGS: +//! <foos>... +//! ----------------------------------------------------- use structopt::StructOpt; diff --git a/examples/basic.rs b/examples/basic.rs index 510e0e0..33e4415 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -1,4 +1,28 @@ //! A somewhat comprehensive example of a typical `StructOpt` usage.use +//! +//! Running this example with --help prints this message: +//! ----------------------------------------------------- +//! basic 0.3.25 +//! A basic example +//! +//! USAGE: +//! basic [FLAGS] [OPTIONS] --output <output> [--] [FILE]... +//! +//! FLAGS: +//! -d, --debug Activate debug mode +//! -h, --help Prints help information +//! -V, --version Prints version information +//! -v, --verbose Verbose mode (-v, -vv, -vvv, etc.) +//! +//! OPTIONS: +//! -l, --level <level>... admin_level to consider +//! -c, --nb-cars <nb-cars> Number of cars +//! -o, --output <output> Output file +//! -s, --speed <speed> Set speed [default: 42] +//! +//! ARGS: +//! <FILE>... Files to process +//! ----------------------------------------------------- use std::path::PathBuf; use structopt::StructOpt; diff --git a/examples/deny_missing_docs.rs b/examples/deny_missing_docs.rs index 82b1e63..05ceca9 100644 --- a/examples/deny_missing_docs.rs +++ b/examples/deny_missing_docs.rs @@ -10,6 +10,26 @@ // https://github.com/rust-lang/rust/issues/24584 is fixed //! A test to check that structopt compiles with deny(missing_docs) +//! +//! Running this example with --help prints this message: +//! ----------------------------------------------------- +//! structopt 0.3.25 +//! Some subcommands +//! +//! USAGE: +//! deny_missing_docs [FLAGS] [SUBCOMMAND] +//! +//! FLAGS: +//! -h, --help Prints help information +//! -V, --version Prints version information +//! -v +//! +//! SUBCOMMANDS: +//! a command A +//! b command B +//! c command C +//! help Prints this message or the help of the given subcommand(s) +//! ----------------------------------------------------- #![deny(missing_docs)] diff --git a/examples/doc_comments.rs b/examples/doc_comments.rs index 810101f..3d22152 100644 --- a/examples/doc_comments.rs +++ b/examples/doc_comments.rs @@ -1,4 +1,54 @@ //! How to use doc comments in place of `help/long_help`. +//! +//! Running this example with --help prints this message: +//! ----------------------------------------------------- +//! basic 0.3.25 +//! A basic example for the usage of doc comments as replacement of the arguments `help`, `long_help`, `about` and +//! `long_about` +//! +//! USAGE: +//! doc_comments [FLAGS] <SUBCOMMAND> +//! +//! FLAGS: +//! -f, --first-flag +//! Just use doc comments to replace `help`, `long_help`, `about` or `long_about` input +//! +//! -h, --help +//! Prints help information +//! +//! -s, --second-flag +//! Split between `help` and `long_help`. +//! +//! In the previous case structopt is going to present the whole comment both as text for the `help` and the +//! `long_help` argument. +//! +//! But if the doc comment is formatted like this example -- with an empty second line splitting the heading and +//! the rest of the comment -- only the first line is used as `help` argument. The `long_help` argument will +//! still contain the whole comment. +//! +//! ## Attention +//! +//! Any formatting next to empty lines that could be used inside a doc comment is currently not preserved. If +//! lists or other well formatted content is required it is necessary to use the related structopt argument with +//! a raw string as shown on the `third_flag` description. +//! -t, --third-flag +//! This is a raw string. +//! +//! It can be used to pass well formatted content (e.g. lists or source +//! code) in the description: +//! +//! - first example list entry +//! - second example list entry +//! +//! -V, --version +//! Prints version information +//! +//! +//! SUBCOMMANDS: +//! first The same rules described previously for flags. Are also true for in regards of sub-commands +//! help Prints this message or the help of the given subcommand(s) +//! second Applicable for both `about` an `help` +//! ----------------------------------------------------- use structopt::StructOpt; diff --git a/examples/enum_in_args.rs b/examples/enum_in_args.rs index 70347da..0722140 100644 --- a/examples/enum_in_args.rs +++ b/examples/enum_in_args.rs @@ -1,4 +1,19 @@ //! How to use `arg_enum!` with `StructOpt`. +//! +//! Running this example with --help prints this message: +//! ----------------------------------------------------- +//! structopt 0.3.25 +//! +//! USAGE: +//! enum_in_args <i> +//! +//! FLAGS: +//! -h, --help Prints help information +//! -V, --version Prints version information +//! +//! ARGS: +//! <i> Important argument [possible values: Foo, Bar, FooBar] +//! ----------------------------------------------------- use clap::arg_enum; use structopt::StructOpt; diff --git a/examples/enum_in_args_with_strum.rs b/examples/enum_in_args_with_strum.rs new file mode 100644 index 0000000..7893e78 --- /dev/null +++ b/examples/enum_in_args_with_strum.rs @@ -0,0 +1,42 @@ +//! Running this example with --help prints this message: +//! ----------------------------------------------------- +//! structopt 0.3.25 +//! +//! USAGE: +//! enum_in_args_with_strum [OPTIONS] +//! +//! FLAGS: +//! -h, --help Prints help information +//! -V, --version Prints version information +//! +//! OPTIONS: +//! --format <format> [default: txt] [possible values: txt, md, html] +//! ----------------------------------------------------- + +use structopt::StructOpt; +use strum::{EnumString, EnumVariantNames, VariantNames}; + +const DEFAULT: &str = "txt"; + +#[derive(StructOpt, Debug)] +struct Opt { + #[structopt( + long, + possible_values = Format::VARIANTS, + case_insensitive = true, + default_value = DEFAULT, + )] + format: Format, +} + +#[derive(EnumString, EnumVariantNames, Debug)] +#[strum(serialize_all = "kebab_case")] +enum Format { + Txt, + Md, + Html, +} + +fn main() { + println!("{:?}", Opt::from_args()); +} diff --git a/examples/enum_tuple.rs b/examples/enum_tuple.rs index 0bad2e6..a88adc2 100644 --- a/examples/enum_tuple.rs +++ b/examples/enum_tuple.rs @@ -1,4 +1,20 @@ //! How to extract subcommands' args into external structs. +//! +//! Running this example with --help prints this message: +//! ----------------------------------------------------- +//! classify 0.3.25 +//! +//! USAGE: +//! enum_tuple <SUBCOMMAND> +//! +//! FLAGS: +//! -h, --help Prints help information +//! -V, --version Prints version information +//! +//! SUBCOMMANDS: +//! foo +//! help Prints this message or the help of the given subcommand(s) +//! ----------------------------------------------------- use structopt::StructOpt; diff --git a/examples/env.rs b/examples/env.rs index 0477089..437f3c6 100644 --- a/examples/env.rs +++ b/examples/env.rs @@ -1,5 +1,22 @@ //! How to use environment variable fallback an how it //! interacts with `default_value`. +//! +//! Running this example with --help prints this message: +//! ----------------------------------------------------- +//! env 0.3.25 +//! Example for allowing to specify options via environment variables +//! +//! USAGE: +//! env [OPTIONS] --api-url <api-url> +//! +//! FLAGS: +//! -h, --help Prints help information +//! -V, --version Prints version information +//! +//! OPTIONS: +//! --api-url <api-url> URL for the API server [env: API_URL=] +//! --retries <retries> Number of retries [env: RETRIES=] [default: 5] +//! ----------------------------------------------------- use structopt::StructOpt; diff --git a/examples/example.rs b/examples/example.rs index 7a9a514..4dfd341 100644 --- a/examples/example.rs +++ b/examples/example.rs @@ -1,4 +1,27 @@ //! Somewhat complex example of usage of structopt. +//! +//! Running this example with --help prints this message: +//! ----------------------------------------------------- +//! example 0.3.25 +//! An example of StructOpt usage +//! +//! USAGE: +//! example [FLAGS] [OPTIONS] <input> [--] [output] +//! +//! FLAGS: +//! -d, --debug Activate debug mode +//! -h, --help Prints help information +//! -V, --version Prints version information +//! +//! OPTIONS: +//! --log <log> Log file, stdout if no file, no logging if not present +//! --optv <optv>... +//! -s, --speed <speed> Set speed [default: 42] +//! +//! ARGS: +//! <input> Input file +//! <output> Output file, stdout if not present +//! ----------------------------------------------------- use structopt::StructOpt; @@ -37,7 +60,7 @@ struct Opt { // An optional list of values, will be `None` if not present on // the command line, will be `Some(vec![])` if no argument is - // provided (i.e. `--optv`) and will be `Some(Some(String))` if + // provided (i.e. `--optv`) and will be `Some(Vec<String>)` if // argument list is provided (e.g. `--optv a b c`). #[structopt(long)] optv: Option<Vec<String>>, diff --git a/examples/flatten.rs b/examples/flatten.rs index d51647f..19208ec 100644 --- a/examples/flatten.rs +++ b/examples/flatten.rs @@ -1,4 +1,21 @@ //! How to use flattening. +//! +//! Running this example with --help prints this message: +//! ----------------------------------------------------- +//! structopt 0.3.25 +//! +//! USAGE: +//! flatten [FLAGS] -g <group> -u <user> +//! +//! FLAGS: +//! -h, --help Prints help information +//! -V, --version Prints version information +//! -v switch verbosity on +//! +//! OPTIONS: +//! -g <group> daemon group +//! -u <user> daemon user +//! ----------------------------------------------------- use structopt::StructOpt; diff --git a/examples/gen_completions.rs b/examples/gen_completions.rs index 6dbd97f..e9e9693 100644 --- a/examples/gen_completions.rs +++ b/examples/gen_completions.rs @@ -6,6 +6,20 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +//! Running this example with --help prints this message: +//! ----------------------------------------------------- +//! structopt 0.3.25 +//! An example of how to generate bash completions with structopt +//! +//! USAGE: +//! gen_completions [FLAGS] +//! +//! FLAGS: +//! -d, --debug Activate debug mode +//! -h, --help Prints help information +//! -V, --version Prints version information +//! ----------------------------------------------------- + use structopt::clap::Shell; use structopt::StructOpt; diff --git a/examples/git.rs b/examples/git.rs index 494e9d1..6e4137b 100644 --- a/examples/git.rs +++ b/examples/git.rs @@ -2,6 +2,24 @@ //! as well as a demonstration of adding documentation to subcommands. //! Documentation can be added either through doc comments or //! `help`/`about` attributes. +//! +//! Running this example with --help prints this message: +//! ----------------------------------------------------- +//! git 0.3.25 +//! the stupid content tracker +//! +//! USAGE: +//! git <SUBCOMMAND> +//! +//! FLAGS: +//! -h, --help Prints help information +//! -V, --version Prints version information +//! +//! SUBCOMMANDS: +//! add +//! fetch fetch branches from remote repository +//! help Prints this message or the help of the given subcommand(s) +//! ----------------------------------------------------- use structopt::StructOpt; diff --git a/examples/group.rs b/examples/group.rs index d53de6a..16ca366 100644 --- a/examples/group.rs +++ b/examples/group.rs @@ -1,4 +1,24 @@ //! How to use `clap::Arg::group` +//! +//! Running this example with --help prints this message: +//! ----------------------------------------------------- +//! structopt 0.3.25 +//! +//! USAGE: +//! group [OPTIONS] <--method <method>|--get|--head|--post|--put|--delete> +//! +//! FLAGS: +//! --delete HTTP DELETE +//! --get HTTP GET +//! -h, --help Prints help information +//! --head HTTP HEAD +//! --post HTTP POST +//! --put HTTP PUT +//! -V, --version Prints version information +//! +//! OPTIONS: +//! --method <method> Set a custom HTTP verb +//! ----------------------------------------------------- use structopt::{clap::ArgGroup, StructOpt}; diff --git a/examples/keyvalue.rs b/examples/keyvalue.rs index 12ce6fc..92acafa 100644 --- a/examples/keyvalue.rs +++ b/examples/keyvalue.rs @@ -1,4 +1,19 @@ //! How to parse "key=value" pairs with structopt. +//! +//! Running this example with --help prints this message: +//! ----------------------------------------------------- +//! structopt 0.3.25 +//! +//! USAGE: +//! keyvalue [OPTIONS] +//! +//! FLAGS: +//! -h, --help Prints help information +//! -V, --version Prints version information +//! +//! OPTIONS: +//! -D <defines>... +//! ----------------------------------------------------- use std::error::Error; use structopt::StructOpt; diff --git a/examples/negative_flag.rs b/examples/negative_flag.rs index b178bf5..0d9337c 100644 --- a/examples/negative_flag.rs +++ b/examples/negative_flag.rs @@ -1,5 +1,18 @@ //! How to add `no-thing` flag which is `true` by default and //! `false` if passed. +//! +//! Running this example with --help prints this message: +//! ----------------------------------------------------- +//! structopt 0.3.25 +//! +//! USAGE: +//! negative_flag [FLAGS] +//! +//! FLAGS: +//! -h, --help Prints help information +//! -V, --version Prints version information +//! --no-verbose +//! ----------------------------------------------------- use structopt::StructOpt; diff --git a/examples/no_version.rs b/examples/no_version.rs index a542ec1..5fc6274 100644 --- a/examples/no_version.rs +++ b/examples/no_version.rs @@ -1,4 +1,15 @@ //! How to completely remove version. +//! +//! Running this example with --help prints this message: +//! ----------------------------------------------------- +//! no_version +//! +//! USAGE: +//! no_version +//! +//! FLAGS: +//! -h, --help Prints help information +//! ----------------------------------------------------- use structopt::clap::AppSettings; use structopt::StructOpt; diff --git a/examples/rename_all.rs b/examples/rename_all.rs index c7c3538..6958c01 100644 --- a/examples/rename_all.rs +++ b/examples/rename_all.rs @@ -20,7 +20,24 @@ //! //! - **Lower Case**: Keep all letters lowercase and remove word boundaries. //! -//! - **Upper Case**: Keep all letters upperrcase and remove word boundaries. +//! - **Upper Case**: Keep all letters uppercase and remove word boundaries. +//! +//! Running this example with --help prints this message: +//! ----------------------------------------------------- +//! rename_all 0.3.25 +//! +//! USAGE: +//! rename_all <SUBCOMMAND> +//! +//! FLAGS: +//! -h, --help Prints help information +//! -V, --version Prints version information +//! +//! SUBCOMMANDS: +//! FIRST_COMMAND A screaming loud first command. Only use if necessary +//! SecondCommand Not nearly as loud as the first command +//! help Prints this message or the help of the given subcommand(s) +//! ----------------------------------------------------- use structopt::StructOpt; diff --git a/examples/required_if.rs b/examples/required_if.rs index cb6b414..e3497b2 100644 --- a/examples/required_if.rs +++ b/examples/required_if.rs @@ -1,4 +1,23 @@ //! How to use `required_if` with structopt. +//! +//! Running this example with --help prints this message: +//! ----------------------------------------------------- +//! structopt 0.3.25 +//! +//! USAGE: +//! required_if -o <out-type> [FILE] +//! +//! FLAGS: +//! -h, --help Prints help information +//! -V, --version Prints version information +//! +//! OPTIONS: +//! -o <out-type> Where to write the output: to `stdout` or `file` +//! +//! ARGS: +//! <FILE> File name: only required when `out-type` is set to `file` +//! ----------------------------------------------------- + use structopt::StructOpt; #[derive(Debug, StructOpt, PartialEq)] diff --git a/examples/subcommand_aliases.rs b/examples/subcommand_aliases.rs index 30b8cc3..1837ddb 100644 --- a/examples/subcommand_aliases.rs +++ b/examples/subcommand_aliases.rs @@ -1,4 +1,21 @@ //! How to assign some aliases to subcommands +//! +//! Running this example with --help prints this message: +//! ----------------------------------------------------- +//! structopt 0.3.25 +//! +//! USAGE: +//! subcommand_aliases <SUBCOMMAND> +//! +//! FLAGS: +//! -h, --help Prints help information +//! -V, --version Prints version information +//! +//! SUBCOMMANDS: +//! bar +//! foo +//! help Prints this message or the help of the given subcommand(s) +//! ----------------------------------------------------- use structopt::clap::AppSettings; use structopt::StructOpt; diff --git a/examples/true_or_false.rs b/examples/true_or_false.rs index 31a543e..814f3d8 100644 --- a/examples/true_or_false.rs +++ b/examples/true_or_false.rs @@ -23,7 +23,7 @@ struct Opt { bar: bool, // `bool` can be positional only with explicit `parse(...)` annotation - #[structopt(long, parse(try_from_str))] + #[structopt(parse(try_from_str))] boom: bool, } @@ -11,6 +11,14 @@ //! This crate defines the `StructOpt` trait and its custom derive. //! +//! ## Maintenance +//! +//! As clap v3 is now out, and the structopt features are integrated +//! into (almost as-is), structopt is now in maintenance mode: no new +//! feature will be added. +//! +//! Bugs will be fixed, and documentation improvements will be accepted. +//! //! ## Features //! //! If you want to disable all the `clap` features (colors, @@ -52,6 +60,7 @@ //! - [Flattening subcommands](#flattening-subcommands) //! - [Flattening](#flattening) //! - [Custom string parsers](#custom-string-parsers) +//! - [Generics](#generics) //! //! //! @@ -59,7 +68,7 @@ //! //! First, let's look at the example: //! -//! ```should_panic +//! ``` //! use std::path::PathBuf; //! use structopt::StructOpt; //! @@ -94,7 +103,10 @@ //! } //! //! fn main() { +//! # /* //! let opt = Opt::from_args(); +//! # */ +//! # let opt = Opt::from_iter(&["binary", "-o", "stdout", "input"]); //! println!("{:?}", opt); //! } //! ``` @@ -133,13 +145,17 @@ //! They are what used to be explicit `#[structopt(raw(...))]` attrs in pre-0.3 `structopt` //! //! Every `structopt attribute` looks like comma-separated sequence of methods: -//! ```rust,ignore +//! ``` +//! # #[derive(structopt::StructOpt)] struct S { +//! # //! #[structopt( //! short, // method with no arguments - always magical //! long = "--long-option", // method with one argument //! required_if("out", "file"), // method with one and more args //! parse(from_os_str = path::to::parser) // some magical methods have their own syntax //! )] +//! # +//! # s: () } mod path { pub(crate) mod to { pub(crate) fn parser(_: &std::ffi::OsStr) {} }} //! ``` //! //! `#[structopt(...)]` attributes can be placed on top of `struct`, `enum`, @@ -171,13 +187,19 @@ //! ## Raw methods //! //! They are the reason why `structopt` is so flexible. **Every and each method from -//! `clap::App/Arg` can be used this way!** +//! `clap::App/Arg` can be used this way!** See the [`clap::App` +//! methods](https://docs.rs/clap/2/clap/struct.App.html) and [`clap::Arg` +//! methods](https://docs.rs/clap/2/clap/struct.Arg.html). //! -//! ```ignore +//! ``` +//! # #[derive(structopt::StructOpt)] struct S { +//! # //! #[structopt( //! global = true, // name = arg form, neat for one-arg methods //! required_if("out", "file") // name(arg1, arg2, ...) form. //! )] +//! # +//! # s: String } //! ``` //! //! The first form can only be used for methods which take only one argument. @@ -321,7 +343,7 @@ //! //! ## Type magic //! -//! One of major things that makes `structopt` so awesome is it's type magic. +//! One of major things that makes `structopt` so awesome is its type magic. //! Do you want optional positional argument? Use `Option<T>`! Or perhaps optional argument //! that optionally takes value (`[--opt=[val]]`)? Use `Option<Option<T>>`! //! @@ -434,7 +456,6 @@ //! /// for its type (in this case 0). //! #[structopt(skip)] //! skipped: u32, -//! //! } //! //! # Opt::from_iter( @@ -451,7 +472,7 @@ //! #[derive(StructOpt)] //! struct Opt { //! #[structopt(default_value = "", long)] -//! prefix: String +//! prefix: String, //! } //! ``` //! @@ -473,7 +494,7 @@ //! struct Opt { //! // just leave the `= "..."` part and structopt will figure it for you //! #[structopt(default_value, long)] -//! prefix: String // `String` implements both `Default` and `ToString` +//! prefix: String, // `String` implements both `Default` and `ToString` //! } //! ``` //! @@ -498,8 +519,8 @@ //! #[derive(StructOpt)] //! #[structopt(about = "I am a program and I work, just pass `-h`")] //! struct Foo { -//! #[structopt(short, help = "Pass `-h` and you'll see me!")] -//! bar: String +//! #[structopt(short, help = "Pass `-h` and you'll see me!")] +//! bar: String, //! } //! ``` //! @@ -512,8 +533,8 @@ //! #[derive(StructOpt)] //! /// I am a program and I work, just pass `-h` //! struct Foo { -//! /// Pass `-h` and you'll see me! -//! bar: String +//! /// Pass `-h` and you'll see me! +//! bar: String, //! } //! ``` //! @@ -554,7 +575,7 @@ //! /// until I'll have destroyed humanity. Enjoy your //! /// pathetic existence, you mere mortals. //! #[structopt(long)] -//! kill_all_humans: bool +//! kill_all_humans: bool, //! } //! ``` //! @@ -631,7 +652,7 @@ //! Also, `structopt` will *still* remove leading and trailing blank lines so //! these formats are equivalent: //! -//! ```ignore +//! ``` //! /** This is a doc comment //! //! Hello! */ @@ -645,6 +666,8 @@ //! /// This is a doc comment //! /// //! /// Hello! +//! # +//! # mod m {} //! ``` //! ______________ //! @@ -664,8 +687,8 @@ //! //! #[derive(StructOpt)] //! struct Foo { -//! #[structopt(short, long, env = "PARAMETER_VALUE")] -//! parameter_value: String +//! #[structopt(short, long, env = "PARAMETER_VALUE")] +//! parameter_value: String, //! } //! ``` //! @@ -687,8 +710,8 @@ //! //! #[derive(StructOpt)] //! struct Foo { -//! #[structopt(long = "secret", env = "SECRET_VALUE", hide_env_values = true)] -//! secret_value: String +//! #[structopt(long = "secret", env = "SECRET_VALUE", hide_env_values = true)] +//! secret_value: String, //! } //! ``` //! @@ -706,8 +729,8 @@ //! //! #[derive(StructOpt)] //! struct Foo { -//! #[structopt(long = "secret", env)] -//! secret_value: String +//! #[structopt(long = "secret", env)] +//! secret_value: String, //! } //! ``` //! @@ -773,21 +796,21 @@ //! #[structopt(short)] //! patch: bool, //! #[structopt(parse(from_os_str))] -//! files: Vec<PathBuf> +//! files: Vec<PathBuf>, //! }, //! Fetch { //! #[structopt(long)] //! dry_run: bool, //! #[structopt(long)] //! all: bool, -//! repository: Option<String> +//! repository: Option<String>, //! }, //! Commit { //! #[structopt(short)] //! message: Option<String>, //! #[structopt(short)] -//! all: bool -//! } +//! all: bool, +//! }, //! } //! ``` //! @@ -806,22 +829,22 @@ //! supervising_faerie: String, //! /// The faerie tree this cookie is being made in. //! tree: Option<String>, -//! #[structopt(subcommand)] // Note that we mark a field as a subcommand -//! cmd: Command +//! #[structopt(subcommand)] // Note that we mark a field as a subcommand +//! cmd: Command, //! } //! //! #[derive(StructOpt)] //! enum Command { //! /// Pound acorns into flour for cookie dough. //! Pound { -//! acorns: u32 +//! acorns: u32, //! }, //! /// Add magical sparkles -- the secret ingredient! //! Sparkle { //! #[structopt(short, parse(from_occurrences))] //! magicality: u64, //! #[structopt(short)] -//! color: String +//! color: String, //! }, //! Finish(Finish), //! } @@ -831,19 +854,19 @@ //! struct Finish { //! #[structopt(short)] //! time: u32, -//! #[structopt(subcommand)] // Note that we mark a field as a subcommand -//! finish_type: FinishType +//! #[structopt(subcommand)] // Note that we mark a field as a subcommand +//! finish_type: FinishType, //! } //! //! // subsubcommand! //! #[derive(StructOpt)] //! enum FinishType { //! Glaze { -//! applications: u32 +//! applications: u32, //! }, //! Powder { //! flavor: String, -//! dips: u32 +//! dips: u32, //! } //! } //! ``` @@ -867,14 +890,14 @@ //! struct Foo { //! file: String, //! #[structopt(subcommand)] -//! cmd: Option<Command> +//! cmd: Option<Command>, //! } //! //! #[derive(StructOpt)] //! enum Command { //! Bar, //! Baz, -//! Quux +//! Quux, //! } //! ``` //! @@ -952,7 +975,7 @@ //! BaseCli(BaseCli), //! Dex { //! arg2: i32, -//! } +//! }, //! } //! ``` //! @@ -1053,6 +1076,40 @@ //! In the `try_from_*` variants, the function will run twice on valid input: //! once to validate, and once to parse. Hence, make sure the function is //! side-effect-free. +//! +//! ## Generics +//! +//! Generic structs and enums can be used. They require explicit trait bounds +//! on any generic types that will be used by the `StructOpt` derive macro. In +//! some cases, associated types will require additional bounds. See the usage +//! of `FromStr` below for an example of this. +//! +//! ``` +//! # use structopt::StructOpt; +//! use std::{fmt, str::FromStr}; +//! +//! // a struct with single custom argument +//! #[derive(StructOpt)] +//! struct GenericArgs<T: FromStr> where <T as FromStr>::Err: fmt::Display + fmt::Debug { +//! generic_arg_1: String, +//! generic_arg_2: String, +//! custom_arg_1: T, +//! } +//! ``` +//! +//! or +//! +//! ``` +//! # use structopt::StructOpt; +//! // a struct with multiple custom arguments in a substructure +//! #[derive(StructOpt)] +//! struct GenericArgs<T: StructOpt> { +//! generic_arg_1: String, +//! generic_arg_2: String, +//! #[structopt(flatten)] +//! custom_args: T, +//! } +//! ``` // those mains are for a reason #![allow(clippy::needless_doctest_main)] diff --git a/tests/custom-string-parsers.rs b/tests/custom-string-parsers.rs index 89070ed..8fe055b 100644 --- a/tests/custom-string-parsers.rs +++ b/tests/custom-string-parsers.rs @@ -76,7 +76,11 @@ fn test_parse_hex() { let err = HexOpt::clap() .get_matches_from_safe(&["test", "-n", "gg"]) .unwrap_err(); - assert!(err.message.contains("invalid digit found in string"), err); + assert!( + err.message.contains("invalid digit found in string"), + "{}", + err + ); } fn custom_parser_1(_: &str) -> &'static str { diff --git a/tests/generics.rs b/tests/generics.rs new file mode 100644 index 0000000..0da349b --- /dev/null +++ b/tests/generics.rs @@ -0,0 +1,145 @@ +use structopt::StructOpt; + +#[test] +fn generic_struct_flatten() { + #[derive(StructOpt, PartialEq, Debug)] + struct Inner { + pub answer: isize, + } + + #[derive(StructOpt, PartialEq, Debug)] + struct Outer<T: StructOpt> { + #[structopt(flatten)] + pub inner: T, + } + + assert_eq!( + Outer { + inner: Inner { answer: 42 } + }, + Outer::from_iter(&["--answer", "42"]) + ) +} + +#[test] +fn generic_struct_flatten_w_where_clause() { + #[derive(StructOpt, PartialEq, Debug)] + struct Inner { + pub answer: isize, + } + + #[derive(StructOpt, PartialEq, Debug)] + struct Outer<T> + where + T: StructOpt, + { + #[structopt(flatten)] + pub inner: T, + } + + assert_eq!( + Outer { + inner: Inner { answer: 42 } + }, + Outer::from_iter(&["--answer", "42"]) + ) +} + +#[test] +fn generic_enum() { + #[derive(StructOpt, PartialEq, Debug)] + struct Inner { + pub answer: isize, + } + + #[derive(StructOpt, PartialEq, Debug)] + enum GenericEnum<T: StructOpt> { + Start(T), + Stop, + } + + assert_eq!( + GenericEnum::Start(Inner { answer: 42 }), + GenericEnum::from_iter(&["test", "start", "42"]) + ) +} + +#[test] +fn generic_enum_w_where_clause() { + #[derive(StructOpt, PartialEq, Debug)] + struct Inner { + pub answer: isize, + } + + #[derive(StructOpt, PartialEq, Debug)] + enum GenericEnum<T> + where + T: StructOpt, + { + Start(T), + Stop, + } + + assert_eq!( + GenericEnum::Start(Inner { answer: 42 }), + GenericEnum::from_iter(&["test", "start", "42"]) + ) +} + +#[test] +fn generic_w_fromstr_trait_bound() { + use std::{fmt, str::FromStr}; + + #[derive(StructOpt, PartialEq, Debug)] + struct Opt<T> + where + T: FromStr, + <T as FromStr>::Err: fmt::Debug + fmt::Display, + { + answer: T, + } + + assert_eq!( + Opt::<isize> { answer: 42 }, + Opt::<isize>::from_iter(&["--answer", "42"]) + ) +} + +#[test] +fn generic_wo_trait_bound() { + use std::time::Duration; + + #[derive(StructOpt, PartialEq, Debug)] + struct Opt<T> { + answer: isize, + #[structopt(skip)] + took: Option<T>, + } + + assert_eq!( + Opt::<Duration> { + answer: 42, + took: None + }, + Opt::<Duration>::from_iter(&["--answer", "42"]) + ) +} + +#[test] +fn generic_where_clause_w_trailing_comma() { + use std::{fmt, str::FromStr}; + + #[derive(StructOpt, PartialEq, Debug)] + struct Opt<T> + where + T: FromStr, + <T as FromStr>::Err: fmt::Debug + fmt::Display, + { + pub answer: T, + } + + assert_eq!( + Opt::<isize> { answer: 42 }, + Opt::<isize>::from_iter(&["--answer", "42"]) + ) +} diff --git a/tests/issues.rs b/tests/issues.rs index 8b4ac4b..3f9e1af 100644 --- a/tests/issues.rs +++ b/tests/issues.rs @@ -115,3 +115,60 @@ fn issue_359() { Opt::from_iter(&["test", "only_one_arg"]) ); } + +#[test] +fn issue_418() { + use structopt::StructOpt; + + #[derive(Debug, StructOpt)] + struct Opts { + #[structopt(subcommand)] + /// The command to run + command: Command, + } + + #[derive(Debug, StructOpt)] + enum Command { + /// Reticulate the splines + #[structopt(visible_alias = "ret")] + Reticulate { + /// How many splines + num_splines: u8, + }, + /// Frobnicate the rest + #[structopt(visible_alias = "frob")] + Frobnicate, + } + + let help = get_long_help::<Opts>(); + assert!(help.contains("Reticulate the splines [aliases: ret]")); +} + +#[test] +fn issue_490() { + use std::iter::FromIterator; + use std::str::FromStr; + use structopt::StructOpt; + + struct U16ish; + impl FromStr for U16ish { + type Err = (); + fn from_str(_: &str) -> Result<Self, Self::Err> { + unimplemented!() + } + } + impl<'a> FromIterator<&'a U16ish> for Vec<u16> { + fn from_iter<T: IntoIterator<Item = &'a U16ish>>(_: T) -> Self { + unimplemented!() + } + } + + #[derive(StructOpt, Debug)] + struct Opt { + opt_vec: Vec<u16>, + #[structopt(long)] + opt_opt_vec: Option<Vec<u16>>, + } + + // Assert that it compiles +} diff --git a/tests/macro-errors.rs b/tests/macro-errors.rs index 54b405a..74342f7 100644 --- a/tests/macro-errors.rs +++ b/tests/macro-errors.rs @@ -5,7 +5,7 @@ // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed -#[rustversion::attr(any(not(stable), before(1.43)), ignore)] +#[rustversion::attr(any(not(stable), before(1.54)), ignore)] #[test] fn ui() { let t = trybuild::TestCases::new(); diff --git a/tests/non_literal_attributes.rs b/tests/non_literal_attributes.rs index 75b6b71..4c3a442 100644 --- a/tests/non_literal_attributes.rs +++ b/tests/non_literal_attributes.rs @@ -143,5 +143,9 @@ fn test_parse_hex_function_path() { let err = HexOpt::clap() .get_matches_from_safe(&["test", "-n", "gg"]) .unwrap_err(); - assert!(err.message.contains("invalid digit found in string"), err); + assert!( + err.message.contains("invalid digit found in string"), + "{}", + err + ); } diff --git a/tests/special_types.rs b/tests/special_types.rs index ffed5e2..ac7d143 100644 --- a/tests/special_types.rs +++ b/tests/special_types.rs @@ -17,7 +17,7 @@ fn special_types_bool() { Ok(self::bool(s.into())) } } - }; + } #[derive(StructOpt, PartialEq, Debug)] struct Opt { diff --git a/tests/subcommands.rs b/tests/subcommands.rs index 1fc8e76..4ee738b 100644 --- a/tests/subcommands.rs +++ b/tests/subcommands.rs @@ -301,3 +301,49 @@ fn external_subcommand_optional() { assert_eq!(Opt::from_iter(&["test"]), Opt { sub: None }); } + +#[test] +fn skip_subcommand() { + #[derive(Debug, PartialEq, StructOpt)] + struct Opt { + #[structopt(subcommand)] + sub: Subcommands, + } + + #[derive(Debug, PartialEq, StructOpt)] + enum Subcommands { + Add, + Remove, + + #[allow(dead_code)] + #[structopt(skip)] + Skip, + } + + assert_eq!( + Opt::from_iter(&["test", "add"]), + Opt { + sub: Subcommands::Add + } + ); + + assert_eq!( + Opt::from_iter(&["test", "remove"]), + Opt { + sub: Subcommands::Remove + } + ); + + let res = Opt::from_iter_safe(&["test", "skip"]); + assert!( + matches!( + res, + Err(clap::Error { + kind: clap::ErrorKind::UnknownArgument, + .. + }) + ), + "Unexpected result: {:?}", + res + ); +} diff --git a/tests/ui/non_existent_attr.stderr b/tests/ui/non_existent_attr.stderr index 61f784e..5765597 100644 --- a/tests/ui/non_existent_attr.stderr +++ b/tests/ui/non_existent_attr.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `non_existing_attribute` found for struct `Arg<'_, '_>` in the current scope +error[E0599]: no method named `non_existing_attribute` found for struct `Arg` in the current scope --> $DIR/non_existent_attr.rs:14:24 | 14 | #[structopt(short, non_existing_attribute = 1)] diff --git a/tests/ui/skip_without_default.stderr b/tests/ui/skip_without_default.stderr index b5d702a..d08be0c 100644 --- a/tests/ui/skip_without_default.stderr +++ b/tests/ui/skip_without_default.stderr @@ -1,7 +1,7 @@ error[E0277]: the trait bound `Kind: Default` is not satisfied - --> $DIR/skip_without_default.rs:22:17 - | -22 | #[structopt(skip)] - | ^^^^ the trait `Default` is not implemented for `Kind` - | - = note: required by `std::default::Default::default` + --> $DIR/skip_without_default.rs:22:17 + | +22 | #[structopt(skip)] + | ^^^^ the trait `Default` is not implemented for `Kind` + | +note: required by `std::default::Default::default` diff --git a/tests/ui/tuple_struct.stderr b/tests/ui/tuple_struct.stderr index 31705c9..ad92385 100644 --- a/tests/ui/tuple_struct.stderr +++ b/tests/ui/tuple_struct.stderr @@ -4,4 +4,4 @@ error: structopt only supports non-tuple structs and enums 11 | #[derive(StructOpt, Debug)] | ^^^^^^^^^ | - = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the derive macro `StructOpt` (in Nightly builds, run with -Z macro-backtrace for more info) |