From 3618449d42f4cc5b667d8a9730b5e6fbe43d7dfb Mon Sep 17 00:00:00 2001 From: Clement Tsang <34804052+ClementTsang@users.noreply.github.com> Date: Fri, 21 Apr 2023 00:07:34 -0400 Subject: [PATCH] deps: update clap to 4.x (#1107) * deps: update clap to 4.x * changelog * fix test * add gpu feature/flag test --- CHANGELOG.md | 1 + Cargo.lock | 210 ++++++++++++++++++++++++++++++++------------- Cargo.toml | 8 +- build.rs | 2 +- src/clap.rs | 77 ++++++++++++----- src/options.rs | 28 +++--- tests/arg_tests.rs | 23 +++-- tests/util.rs | 4 +- 8 files changed, 245 insertions(+), 108 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d65c9eac..50992d57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Other - [#1100](https://github.com/ClementTsang/bottom/pull/1100): Speed up first draw and first data collection. +- [#1107](https://github.com/ClementTsang/bottom/pull/1107): Update to clap v4. ## [0.8.0] - 2023-01-22 diff --git a/Cargo.lock b/Cargo.lock index eab63a38..8ecc470f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -37,12 +37,61 @@ dependencies = [ "memchr", ] +[[package]] +name = "anstream" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e579a7752471abc2a8268df8b20005e3eadd975f585398f17efcfd8d4927371" +dependencies = [ + "anstyle 1.0.0", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is-terminal", + "utf8parse", +] + [[package]] name = "anstyle" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23ea9e81bd02e310c216d080f6223c179012256e5151c41db88d12c88a1684d2" +[[package]] +name = "anstyle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" + +[[package]] +name = "anstyle-parse" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "anstyle-wincon" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcd8291a340dd8ac70e18878bc4501dd7b4ff970cfa21c207d36ece51ea88fd" +dependencies = [ + "anstyle 1.0.0", + "windows-sys 0.48.0", +] + [[package]] name = "anyhow" version = "1.0.70" @@ -55,7 +104,7 @@ version = "2.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0b2340f55d9661d76793b2bfc2eb0e62689bd79d067a95707ea762afd5e9dd" dependencies = [ - "anstyle", + "anstyle 0.3.5", "bstr", "doc-comment", "predicates", @@ -64,17 +113,6 @@ dependencies = [ "wait-timeout", ] -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -195,49 +233,59 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "3.2.2" +version = "4.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e538f9ee5aa3b3963f09a997035f883677966ed50fce0292611927ce6f6d8c6" +checksum = "956ac1f6381d8d82ab4684768f89c0ea3afe66925ceadb4eeb3fc452ffc55d62" dependencies = [ - "atty", + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84080e799e54cff944f4b4a4b0e71630b0e0443b25b985175c7dddc1a859b749" +dependencies = [ + "anstream", + "anstyle 1.0.0", "bitflags", "clap_lex", - "indexmap", - "lazy_static", + "once_cell", "strsim 0.10.0", - "termcolor", "terminal_size", - "textwrap", ] [[package]] name = "clap_complete" -version = "3.2.5" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f7a2e0a962c45ce25afce14220bc24f9dade0a1787f185cecf96bfba7847cd8" +checksum = "01c22dcfb410883764b29953103d9ef7bb8fe21b3fa1158bc99986c2067294bd" dependencies = [ "clap", ] [[package]] name = "clap_lex" -version = "0.2.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", -] +checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" [[package]] name = "clap_mangen" -version = "0.1.11" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "105180c05a72388d5f5e4e4f6c79eecb92497bda749fa8f963a16647c5d5377f" +checksum = "4237e29de9c6949982ba87d51709204504fb8ed2fd38232fcb1e5bf7d4ba48c8" dependencies = [ "clap", "roff", ] +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + [[package]] name = "concat-string" version = "1.0.1" @@ -456,6 +504,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "errno-dragonfly" version = "0.1.2" @@ -548,6 +607,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + [[package]] name = "hex" version = "0.4.3" @@ -596,6 +661,18 @@ dependencies = [ "windows-sys 0.42.0", ] +[[package]] +name = "is-terminal" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" +dependencies = [ + "hermit-abi 0.3.1", + "io-lifetimes", + "rustix 0.37.7", + "windows-sys 0.48.0", +] + [[package]] name = "itertools" version = "0.10.5" @@ -654,6 +731,12 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" +[[package]] +name = "linux-raw-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b085a4f2cde5781fc4b1717f2e86c62f5cda49de7ba99a7c2eae02b61c9064c" + [[package]] name = "lock_api" version = "0.4.7" @@ -760,7 +843,7 @@ version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", ] @@ -802,12 +885,6 @@ version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" -[[package]] -name = "os_str_bytes" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" - [[package]] name = "parking_lot" version = "0.12.1" @@ -837,7 +914,7 @@ version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c575290b64d24745b6c57a12a31465f0a66f3a4799686a6921526a33b0797965" dependencies = [ - "anstyle", + "anstyle 0.3.5", "difflib", "float-cmp", "itertools", @@ -881,7 +958,7 @@ dependencies = [ "byteorder", "hex", "lazy_static", - "rustix", + "rustix 0.36.6", ] [[package]] @@ -992,13 +1069,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4feacf7db682c6c329c4ede12649cd36ecab0f3be5b7d74e6a20304725db4549" dependencies = [ "bitflags", - "errno", + "errno 0.2.8", "io-lifetimes", "libc", - "linux-raw-sys", + "linux-raw-sys 0.1.4", "windows-sys 0.42.0", ] +[[package]] +name = "rustix" +version = "0.37.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2aae838e49b3d63e9274e1c01833cc8139d3fec468c3b84688c628f44b1ae11d" +dependencies = [ + "bitflags", + "errno 0.3.1", + "io-lifetimes", + "libc", + "linux-raw-sys 0.3.3", + "windows-sys 0.45.0", +] + [[package]] name = "ryu" version = "1.0.10" @@ -1182,23 +1273,14 @@ dependencies = [ "winapi", ] -[[package]] -name = "termcolor" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" -dependencies = [ - "winapi-util", -] - [[package]] name = "terminal_size" -version = "0.1.17" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" +checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237" dependencies = [ - "libc", - "winapi", + "rustix 0.37.7", + "windows-sys 0.48.0", ] [[package]] @@ -1207,15 +1289,6 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "507e9898683b6c43a9aa55b64259b721b52ba226e0f3779137e50ad114a4c90b" -[[package]] -name = "textwrap" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" -dependencies = [ - "terminal_size", -] - [[package]] name = "thiserror" version = "1.0.40" @@ -1336,6 +1409,12 @@ dependencies = [ "typenum", ] +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + [[package]] name = "version_check" version = "0.9.4" @@ -1438,6 +1517,15 @@ dependencies = [ "windows-targets 0.42.2", ] +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", +] + [[package]] name = "windows-targets" version = "0.42.2" diff --git a/Cargo.toml b/Cargo.toml index 314f0fca..a391945f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,7 +75,7 @@ deploy = ["battery", "gpu", "zfs"] anyhow = "1.0.70" backtrace = "0.3.67" cfg-if = "1.0.0" -clap = { version = "3.2.2", features = ["default", "cargo", "wrap_help"] } +clap = { version = "4.2.4", features = ["default", "cargo", "wrap_help"] } concat-string = "1.0.1" const_format = "0.2.30" crossterm = "0.26.1" @@ -140,9 +140,9 @@ default-features = false features = ["user-hooks"] [build-dependencies] -clap = { version = "3.2.2", features = ["default", "cargo", "wrap_help"] } -clap_complete = "3.2.4" -clap_mangen = "0.1.11" +clap = { version = "4.2.4", features = ["default", "cargo", "wrap_help"] } +clap_complete = "4.2.0" +clap_mangen = "0.2.10" [package.metadata.deb] section = "utility" diff --git a/build.rs b/build.rs index 7b5c0161..f704ab38 100644 --- a/build.rs +++ b/build.rs @@ -88,7 +88,7 @@ fn nightly_version() { println!("cargo:rerun-if-env-changed=CIRRUS_CHANGE_IN_REPO"); } -fn main() -> Result<()> { +fn main() -> io::Result<()> { btm_generate()?; nightly_version(); diff --git a/src/clap.rs b/src/clap.rs index 82e94716..1b57a7ba 100644 --- a/src/clap.rs +++ b/src/clap.rs @@ -2,18 +2,16 @@ use clap::builder::PossibleValuesParser; use clap::*; const TEMPLATE: &str = "\ -{bin} {version} +{name} {version} {author} {about} -USAGE:{usage} +{usage-heading} {usage} -FLAGS: -{options}"; +{all-args}"; -const USAGE: &str = " - btm [FLAG]"; +const USAGE: &str = "btm [OPTIONS]"; const DEFAULT_WIDGET_TYPE_STR: &str = if cfg!(feature = "battery") { "\ @@ -87,29 +85,33 @@ pub fn get_matches() -> clap::ArgMatches { // TODO: Refactor this a bit, it's quite messy atm // TODO: [DEBUG] Add a proper debugging solution. -pub fn build_app() -> Command<'static> { +pub fn build_app() -> Command { // Temps let kelvin = Arg::new("kelvin") .short('k') .long("kelvin") + .action(ArgAction::SetTrue) .help("Sets the temperature type to Kelvin.") .long_help("Sets the temperature type to Kelvin."); let fahrenheit = Arg::new("fahrenheit") .short('f') .long("fahrenheit") + .action(ArgAction::SetTrue) .help("Sets the temperature type to Fahrenheit.") .long_help("Sets the temperature type to Fahrenheit."); let celsius = Arg::new("celsius") .short('c') .long("celsius") + .action(ArgAction::SetTrue) .help("Sets the temperature type to Celsius.") .long_help("Sets the temperature type to Celsius. This is the default option."); // All flags. These are in alphabetical order let autohide_time = Arg::new("autohide_time") .long("autohide_time") + .action(ArgAction::SetTrue) .help("Temporarily shows the time scale in graphs.") .long_help( "Automatically hides the time scale in graphs after being shown for \ @@ -120,6 +122,7 @@ pub fn build_app() -> Command<'static> { let basic = Arg::new("basic") .short('b') .long("basic") + .action(ArgAction::SetTrue) .help("Hides graphs and uses a more basic look.") .long_help( "Hides graphs and uses a more basic look. Design is largely inspired by htop's.", @@ -128,18 +131,21 @@ pub fn build_app() -> Command<'static> { let case_sensitive = Arg::new("case_sensitive") .short('S') .long("case_sensitive") + .action(ArgAction::SetTrue) .help("Enables case sensitivity by default.") .long_help("When searching for a process, enables case sensitivity by default."); let current_usage = Arg::new("current_usage") .short('u') .long("current_usage") + .action(ArgAction::SetTrue) .help("Sets process CPU% to be based on current CPU%.") .long_help("Sets process CPU% usage to be based on the current system CPU% usage rather than total CPU usage."); let unnormalized_cpu = Arg::new("unnormalized_cpu") .short('n') .long("unnormalized_cpu") + .action(ArgAction::SetTrue) .help("Show process CPU% without normalizing over the number of cores.") .long_help( "Shows process CPU usage without averaging over the number of CPU cores in the system.", @@ -147,66 +153,78 @@ pub fn build_app() -> Command<'static> { let disable_click = Arg::new("disable_click") .long("disable_click") + .action(ArgAction::SetTrue) .help("Disables mouse clicks.") .long_help("Disables mouse clicks from interacting with the program."); let dot_marker = Arg::new("dot_marker") .short('m') .long("dot_marker") + .action(ArgAction::SetTrue) .help("Uses a dot marker for graphs.") .long_help("Uses a dot marker for graphs as opposed to the default braille marker."); let group = Arg::new("group") // TODO: Rename this to something like "group_process", would be "breaking" though. .short('g') .long("group") + .action(ArgAction::SetTrue) .help("Groups processes with the same name by default.") .long_help("Groups processes with the same name by default."); let hide_avg_cpu = Arg::new("hide_avg_cpu") .short('a') .long("hide_avg_cpu") + .action(ArgAction::SetTrue) .help("Hides the average CPU usage.") .long_help("Hides the average CPU usage from being shown."); let hide_table_gap = Arg::new("hide_table_gap") .long("hide_table_gap") + .action(ArgAction::SetTrue) .help("Hides spacing between table headers and entries.") .long_help("Hides the spacing between table headers and entries."); let hide_time = Arg::new("hide_time") .long("hide_time") + .action(ArgAction::SetTrue) .help("Hides the time scale.") .long_help("Completely hides the time scale from being shown."); let process_command = Arg::new("process_command") .long("process_command") + .action(ArgAction::SetTrue) .help("Show processes as their commands by default.") .long_help("Show processes as their commands by default in the process widget."); let left_legend = Arg::new("left_legend") .short('l') .long("left_legend") + .action(ArgAction::SetTrue) .help("Puts the CPU chart legend to the left side.") .long_help("Puts the CPU chart legend to the left side rather than the right side."); let regex = Arg::new("regex") .short('R') .long("regex") + .action(ArgAction::SetTrue) .help("Enables regex by default.") .long_help("When searching for a process, enables regex by default."); let disable_advanced_kill = Arg::new("disable_advanced_kill") .long("disable_advanced_kill") + .action(ArgAction::SetTrue) .help("Hides advanced process killing.") .long_help("Hides advanced options to stop a process on Unix-like systems. The only option shown is 15 (TERM)."); let show_table_scroll_position = Arg::new("show_table_scroll_position") .long("show_table_scroll_position") + .action(ArgAction::SetTrue) .help("Shows the scroll position tracker in table widgets.") .long_help("Shows the list scroll position tracker in the widget title for table widgets."); let use_old_network_legend = Arg::new("use_old_network_legend") .long("use_old_network_legend") + .action(ArgAction::SetTrue) .help("DEPRECATED - uses a separate network legend.") .long_help( "DEPRECATED - uses an older (pre-0.4), separate network widget legend. This display is not \ @@ -216,6 +234,7 @@ pub fn build_app() -> Command<'static> { let whole_word = Arg::new("whole_word") .short('W') .long("whole_word") + .action(ArgAction::SetTrue) .help("Enables whole-word matching by default.") .long_help( "When searching for a process, return results that match the entire query by default.", @@ -225,7 +244,7 @@ pub fn build_app() -> Command<'static> { let config_location = Arg::new("config_location") .short('C') .long("config") - .takes_value(true) + .action(ArgAction::Set) .value_name("CONFIG PATH") .help("Sets the location of the config file.") .long_help( @@ -236,7 +255,7 @@ pub fn build_app() -> Command<'static> { // TODO: Fix this, its broken in the manpage let color = Arg::new("color") .long("color") - .takes_value(true) + .action(ArgAction::Set) .value_name("COLOR SCHEME") .value_parser(PossibleValuesParser::new([ "default", @@ -272,13 +291,14 @@ Defaults to \"default\". let mem_as_value = Arg::new("mem_as_value") .long("mem_as_value") + .action(ArgAction::SetTrue) .help("Defaults to showing process memory usage by value.") .long_help("Defaults to showing process memory usage by value. Otherwise, it defaults to showing it by percentage."); let default_time_value = Arg::new("default_time_value") .short('t') .long("default_time_value") - .takes_value(true) + .action(ArgAction::Set) .value_name("MS") .help("Default time value for graphs in ms.") .long_help("Default time value for graphs in milliseconds. The minimum time is 30s (30000), and the default is 60s (60000)."); @@ -286,8 +306,8 @@ Defaults to \"default\". // TODO: Fix this, its broken in the manpage let default_widget_count = Arg::new("default_widget_count") .long("default_widget_count") - .takes_value(true) - .requires_all(&["default_widget_type"]) + .action(ArgAction::Set) + .requires_all(["default_widget_type"]) .value_name("INT") .help("Sets the n'th selected widget type as the default.") .long_help( @@ -312,21 +332,22 @@ use CPU (3) as the default instead. let default_widget_type = Arg::new("default_widget_type") .long("default_widget_type") - .takes_value(true) + .action(ArgAction::Set) .value_name("WIDGET TYPE") .help("Sets the default widget type, use --help for info.") .long_help(DEFAULT_WIDGET_TYPE_STR); let expanded_on_startup = Arg::new("expanded_on_startup") - .long("expanded") .short('e') + .long("expanded") + .action(ArgAction::SetTrue) .help("Expand the default widget upon starting the app.") .long_help("Expand the default widget upon starting the app. Same as pressing \"e\" inside the app. Use with \"default_widget_type\" and \"default_widget_count\" to select desired expanded widget. This flag has no effect in basic mode (--basic)"); let rate = Arg::new("rate") .short('r') .long("rate") - .takes_value(true) + .action(ArgAction::Set) .value_name("MS") .help("Sets a refresh rate in ms.") .long_help("Sets a refresh rate in milliseconds. The minimum is 250ms, and defaults to 1000ms. Smaller values may take more computer resources."); @@ -334,7 +355,7 @@ use CPU (3) as the default instead. let time_delta = Arg::new("time_delta") .short('d') .long("time_delta") - .takes_value(true) + .action(ArgAction::Set) .value_name("MS") .help("The amount in ms changed upon zooming.") .long_help("The amount of time in milliseconds changed when zooming in/out. The minimum is 1s (1000), and defaults to 15s (15000)."); @@ -342,21 +363,25 @@ use CPU (3) as the default instead. let tree = Arg::new("tree") .short('T') .long("tree") + .action(ArgAction::SetTrue) .help("Defaults the process widget be in tree mode.") .long_help("Defaults to showing the process widget in tree mode."); let network_use_bytes = Arg::new("network_use_bytes") .long("network_use_bytes") + .action(ArgAction::SetTrue) .help("Displays the network widget using bytes.") .long_help("Displays the network widget using bytes. Defaults to bits."); let network_use_log = Arg::new("network_use_log") .long("network_use_log") + .action(ArgAction::SetTrue) .help("Displays the network widget with a log scale.") .long_help("Displays the network widget with a log scale. Defaults to a non-log scale."); let network_use_binary_prefix = Arg::new("network_use_binary_prefix") .long("network_use_binary_prefix") + .action(ArgAction::SetTrue) .help("Displays the network widget with binary prefixes.") .long_help( "Displays the network widget with binary prefixes (i.e. kibibits, mebibits) rather than a decimal prefix (i.e. kilobits, megabits). Defaults to decimal prefixes.", @@ -364,11 +389,17 @@ use CPU (3) as the default instead. let retention = Arg::new("retention") .long("retention") - .takes_value(true) + .action(ArgAction::Set) .value_name("time") .help("The timespan of data kept.") .long_help("How much data is stored at once in terms of time. Takes in human-readable time spans (e.g. 10m, 1h), with a minimum of 1 minute. Note higher values will take up more memory. Defaults to 10 minutes."); + let version = Arg::new("version") + .short('V') + .long("version") + .action(ArgAction::Version) + .help("Prints version information."); + const VERSION: &str = match option_env!("NIGHTLY_VERSION") { Some(nightly_version) => nightly_version, None => crate_version!(), @@ -379,16 +410,15 @@ use CPU (3) as the default instead. .version(VERSION) .author(crate_authors!()) .about(crate_description!()) + .color(ColorChoice::Auto) .override_usage(USAGE) .help_template(TEMPLATE) - .mut_arg("help", |a| { - a.help("Prints help information. Use --help for info.") - }) - .mut_arg("version", |a| a.help("Prints version information.")) + .disable_version_flag(true) + .arg(version) .arg(kelvin) .arg(fahrenheit) .arg(celsius) - .group(ArgGroup::new("TEMPERATURE_TYPE").args(&["kelvin", "fahrenheit", "celsius"])) + .group(ArgGroup::new("TEMPERATURE_TYPE").args(["kelvin", "fahrenheit", "celsius"])) .arg(autohide_time) .arg(basic) .arg(case_sensitive) @@ -426,6 +456,7 @@ use CPU (3) as the default instead. { let battery = Arg::new("battery") .long("battery") + .action(ArgAction::SetTrue) .help("Shows the battery widget.") .long_help( "Shows the battery widget in default or basic mode. No effect on custom layouts.", @@ -437,6 +468,7 @@ use CPU (3) as the default instead. { let enable_gpu_memory = Arg::new("enable_gpu_memory") .long("enable_gpu_memory") + .action(ArgAction::SetTrue) .help("Enable collecting and displaying GPU memory usage."); app = app.arg(enable_gpu_memory); } @@ -445,6 +477,7 @@ use CPU (3) as the default instead. { let cache = Arg::new("enable_cache_memory") .long("enable_cache_memory") + .action(ArgAction::SetTrue) .help("Enable collecting and displaying cache and buffer memory."); app = app.arg(cache); } diff --git a/src/options.rs b/src/options.rs index 37028be3..4de8f60c 100644 --- a/src/options.rs +++ b/src/options.rs @@ -147,7 +147,7 @@ pub struct IgnoreList { macro_rules! is_flag_enabled { ($flag_name:ident, $matches:expr, $config:expr) => { - if $matches.contains_id(stringify!($flag_name)) { + if $matches.get_flag(stringify!($flag_name)) { true } else if let Some(flags) = &$config.flags { flags.$flag_name.unwrap_or(false) @@ -157,7 +157,7 @@ macro_rules! is_flag_enabled { }; ($cmd_flag:literal, $cfg_flag:ident, $matches:expr, $config:expr) => { - if $matches.contains_id($cmd_flag) { + if $matches.get_flag($cmd_flag) { true } else if let Some(flags) = &$config.flags { flags.$cfg_flag.unwrap_or(false) @@ -522,11 +522,11 @@ fn get_update_rate_in_milliseconds(matches: &ArgMatches, config: &Config) -> err fn get_temperature( matches: &ArgMatches, config: &Config, ) -> error::Result { - if matches.contains_id("fahrenheit") { + if matches.get_flag("fahrenheit") { return Ok(data_harvester::temperature::TemperatureType::Fahrenheit); - } else if matches.contains_id("kelvin") { + } else if matches.get_flag("kelvin") { return Ok(data_harvester::temperature::TemperatureType::Kelvin); - } else if matches.contains_id("celsius") { + } else if matches.get_flag("celsius") { return Ok(data_harvester::temperature::TemperatureType::Celsius); } else if let Some(flags) = &config.flags { if let Some(temp_type) = &flags.temperature_type { @@ -547,7 +547,7 @@ fn get_temperature( /// Yes, this function gets whether to show average CPU (true) or not (false) fn get_show_average_cpu(matches: &ArgMatches, config: &Config) -> bool { - if matches.contains_id("hide_avg_cpu") { + if matches.get_flag("hide_avg_cpu") { return false; } else if let Some(flags) = &config.flags { if let Some(avg_cpu) = flags.hide_avg_cpu { @@ -689,7 +689,7 @@ fn get_use_battery(matches: &ArgMatches, config: &Config) -> bool { } } - if matches.contains_id("battery") { + if matches.get_flag("battery") { return true; } else if let Some(flags) = &config.flags { if let Some(battery) = flags.battery { @@ -705,7 +705,7 @@ fn get_use_battery(matches: &ArgMatches, config: &Config) -> bool { fn get_enable_gpu_memory(matches: &ArgMatches, config: &Config) -> bool { #[cfg(feature = "gpu")] { - if matches.contains_id("enable_gpu_memory") { + if matches.get_flag("enable_gpu_memory") { return true; } else if let Some(flags) = &config.flags { if let Some(enable_gpu_memory) = flags.enable_gpu_memory { @@ -721,7 +721,7 @@ fn get_enable_gpu_memory(matches: &ArgMatches, config: &Config) -> bool { fn get_enable_cache_memory(matches: &ArgMatches, config: &Config) -> bool { #[cfg(not(target_os = "windows"))] { - if matches.contains_id("enable_cache_memory") { + if matches.get_flag("enable_cache_memory") { return true; } else if let Some(flags) = &config.flags { if let Some(enable_cache_memory) = flags.enable_cache_memory { @@ -796,7 +796,7 @@ pub fn get_color_scheme(matches: &ArgMatches, config: &Config) -> error::Result< } fn get_network_unit_type(matches: &ArgMatches, config: &Config) -> DataUnit { - if matches.contains_id("network_use_bytes") { + if matches.get_flag("network_use_bytes") { return DataUnit::Byte; } else if let Some(flags) = &config.flags { if let Some(network_use_bytes) = flags.network_use_bytes { @@ -810,7 +810,7 @@ fn get_network_unit_type(matches: &ArgMatches, config: &Config) -> DataUnit { } fn get_network_scale_type(matches: &ArgMatches, config: &Config) -> AxisScaling { - if matches.contains_id("network_use_log") { + if matches.get_flag("network_use_log") { return AxisScaling::Log; } else if let Some(flags) = &config.flags { if let Some(network_use_log) = flags.network_use_log { @@ -858,7 +858,7 @@ mod test { } // TODO: There's probably a better way to create clap options AND unify together to avoid the possibility of - // typos/mixing up. Use macros! + // typos/mixing up. Use proc macros to unify on one struct? #[test] fn verify_cli_options_build() { let app = crate::clap::build_app(); @@ -871,7 +871,7 @@ mod test { create_app(config, matches) }; - // Skip battery since it's tricky to test depending on the platform testing. + // Skip battery since it's tricky to test depending on the platform/features we're testing with. let skip = ["help", "version", "celsius", "battery"]; for arg in app.get_arguments().collect::>() { @@ -882,7 +882,7 @@ mod test { .unwrap() .to_owned(); - if !arg.is_takes_value_set() && !skip.contains(&arg_name) { + if !arg.get_action().takes_values() && !skip.contains(&arg_name) { let arg = format!("--{arg_name}"); let arguments = vec!["btm", &arg]; diff --git a/tests/arg_tests.rs b/tests/arg_tests.rs index 372955da..95e79994 100644 --- a/tests/arg_tests.rs +++ b/tests/arg_tests.rs @@ -93,9 +93,7 @@ fn test_negative_rate() { .arg("-1000") .assert() .failure() - .stderr(predicate::str::contains( - "wasn't expected, or isn't valid in this context", - )); + .stderr(predicate::str::contains("unexpected argument")); } #[test] @@ -160,11 +158,12 @@ fn test_missing_default_widget_type() { .assert() .failure() .stderr(predicate::str::contains( - "The following required arguments were not provided", + "the following required arguments were not provided", )); } #[test] +#[cfg_attr(feature = "battery", ignore)] fn test_battery_flag() { if !cfg!(feature = "battery") { btm_command() @@ -172,7 +171,21 @@ fn test_battery_flag() { .assert() .failure() .stderr(predicate::str::contains( - "'--battery' which wasn't expected", + "unexpected argument '--battery' found", + )); + } +} + +#[test] +#[cfg_attr(feature = "gpu", ignore)] +fn test_gpu_flag() { + if !cfg!(feature = "gpu") { + btm_command() + .arg("--enable_gpu_memory") + .assert() + .failure() + .stderr(predicate::str::contains( + "unexpected argument '--enable_gpu_memory' found", )); } } diff --git a/tests/util.rs b/tests/util.rs index 40e50305..5a9dbc1a 100644 --- a/tests/util.rs +++ b/tests/util.rs @@ -60,13 +60,15 @@ fn cross_runner() -> Option { } } -/// Returns the [`Command`] of a binary invocation of bottom. +/// Returns the [`Command`] of a binary invocation of bottom, alongside +/// any required env variables. pub fn btm_command() -> Command { let btm_exe = env!("CARGO_BIN_EXE_btm"); match cross_runner() { None => Command::new(btm_exe), Some(runner) => { let mut cmd = Command::new(runner); + cmd.env("NO_COLOR", "1"); cmd.arg(btm_exe); cmd }