From 899914591eb382de69b0a40ab569fa8a90993dcf Mon Sep 17 00:00:00 2001 From: Clement Tsang <34804052+ClementTsang@users.noreply.github.com> Date: Wed, 13 May 2026 03:14:19 -0400 Subject: [PATCH] other: migrate over process config fields to `[processes]` (#2063) Migrate over process config fields from the general `[flags]` to `[processes]`. Similar to #2062, this only deprecates them at the moment. --- CHANGELOG.md | 3 +- .../configuration/command-line-options.md | 4 +- .../configuration/config-file/flags.md | 2 +- .../configuration/config-file/processes.md | 18 ++- schema/nightly/bottom.json | 84 ++++++++++++ src/constants.rs | 38 +++++- src/options.rs | 129 +++++++++++++----- src/options/args.rs | 2 +- src/options/config/flags.rs | 57 ++++---- src/options/config/process.rs | 45 ++++++ tests/integration/valid_config_tests.rs | 13 +- .../mem_network.toml} | 0 tests/valid_configs/deprecated/processes.toml | 15 ++ tests/valid_configs/newer_processes.toml | 15 ++ 14 files changed, 348 insertions(+), 77 deletions(-) rename tests/valid_configs/{deprecated_mem_network.toml => deprecated/mem_network.toml} (100%) create mode 100644 tests/valid_configs/deprecated/processes.toml create mode 100644 tests/valid_configs/newer_processes.toml diff --git a/CHANGELOG.md b/CHANGELOG.md index 76a247ba..bcbd916d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,7 +46,8 @@ That said, these are more guidelines rather than hard rules, though the project - [#2039](https://github.com/ClementTsang/bottom/pull/2039): Replace `hide_table_gap` with `table_gap`. - [#2061](https://github.com/ClementTsang/bottom/pull/2061): Take cgroup into account for RAM/swap usage. - [#2062](https://github.com/ClementTsang/bottom/pull/2062): Rename `[network]` to `[network_graph]` in the config file; `[network]` remains valid as an alias. -- [#2062](https://github.com/ClementTsang/bottom/pull/2062): Move network and memory graph config file options from flags to be under `[network_graph]` and `[memory_graph]`. +- [#2062](https://github.com/ClementTsang/bottom/pull/2062): Move network and memory graph config file options from `[flags]` to be under `[network_graph]` and `[memory_graph]`. +- [#2063](https://github.com/ClementTsang/bottom/pull/2063): Move process config file options from `[flags]` to be under `[processes]`. ### Other diff --git a/docs/content/configuration/command-line-options.md b/docs/content/configuration/command-line-options.md index 08f9a90c..cc4f740a 100644 --- a/docs/content/configuration/command-line-options.md +++ b/docs/content/configuration/command-line-options.md @@ -35,12 +35,12 @@ see information on these options by running `btm -h`, or run `btm --help` to dis | `--read_only` | Prevents performing any actions that affect the system (e.g. stopping processes). | | `--get_threads` | Also gather process thread information. | | `-g, --group_processes` | Groups processes with the same name by default. No effect if `--tree` is set. | -| `--hide_k_threads` | Hide kernel threads by default. | +| `--hide_k_threads` | Hide kernel threads from being shown. | | `--process_memory_as_value` | Defaults to showing process memory usage by value. | | `--process_command` | Shows the full command name instead of the process name by default. | | `-R, --regex` | Enables regex by default while searching. | | `-T, --tree` | Makes the process widget use tree mode by default. | -| `--tree_collapse` | Collapse process tree by default. | +| `--tree_collapse` | Collapse the process tree by default. | | `-n, --unnormalized_cpu` | Show process CPU% usage without averaging over the number of CPU cores. | | `-W, --whole_word` | Enables whole-word matching by default while searching. | diff --git a/docs/content/configuration/config-file/flags.md b/docs/content/configuration/config-file/flags.md index 41ab5a62..94b191ec 100644 --- a/docs/content/configuration/config-file/flags.md +++ b/docs/content/configuration/config-file/flags.md @@ -58,5 +58,5 @@ each time: | `table_gap` | String (one of ["none", "space", "line"]) | Controls the gap between table headers and data rows. Defaults to "space". | | `disable_keys` | Boolean | Disables keyboard shortcuts, including the ones that stop bottom. | | `no_write` | Boolean | Disables writing to the config file. | -| `hide_k_threads` | Boolean | Hide kernel threads by default. | +| `hide_k_threads` | Boolean | Hide kernel threads from being shown. | | `free_arc` | Boolean | Subtract freeable ARC from memory usage. | diff --git a/docs/content/configuration/config-file/processes.md b/docs/content/configuration/config-file/processes.md index fa9bcb70..46a4c829 100644 --- a/docs/content/configuration/config-file/processes.md +++ b/docs/content/configuration/config-file/processes.md @@ -4,9 +4,21 @@ If you want to change some of the default behaviour of the processes widget, you can configure some things in the config file. -| Field | Type | Functionality | -| ------------- | ------- | ---------------------------------- | -| `get_threads` | Boolean | Gather process thread information. | +| Field | Type | Functionality | +| ----------------------- | ------- | --------------------------------------------------------------------------------------------------------- | +| `get_threads` | Boolean | Gather process thread information. | +| `hide_k_threads` | Boolean | Hide kernel threads from being shown. Linux only. | +| `tree_collapse` | Boolean | Collapse the process tree by default when tree mode is set. | +| `process_command` | Boolean | Shows the full command name instead of the process name by default. | +| `disable_advanced_kill` | Boolean | Disable the advanced kill dialog and just show the basic one with no options. Linux, macOS, FreeBSD only. | +| `default_memory_value` | Boolean | Defaults to showing process memory usage by value. | +| `default_grouped` | Boolean | Groups processes with the same name by default. No effect if `--tree` is set. | +| `regex` | Boolean | Enables regex by default while searching. | +| `case_sensitive` | Boolean | Enables case sensitivity by default when searching. | +| `whole_word` | Boolean | Enables whole-word matching by default while searching. | +| `default_tree` | Boolean | Makes the process widget use tree mode by default. | +| `current_usage` | Boolean | Calculates process CPU usage as a percentage of current usage rather than total usage. | +| `unnormalized_cpu` | Boolean | Show process CPU% usage without averaging over the number of CPU cores. | ## Columns diff --git a/schema/nightly/bottom.json b/schema/nightly/bottom.json index 7853d64e..d19b877f 100644 --- a/schema/nightly/bottom.json +++ b/schema/nightly/bottom.json @@ -912,6 +912,13 @@ "description": "Process configuration fields.", "type": "object", "properties": { + "case_sensitive": { + "description": "Enables case sensitivity by default when searching.", + "type": [ + "boolean", + "null" + ] + }, "columns": { "description": "A list of process widget columns.", "type": "array", @@ -919,6 +926,27 @@ "$ref": "#/$defs/ProcColumn" } }, + "current_usage": { + "description": "Calculates process CPU usage as a percentage of current usage rather than total usage.", + "type": [ + "boolean", + "null" + ] + }, + "default_grouped": { + "description": "Groups processes with the same name by default. No effect if `--tree` is set.", + "type": [ + "boolean", + "null" + ] + }, + "default_memory_value": { + "description": "Defaults to showing process memory usage by value.", + "type": [ + "boolean", + "null" + ] + }, "default_sort": { "description": "The default sort column.", "anyOf": [ @@ -930,12 +958,68 @@ } ] }, + "default_tree": { + "description": "Makes the process widget use tree mode by default.", + "type": [ + "boolean", + "null" + ] + }, + "disable_advanced_kill": { + "description": "Disable the advanced kill dialog and just show the basic one with no options.", + "type": [ + "boolean", + "null" + ] + }, "get_threads": { "description": "Whether to get process child threads.", "type": [ "boolean", "null" ] + }, + "hide_k_threads": { + "description": "Hide kernel threads from being shown.", + "type": [ + "boolean", + "null" + ] + }, + "process_command": { + "description": "Shows the full command name instead of the process name by default.", + "type": [ + "boolean", + "null" + ] + }, + "regex": { + "description": "Enables regex by default while searching.", + "type": [ + "boolean", + "null" + ] + }, + "tree_collapse": { + "description": "Collapse the process tree by default when tree mode is set.", + "type": [ + "boolean", + "null" + ] + }, + "unnormalized_cpu": { + "description": "Show process CPU% usage without averaging over the number of CPU cores.", + "type": [ + "boolean", + "null" + ] + }, + "whole_word": { + "description": "Enables whole-word matching by default while searching.", + "type": [ + "boolean", + "null" + ] } } }, diff --git a/src/constants.rs b/src/constants.rs index e3617c5a..4665e041 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -362,7 +362,7 @@ pub(crate) const CONFIG_TEXT: &str = r#"# This is a default config file for bott # Prevents performing any actions that affect the system (e.g. stopping processes). #read_only = false -# Hides the kernel threads +# Hide kernel threads from being shown. #hide_k_threads = false # Hide GPU(s) information @@ -397,6 +397,42 @@ pub(crate) const CONFIG_TEXT: &str = r#"# This is a default config file for bott # Gather process child thread information #get_threads = false +# Hide kernel threads from being shown. Linux only. +#hide_k_threads = false + +# Collapse the process tree by default when tree mode is set. +#tree_collapse = false + +# Shows the full command name instead of the process name by default. +#process_command = false + +# Disable the advanced kill dialog and just show the basic one with no options. Only available on Linux, macOS, and FreeBSD. +#disable_advanced_kill = false + +# Defaults to showing process memory usage by value. +#default_memory_value = false + +# Groups processes with the same name by default. No effect if tree is set. +#default_grouped = false + +# Enables regex by default while searching. +#regex = false + +# Enables case sensitivity by default when searching. +#case_sensitive = false + +# Enables whole-word matching by default while searching. +#whole_word = false + +# Makes the process widget use tree mode by default. +#default_tree = false + +# Calculates process CPU usage as a percentage of current usage rather than total usage. +#current_usage = false + +# Show process CPU% usage without averaging over the number of CPU cores. +#unnormalized_cpu = false + # CPU widget configuration #[cpu] diff --git a/src/options.rs b/src/options.rs index 88cc4e06..11312bdd 100644 --- a/src/options.rs +++ b/src/options.rs @@ -77,6 +77,23 @@ macro_rules! is_flag_enabled_in { }; } +/// A version of [`is_flag_enabled`] which should be used to deprecate old config flags. +macro_rules! enabled_option_with_deprecated { + ($arg:expr, $config:expr, $section:ident . $field:ident, $flags:ident . $deprecated_flag:ident $(,)?) => { + if $arg { + true + } else if let Some(section) = &$config.$section { + section.$field.unwrap_or(false) + } else if let Some(flags) = &$config.flags { + deprecated_warning(stringify!($deprecated_flag), stringify!($section.$field)); + + flags.$deprecated_flag.unwrap_or(false) + } else { + false + } + }; +} + /// Get the value of a field for a specific section in the config file if set. If not set, the default is used. macro_rules! config_or_default { ($config:expr, $section:ident . $field:ident) => { @@ -262,20 +279,66 @@ pub(crate) fn init_app(args: BottomArgs, config: Config) -> Result<(App, BottomL let free_arc = is_flag_enabled!(free_arc, args.memory, config); // For processes - let is_grouped = is_flag_enabled!(group_processes, args.process, config); - let is_case_sensitive = is_flag_enabled!(case_sensitive, args.process, config); - let is_match_whole_word = is_flag_enabled!(whole_word, args.process, config); - let is_use_regex = is_flag_enabled!(regex, args.process, config); - let is_default_tree = is_flag_enabled!(tree, args.process, config); - let is_default_command = is_flag_enabled!(process_command, args.process, config); + let is_grouped = enabled_option_with_deprecated!( + args.process.group_processes, + config, + processes.default_grouped, + flags.group_processes, + ); + let is_case_sensitive = enabled_option_with_deprecated!( + args.process.case_sensitive, + config, + processes.case_sensitive, + flags.case_sensitive, + ); + let is_match_whole_word = enabled_option_with_deprecated!( + args.process.whole_word, + config, + processes.whole_word, + flags.whole_word, + ); + let is_use_regex = + enabled_option_with_deprecated!(args.process.regex, config, processes.regex, flags.regex,); + let is_default_tree = enabled_option_with_deprecated!( + args.process.tree, + config, + processes.default_tree, + flags.tree, + ); + let is_default_command = enabled_option_with_deprecated!( + args.process.process_command, + config, + processes.process_command, + flags.process_command, + ); #[cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd"))] - let is_advanced_kill = !(is_flag_enabled!(disable_advanced_kill, args.process, config)); + let is_advanced_kill = !(enabled_option_with_deprecated!( + args.process.disable_advanced_kill, + config, + processes.disable_advanced_kill, + flags.disable_advanced_kill, + )); let is_read_only = is_flag_enabled!(read_only, args.process, config); #[cfg(target_os = "linux")] - let hide_k_threads = is_flag_enabled!(hide_k_threads, args.process, config); + let hide_k_threads = enabled_option_with_deprecated!( + args.process.hide_k_threads, + config, + processes.hide_k_threads, + flags.hide_k_threads, + ); - let process_memory_as_value = is_flag_enabled!(process_memory_as_value, args.process, config); - let is_default_tree_collapsed = is_flag_enabled!(tree_collapse, args.process, config); + let process_memory_as_value = enabled_option_with_deprecated!( + args.process.process_memory_as_value, + config, + processes.default_memory_value, + flags.process_memory_as_value, + ); + let is_default_tree_collapsed = enabled_option_with_deprecated!( + args.process.tree_collapse, + config, + processes.tree_collapse, + flags.tree_collapse, + ); // For CPU let default_cpu_selection = get_default_cpu_selection(args, config); @@ -305,7 +368,12 @@ pub(crate) fn init_app(args: BottomArgs, config: Config) -> Result<(App, BottomL let network_scale_type = get_network_scale_type(args, config); // Use + update this again after deprecation // let network_use_binary_prefix = is_flag_enabled!(network_use_binary_prefix, args.network, config); - let network_use_binary_prefix = get_network_use_binary_prefix(args, config); + let network_use_binary_prefix = enabled_option_with_deprecated!( + args.network.network_use_binary_prefix, + config, + network_graph.use_binary_prefix, + flags.network_use_binary_prefix, + ); let network_show_packets = is_flag_enabled_in!(show_packets, args.network, config.network_graph); @@ -335,8 +403,18 @@ pub(crate) fn init_app(args: BottomArgs, config: Config) -> Result<(App, BottomL show_cpu_decimal: config_or!(config, cpu.show_decimal, false), use_dot: is_flag_enabled!(dot_marker, args.general, config), cpu_left_legend: is_flag_enabled!(cpu_left_legend, args.cpu, config), - use_current_cpu_total: is_flag_enabled!(current_usage, args.process, config), - unnormalized_cpu: is_flag_enabled!(unnormalized_cpu, args.process, config), + use_current_cpu_total: enabled_option_with_deprecated!( + args.process.current_usage, + config, + processes.current_usage, + flags.current_usage, + ), + unnormalized_cpu: enabled_option_with_deprecated!( + args.process.unnormalized_cpu, + config, + processes.unnormalized_cpu, + flags.unnormalized_cpu, + ), get_process_threads: is_flag_enabled_in!(get_threads, args.process, config.processes), use_basic_mode, default_time_value, @@ -1063,29 +1141,6 @@ fn get_network_scale_type(args: &BottomArgs, config: &Config) -> AxisScaling { AxisScaling::Linear } -fn get_network_use_binary_prefix(args: &BottomArgs, config: &Config) -> bool { - if args.network.network_use_binary_prefix { - return true; - } else if let Some(use_binary_prefix) = config - .network_graph - .as_ref() - .and_then(|cfg| cfg.use_binary_prefix) - { - return use_binary_prefix; - } else if let Some(flags) = &config.flags { - if let Some(network_use_binary_prefix) = flags.network_use_binary_prefix { - deprecated_warning( - "network_use_binary_prefix", - "network_graph.use_binary_prefix", - ); - - return network_use_binary_prefix; - } - } - - false -} - fn get_retention(args: &BottomArgs, config: &Config) -> OptionResult { const DEFAULT_RETENTION_MS: u64 = 600 * 1000; // Keep 10 minutes of data. @@ -1144,7 +1199,7 @@ fn get_network_legend_position( .as_ref() .and_then(|flags| flags.network_legend.as_ref()) .map(|s| (s, "network_legend")), - "network.legend_position", + "network_graph.legend_position", ) } diff --git a/src/options/args.rs b/src/options/args.rs index c56a7455..f5d286e7 100644 --- a/src/options/args.rs +++ b/src/options/args.rs @@ -330,7 +330,7 @@ pub struct ProcessArgs { #[arg( long, action = ArgAction::SetTrue, - help = "Hide kernel threads by default.", + help = "Hide kernel threads.", alias = "hide-k-threads" )] pub hide_k_threads: bool, diff --git a/src/options/config/flags.rs b/src/options/config/flags.rs index e36fec7e..8ccbfc01 100644 --- a/src/options/config/flags.rs +++ b/src/options/config/flags.rs @@ -32,12 +32,6 @@ pub(crate) struct GeneralConfig { pub(crate) temperature_type: Option, pub(crate) rate: Option, pub(crate) cpu_left_legend: Option, - pub(crate) current_usage: Option, - pub(crate) unnormalized_cpu: Option, - pub(crate) group_processes: Option, - pub(crate) case_sensitive: Option, - pub(crate) whole_word: Option, - pub(crate) regex: Option, pub(crate) basic: Option, pub(crate) default_time_value: Option, pub(crate) time_delta: Option, @@ -53,36 +47,39 @@ pub(crate) struct GeneralConfig { pub(crate) disable_click: Option, pub(crate) disable_keys: Option, pub(crate) no_write: Option, - // FIXME: Deprecate this in the future. - pub(crate) network_legend: Option, - // FIXME: Deprecate this in the future. - pub(crate) memory_legend: Option, - pub(crate) process_memory_as_value: Option, - pub(crate) tree: Option, pub(crate) show_table_scroll_position: Option, pub(crate) show_table_scroll_bar: Option, + pub(crate) read_only: Option, + // #[cfg(feature = "zfs")] + pub(crate) free_arc: Option, + pub(crate) disable_gpu: Option, + // FIXME: This makes no sense outside of basic mode, add a basic mode config section. + // FIXME: This also should be moved to CPU-specific... same with all the other entries. + pub(crate) average_cpu_row: Option, + pub(crate) enable_cache_memory: Option, + pub(crate) retention: Option, + + // FIXME: Deprecate these in the future. + pub(crate) network_use_bytes: Option, + pub(crate) network_use_log: Option, + pub(crate) network_use_binary_prefix: Option, + pub(crate) network_legend: Option, + pub(crate) memory_legend: Option, + // #[cfg(target_os = "linux")] + pub(crate) hide_k_threads: Option, + pub(crate) tree_collapse: Option, pub(crate) process_command: Option, // This does nothing on Windows, but we leave it enabled to make the config file consistent // across platforms. // // #[cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd"))] pub(crate) disable_advanced_kill: Option, - pub(crate) read_only: Option, - // #[cfg(target_os = "linux")] - pub(crate) hide_k_threads: Option, - // #[cfg(feature = "zfs")] - pub(crate) free_arc: Option, - // FIXME: Deprecate this in the future. - pub(crate) network_use_bytes: Option, - // FIXME: Deprecate this in the future. - pub(crate) network_use_log: Option, - // FIXME: Deprecate this in the future. - pub(crate) network_use_binary_prefix: Option, - pub(crate) disable_gpu: Option, - pub(crate) enable_cache_memory: Option, - pub(crate) retention: Option, - // FIXME: This makes no sense outside of basic mode, add a basic mode config section. - // FIXME: This also should be moved to CPU-specific... same with all the other entries. - pub(crate) average_cpu_row: Option, - pub(crate) tree_collapse: Option, + pub(crate) process_memory_as_value: Option, + pub(crate) group_processes: Option, + pub(crate) regex: Option, + pub(crate) case_sensitive: Option, + pub(crate) whole_word: Option, + pub(crate) tree: Option, + pub(crate) current_usage: Option, + pub(crate) unnormalized_cpu: Option, } diff --git a/src/options/config/process.rs b/src/options/config/process.rs index ce4a9089..46e2a380 100644 --- a/src/options/config/process.rs +++ b/src/options/config/process.rs @@ -20,6 +20,51 @@ pub(crate) struct ProcessesConfig { /// Whether to get process child threads. pub get_threads: Option, + + /// Hide kernel threads from being shown. Linux only. + #[cfg_attr(not(target_os = "linux"), allow(dead_code))] + pub hide_k_threads: Option, + + /// Collapse the process tree by default when tree mode is set. + pub tree_collapse: Option, + + /// Shows the full command name instead of the process name by default. + pub process_command: Option, + + // This does nothing on Windows, but we leave it enabled to make the config file consistent + // across platforms. + // + // #[cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd"))] + /// Disable the advanced kill dialog and just show the basic one with no options. + #[cfg_attr( + not(any(target_os = "linux", target_os = "macos", target_os = "freebsd")), + allow(dead_code) + )] + pub disable_advanced_kill: Option, + + /// Defaults to showing process memory usage by value. + pub default_memory_value: Option, + + /// Groups processes with the same name by default. No effect if `--tree` is set. + pub default_grouped: Option, + + /// Enables regex by default while searching. + pub regex: Option, + + /// Enables case sensitivity by default when searching. + pub case_sensitive: Option, + + /// Enables whole-word matching by default while searching. + pub whole_word: Option, + + /// Makes the process widget use tree mode by default. + pub default_tree: Option, + + /// Calculates process CPU usage as a percentage of current usage rather than total usage. + pub current_usage: Option, + + /// Show process CPU% usage without averaging over the number of CPU cores. + pub unnormalized_cpu: Option, } #[cfg(test)] diff --git a/tests/integration/valid_config_tests.rs b/tests/integration/valid_config_tests.rs index 1dd39fee..3edd848b 100644 --- a/tests/integration/valid_config_tests.rs +++ b/tests/integration/valid_config_tests.rs @@ -219,7 +219,18 @@ fn test_newer_mem_network() { /// This uses deprecated network and memory settings - once they are removed, this test file should be moved to invalid configs. #[test] fn test_deprecated_mem_network() { - run_and_kill(&["-C", "./tests/valid_configs/deprecated_mem_network.toml"]); + run_and_kill(&["-C", "./tests/valid_configs/deprecated/mem_network.toml"]); +} + +#[test] +fn test_newer_processes() { + run_and_kill(&["-C", "./tests/valid_configs/newer_processes.toml"]); +} + +/// This uses deprecated process settings - once they are removed, this test file should be moved to invalid configs. +#[test] +fn test_deprecated_processes() { + run_and_kill(&["-C", "./tests/valid_configs/deprecated/processes.toml"]); } #[test] diff --git a/tests/valid_configs/deprecated_mem_network.toml b/tests/valid_configs/deprecated/mem_network.toml similarity index 100% rename from tests/valid_configs/deprecated_mem_network.toml rename to tests/valid_configs/deprecated/mem_network.toml diff --git a/tests/valid_configs/deprecated/processes.toml b/tests/valid_configs/deprecated/processes.toml new file mode 100644 index 00000000..0a3a53c8 --- /dev/null +++ b/tests/valid_configs/deprecated/processes.toml @@ -0,0 +1,15 @@ +# This uses deprecated process settings - once they are removed, this test file should be moved to invalid configs. + +[flags] +group_processes = true +case_sensitive = true +whole_word = true +regex = true +tree = true +process_command = true +disable_advanced_kill = true +process_memory_as_value = true +hide_k_threads = true +tree_collapse = true +current_usage = true +unnormalized_cpu = true diff --git a/tests/valid_configs/newer_processes.toml b/tests/valid_configs/newer_processes.toml new file mode 100644 index 00000000..cecb6b14 --- /dev/null +++ b/tests/valid_configs/newer_processes.toml @@ -0,0 +1,15 @@ +# This uses the newer processes config location. + +[processes] +default_grouped = true +case_sensitive = true +whole_word = true +regex = true +default_tree = true +process_command = true +disable_advanced_kill = true +default_memory_value = true +hide_k_threads = true +tree_collapse = true +current_usage = true +unnormalized_cpu = true