aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-05-10 07:08:39 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-05-10 07:08:39 +0000
commit0f74a9e86a58a54e659fa8464c3c3e4a08604484 (patch)
tree5e9db6a19f0e1fbcb8b1819da7ec93b5055eccfc
parent23b1aac127c8d9d5acaeb2354f4d6eccbca192f0 (diff)
parent35041af94f4ebedd5f6f48e62b7e79775d74cfdc (diff)
downloadstructopt-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
-rw-r--r--.cargo_vcs_info.json7
-rw-r--r--.travis.yml2
-rw-r--r--Android.bp24
-rw-r--r--CHANGELOG.md18
-rw-r--r--Cargo.toml17
-rw-r--r--Cargo.toml.orig5
-rw-r--r--METADATA10
-rw-r--r--README.md8
-rw-r--r--TEST_MAPPING10
-rw-r--r--examples/README.md2
-rw-r--r--examples/after_help.rs24
-rw-r--r--examples/at_least_two.rs15
-rw-r--r--examples/basic.rs24
-rw-r--r--examples/deny_missing_docs.rs20
-rw-r--r--examples/doc_comments.rs50
-rw-r--r--examples/enum_in_args.rs15
-rw-r--r--examples/enum_in_args_with_strum.rs42
-rw-r--r--examples/enum_tuple.rs16
-rw-r--r--examples/env.rs17
-rw-r--r--examples/example.rs25
-rw-r--r--examples/flatten.rs17
-rw-r--r--examples/gen_completions.rs14
-rw-r--r--examples/git.rs18
-rw-r--r--examples/group.rs20
-rw-r--r--examples/keyvalue.rs15
-rw-r--r--examples/negative_flag.rs13
-rw-r--r--examples/no_version.rs11
-rw-r--r--examples/rename_all.rs19
-rw-r--r--examples/required_if.rs19
-rw-r--r--examples/subcommand_aliases.rs17
-rw-r--r--examples/true_or_false.rs2
-rw-r--r--src/lib.rs127
-rw-r--r--tests/custom-string-parsers.rs6
-rw-r--r--tests/generics.rs145
-rw-r--r--tests/issues.rs57
-rw-r--r--tests/macro-errors.rs2
-rw-r--r--tests/non_literal_attributes.rs6
-rw-r--r--tests/special_types.rs2
-rw-r--r--tests/subcommands.rs46
-rw-r--r--tests/ui/non_existent_attr.stderr2
-rw-r--r--tests/ui/skip_without_default.stderr12
-rw-r--r--tests/ui/tuple_struct.stderr2
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
diff --git a/Android.bp b/Android.bp
index 9905be3..36e6af0 100644
--- a/Android.bp
+++ b/Android.bp
@@ -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)
diff --git a/Cargo.toml b/Cargo.toml
index d24c98b..321b31e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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"] }
diff --git a/METADATA b/METADATA
index df2195b..4839f47 100644
--- a/METADATA
+++ b/METADATA
@@ -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
}
}
diff --git a/README.md b/README.md
index 6609488..bff1587 100644
--- a/README.md
+++ b/README.md
@@ -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,
}
diff --git a/src/lib.rs b/src/lib.rs
index fb4ad85..92d93ab 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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)