Merge pull request #4258 from epage/features

fix(help)!: Wrapping is behind wrap_help
This commit is contained in:
Ed Page 2022-09-26 12:01:24 -05:00 committed by GitHub
commit 18ed37ee67
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 65 additions and 13 deletions

View file

@ -125,9 +125,12 @@ Steps:
2. *If using Builder API*: Explicitly set the `arg.action(ArgAction::...)` on each argument (`StoreValue` for options and `IncOccurrences` for flags)
3. Run `cargo check --features clap/deprecated` and resolve all deprecation warnings
4. Upgrade to v4
5. Resolve compiler errors
6. Resolve behavior changes (see "subtle changes" under BREAKING CHANGES)
7. *At your leisure:* resolve new deprecation notices
5. Update feature flags
- *If `default-features = false`*, run `cargo add clap -F help,usage,error-context`
- Run `cargo add clap -F wrap_help` unless you want to hard code line wraps
6. Resolve compiler errors
7. Resolve behavior changes (see "subtle changes" under BREAKING CHANGES)
8. *At your leisure:* resolve new deprecation notices
Example test (derive):
```rust
@ -155,7 +158,7 @@ fn verify_cli() {
}
```
Note: the idomatic / recommended way of specifying different types of args in the Builder API has changed:
Note: the idiomatic / recommended way of specifying different types of args in the Builder API has changed:
Before
```rust
@ -184,10 +187,11 @@ Subtle changes (i.e. compiler won't catch):
- `mut_arg` can no longer be used to customize help and version arguments, instead disable them (`Command::disable_help_flag`, `Command::disable_version_flag`) and provide your own (#4056)
- Removed lifetimes from `Command`, `Arg`, `ArgGroup`, and `PossibleValue`, assuming `'static`. `string` feature flag will enable support for `String`s (#1041, #2150, #4223)
- `arg!(--flag <value>)` is now optional, instead of required. Add `.required(true)` at the end to restore the original behavior (#4206)
- Added default feature flags, `help`, `usage` and `error-context` (#4236)
- Added default feature flags, `help`, `usage` and `error-context`, requiring adding them back in if `default-features = false` (#4236)
- *(parser)* Always fill in `""` argument for external subcommands to make it easier to distinguish them from built-in commands (#3263)
- *(parser)* Short flags now have higher precedence than hyphen values with `Arg::allow_hyphen_values`, to be consistent with `Command::allow_hyphen_values` (#4187)
- *(parser)* `Arg::value_terminator` must be its own argument on the CLI rather than being in a delimited list (#4025)
- *(help)* Line wrapping of help is now behind the existing `wrap_help` feature flag, either enable it or hard code your wraps (#4258)
- *(help)* Make `DeriveDisplayOrder` the default and removed the setting. To sort help, set `next_display_order(None)` (#2808)
- *(help)* Subcommand display order respects `Command::next_display_order` instead of `DeriveDisplayOrder` and using its own initial display order value (#2808)
- *(help)* Subcommands are now listed before arguments. To get the old behavior, see `Command::help_template` (#4132)

View file

@ -77,7 +77,7 @@ suggestions = ["dep:strsim", "error-context"]
deprecated = ["clap_derive?/deprecated"] # Guided experience to prepare for next breaking release (at different stages of development, this may become default)
derive = ["clap_derive", "dep:once_cell"]
cargo = ["dep:once_cell"] # Disable if you're not using Cargo, enables Cargo-env-var-dependent macros
wrap_help = ["dep:terminal_size"]
wrap_help = ["help", "dep:terminal_size"]
env = [] # Use environment variables during arg parsing
unicode = ["dep:unicode-width", "dep:unicase"] # Support for unicode characters in arguments and help messages
string = [] # Allow runtime generated strings

View file

@ -19,7 +19,7 @@
//! * **env**: Turns on the usage of environment variables during parsing.
//! * **unicode**: Turns on support for unicode characters (including emoji) in arguments and help messages.
//! * **wrap_help**: Turns on the help text wrapping feature, based on the terminal size.
//! * **string**: Allow runtime generated strings
//! * **string**: Allow runtime generated strings (e.g. with [`Str`][crate::builder::Str]).
//!
//! #### Experimental features
//!

View file

@ -1,6 +1,9 @@
use crate::builder::Str;
/// A UTF-8-encoded fixed string
///
/// **NOTE:** To support dynamic values (i.e. `OsString`), enable the [`string`
/// feature][crate::_features]
#[derive(Default, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
pub struct OsStr {
name: Inner,

View file

@ -1,4 +1,7 @@
/// A UTF-8-encoded fixed string
///
/// **NOTE:** To support dynamic values (i.e. `String`), enable the [`string`
/// feature][crate::_features]
#[derive(Default, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
pub struct Str {
name: Inner,

View file

@ -101,7 +101,10 @@ impl StyledStr {
}
}
#[cfg(feature = "help")]
#[cfg(all(not(feature = "wrap_help"), feature = "help"))]
pub(crate) fn wrap(&mut self, _hard_width: usize) {}
#[cfg(feature = "wrap_help")]
pub(crate) fn wrap(&mut self, hard_width: usize) {
let mut wrapper = crate::output::textwrap::wrap_algorithms::LineWrapper::new(hard_width);
for (_, content) in self.iter_mut() {

View file

@ -1020,10 +1020,11 @@ fn longest_filter(arg: &Arg) -> bool {
#[cfg(test)]
mod test {
use super::*;
#[test]
#[cfg(feature = "wrap_help")]
fn wrap_help_last_word() {
use super::*;
let help = String::from("foo bar baz");
assert_eq!(wrap(&help, 5), "foo\nbar\nbaz");
}
@ -1031,6 +1032,8 @@ mod test {
#[test]
#[cfg(feature = "unicode")]
fn display_width_handles_non_ascii() {
use super::*;
// Popular Danish tongue-twister, the name of a fruit dessert.
let text = "rødgrød med fløde";
assert_eq!(display_width(text), 17);
@ -1042,6 +1045,8 @@ mod test {
#[test]
#[cfg(feature = "unicode")]
fn display_width_handles_emojis() {
use super::*;
let text = "😂";
// There is a single `char`...
assert_eq!(text.chars().count(), 1);

View file

@ -5,9 +5,12 @@
//! - `LineWrapper` is able to incrementally wrap which will help with `StyledStr
pub(crate) mod core;
#[cfg(feature = "wrap_help")]
pub(crate) mod word_separators;
#[cfg(feature = "wrap_help")]
pub(crate) mod wrap_algorithms;
#[cfg(feature = "wrap_help")]
pub(crate) fn wrap(content: &str, hard_width: usize) -> String {
let mut wrapper = wrap_algorithms::LineWrapper::new(hard_width);
let mut total = Vec::new();
@ -19,7 +22,13 @@ pub(crate) fn wrap(content: &str, hard_width: usize) -> String {
total.join("")
}
#[cfg(not(feature = "wrap_help"))]
pub(crate) fn wrap(content: &str, _hard_width: usize) -> String {
content.to_owned()
}
#[cfg(test)]
#[cfg(feature = "wrap_help")]
mod test {
/// Compatibility shim to keep textwrap's tests
fn wrap(content: &str, hard_width: usize) -> Vec<String> {

View file

@ -531,6 +531,7 @@ Options:
}
#[test]
#[cfg(feature = "wrap_help")]
fn issue_626_unicode_cutoff() {
static ISSUE_626_CUTOFF: &str = "\
Usage: ctest [OPTIONS]
@ -679,6 +680,7 @@ Options:
}
#[test]
#[cfg(feature = "wrap_help")]
fn issue_626_panic() {
static ISSUE_626_PANIC: &str = "\
Usage: ctest [OPTIONS]
@ -713,6 +715,7 @@ Options:
}
#[test]
#[cfg(feature = "wrap_help")]
fn issue_626_variable_panic() {
for i in 10..320 {
let _ = Command::new("ctest")
@ -731,6 +734,7 @@ fn issue_626_variable_panic() {
}
#[test]
#[cfg(feature = "wrap_help")]
fn final_word_wrapping() {
static FINAL_WORD_WRAPPING: &str = "\
Usage: ctest
@ -748,7 +752,10 @@ Options:
utils::assert_output(cmd, "ctest --help", FINAL_WORD_WRAPPING, false);
}
static WRAPPING_NEWLINE_CHARS: &str = "\
#[test]
#[cfg(feature = "wrap_help")]
fn wrapping_newline_chars() {
static WRAPPING_NEWLINE_CHARS: &str = "\
Usage: ctest [mode]
Arguments:
@ -763,8 +770,6 @@ Options:
-V, --version Print version information
";
#[test]
fn wrapping_newline_chars() {
let cmd = Command::new("ctest")
.version("0.1")
.term_width(60)
@ -777,7 +782,23 @@ fn wrapping_newline_chars() {
}
#[test]
#[cfg(feature = "wrap_help")]
fn wrapping_newline_variables() {
static WRAPPING_NEWLINE_CHARS: &str = "\
Usage: ctest [mode]
Arguments:
[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.
Options:
-h, --help Print help information
-V, --version Print version information
";
let cmd = Command::new("ctest")
.version("0.1")
.term_width(60)
@ -790,6 +811,7 @@ fn wrapping_newline_variables() {
}
#[test]
#[cfg(feature = "wrap_help")]
fn dont_wrap_urls() {
let cmd = Command::new("Example")
.term_width(30)
@ -849,6 +871,7 @@ fn old_newline_variables() {
}
#[test]
#[cfg(feature = "wrap_help")]
fn issue_688_hide_pos_vals() {
static ISSUE_688: &str = "\
Usage: ctest [OPTIONS]
@ -1147,6 +1170,7 @@ Options:
}
#[test]
#[cfg(feature = "wrap_help")]
fn issue_777_wrap_all_things() {
static ISSUE_777: &str = "A cmd with a crazy very long long
long name hahaha 1.0
@ -1423,6 +1447,7 @@ fn hide_default_val() {
}
#[test]
#[cfg(feature = "wrap_help")]
fn escaped_whitespace_values() {
static ESCAPED_DEFAULT_VAL: &str = "\
Usage: default [OPTIONS]