Previous behavior:
- They'd be sorted by default
- They'd derive display order if `DeriveDisplayOrder` was set
- This could be set recursively
- The initial display order value for subcommands was 0
New behavior:
- Sorted order is derived by default
- Sorting is turned on by `cmd.next_display_order(None)`
- This is not recursive, it must be set on each level
- The display order incrementing is mixed with arguments
- This does make it slightly more difficult to predict
We had some tests for this but not sufficient obviously. The problem is
we were tweaking the positional argument counter when processing flags
and not just positional arguments. Delaying it until after flags seems
to fix this.
Fixes#3959
A couple of things happened when preparing to release 3.0
- We needed derive documentation
- I had liked how serde handled theres
- I had bad experiences finding things in structopt's documentation
- The examples were broken and we needed tests
- The examples seemed to follow a pattern of having tutorial content and
cookbook content
- We had been getting bug reports from people looking at master and
thinking they were looking at what is currently released
- We had gotten feedback to keep down the number of places that
documentation was located
From this, we went with a mix of docs.rs and github
- We kept the number of content locations at 2 rather than 3 by not
having an external site like serde
- We rewrote the examples into explicit tutorials and cookbooks to align
with the 4 styles of documentation
- We could test our examples by running `console` code blocks with
trycmd
- Documentation was versioned and the README pointed to the last release
This had downsides
- The tutorials didn't have the code inlined
- Users still had a hard time finding and navigating between the
different forms of documentation
- In practice, we were less likely to cross-link between the different
types of documentation
Moving to docs.rs would offer a lot of benefits, even if it is only
designed for Rust-reference documentation and isn't good for Rust derive
reference documentation, tutorials, cookbooks, etc. The big problem was
keeping the examples tested to keep maintenance costs down. Maybe its
just me but its easy to overlook
- You can pull documentation from a file using `#[doc = "path"]`
- Repeated doc attributes get concatenated rather than first or last
writer winning
Remember these when specifically thinking about Rust documentation made
me realize that we could get everything into docs.rs.
When doing this
- Tutorial code got brought in as was one of the aims
- We needed to split the lib documentation and the README to have all of
the linking work. This allowed us to specialize them according to
their rule (user vs contributor)
- We needed to avoid users getting caught up in making a decision
between Derive and Builder APIs so we put the focus on the derive API
with links to the FAQ to help users decide when to use one or the
other.
- Improved cross-referencing between different parts of the
documentation
- Limited inline comments were added to example code
- Introductory example code intentionally does not have teaching
comments in it as its meant to give a flavor or sense of things and
not meant to teach on its own.
This is a first attempt. There will be a lot of room for further
improvement. Current know downsides:
- Content source is more split up for the tutorials
This hopefully addresses #3189
This fixes a bug introduced in 4a694f3592
when we were trying to move away from presence checks via occurrences.
I switched it to the common type of presence check but really what we
want is a highest-precedence check.
Fixes#3872
When upgrading our company projects from clap 3.1 to clap 3.2 I had
to fix several references to `clap::lazy_init`. People are not
supposed to do that, but that's hard to enforce.
Hope placing `once_cell` reexport into `__macro_refs` prevent at
least some of the such issues in the future.
Before, I was mixed on doing this as ideally people would upgrade
through the minor releases, going through the release notes. This also
saves us havin to audit deprecations to make sure they are all pointing
to the latest.
First, this isn't practical for users. Its annoying to pin your version (at least
its easier now that we pin `clap_derive` for users) and a lot of work to
go through them one step at a time.
On top of that, we've changed our deprecation policy to put the timing
of responding to deprecations into the user's hands with, with us
putting them behind the `deprecated` feature flag. This means someone
might respond to deprecations every once in a while or might not do it
until right before the 4.0 release. Our deprecation messages should be
updated to respond to that.
This supersedes #3616
This broke when we introduced clap_lex and then did a refactor on top.
We put in guards to say that escapes shouldn't happen but missed `--=`
which isn't quite an escape.
Not fully set on what error should be returned in this case (we are
returning roughly what we used to) but at least
we aren't panicing.
Fixes#3858
Between
- `ArgAction::SetTrue` storing actual values
- `ArgAction::Set` making it easier for derive users to override bool
behavior
- `Arg::default_missing_value` allowing hybrid-flags
- This commit documenting hybrid-flags even further
There shouldn't be anything left for #1649Fixes#1649
This adds a new `Cargo.toml` feature named `deprecated` that opts
controls whether deprecation warnings show up. This is starting off as
non-default though that may change (see below).
Benefits
- Allows a staged rollout so a smaller subset of users see new
deprecations and can report their experience with them before everyone
sees them. For example, this reduces the number of people who have to
deal with #3822.
- This allows people to defer responding to each new batch of
deprecations and instead do it at once. This means we should
reconsider #3616.
The one risk is people who don't follow blog posts and guides having a
harder time upgrading to the next breaking release without the warnings
on by default. For these users, we reserve the right to make the
`deprecated` feature `default`. This is most likely to happen in a
minor release that is released in conjunction with the next major
release (e.g. when releasing 4.0.0, we release a 3.3.0 that enables
deprecations by default). By using a feature, users can still disable
this if they want.
Thanks @joshtriplett for the idea
Though this is changing an API item we export, we do not consider this a
breaking change because
- This was an implementation detail of the macros and people shouldn't be using it directly
- The `macro_rules` macro is coupled to `clap` because they are in the
same crate
- The derive macro is coupled to `clap` because `clap` declares a
`=x.y.z` dependency on `clap_derive
Fixes#3828
- This matches the more container-like naming we are aiming for
- This provides an opportunity to warn people about moving away from
`ArgAction::IncOcccurrences` for flags, like the deprecation for
`ArgMatches::occurrences_of` to help people migrate in preparation for
clap 4 (rather than having the behavior change subtly in a way only
caught by thorough tests)
In addition, I feel `contains_id` has less ambiguous meaning than
`is_present`.
Someone should not reasonably expect a coun flag to go up to billions,
millions, or even thousands. 255 should be sufficient for anyone,
right?
The original type was selected to be consistent with
`ArgMatches::occurrences_of` but that is also used for tracking how
many values appear which can be large with `xargs`.
I'm still conflicted on what the "right type" is an wish we could
support any numeric type. When I did a search on github though, every
case was for debug/quiet flags and only supported 2-3 occurrences,
making a `u8` overkill.
This came out of a discussion on #3792
With `AnyValueParser` now private, we can also make `AnyValue` private.
Most users should not need to call `ValueParser::parse_ref` and doing
this gives us more implementation freedom for the future.
I'm a bit disappointed we don't have a way to control the action for the
help subcommand. Instead, people will need to provide their own and
disable ours. Long term, I want to design actions for subcommands but I
don't think its worth keeping `NoAutoHelp` around for it.
We aren't enumerating arguments but values for an argument, so the name
should reflect that.
This will be important as part of #1807 when we have more specific
attribute names.
This mostly exist for
- Knowing of the value came from the command-line but we now have
`ArgMatches::source`
- Counting the number of flags but we now have `ArgAction::Count`
This shouldn't be needed anymore now that this is effectively the new
behavior for the non-deprecated actions.
This was briefly talked about in
https://github.com/clap-rs/clap/discussions/2627 but I wasn't familiar
enough with the implementation to know how safe it is. Now, maintainrs
and users can be more confident because they are explicitly opting into
it.
See also #3795
Dropping these will help simplify a lot, including removing of
occurrences.
These come at the cost of the derive not yet supporting types that impl
`From`.
This is a follow up to #3420. Its easy to overlook this because it is only
useful for the conditionals (we actually prevent applying unconditional
defaults to unconditional requireds). This became apparent with the
increased use of defaults with `SetTrue`.
As always, there is the question of when is a bug fix a breaking change.
I'm going to consider this safe since we prevent some instances of this
from even happening and we already did #3420 and this is in line with
those.
Originally I hid all, assuming the flag-only use case but we had to
prevent that from showing up anyways. For the takes_value case, we
should be showing something since we know what it accepts. I decided to
only show the most basic values and hide the rest so as to not overwhelm
the user with redundant options and hope the user recognizes they are
redundant.
Now that flags can have meaningful defaults and with defaults being
implicitly set for certain actions, they appear in help but don't quite
make sense.
Actions were inspired by Python and Python does not implicitly default
any field when an action is given. From a Builder API perspective, this
seemed fine because we tend to focus the Builder API on giving the user
all information so they can make their own decisions. When working on
the Derive API, this became a problem because users were going to have
to migrate from an implied default to an explicit default when a common
default is good enough most of the time. This shouldn't interfere with
Builder users getting more details when needed.
This also highlighted two problems
- We set the index for defaults
- We don't debug_assert when applying conditional requirements with a
default present
This round out the new style actions and allow us to start deprecating
occurrences.
As part of an effort to unify code paths, this does change flag parsing
to do splits. This will only be a problem if the user enables splits
but we'll at least not crash. Once we also address #3776, we'll be able
to have envs all work the same.
This is the minimum set of actions for the derive to move off of
`parse`. These are inspired by Python's native actions.
These new actions have a "unified" behavior with defaults/envs. This
mostly means that occurrences aren't tracked. Occurrences were used as
a substitute for `ValueSource` or for counting values. Both cases
shouldn't be needed anymore but we can re-evaluate this later if needed.
If we felt this was important long-term, we should fix this outside of
the Action. Since we might be changing up occurrences (#3772), we can
probably get away with a hack.
This changes how occurrences and values are grouped for multiple values.
Today, it appears as a bug. If we move forward with #3772, then this
can make sense.
When creating `PendingValues`, I can't have the lifetime. I could make
it a `Cow` but decided to hold off instead since we don't need this
right now. Maybe by the time we do need it, we'll have another way of
doing this.
There is a default_missing_vals case which is slightly different because
its not actually a default but closing out the remaining argument that
was started in last iteration.
Before, if we were in trailing values that aren't delimite, we wouldn't
respect this flag and end processing of the value, now we do.
This also has a slight perf benefit of us only splitting the value if
the delimiter is present. We checked for the delimiter anyways, so
doing it first removes a slight bit of work.
I also feel this helps clarify the intended behavior and ooches us
towards a unified code path for actions.
I wrote these tests expecting to highlight a bug but it turns out things
were structured just right to not exhibit it. The fact that the code
looks like its broken is a problem, so I restructured it (put it first,
changed the source) so it doesn't look suspicious anymore.
We were independently starting occurrences and starting value groups.
Now we do them at the same time.
COMPATIBILITY: This changes us from counting occurrences per positional
when using `multiple_values` to one occurrence. This is user visible
and tests were written against it but it goes against the documentation
and doesn't quite make sense.
Inferred flags can make it hard for a future action to trigger behavior
off of the selected alias, like we might want to do for negations, so we
are now translating to the intended arg.
This will also help for debugging.
For most users, this won't be worth doing, they can just specify the
parser if needed. Where this has value is crates that integrate custom
types into clap, like creating click-like file integration. See
https://click.palletsprojects.com/en/8.0.x/arguments/#file-arguments
Clap has focused on reporting development errors through assertions
rather than mixing user errors with development errors. Sometimes,
developers need to handle things more flexibly so included in #3732 was
the reporting of value accessor failures as internal errors with a
distinct type. I've been going back and forth on whether the extra
error pessimises the usability in the common case vs dealing with the
proliferation of different function combinations. In working on
deprecating the `value_of` functions, I decided that it was going to be
worth duplicating so long as we can keep the documentation focused.
The remove functions no longer return `Arc` but the core type, at the
cost of requiring `Clone`. I originally held off on this
in #3732 in the hope of gracefully transition the derive and requiring
`Clone` would have been a breaking change but when it came to #3734, I didn't
find a way to make it work without a breaking change, so I made it
opt-in. This means I can force the `Clone` requirement now.
I added the requirement for `Clone` everywhere else in the hopes that in
the future, we can drop the `Arc` without a breaking change.
When to show usage? We are currently mixed about it. For `validator`,
we didn't show it at all. Sometimes we show the used arguments and
sometimes we don't.
With `ValueParser`, I ran into the problem that we weren't showing the
used arguments like we had previously in some cases. In deciding how to
solve this, I went with the simplest route for now and removed it as the
usage likely doesn't add much context to help people solve their
problem, more so the recommendation for help. We'll see how the
feedback is on this and adjust.
`multicall` allows you to have one binary expose itself as multiple
programs, like busybox does. This also works well for user clap for
parsing REPLs.
Fixes#2861
There are several approaches with this
- `value_parser(N..M)`: creates an i64 range
- `value_parser(value_parser!(u16).range(10..))`: creates an u16 range
that starts at 10
- `RangeI64ValueParser`: create whatever range you want
I was hoping to generalize `RangeI64ValueParser` for any source type,
not just i64, but ran into issues and decided to punt. I chose `i64` as
the source type as it seemed the most general and didn't run into
portability issues like `isize`.
This is a step towards #3199. All that is left is for the derive to use
this.
This identified a problem with the blanket implementations for
`TypedValueParser`: it only worked on function pointer types and not unnamed
function tupes. The user has to explicitly decay the function type to a
function pointer to opt-in, so I changed the blanket impl. The loss of
the `OsStr` impl shouldn't be too bad.