Tests to check for conflicts between flag subcommands long and short and
their aliases and args both long and short and their aliases. Tests to
handle self conflicts, where a flag subcommand short or long with have a
corresponding alias with the same value.
Instead of a `FlagSubCommand` struct the addition of two simple methods
to `App`. `App::long_flag` and `App::short_flag` that cover all the
bases of the many methods that were provided in `FlagSubCommand`. This
API is far simpler to use and more akin to the present `Arg::long` and `Arg::short`.
this implements Arg::short_alias, Arg::short_aliases,
Arg::short_visible_alias, and Arg::short_visible_aliases in addition to
adding their associated tests
These are similar to the tests backported to the 2.x branch in
https://github.com/clap-rs/clap/pull/1907. These are more comprehensive,
because the OsStr splitting methods are more robust now.
In particular, fix macros that take an enum of one of the the following forms:
- `#[...] enum { ... , }`
- `pub enum { ... , }`
- `enum { ... , }`
Previously, these expansions would result in an error message like "error: no
rules expected the token `:`".
Add extensive tests for each pattern. Only two of the patterns had tests
before, so these errors did not surface automatically.
1612: Use about() with help() and long_about() with long_help() r=pksunkara a=TheLostLambda
I was going through the clap documentation and was under the impression that calling `help()` would call `about()` and `long_help()` would call `long_about()`, but I've actually discovered this not to be the case. Instead, the `long_about()` was always shown when it existed, rendering the output (in the about section) of programs called with `-h` and `--help` identical. Issue #1472 shows this and that is fixed here.
Note this doesn't remove the ability to use the same about in both cases: if `long_about()` is unset, then `about()` is used in both cases.
I've changed the implementation here to use `is_some()` and `unwrap()` as opposed to `if let` because it ultimately allows for less repetitive code. Ideally, I'd be able to pair `if let` with a secondary condition (namely `self.use_long`), but to my dismay, let-chains are not stabilized yet.
For a second opinion, here is the code a settled on:
```
if self.use_long && parser.meta.long_about.is_some() {
debugln!("Help::write_default_help: writing long about");
write_thing!(parser.meta.long_about.unwrap())
} else if parser.meta.about.is_some() {
debugln!("Help::write_default_help: writing about");
write_thing!(parser.meta.about.unwrap())
}
```
Here is the alternative:
```
if self.use_long {
if let Some(about) = parser.meta.long_about {
debugln!("Help::write_default_help: writing long about");
write_thing!(about)
} else if let Some(about) = parser.meta.about {
debugln!("Help::write_default_help: writing about");
write_thing!(about)
}
} else {
if let Some(about) = parser.meta.about {
debugln!("Help::write_default_help: writing about");
write_thing!(about)
}
}
```
Co-authored-by: Brooks J Rady <b.j.rady@gmail.com>
> incidentally, how do we feel about adding a rustfmt check to the CI(s)?
yes we should be doing that. you can send another pr that adds the check to the Ci
The example code.
~~~rust
use clap::{App, Arg};
fn main() {
let matches = App::new("My Super Program")
.arg(
Arg::with_name("verbose")
.help("Sets the level of verbosity")
.short('v')
.long("verbose")
.takes_value(false)
.multiple_occurrences(true)
.env("VERBOSE"),
)
.get_matches();
match matches.occurrences_of("verbose") {
0 => println!("0 No verbose info"),
1 => println!("1 Some verbose info"),
2 => println!("2 Tons of verbose info"),
3 | _ => println!("3 >= Don't be crazy"),
}
}
~~~
It code use multiple_occurrences with env.
But it do not work.
`env` method set require take value.
It result see under.
~~~console
% cargo run -- -v
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/foo -v`
error: The argument '--verbose <verbose>...' requires a value but none was supplied
USAGE:
foo [OPTIONS]
For more information try --help
~~~
And, structopt or clap_derive may be create similar code.
So I am confused by structopt.
This to fix code small.
- Manually fix some problems
- Run 'cargo fix --clippy'
Commits taken from similar PRs open at that time:
- Replace indexmap remove with swap_remove
Resolves#1562 and closes#1563
- Use cognitive_complexity for clippy lint
Resolves#1564 and closes#1565
- Replace deprecated trim_left_matches with trim_start_matches
Closes#1539
Co-authored-by: Antoine Martin <antoine97.martin@gmail.com>
Co-authored-by: Brian Foley <bpfoley@users.noreply.github.com>
This patch:
* Removes the `ArgSettings::Global` variant, and replaces all
users of it to `Arg::global(...)`. The variant itself is lifted up
into a field on Arg. This was deprecated in clap 2.32.0.
* Removes AppFlags::PropagateGlobalValuesDown. This was deprecated in
clap 2.27.0.
* Removes `Arg::empty_values`. This was deprecated in clap 2.30.0.
* Removes `ArgMatches::usage`. This was deprecated in clap 2.32.0.
subcommands
This commit changes the internal ID to a u64 which will allow for
greater optimizations down the road. In addition, it lays the ground
work for allowing users to use things like enum variants as argument
keys instead of strings.
The only downside is each key needs to be hashed (the implementation
used is an FNV hasher for performance). However, the performance gains
in faster iteration, comparison, etc. should easily outweigh the single
hash of each argument.
Another benefit of if this commit is the removal of several lifetime
parameters, as it stands Arg and App now only have a single lifetime
parameter, and ArgMatches and ArgGroup have no lifetime parameter.
Args can now be added to custom help sections. This breaks up the builder pattern a little by adding help section declarations inline, but it's the most intuitive method and doesn't require strange nesting that feels awkward.
```rust
app::new("foo")
.arg(Arg::with_name("arg1")) // under normal headers
.help_heading("SPECIAL")
.arg(Arg::with_name("arg2")) // under SPECIAL: heading
```
Closes#805
Add logic to filter based on hidden long/short.
There is still an issue with the logic in parser.rs use_long_help. This
causes invalid evaluation of whether to show/hide based on long or short help
Complete check for use_long_help, add tests
For version 3, we want the args section to immediately follow
the usage section in the default help message.
One change that I am unhappy with is needing to make "write_arg"
in app/help.rs accept an extra param that makes it suppress the
extra line. This is to prevent an extra blank line from appearing
between args and options in the default help, and seems necessary,
but there might be a better way.
Optional positionals mixed with subcommands will still break this, since
I can't see how to tell which element of $line is the command than.
Mixing optional positionals with subcommands is a bit weird and awkward
though...
This changes the way we complete positionals to complete them using
_arguments, as should be done, instead of completing their uppercase name
as a string.
Currently I made it offer _files completion for all positional arguments.
This can be improved to complete actual possible values of the arguments
and only complete files if the argument truly takes them. But this will
require further changes in clap to actually have the required
functionality to get this information.
Long options take their argument either in the next word or after an
equals sign, but the Zsh completion specified that they take it either
in the same word with no separator or in the next word. See the
documentation of the Zsh _arguments function for more information.
From -> To
===========================================
with_underscore -> (with_)?special_commands
WUS -> SPECIAL_CMDS
special -> special_help
SPECIAL -> SPECIAL_HELP
When used with `Arg::possible_values` it allows the argument value to pass validation even if
the case differs from that of the specified `possible_value`.
```rust
let m = App::new("pv")
.arg(Arg::with_name("option")
.long("--option")
.takes_value(true)
.possible_value("test123")
.case_insensitive(true))
.get_matches_from(vec![
"pv", "--option", "TeSt123",
]);
assert!(m.value_of("option").unwrap().eq_ignore_ascii_case("test123"));
```
This setting also works when multiple values can be defined:
```rust
let m = App::new("pv")
.arg(Arg::with_name("option")
.short("-o")
.long("--option")
.takes_value(true)
.possible_value("test123")
.possible_value("test321")
.multiple(true)
.case_insensitive(true))
.get_matches_from(vec![
"pv", "--option", "TeSt123", "teST123", "tESt321"
]);
let matched_vals = m.values_of("option").unwrap().collect::<Vec<_>>();
assert_eq!(&*matched_vals, &["TeSt123", "teST123", "tESt321"]);
```
Closes#1118
If one is using a nightly Rust compiler they should compile clap
with the `nightly` feature.
```toml
[dependencies]
clap = { version = "2.27", features = ["nightly"] }
```
This isn't required for compilation to succeed, only to take
advantage of any nightly features used by clap.
If one is compiling with `#[deny(warnings)]` this commit will cause
compilation to fail if one *does not* compile with the `nightly`
since `std::ascii::AsciiExt` is no longer required in in multiple
files as of the latest Rust nightly (Nov 6th, 2017).
Closes#1095
Issue 978 mentions that subcommands cannot see the value
of globals that get passed, even if ArgSettings::PropagateGlobalsDown
is true.
This change commits a failing test that reproduces this error.
This doc attribute is used by rustdoc when generating documentation
for other crates that depend on this crate. With the html_root_url,
rustdoc will be able to generate correct links into this crate.
See C-HTML-ROOT in the Rust API Guidelines for more information:
https://rust-lang-nursery.github.io/api-guidelines/documentation.html#crate-sets-html_root_url-attribute-c-html-root
A version-sync check was added to ensure that the URL is kept up to
date when the crate version changes.
The textwrap crate uses a simpler linear-time algorithm for wrapping
the text. The current algorithm in wrap_help uses several O(n) calls
to String::insert and String::remove, which makes it potentially
quadratic in complexity.
Comparing the 05_ripgrep benchmark at commits textwrap~2 and textwrap
gives this result on my machine:
name before ns/iter after ns/iter diff ns/iter diff %
build_app_long 22,101 21,099 -1,002 -4.53%
build_app_short 22,138 21,205 -933 -4.21%
build_help_long 514,265 284,467 -229,798 -44.68%
build_help_short 85,720 85,693 -27 -0.03%
parse_clean 23,471 22,859 -612 -2.61%
parse_complex 29,535 28,919 -616 -2.09%
parse_lots 422,815 414,577 -8,238 -1.95%
As part of this commit, the wrapping_newline_chars test was updated.
The old algorithm had a subtle bug where it would break lines too
early. That is, it wrapped the text like
ARGS:
<mode> x, max, maximum 20 characters, contains
symbols.
l, long Copy-friendly,
14 characters, contains symbols.
m, med, medium Copy-friendly, 8
characters, contains symbols.";
when it should really have wrapped it like
ARGS:
<mode> x, max, maximum 20 characters, contains
symbols.
l, long Copy-friendly, 14
characters, contains symbols.
m, med, medium Copy-friendly, 8
characters, contains symbols.";
Notice how the word "14" was incorrectly moved to the next line. There
is clearly room for the word on the line with the "l, long" option
since there is room for "contains" just above it.
I'm not sure why this is, but the algorithm in textwrap handles this
case correctly.
* tests: adds tests for default values triggering conditional requirements
* fix: fixes a bug where default values should have triggered a conditional requirement but didnt
Closes#831
* tests: adds tests for missing conditional requirements in usage string of errors
* fix: fixes a bug where conditionally required args werent appearing in errors
* tests: adds tests for completion generators
* tests: adds tests for completions with binaries names that have underscores
* fix: fixes a bug where ZSH completions would panic if the binary name had an underscore in it
Closes#581
* fix: fixes bash completions for commands that have an underscore in the name
Closes#581
* chore: fix the category for crates.io
* docs(Macros): adds a warning about changing values in Cargo.toml not triggering a rebuild automatically
Closes#838
* fix(Completions): fixes a bug where global args weren't included in the generated completion scripts
Closes#841
* fix: fixes a println->debugln typo
* chore: increase version
Before, inserting a newline did not move the prev_space index forward.
This meant that the next word was measured incorrectly since the
length was measured back to the word before the newly inserted
linebreak.
Fixes#828.
Before, wrapping the help text at, say, 80 characters really meant
that every line could be at most 79 characters wide.
Lines can now be up to and including avail_chars columns wide.
If needed, a desired margin or padding can be subtracted from the
avail_chars argument at a later point.
* tests: remove unnecessary mut
When building the projec, I was told
warning: variable does not need to be mutable, #[warn(unused_mut)]
on by default
--> tests/macros.rs:39:9
|
39 | let mut app = clap_app!(("app name with spaces-and-hyphens") =>
| ^^^^^^^
* examples: remove unused variable
The inner Some value is not used in the match arm:
warning: unused variable: `local_matches`,
#[warn(unused_variables)] on by default
--> examples/20_subcommands.rs:128:32
|
128 | ("local", Some(local_matches)) =>{
| ^^^^^^^^^^^^^
With these options, in case the completion function cannot provide
suggestions, Bash will perform its default completions, based on e.g.
files, directories, and variable names. This is particularly useful for
argument values.
Flags, Opts, and Positionals now store their internals using compartmented Base, Valued, and
Switched structs to keep the code duplication down and make it easier to maintain.
Iniside the src/app/parser.rs there have been several changes to make reasoning about the code
easier. Primarily moving related sections out of the large get_matches_with into their own
functions.
Try and stress the combinations of DeriveDisplayOrder and UnifiedHelpMessage
along with propagating them to subcommands and explicitly setting a display
order.
The new tests
derive_order_subcommand_propagate
unified_help_and_derive_order_subcommand_propagate
unified_help_and_derive_order_subcommand_propagate_with_explicit_display_order
are currently failing because of bug #706.
The new version of rustc 1.14.0-nightly (144af3e97 2016-10-02) has new
linting warnings/errors. This commit fixes them.
Signed-off-by: Salim Afiune <afiune@chef.io>
Added same alias funtionality for flags, now you can do:
```
Arg::with_name("flg")
.long("flag")
.short("f")
.alias("not_visible_flag")
.visible_alias("awesome_v_flag")
```
Signed-off-by: Salim Afiune <afiune@chef.io>
There are some cases where you need to have an argument to have an
alias, an example could be when you depricate one option in favor of
another one.
Now you are going to be able to alias arguments as follows:
```
Arg::with_name("opt")
.long("opt")
.short("o")
.takes_value(true)
.alias("invisible")
.visible_alias("visible")
```
Closes#669
* feat: adds App::with_defaults to automatically use crate_authors! and crate_version! macros
One can now use
```rust
let a = App::with_defaults("My Program");
// same as
let a2 = App::new("My Program")
.version(crate_version!())
.author(crate_authors!());
```
Closes#600
* imp(YAML Errors): vastly improves error messages when using YAML
When errors are made while developing, the panic error messages have
been improved instead of relying on the default panic message which is
extremely unhelpful.
Closes#574
* imp(Completions): uses standard conventions for bash completion files, namely '{bin}.bash-completion'
Closes#567
* imp(Help): automatically moves help text to the next line and wraps when term width is determined to be too small, or help text is too long
Now `clap` will check if it should automatically place long help
messages on the next line after the flag/option. This is determined by
checking to see if the space taken by flag/option plus spaces and values
doesn't leave enough room for the entirety of the help message, with the
single exception of of if the flag/option/spaces/values is less than 25%
of the width.
Closes#597
* tests: updates help tests to new forced new line rules
* fix(Groups): fixes some usage strings that contain both args in groups and ones that conflict with each other
Args that conflict *and* are in a group will now only display in the
group and not in the usage string itself.
Closes#616
* chore: updates dep graph
Closes#633
* chore: clippy run
* style: changes debug header to match other Rust projects
* chore: increase version
* test: `require_unless_one` with second argument
Add the `require_unless_one_2` test. This tests that when the second
argument in the array is used at the command line, that the required
argument is not present. This test was added because it appears the
`require_unless_one` function only works for the first argument in the
array.
* Fix: assertions for test
The assertions did not check for the `infile` to be present.
The strategy is to copy the template from the the reader to wrapped stream
until a tag is found. Depending on its value, the appropriate content is copied
to the wrapped stream.
The copy from template is then resumed, repeating this sequence until reading
the complete template.
Tags arg given inside curly brackets:
Valid tags are:
* `{bin}` - Binary name.
* `{version}` - Version number.
* `{author}` - Author information.
* `{usage}` - Automatically generated or given usage string.
* `{all-args}` - Help for all arguments (options, flags, positionals arguments,
and subcommands) including titles.
* `{unified}` - Unified help for options and flags.
* `{flags}` - Help for flags.
* `{options}` - Help for options.
* `{positionals}` - Help for positionals arguments.
* `{subcommands}` - Help for subcommands.
* `{after-help}` - Help for flags.
The largest organizational change is that methods used to generate the help are
implemented by the Help object and not the App, FlagBuilder, Parser, etc.
The new code is based heavily on the old one with a few minor modifications
aimed to reduce code duplication and coupling between the Help and the rest
of the code.
The new code turn things around: instead of having a HelpWriter that holds an
AnyArg object and a method that is called with a writer as argument,
there is a Help Object that holds a writer and a method that is called with a
writer as an argument.
There are still things to do such as moving `create_usage` outside the Parser.
The peformance has been affected, probably by the use of Trait Objects. This
was done as a way to reduce code duplication (i.e. in the unified help code).
This performance hit should not affect the usability as generating and printing
the help is dominated by user interaction and IO.
The old code to generate the help is still functional and is the active one.
The new code has been tested against the old one by generating help strings
for most of the examples in the repo.
The method `starts_with` as implemented for the `OsStrExt2` trait on
`OsStr` assumed that the needle given is shorter than the haystack. When
this is not the case, the method panics due to an attempted
out-of-bounds access on the byte representation of `self`. Problematic
if, say, an end-user gives us `"-"` and the library tries to see if that
starts with `"--"`.
Fortunately, slices already implement a `starts_with` method, and we can
delegate to it.
This *does* create a semantics change: if both `self` and the needle
have length 0, this implementation will return `true`, but the old
implementation would return `false`. Based on the test suite still
passing, acknowledging the vacuous truth doesn't seem to cause any
problems.
Fixes#410
Tons of code has been moved into functions, deduplicated, made much
easier to read, maintain, and understand. Comments still need to be
added, but that will happen shortly. Modules have also been moved around
to follow Rust conventions and best practices.
All functionality remains exactly the same