mirror of
https://github.com/clap-rs/clap
synced 2025-03-04 15:27:16 +00:00
feat(help): 'usage' feature flag for auto-genned usage
This commit is contained in:
parent
80f616a4b3
commit
bfa365a2cc
9 changed files with 42 additions and 11 deletions
|
@ -58,6 +58,7 @@ default = [
|
|||
"std",
|
||||
"color",
|
||||
"help",
|
||||
"usage",
|
||||
"error-context",
|
||||
"suggestions",
|
||||
]
|
||||
|
@ -68,6 +69,7 @@ unstable-doc = ["derive", "cargo", "wrap_help", "env", "unicode", "string", "uns
|
|||
std = [] # support for no_std in a backwards-compatible way
|
||||
color = ["dep:atty", "dep:termcolor"]
|
||||
help = []
|
||||
usage = []
|
||||
error-context = []
|
||||
suggestions = ["dep:strsim", "error-context"]
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
//! * **std**: _Not Currently Used._ Placeholder for supporting `no_std` environments in a backwards compatible manner.
|
||||
//! * **color**: Turns on colored error messages.
|
||||
//! * **help**: Auto-generate help output
|
||||
//! * **usage**: Auto-generate usage
|
||||
//! * **error-context**: Include contextual information for errors (which arg failed, etc)
|
||||
//! * **suggestions**: Turns on the `Did you mean '--myoption'?` feature for when users make typos.
|
||||
//!
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#![cfg_attr(not(feature = "usage"), allow(unused_mut))]
|
||||
|
||||
// Std
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
|
@ -3142,6 +3144,7 @@ impl Command {
|
|||
/// # Reflection
|
||||
impl Command {
|
||||
#[inline]
|
||||
#[cfg(feature = "usage")]
|
||||
pub(crate) fn get_usage_name(&self) -> Option<&str> {
|
||||
self.usage_name.as_deref()
|
||||
}
|
||||
|
@ -3851,6 +3854,7 @@ impl Command {
|
|||
use std::fmt::Write;
|
||||
|
||||
let mut mid_string = String::from(" ");
|
||||
#[cfg(feature = "usage")]
|
||||
if !self.is_subcommand_negates_reqs_set() && !self.is_args_conflicts_with_subcommands_set()
|
||||
{
|
||||
let reqs = Usage::new(self).get_required_usage_from(&[], None, true); // maybe Some(m)
|
||||
|
@ -3936,6 +3940,7 @@ impl Command {
|
|||
|
||||
if !self.is_set(AppSettings::BinNameBuilt) {
|
||||
let mut mid_string = String::from(" ");
|
||||
#[cfg(feature = "usage")]
|
||||
if !self.is_subcommand_negates_reqs_set()
|
||||
&& !self.is_args_conflicts_with_subcommands_set()
|
||||
{
|
||||
|
@ -4290,6 +4295,7 @@ impl<'a, T> Captures<'a> for T {}
|
|||
// Internal Query Methods
|
||||
impl Command {
|
||||
/// Iterate through the *flags* & *options* arguments.
|
||||
#[cfg(any(feature = "usage", feature = "help"))]
|
||||
pub(crate) fn get_non_positionals(&self) -> impl Iterator<Item = &Arg> {
|
||||
self.get_arguments().filter(|a| !a.is_positional())
|
||||
}
|
||||
|
@ -4318,6 +4324,7 @@ impl Command {
|
|||
self.get_positionals().next().is_some()
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "usage", feature = "help"))]
|
||||
pub(crate) fn has_visible_subcommands(&self) -> bool {
|
||||
self.subcommands
|
||||
.iter()
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
#![cfg_attr(not(feature = "usage"), allow(unused_imports))]
|
||||
#![cfg_attr(not(feature = "usage"), allow(unused_variables))]
|
||||
#![cfg_attr(not(feature = "usage"), allow(clippy::manual_map))]
|
||||
#![cfg_attr(not(feature = "usage"), allow(dead_code))]
|
||||
|
||||
// Internal
|
||||
use crate::builder::StyledStr;
|
||||
use crate::builder::{ArgPredicate, Command};
|
||||
|
@ -44,13 +49,26 @@ impl<'cmd> Usage<'cmd> {
|
|||
debug!("Usage::create_usage_no_title");
|
||||
if let Some(u) = self.cmd.get_override_usage() {
|
||||
Some(u.clone())
|
||||
} else if used.is_empty() {
|
||||
Some(self.create_help_usage(true))
|
||||
} else {
|
||||
Some(self.create_smart_usage(used))
|
||||
#[cfg(feature = "usage")]
|
||||
{
|
||||
if used.is_empty() {
|
||||
Some(self.create_help_usage(true))
|
||||
} else {
|
||||
Some(self.create_smart_usage(used))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "usage"))]
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "usage")]
|
||||
impl<'cmd> Usage<'cmd> {
|
||||
// Creates a usage string for display in help messages (i.e. not for errors)
|
||||
fn create_help_usage(&self, incl_reqs: bool) -> StyledStr {
|
||||
debug!("Usage::create_help_usage; incl_reqs={:?}", incl_reqs);
|
||||
|
@ -177,7 +195,7 @@ impl<'cmd> Usage<'cmd> {
|
|||
}
|
||||
|
||||
pub(crate) fn get_args(&self, incls: &[Id], force_optional: bool) -> Vec<StyledStr> {
|
||||
debug!("Usage::get_required_usage_from: incls={:?}", incls,);
|
||||
debug!("Usage::get_args: incls={:?}", incls,);
|
||||
|
||||
let required_owned;
|
||||
let required = if let Some(required) = self.required {
|
||||
|
@ -206,10 +224,7 @@ impl<'cmd> Usage<'cmd> {
|
|||
// by unroll_requirements_for_arg.
|
||||
unrolled_reqs.push(a.clone());
|
||||
}
|
||||
debug!(
|
||||
"Usage::get_required_usage_from: unrolled_reqs={:?}",
|
||||
unrolled_reqs
|
||||
);
|
||||
debug!("Usage::get_args: unrolled_reqs={:?}", unrolled_reqs);
|
||||
|
||||
let mut required_groups_members = FlatSet::new();
|
||||
let mut required_groups = FlatSet::new();
|
||||
|
@ -294,10 +309,12 @@ impl<'cmd> Usage<'cmd> {
|
|||
ret_val.push(pos);
|
||||
}
|
||||
|
||||
debug!("Usage::get_required_usage_from: ret_val={:?}", ret_val);
|
||||
debug!("Usage::get_args: ret_val={:?}", ret_val);
|
||||
ret_val
|
||||
}
|
||||
}
|
||||
|
||||
impl<'cmd> Usage<'cmd> {
|
||||
pub(crate) fn get_required_usage_from(
|
||||
&self,
|
||||
incls: &[Id],
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#![allow(clippy::bool_assert_comparison)]
|
||||
#![allow(clippy::redundant_clone)]
|
||||
#![cfg(feature = "help")]
|
||||
#![cfg(feature = "usage")]
|
||||
|
||||
mod action;
|
||||
mod app_settings;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#![cfg(feature = "help")]
|
||||
#![cfg(feature = "derive")]
|
||||
#![cfg(feature = "help")]
|
||||
#![cfg(feature = "usage")]
|
||||
|
||||
mod app_name;
|
||||
mod arguments;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#[test]
|
||||
#[cfg(feature = "help")]
|
||||
#[cfg(feature = "error-context")]
|
||||
#[cfg(feature = "usage")]
|
||||
fn example_tests() {
|
||||
let t = trycmd::TestCases::new();
|
||||
let features = [
|
||||
|
|
|
@ -277,7 +277,7 @@ mod arg {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "help")]
|
||||
#[cfg(all(feature = "help", featiure = "usage"))]
|
||||
fn optional_value() {
|
||||
let mut cmd = clap::Command::new("test").arg(clap::arg!(port: -p [NUM]));
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#[test]
|
||||
#[cfg(feature = "help")]
|
||||
#[cfg(feature = "error-context")]
|
||||
#[cfg(feature = "usage")]
|
||||
fn ui_tests() {
|
||||
let t = trycmd::TestCases::new();
|
||||
let features = [
|
||||
|
|
Loading…
Add table
Reference in a new issue