This contains two types of re-ordering:
- Internal, putting the focus of each file first.
- Public, re-arranging items and grouping impl blocks to try to better
organize the documentation and find related items.
The main weakness of the docs work is in `Args`. Its just a mess. In
particular, we should probably link the simple casesm like `required` to
the advanced impl block.
Fixes#55
Adding in a `StructOpt` derive with `structopt` attributes, with
deprecation notices. Unofrtunately, not as many deprecation warnings as
I would like. Apparently, you can't do them for a `use` of a derive? I
also wanted to inject code that would trigger a deprecation notice for
attributes but that would require enough of a refactor that I didn't
consider it worth it. We are at least providing a transition window
even if it means we'll have to remvoe it next major release without a
deprecation warning.
This creates distinct tutorial examples from complex feature examples
(more how-tos). Both sets are getting builder / derive versions (at
least the critical ones).
I've been finding I've been setting `AppSettings` without it which is
likely leading to bugs. This tries to raise the visibility by using it
based on the setting being used and not whether the application needs
it.
Before:
- `bool`: a flag
- `Option<_>`: not required
- `Option<Option<_>>` is not required and when it is present, the value
is not required
- `Vec<_>`: multiple values, optional
- `Option<Vec<_>>`: multiple values, min values of 0, optional
After:
- `bool`: a flag
- `Option<_>`: not required
- `Option<Option<_>>` is not required and when it is present, the value
is not required
- `Vec<_>`: multiple occurrences, optional
- optional: `Vec` implies 0 or more, so should not imply required
- `Option<Vec<_>>`: multiple occurrences, optional
- optional: Use over `Vec` to detect when no option being present when
using multiple values
Motivations:
My priorities were:
1. Are we getting in the users way?
2. Does the API make sense?
3. Does the API encourage best practices?
I was originally concerned about the lack of composability with
`Option<Option<_>>` and `Option<Vec<_>>` (and eventually `Vec<Vec<_>>`).
It prescribes special meaning to each type depending on where it shows
up, rather than providing a single meaning for a type generally. You
then can't do things like have `Option<_>` mean "required argument with
optional value" without hand constructing it. However, in practice the
outer type correlates with the argument occurrence and the inner type
with the value. It is rare to want the value behavior without also the
occurrence behavior. So I figure it is probably fine as long as people
can set the flags to manually get the behavior they want.
`Vec<_>` implies multiple occurrences, rather than multiple values.
Anecdotally, whenever I've used the old `Arg::multiple`, I thought I was
getting `Arg::multiple_occurrences` only. `Arg::multiple_values`,
without any bounds or delimiter requirement, can lead to a confusing
user experience and isn't a good default for these. On top of that, if
someone does have an unbounded or a delimiter multiple values, they are
probably also using multiple occurrences.
`Vec<_>` is optional because a `Vec` implies 0 or more, so we stick to
the meaning of the rust type. At least for me, I also rarely need a
required with multiple occurrences argument but more often need optional
with multiple occurrences.
`Option<Vec<_>>` ends up matching `Vec<_>` which can raise the question
of why have it. Some users might prefer the type. Otherwise, this is
so users can detect whether the argument is present or not when using
`min_values(0)`. Rather than defining an entire policy around this and
having users customize it, or setting `min_values(0)` without the rest
of a default policy, this gives people a blank slate to work from.
Another design option would have been to not infer any special-type
settings if someone sets a handful of settings manually, which would
have avoided the confusion in Issue clap-rs/clap 2599 but I see that
being confusing (for someone who knows the default, they will be
expecting it to be additive; which flags disable inferred settings?) and
brittle (as flags are added or changed, how do we ensure we keep this
up?).
Tests were added to ensure we support people customizing the behavior to
match their needs.
This is not solving:
- `Vec<Vec<_>>`, see clap-rs/clap 2924
- `(T1, T2)`, `Vec<(T1, T2)>`, etc, see clap-rs/clap 1717
- `Vec<Option<_>>` and many other potential combinations
Fixes clap-rs/clap 1772
Fixes clap-rs/clap 2599
See also clap-rs/clap 2195
This reverts commits 24cb8b1..d0abb37 from clap-rs/clap#1840
This is part of #16. clap-rs/clap#1840 wasn't the right call but we
don't have time to make the decision now, so instead of having one
option and changing it in 4.0, this reverts back to clap2 behavior.
Looks like this is coming from `update_from_arg_matches` where we do a
ladder of `if __clap_arg_matches.is_present(...)` that clippy wants to
be `else if`s. While for human edited code, that does clarify intent,
for machine generated code that is rarely read, its a pain to do, so
silencing it.
Unfortunately, it isn't in a group we can overall silence.
Fixes#3017
In experimenting on #1772, I want to write test cases for various
combinations of required or not, values vs occurrences, etc. There
wasn't really a clear place to put these.
On top of that, I wanted there to be a clear place in the tests for
describing the behavior of special types, to make it easier to audit and
easier to see how a PR for #1772 changes things.
As part of this effort in organizing these tests, I reduced the number
of tests that use special types. This better focuses these tests on the
cases they are intending to cover, rather than pulling in unrelated
features. This makes it easier to audit special types and makes it so
failures give more focused results, making it easier to see what broke.
PR #2979 reduced what dependencies we push on users and made us one step
closer to being able to test more with fewer features. Looks like I
also need to update `clap_derive`. I verified locally that #2976 fails
with this.
`clap_derive` still needs `env` because of examples / tests that use it.
I feel like moving `clap_derive`s tests out to `clap` would be the way
to fix this.
The tests are using `to_string` which maps to `Display::fmt` and the
`Colorizer` version is colorless. To get color, it is only supported
with `print()` which has to go to stdout / stderr and can't be directed
to an arbitrary stream.
`Parser::parse_from` will call `exit` on failure and we don't just lose
backtrace information but we don't even know which of the tests running
in parallel panicked. I ran into this when experimenting with
`clap_derive` and I couldn't tell what actually failed.
So let's switch to `Parse::try_parse_from`.
Errors went from:
```
test option_option ... ok
error: Found argument 'bar' which wasn't expected, or isn't valid in this context
USAGE:
clap_derive [OPTIONS]
For more information try --help
error: test failed, to rerun pass '--test arg_enum'
```
To:
```
test option_option ... ok
test variant_with_defined_casing ... ok
test skip_variant ... ok
test default_value ... ok
test vector ... FAILED
test option_vector ... ok
failures:
---- vector stdout ----
thread 'vector' panicked at 'called `Result::unwrap()` on an `Err` value: Error { message: Formatted(Colorizer { use_stderr: true, color_when: Auto
, pieces: [("error:", Some(Red)), (" ", None), ("Found argument '", None), ("bar", Some(Yellow)), ("' which wasn't expected, or isn't valid in this
context", None), ("\n\n", None), ("USAGE:\n clap_derive [OPTIONS]", None), ("\n\nFor more information try ", None), ("--help", Some(Green)), ("
\n", None)] }), kind: UnknownArgument, info: ["bar"], source: None, backtrace: Backtrace }', clap_derive/tests/arg_enum.rs:388:56
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
failures:
vector
test result: FAILED. 15 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
error: test failed, to rerun pass '--test arg_enum'
```
This is to help verify behavior added in #2943. We separated the error
raising site from the error formatting site and this verifies that the
formatting actually happens.
When an anonymous struct is inside of an enum, we end up applying the
App methods twice, once for the `augment_args` and once for variant.
This consolidates those calls.
Fixes#2898
2926: Put `grouped_values_of` behind a feature gate r=pksunkara a=epage
2948: docs(generate): Move derive example to generate r=pksunkara a=epage
Co-authored-by: Ed Page <eopage@gmail.com>
From a users perspective, `clap_derive` is baked into `clap`.
`clap_generate is an add on to `clap`. So it seems best to have all
`clap_generate` examples in `clap_generate` where a user will look for
them.
Fixes#2939
Due to a copy/paste bug, we were reading the `help_heading` for
Subcommands from the enum's attribute and not the variant's attribute.
It doesn't make sense for the outer command's help_heading to control
the subcommands help_heading.
This does raise an interesting question on inheriting / propagating help_heading,
which I originally wrote the tests for. We'd first need to answer
whether it should be built-in to the builder or derive-specific.
In working on converting unwraps to errors, I noticed that we did not
spport `arg_enum` for `Option<Option<_>>` and `Option<Vec<_>>`, so this
addresses that.
My main motivation was to consolidate and make the logic more
consistent, the bug fix just fell out of that work.
PR #2751 highlighted a problem we have where the variable names we use
could collide with users. Rather than parse out when or not to use
special names, and worry about people keeping that up to date through
refactors, I globally renamed all variables by adding a `__clap_`
prefix, which looks like what serde does to solve this problem.
I audited the result with `cargo expand`. I didn't add any tests
because any tests would be reactionary and would give us a false sense
of protection since any new code could hit this with anything we do.
Our best route for naming is consistency so people are likely to notice
and copy.
Fixes#2934
In considering potential work for #2683, I realized we might need a type to carry data for
each of the `multiple_values`. `ArgValue` works both for that and for
possible values, so we need to come up with a better name for one or
both. Changing `ArgValue`s name now would be ideal since its new in
clap3 and by renaming it, we can reduce churn for users.
While thinking about this, I realized I regularly get these mixed
up, so renaming `ArgValue` to `PossibleValue` I think will help clear
things up, regardless of #2683.
Before, when `flatten`ing, the struct you flattened in could set the
help heading for all the following arguments. Now, we scope each
`flatten` to not do that.
I had originally intended to bake this into the initial / final methods
but that would have required some re-work to allow capturing state
between them that seemed unnecessary.
Fixes#2803
Our goal is to not panic inside of the macro (e.g. #2255). Currently,
we `.unwrap()` everywhere except when turning an `ArgMatches` into an
`enum`. To handle `flatten`, we walk through each `flatten`ed enum to
see if it can be instantiated. We don't want to mix this up with any of
the other eror cases (including further nested versions of this).
If we went straight to `Result<T>`, we'd have to differentiate this case
through the `ErrorKind` and `map_err` it in all other cases to prevent
it from bubbling up and confusing us.
Alternatively, we could do a more complicated type `Result<Option<T>>`
where the `Option` exists purely for this case and we can use type
checking to make sure we properly turn the `None`s into errors when
needed.
Or we can bypass all of this and just ask the `flatten`ed` subcommand if
it supports the current command.
We normally set all app attributes at the end. This can be changed but
will require some work to ensure
- Top-level item's doc cmment ins our over flattened
- We still support `Args` / `Subcommand` be used to initialize an `App` when
creating a subcommand
In the mean time, this special cases `help_heading` to happen first.
We'll need this special casing anyways to address #2803 since we'll need
to capture the old help heading before addings args and then restore it
after. I guess we could unconditionally do that but its extra work /
boilerplate for when people have to dig into their what the derives do.
Fixes#2785