diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 46d9595fd..2d840ec0e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -90,6 +90,7 @@ /modules/programs/home-manager.nix @rycee /modules/programs/htop.nix @bjpbakker +/tests/modules/htop @bjpbakker /modules/programs/i3status.nix @JustinLovinger diff --git a/modules/lib/maintainers.nix b/modules/lib/maintainers.nix index 2f14dbef1..20663a281 100644 --- a/modules/lib/maintainers.nix +++ b/modules/lib/maintainers.nix @@ -121,4 +121,10 @@ githubId = 5646732; name = "Andreas Mager"; }; + bjpbakker = { + email = "bart@thesoftwarecraft.com"; + github = "bjpbakker"; + githubId = 605641; + name = "Bart Bakker"; + }; } diff --git a/modules/programs/htop.nix b/modules/programs/htop.nix index 1edd0f7ab..81abc8c63 100644 --- a/modules/programs/htop.nix +++ b/modules/programs/htop.nix @@ -10,14 +10,10 @@ let let v' = if isBool v then (if v then "1" else "0") else toString v; in "${n}=${v'}"; - formatMeters = side: meters: - let - warn' = warn "htop: meters should be passed as a list"; - meters' = if isList meters then meters else warn' [ meters ]; - in { - "${side}_meters" = concatMap (mapAttrsToList (x: _: x)) meters'; - "${side}_meter_modes" = concatMap (mapAttrsToList (_: y: y)) meters'; - }; + formatMeters = side: meters: { + "${side}_meters" = concatMap (mapAttrsToList (x: _: x)) meters; + "${side}_meter_modes" = concatMap (mapAttrsToList (_: y: y)) meters; + }; leftMeters = formatMeters "left"; rightMeters = formatMeters "right"; @@ -92,168 +88,15 @@ let led = meter modes.LED; blank = text "Blank"; - # Mapping from names to defaults - meters = { - Clock = 2; - Date = 2; - DateTime = 2; - LoadAverage = 2; - Load = 2; - Memory = 1; - Swap = 1; - Zram = 2; - HugePages = 2; - Tasks = 2; - Uptime = 2; - Battery = 2; - Hostname = 2; - AllCPUs = 1; - AllCPUs2 = 1; - AllCPUs4 = 1; - AllCPUs8 = 1; - LeftCPUs = 1; - RightCPUs = 1; - Right = 1; - CPUs = 1; - LeftCPUs2 = 1; - RightCPUs2 = 1; - LeftCPUs4 = 1; - RightCPUs4 = 1; - LeftCPUs8 = 1; - RightCPUs8 = 1; - Blank = 2; - PressureStallCPUSome = 2; - PressureStallIOSome = 2; - PressureStallIOFull = 2; - PressureStallMemorySome = 2; - PressureStallMemoryFull = 2; - ZFSARC = 2; - ZFSCARC = 2; - CPU = 1; - "CPU(1)" = 1; - "CPU(2)" = 1; - "CPU(3)" = 1; - "CPU(4)" = 1; - "CPU(5)" = 1; - "CPU(6)" = 1; - "CPU(7)" = 1; - "CPU(8)" = 1; - SELinux = 2; - Systemd = 2; - DiskIO = 2; - NetworkIO = 2; - }; - - singleMeterType = let - meterEnum = types.enum (attrNames meters); - meterSubmodule = types.submodule { - options = { - kind = mkOption { - type = types.enum (attrNames meters); - example = "AllCPUs"; - description = "What kind of meter."; - }; - - mode = mkOption { - type = types.enum [ 1 2 3 4 ]; - example = 2; - description = - "Which mode the meter should use, one of 1(Bar) 2(Text) 3(Graph) 4(LED)."; - }; - }; - }; - in types.coercedTo meterEnum (m: { - kind = m; - mode = meters.${m}; - }) meterSubmodule; - - meterType = types.submodule { - options = { - left = mkOption { - description = "Meters shown in the left header."; - default = [ "AllCPUs" "Memory" "Swap" ]; - example = [ - "Memory" - "LeftCPUs2" - "RightCPUs2" - { - kind = "CPU"; - mode = 3; - } - ]; - type = types.listOf singleMeterType; - }; - right = mkOption { - description = "Meters shown in the right header."; - default = [ "Tasks" "LoadAverage" "Uptime" ]; - example = [ - { - kind = "Clock"; - mode = 4; - } - "Uptime" - "Tasks" - ]; - type = types.listOf singleMeterType; - }; - }; - }; - in { + meta.maintainers = [ maintainers.bjpbakker ]; + options.programs.htop = { enable = mkEnableOption "htop"; settings = mkOption { type = types.attrs; - default = { - account_guest_in_cpu_meter = false; - color_scheme = 0; - cpu_count_from_zero = false; - delay = 15; - detailed_cpu_time = false; - enable_mouse = true; - fields = with fields; [ - PID - USER - PRIORITY - NICE - M_SIZE - M_RESIDENT - M_SHARE - STATE - PERCENT_CPU - PERCENT_MEM - TIME - COMM - ]; - header_margin = true; - hide_kernel_threads = true; - hide_threads = false; - hide_userland_threads = false; - highlight_base_name = false; - highlight_megabytes = true; - highlight_threads = true; - shadow_other_users = false; - show_cpu_frequency = false; - show_cpu_usage = false; - show_program_path = true; - show_thread_names = false; - sort_direction = 1; - sort_key = fields.PERCENT_CPU; - tree_view = false; - update_process_names = false; - vim_mode = false; - } // (leftMeters [ - (bar "AllCPUs2") - (bar "Memory") - (bar "Swap") - (text "Zram") - ]) // (rightMeters [ - (text "Tasks") - (text "LoadAverage") - (text "Uptime") - (text "Systemd") - ]); + default = { }; example = literalExample '' { color_scheme = 6; @@ -291,300 +134,6 @@ in { description = '' Configuration options to add to ~/.config/htop/htoprc. - - This superseedes any other (deprecated) settings in this module. - ''; - }; - - fields = mkOption { - type = types.nullOr (types.listOf (types.enum (attrNames fields))); - default = null; - example = [ - "PID" - "USER" - "PRIORITY" - "PERCENT_CPU" - "M_RESIDENT" - "PERCENT_MEM" - "TIME" - "COMM" - ]; - description = '' - Deprecated. Please use programs.htop.settings.fields instead. - - Active fields shown in the table. - ''; - }; - - sortKey = mkOption { - type = types.nullOr (types.enum (attrNames fields)); - default = null; - example = "TIME"; - description = '' - Deprecated. Please use programs.htop.settings.sort_key instead. - - Which field to use for sorting. - ''; - }; - - sortDescending = mkOption { - type = types.nullOr types.bool; - default = null; - description = '' - Deprecated. Please use programs.htop.settings.sort_direction instead. - - Whether to sort descending or not. - ''; - }; - - hideThreads = mkOption { - type = types.nullOr types.bool; - default = null; - description = '' - Deprecated. Please use programs.htop.settings.hide_threads instead. - - Hide threads. - ''; - }; - - hideKernelThreads = mkOption { - type = types.nullOr types.bool; - default = null; - description = '' - Deprecated. Please use programs.htop.settings.hide_kernel_threads instead. - - Hide kernel threads. - ''; - }; - - hideUserlandThreads = mkOption { - type = types.nullOr types.bool; - default = null; - description = '' - Deprecated. Please use programs.htop.settings.hide_userland_threads instead. - - Hide userland process threads. - ''; - }; - - shadowOtherUsers = mkOption { - type = types.nullOr types.bool; - default = null; - description = '' - Deprecated. Please use programs.htop.settings.shadow_other_users instead. - - Shadow other users' processes. - ''; - }; - - showThreadNames = mkOption { - type = types.nullOr types.bool; - default = null; - description = '' - Deprecated. Please use programs.htop.settings.show_thread_names instead. - - Show custom thread names. - ''; - }; - - showProgramPath = mkOption { - type = types.nullOr types.bool; - default = null; - description = '' - Deprecated. Please use programs.htop.settings.show_program_path instead. - - Show program path. - ''; - }; - - highlightBaseName = mkOption { - type = types.nullOr types.bool; - default = null; - description = '' - Deprecated. Please use programs.htop.settings.highlight_base_name instead. - - Highlight program basename. - ''; - }; - - highlightMegabytes = mkOption { - type = types.nullOr types.bool; - default = null; - description = '' - Deprecated. Please use programs.htop.settings.highlight_megabytes instead. - - Highlight large numbers in memory counters. - ''; - }; - - highlightThreads = mkOption { - type = types.nullOr types.bool; - default = null; - description = '' - Deprecated. Please use programs.htop.settings.highlight_threads instead. - - Display threads in a different color. - ''; - }; - - treeView = mkOption { - type = types.nullOr types.bool; - default = null; - description = '' - Deprecated. Please use programs.htop.settings.tree_view instead. - - Tree view. - ''; - }; - - headerMargin = mkOption { - type = types.nullOr types.bool; - default = null; - description = '' - Deprecated. Please use programs.htop.settings.header_margin instead. - - Leave a margin around header. - ''; - }; - - detailedCpuTime = mkOption { - type = types.nullOr types.bool; - default = null; - description = '' - Deprecated. Please use programs.htop.settings.detailed_cpu_time instead. - - Detailed CPU time (System/IO-Wait/Hard-IRQ/Soft-IRQ/Steal/Guest). - ''; - }; - - cpuCountFromZero = mkOption { - type = types.nullOr types.bool; - default = null; - description = '' - Deprecated. Please use programs.htop.settings.cpu_count_from_zero instead. - - Count CPUs from 0 instead of 1. - ''; - }; - - showCpuUsage = mkOption { - type = types.nullOr types.bool; - default = null; - description = '' - Deprecated. Please use programs.htop.settings.show_cpu_usage instead. - - Show CPU usage frequency. - ''; - }; - - showCpuFrequency = mkOption { - type = types.nullOr types.bool; - default = null; - description = '' - Deprecated. Please use programs.htop.settings.show_cpu_frequency instead. - - Show CPU frequency. - ''; - }; - - updateProcessNames = mkOption { - type = types.nullOr types.bool; - default = null; - description = '' - Deprecated. Please use programs.htop.settings.update_process_names instead. - - Update process names on every refresh. - ''; - }; - - accountGuestInCpuMeter = mkOption { - type = types.nullOr types.bool; - default = null; - description = '' - Deprecated. Please use programs.htop.settings.account_guest_in_cpu_meter instead. - - Add guest time in CPU meter percentage. - ''; - }; - - colorScheme = mkOption { - type = types.nullOr (types.enum [ 0 1 2 3 4 5 6 ]); - default = null; - example = 6; - description = '' - Deprecated. Please use programs.htop.settings.color_scheme instead. - - Which color scheme to use. - ''; - }; - - enableMouse = mkOption { - type = types.nullOr types.bool; - default = null; - description = '' - Deprecated. Please use programs.htop.settings.enable_mouse instead. - - Enable mouse support. - ''; - }; - - delay = mkOption { - type = types.nullOr types.int; - default = null; - example = 2; - description = '' - Deprecated. Please use programs.htop.settings.delay instead. - - Set the delay between updates, in tenths of seconds. - ''; - }; - - meters = mkOption { - description = '' - Deprecated. Please use programs.htop.settings.left_meters, - programs.htop.settings.left_meter_modes, - programs.htop.settings.right_meters and - programs.htop.settings.right_meter_modes instead. Or consider using - lib.htop.leftMeters and lib.htop.rightMeters. - - Meters shown in the header. - ''; - default = null; - example = { - left = [ - "Memory" - "CPU" - "LeftCPUs2" - "RightCPUs2" - { - kind = "CPU"; - mode = 3; - } - ]; - right = [ - { - kind = "Clock"; - mode = 4; - } - "Uptime" - "Tasks" - "LoadAverage" - { - kind = "Battery"; - mode = 1; - } - ]; - }; - type = types.nullOr meterType; - }; - - vimMode = mkOption { - type = types.nullOr types.bool; - default = null; - description = '' - Deprecated. Please use programs.htop.settings.vim_mode instead. - - Vim key bindings. ''; }; }; @@ -596,72 +145,27 @@ in { home.packages = [ pkgs.htop ]; - xdg.configFile."htop/htoprc".text = let + xdg.configFile."htop/htoprc" = let + defaults = { + fields = with fields; [ + PID + USER + PRIORITY + NICE + M_SIZE + M_RESIDENT + M_SHARE + STATE + PERCENT_CPU + PERCENT_MEM + TIME + COMM + ]; + }; - deprecate = settingsKey: optionKey: optionValue: - let - warn' = warn - "htop: programs.htop.${optionKey} is deprecated; please is programs.htop.settings.${settingsKey} instead"; - in if !isNull optionValue then - warn' optionValue - else if hasAttr settingsKey cfg.settings then - cfg.settings.${settingsKey} - else - null; - - deprecate' = settingsKey: optionKey: - deprecate settingsKey optionKey cfg.${optionKey}; - - ifNonNull = x: y: if isNull x then null else y; - - leftMeters = deprecate "left_meters" "meters.left" - (ifNonNull cfg.meters (map (m: m.kind) cfg.meters.left)); - leftModes = deprecate "left_meter_modes" "meters.left" - (ifNonNull cfg.meters (map (m: m.mode) cfg.meters.left)); - rightMeters = deprecate "right_meters" "meters.right" - (ifNonNull cfg.meters (map (m: m.kind) cfg.meters.right)); - rightModes = deprecate "right_meter_modes" "meters.right" - (ifNonNull cfg.meters (map (m: m.mode) cfg.meters.right)); - - settings' = cfg.settings // (filterAttrs (_: v: !isNull v) { - fields = deprecate "fields" "fields" - (ifNonNull cfg.fields (map (n: fields.${n}) cfg.fields)); - sort_key = deprecate "sort_key" "sortKey" - (ifNonNull cfg.sortKey fields.${cfg.sortKey}); - sort_direction = deprecate' "sort_direction" "sortDescending"; - hide_threads = deprecate' "hide_threads" "hideThreads"; - hide_kernel_threads = - deprecate' "hide_kernel_threads" "hideKernelThreads"; - hide_userland_threads = - deprecate' "hide_userland_threads" "hideUserlandThreads"; - shadow_other_users = deprecate' "shadow_other_users" "shadowOtherUsers"; - show_thread_names = deprecate' "show_thread_names" "showThreadNames"; - show_program_path = deprecate' "show_program_path" "showProgramPath"; - highlight_base_name = - deprecate' "highlight_base_name" "highlightBaseName"; - highlight_megabytes = - deprecate' "highlight_megabytes" "highlightMegabytes"; - highlight_threads = deprecate' "highlight_threads" "highlightThreads"; - tree_view = deprecate' "tree_view" "treeView"; - header_margin = deprecate' "header_margin" "headerMargin"; - detailed_cpu_time = deprecate' "detailed_cpu_time" "detailedCpuTime"; - cpu_count_from_zero = - deprecate' "cpu_count_from_zero" "cpuCountFromZero"; - show_cpu_usage = deprecate' "show_cpu_usage" "showCpuUsage"; - show_cpu_frequency = deprecate' "show_cpu_frequency" "showCpuFrequency"; - update_process_names = - deprecate' "update_process_names" "updateProcessNames"; - account_guest_in_cpu_meter = - deprecate' "account_guest_in_cpu_meter" "accountGuestInCpuMeter"; - color_scheme = deprecate' "color_scheme" "colorScheme"; - enable_mouse = deprecate' "enable_mouse" "enableMouse"; - delay = deprecate' "delay" "delay"; - left_meters = leftMeters; - left_meter_modes = leftModes; - right_meters = rightMeters; - right_meter_modes = rightModes; - vim_mode = deprecate' "vim_mode" "vimMode"; - }); - in concatStringsSep "\n" (mapAttrsToList formatOption settings'); + in mkIf (cfg.settings != { }) { + text = concatStringsSep "\n" + (mapAttrsToList formatOption (defaults // cfg.settings)) + "\n"; + }; }; } diff --git a/tests/modules/programs/htop/default-settings.nix b/tests/modules/programs/htop/default-settings.nix deleted file mode 100644 index f67e58276..000000000 --- a/tests/modules/programs/htop/default-settings.nix +++ /dev/null @@ -1,13 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; - -{ - config = { - programs.htop.enable = true; - - nmt.script = '' - assertFileExists home-files/.config/htop/htoprc - ''; - }; -} diff --git a/tests/modules/programs/htop/default.nix b/tests/modules/programs/htop/default.nix index 53653285e..ebb3cefcf 100644 --- a/tests/modules/programs/htop/default.nix +++ b/tests/modules/programs/htop/default.nix @@ -1,4 +1,5 @@ { - htop-default-settings = ./default-settings.nix; + htop-empty-settings = ./empty-settings.nix; htop-example-settings = ./example-settings.nix; + settings-without-fields = ./settings-without-fields.nix; } diff --git a/tests/modules/programs/htop/empty-settings.nix b/tests/modules/programs/htop/empty-settings.nix new file mode 100644 index 000000000..ae4e437fd --- /dev/null +++ b/tests/modules/programs/htop/empty-settings.nix @@ -0,0 +1,16 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.htop.enable = true; + + nixpkgs.overlays = + [ (self: super: { htop = pkgs.writeScriptBin "dummy" ""; }) ]; + + nmt.script = '' + assertPathNotExists home-files/.config/htop + ''; + }; +} diff --git a/tests/modules/programs/htop/example-htoprc.txt b/tests/modules/programs/htop/example-htoprc.txt new file mode 100644 index 000000000..ff06ed5ea --- /dev/null +++ b/tests/modules/programs/htop/example-htoprc.txt @@ -0,0 +1,11 @@ +color_scheme=6 +cpu_count_from_one=0 +delay=15 +fields=0 48 17 18 38 39 40 2 46 47 49 1 +highlight_base_name=1 +highlight_megabytes=1 +highlight_threads=1 +left_meter_modes=1 1 1 2 +left_meters=AllCPUs2 Memory Swap Zram +right_meter_modes=2 2 2 2 +right_meters=Tasks LoadAverage Uptime Systemd diff --git a/tests/modules/programs/htop/example-settings.nix b/tests/modules/programs/htop/example-settings.nix index 66698c844..412b8c7d8 100644 --- a/tests/modules/programs/htop/example-settings.nix +++ b/tests/modules/programs/htop/example-settings.nix @@ -36,8 +36,13 @@ with lib; (text "Systemd") ]); + nixpkgs.overlays = + [ (self: super: { htop = pkgs.writeScriptBin "dummy" ""; }) ]; + nmt.script = '' - assertFileExists home-files/.config/htop/htoprc + htoprc=home-files/.config/htop/htoprc + assertFileExists $htoprc + assertFileContent $htoprc ${./example-htoprc.txt} ''; }; } diff --git a/tests/modules/programs/htop/settings-without-fields.nix b/tests/modules/programs/htop/settings-without-fields.nix new file mode 100644 index 000000000..7a6ebe8dc --- /dev/null +++ b/tests/modules/programs/htop/settings-without-fields.nix @@ -0,0 +1,28 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.htop.enable = true; + programs.htop.settings = { color_scheme = 6; }; + + nixpkgs.overlays = + [ (self: super: { htop = pkgs.writeScriptBin "dummy" ""; }) ]; + + # Test that the 'fields' key is written in addition to the customized + # settings or htop won't read the options. + nmt.script = '' + htoprc=home-files/.config/htop/htoprc + assertFileExists $htoprc + assertFileContent $htoprc \ + ${ + builtins.toFile "htoprc-expected" '' + color_scheme=6 + fields=0 48 17 18 38 39 40 2 46 47 49 1 + '' + } + ''; + }; + +}