From bc623830e619cef86a2d3750625ffe4e24ea7e64 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 11:44:28 +0200 Subject: [PATCH 001/546] ci: bump cachix/install-nix-action from 27 to 30 Bumps [cachix/install-nix-action](https://github.com/cachix/install-nix-action) from 27 to 30. - [Release notes](https://github.com/cachix/install-nix-action/releases) - [Commits](https://github.com/cachix/install-nix-action/compare/v27...v30) --- updated-dependencies: - dependency-name: cachix/install-nix-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/github_pages.yml | 2 +- .github/workflows/test.yml | 2 +- .github/workflows/update-flake.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/github_pages.yml b/.github/workflows/github_pages.yml index 9f49d49a8..4e10f9ccb 100644 --- a/.github/workflows/github_pages.yml +++ b/.github/workflows/github_pages.yml @@ -11,7 +11,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - - uses: cachix/install-nix-action@v27 + - uses: cachix/install-nix-action@v30 with: nix_path: nixpkgs=channel:nixos-unstable - uses: cachix/cachix-action@v15 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 99a2f5a1a..ff67b6760 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,7 +12,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - - uses: cachix/install-nix-action@v27 + - uses: cachix/install-nix-action@v30 with: nix_path: nixpkgs=channel:nixos-unstable - run: | diff --git a/.github/workflows/update-flake.yml b/.github/workflows/update-flake.yml index ba9b5f818..9b0e4b443 100644 --- a/.github/workflows/update-flake.yml +++ b/.github/workflows/update-flake.yml @@ -12,7 +12,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - name: Install Nix - uses: cachix/install-nix-action@v27 + uses: cachix/install-nix-action@v30 - name: Update flake.lock uses: DeterminateSystems/update-flake-lock@v24 with: From fcf5e608ac65f64463bc0ccc5ea86f2170f20689 Mon Sep 17 00:00:00 2001 From: MithicSpirit Date: Mon, 7 Oct 2024 06:18:19 -0400 Subject: [PATCH 002/546] kitty: allow float values in settings (#5925) Some settings in kitty allow floating-point values, but this was not reflected in the type. --- modules/programs/kitty.nix | 4 ++-- tests/modules/programs/kitty/example-settings-expected.conf | 1 + tests/modules/programs/kitty/example-settings.nix | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/programs/kitty.nix b/modules/programs/kitty.nix index e9594ec12..9854fe69c 100644 --- a/modules/programs/kitty.nix +++ b/modules/programs/kitty.nix @@ -5,7 +5,7 @@ with lib; let cfg = config.programs.kitty; - eitherStrBoolInt = with types; either str (either bool int); + settingsValueType = with types; oneOf [ str bool int float ]; optionalPackage = opt: optional (opt != null && opt.package != null) opt.package; @@ -102,7 +102,7 @@ in { }; settings = mkOption { - type = types.attrsOf eitherStrBoolInt; + type = types.attrsOf settingsValueType; default = { }; example = literalExpression '' { diff --git a/tests/modules/programs/kitty/example-settings-expected.conf b/tests/modules/programs/kitty/example-settings-expected.conf index aca1b0c18..41a9cb772 100644 --- a/tests/modules/programs/kitty/example-settings-expected.conf +++ b/tests/modules/programs/kitty/example-settings-expected.conf @@ -7,6 +7,7 @@ font_size 8 # Shell integration is sourced and configured manually shell_integration no-rc +background_opacity 0.500000 enable_audio_bell no scrollback_lines 10000 update_check_interval 0 diff --git a/tests/modules/programs/kitty/example-settings.nix b/tests/modules/programs/kitty/example-settings.nix index 8d609a5ab..8f2e0b894 100644 --- a/tests/modules/programs/kitty/example-settings.nix +++ b/tests/modules/programs/kitty/example-settings.nix @@ -17,6 +17,7 @@ with lib; scrollback_lines = 10000; enable_audio_bell = false; update_check_interval = 0; + background_opacity = 0.5; }; font.name = "DejaVu Sans"; From 3ac39b2a8b7cbfc0f96628d8a84867c885bc988b Mon Sep 17 00:00:00 2001 From: Akshett Rai Jindal Date: Mon, 7 Oct 2024 18:46:25 +0530 Subject: [PATCH 003/546] zathura: Fix the type for config options (#5934) * zathura: add float to acceptable types for `options` attrset The man page states that the `set` directive can take 4 types of values: INT, FLOAT, STRING, BOOL. But the FLOAT part was missing from the home-manager module * zathura: make type of `programs.zathura.options` more readable Change from cascading mess of `either` to `oneOf` --- modules/programs/zathura.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/programs/zathura.nix b/modules/programs/zathura.nix index ba34af590..3e41256d3 100644 --- a/modules/programs/zathura.nix +++ b/modules/programs/zathura.nix @@ -31,7 +31,7 @@ in { options = mkOption { default = { }; - type = with types; attrsOf (either str (either bool int)); + type = with types; attrsOf (oneOf [ str bool int float ]); description = '' Add {option}`:set` command options to zathura and make them permanent. See From 271c83e21ea81f39a42ad128384e0e6804956a88 Mon Sep 17 00:00:00 2001 From: Kira Bruneau Date: Mon, 7 Oct 2024 17:06:52 -0400 Subject: [PATCH 004/546] firefox: organize tests by submodule (#5698) Split off from #5697, organizes firefox tests by submodule. This is intended to match directory structure setup for the new search submodule. --- tests/modules/programs/firefox/firefox.nix | 15 +- .../programs/firefox/profile-settings.nix | 215 ------------------ .../firefox/profiles/bookmarks/default.nix | 84 +++++++ .../bookmarks/expected-bookmarks-user.js} | 0 .../bookmarks/expected-bookmarks.html} | 0 .../firefox/profiles/containers/default.nix | 32 +++ .../containers/duplicate-ids.nix} | 2 +- .../containers/expected-containers.json} | 2 +- .../containers/id-out-of-range.nix} | 2 +- .../duplicate-ids.nix} | 2 +- .../firefox/profiles/search/default.nix | 112 +++++++++ .../expected-search-without-default.json} | 0 .../search/expected-search.json} | 0 .../firefox/profiles/settings/default.nix | 43 ++++ .../settings/expected-user.js} | 0 15 files changed, 285 insertions(+), 224 deletions(-) delete mode 100644 tests/modules/programs/firefox/profile-settings.nix create mode 100644 tests/modules/programs/firefox/profiles/bookmarks/default.nix rename tests/modules/programs/firefox/{profile-settings-expected-bookmarks-user.js => profiles/bookmarks/expected-bookmarks-user.js} (100%) rename tests/modules/programs/firefox/{profile-settings-expected-bookmarks.html => profiles/bookmarks/expected-bookmarks.html} (100%) create mode 100644 tests/modules/programs/firefox/profiles/containers/default.nix rename tests/modules/programs/firefox/{duplicate-container-ids.nix => profiles/containers/duplicate-ids.nix} (90%) rename tests/modules/programs/firefox/{profile-settings-expected-containers.json => profiles/containers/expected-containers.json} (66%) rename tests/modules/programs/firefox/{container-id-out-of-range.nix => profiles/containers/id-out-of-range.nix} (86%) rename tests/modules/programs/firefox/{duplicate-profile-ids.nix => profiles/duplicate-ids.nix} (87%) create mode 100644 tests/modules/programs/firefox/profiles/search/default.nix rename tests/modules/programs/firefox/{profile-settings-expected-search-without-default.json => profiles/search/expected-search-without-default.json} (100%) rename tests/modules/programs/firefox/{profile-settings-expected-search.json => profiles/search/expected-search.json} (100%) create mode 100644 tests/modules/programs/firefox/profiles/settings/default.nix rename tests/modules/programs/firefox/{profile-settings-expected-user.js => profiles/settings/expected-user.js} (100%) diff --git a/tests/modules/programs/firefox/firefox.nix b/tests/modules/programs/firefox/firefox.nix index 6598d6ec2..6d92a5f49 100644 --- a/tests/modules/programs/firefox/firefox.nix +++ b/tests/modules/programs/firefox/firefox.nix @@ -1,11 +1,16 @@ let name = "firefox"; in builtins.mapAttrs (test: module: import module [ "programs" name ]) { - "${name}-profile-settings" = ./profile-settings.nix; - "${name}-state-version-19_09" = ./state-version-19_09.nix; "${name}-deprecated-native-messenger" = ./deprecated-native-messenger.nix; - "${name}-duplicate-profile-ids" = ./duplicate-profile-ids.nix; - "${name}-duplicate-container-ids" = ./duplicate-container-ids.nix; - "${name}-container-id-out-of-range" = ./container-id-out-of-range.nix; "${name}-policies" = ./policies.nix; + "${name}-profiles-bookmarks" = ./profiles/bookmarks; + "${name}-profiles-containers" = ./profiles/containers; + "${name}-profiles-containers-duplicate-ids" = + ./profiles/containers/duplicate-ids.nix; + "${name}-profiles-containers-id-out-of-range" = + ./profiles/containers/id-out-of-range.nix; + "${name}-profiles-duplicate-ids" = ./profiles/duplicate-ids.nix; + "${name}-profiles-search" = ./profiles/search; + "${name}-profiles-settings" = ./profiles/settings; + "${name}-state-version-19_09" = ./state-version-19_09.nix; } diff --git a/tests/modules/programs/firefox/profile-settings.nix b/tests/modules/programs/firefox/profile-settings.nix deleted file mode 100644 index d7776eb4f..000000000 --- a/tests/modules/programs/firefox/profile-settings.nix +++ /dev/null @@ -1,215 +0,0 @@ -modulePath: -{ config, lib, pkgs, ... }: - -with lib; - -let - - cfg = getAttrFromPath modulePath config; - - firefoxMockOverlay = import ./setup-firefox-mock-overlay.nix modulePath; - -in { - imports = [ firefoxMockOverlay ]; - - config = mkIf config.test.enableBig (setAttrByPath modulePath { - enable = true; - profiles.basic.isDefault = true; - - profiles.test = { - id = 1; - settings = { - "general.smoothScroll" = false; - "browser.newtabpage.pinned" = [{ - title = "NixOS"; - url = "https://nixos.org"; - }]; - }; - }; - - profiles.bookmarks = { - id = 2; - settings = { "general.smoothScroll" = false; }; - bookmarks = [ - { - toolbar = true; - bookmarks = [{ - name = "Home Manager"; - url = "https://wiki.nixos.org/wiki/Home_Manager"; - }]; - } - { - name = "wikipedia"; - tags = [ "wiki" ]; - keyword = "wiki"; - url = "https://en.wikipedia.org/wiki/Special:Search?search=%s&go=Go"; - } - { - name = "kernel.org"; - url = "https://www.kernel.org"; - } - { - name = "Nix sites"; - bookmarks = [ - { - name = "homepage"; - url = "https://nixos.org/"; - } - { - name = "wiki"; - tags = [ "wiki" "nix" ]; - url = "https://wiki.nixos.org/"; - } - { - name = "Nix sites"; - bookmarks = [ - { - name = "homepage"; - url = "https://nixos.org/"; - } - { - name = "wiki"; - url = "https://wiki.nixos.org/"; - } - ]; - } - ]; - } - ]; - }; - - profiles.search = { - id = 3; - search = { - force = true; - default = "Google"; - privateDefault = "DuckDuckGo"; - order = [ "Nix Packages" "NixOS Wiki" ]; - engines = { - "Nix Packages" = { - urls = [{ - template = "https://search.nixos.org/packages"; - params = [ - { - name = "type"; - value = "packages"; - } - { - name = "query"; - value = "{searchTerms}"; - } - ]; - }]; - - icon = - "/run/current-system/sw/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; - - definedAliases = [ "@np" ]; - }; - - "NixOS Wiki" = { - urls = [{ - template = - "https://wiki.nixos.org/index.php?search={searchTerms}"; - }]; - iconUpdateURL = "https://wiki.nixos.org/favicon.png"; - updateInterval = 24 * 60 * 60 * 1000; - definedAliases = [ "@nw" ]; - }; - - "Bing".metaData.hidden = true; - "Google".metaData.alias = "@g"; - }; - }; - }; - - profiles.searchWithoutDefault = { - id = 4; - search = { - force = true; - order = [ "Google" "Nix Packages" ]; - engines = { - "Nix Packages" = { - urls = [{ - template = "https://search.nixos.org/packages"; - params = [ - { - name = "type"; - value = "packages"; - } - { - name = "query"; - value = "{searchTerms}"; - } - ]; - }]; - - definedAliases = [ "@np" ]; - }; - }; - }; - }; - - profiles.containers = { - id = 5; - containers = { - "shopping" = { - id = 6; - icon = "circle"; - color = "yellow"; - }; - }; - }; - } // { - - nmt.script = '' - assertFileRegex \ - home-path/bin/${cfg.wrappedPackageName} \ - MOZ_APP_LAUNCHER - - assertDirectoryExists home-files/${cfg.configPath}/basic - - assertFileContent \ - home-files/${cfg.configPath}/test/user.js \ - ${./profile-settings-expected-user.js} - - assertFileContent \ - home-files/${cfg.configPath}/containers/containers.json \ - ${./profile-settings-expected-containers.json} - - bookmarksUserJs=$(normalizeStorePaths \ - home-files/${cfg.configPath}/bookmarks/user.js) - - assertFileContent \ - $bookmarksUserJs \ - ${./profile-settings-expected-bookmarks-user.js} - - bookmarksFile="$(sed -n \ - '/browser.bookmarks.file/ {s|^.*\(/nix/store[^"]*\).*|\1|;p}' \ - $TESTED/home-files/${cfg.configPath}/bookmarks/user.js)" - - assertFileContent \ - $bookmarksFile \ - ${./profile-settings-expected-bookmarks.html} - - function assertFirefoxSearchContent() { - compressedSearch=$(normalizeStorePaths "$1") - - decompressedSearch=$(dirname $compressedSearch)/search.json - ${pkgs.mozlz4a}/bin/mozlz4a -d "$compressedSearch" >(${pkgs.jq}/bin/jq . > "$decompressedSearch") - - assertFileContent \ - $decompressedSearch \ - "$2" - } - - assertFirefoxSearchContent \ - home-files/${cfg.configPath}/search/search.json.mozlz4 \ - ${./profile-settings-expected-search.json} - - assertFirefoxSearchContent \ - home-files/${cfg.configPath}/searchWithoutDefault/search.json.mozlz4 \ - ${./profile-settings-expected-search-without-default.json} - ''; - }); -} diff --git a/tests/modules/programs/firefox/profiles/bookmarks/default.nix b/tests/modules/programs/firefox/profiles/bookmarks/default.nix new file mode 100644 index 000000000..7bf508ab0 --- /dev/null +++ b/tests/modules/programs/firefox/profiles/bookmarks/default.nix @@ -0,0 +1,84 @@ +modulePath: +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = getAttrFromPath modulePath config; + + firefoxMockOverlay = import ../../setup-firefox-mock-overlay.nix modulePath; + +in { + imports = [ firefoxMockOverlay ]; + + config = mkIf config.test.enableBig (setAttrByPath modulePath { + enable = true; + profiles.bookmarks = { + settings = { "general.smoothScroll" = false; }; + bookmarks = [ + { + toolbar = true; + bookmarks = [{ + name = "Home Manager"; + url = "https://wiki.nixos.org/wiki/Home_Manager"; + }]; + } + { + name = "wikipedia"; + tags = [ "wiki" ]; + keyword = "wiki"; + url = "https://en.wikipedia.org/wiki/Special:Search?search=%s&go=Go"; + } + { + name = "kernel.org"; + url = "https://www.kernel.org"; + } + { + name = "Nix sites"; + bookmarks = [ + { + name = "homepage"; + url = "https://nixos.org/"; + } + { + name = "wiki"; + tags = [ "wiki" "nix" ]; + url = "https://wiki.nixos.org/"; + } + { + name = "Nix sites"; + bookmarks = [ + { + name = "homepage"; + url = "https://nixos.org/"; + } + { + name = "wiki"; + url = "https://wiki.nixos.org/"; + } + ]; + } + ]; + } + ]; + }; + } // { + nmt.script = '' + bookmarksUserJs=$(normalizeStorePaths \ + home-files/${cfg.configPath}/bookmarks/user.js) + + assertFileContent \ + $bookmarksUserJs \ + ${./expected-bookmarks-user.js} + + bookmarksFile="$(sed -n \ + '/browser.bookmarks.file/ {s|^.*\(/nix/store[^"]*\).*|\1|;p}' \ + $TESTED/home-files/${cfg.configPath}/bookmarks/user.js)" + + assertFileContent \ + $bookmarksFile \ + ${./expected-bookmarks.html} + ''; + }); +} diff --git a/tests/modules/programs/firefox/profile-settings-expected-bookmarks-user.js b/tests/modules/programs/firefox/profiles/bookmarks/expected-bookmarks-user.js similarity index 100% rename from tests/modules/programs/firefox/profile-settings-expected-bookmarks-user.js rename to tests/modules/programs/firefox/profiles/bookmarks/expected-bookmarks-user.js diff --git a/tests/modules/programs/firefox/profile-settings-expected-bookmarks.html b/tests/modules/programs/firefox/profiles/bookmarks/expected-bookmarks.html similarity index 100% rename from tests/modules/programs/firefox/profile-settings-expected-bookmarks.html rename to tests/modules/programs/firefox/profiles/bookmarks/expected-bookmarks.html diff --git a/tests/modules/programs/firefox/profiles/containers/default.nix b/tests/modules/programs/firefox/profiles/containers/default.nix new file mode 100644 index 000000000..6a0d9e93f --- /dev/null +++ b/tests/modules/programs/firefox/profiles/containers/default.nix @@ -0,0 +1,32 @@ +modulePath: +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = getAttrFromPath modulePath config; + + firefoxMockOverlay = import ../../setup-firefox-mock-overlay.nix modulePath; + +in { + imports = [ firefoxMockOverlay ]; + + config = mkIf config.test.enableBig (setAttrByPath modulePath { + enable = true; + profiles.containers = { + containers = { + "shopping" = { + icon = "circle"; + color = "yellow"; + }; + }; + }; + } // { + nmt.script = '' + assertFileContent \ + home-files/${cfg.configPath}/containers/containers.json \ + ${./expected-containers.json} + ''; + }); +} diff --git a/tests/modules/programs/firefox/duplicate-container-ids.nix b/tests/modules/programs/firefox/profiles/containers/duplicate-ids.nix similarity index 90% rename from tests/modules/programs/firefox/duplicate-container-ids.nix rename to tests/modules/programs/firefox/profiles/containers/duplicate-ids.nix index 2ad99b4b7..a60522165 100644 --- a/tests/modules/programs/firefox/duplicate-container-ids.nix +++ b/tests/modules/programs/firefox/profiles/containers/duplicate-ids.nix @@ -7,7 +7,7 @@ let cfg = getAttrFromPath modulePath config; - firefoxMockOverlay = import ./setup-firefox-mock-overlay.nix modulePath; + firefoxMockOverlay = import ../../setup-firefox-mock-overlay.nix modulePath; in { imports = [ firefoxMockOverlay ]; diff --git a/tests/modules/programs/firefox/profile-settings-expected-containers.json b/tests/modules/programs/firefox/profiles/containers/expected-containers.json similarity index 66% rename from tests/modules/programs/firefox/profile-settings-expected-containers.json rename to tests/modules/programs/firefox/profiles/containers/expected-containers.json index 8eea55558..d957b0c50 100644 --- a/tests/modules/programs/firefox/profile-settings-expected-containers.json +++ b/tests/modules/programs/firefox/profiles/containers/expected-containers.json @@ -1 +1 @@ -{"identities":[{"color":"yellow","icon":"circle","name":"shopping","public":true,"userContextId":6},{"accessKey":"","color":"","icon":"","name":"userContextIdInternal.thumbnail","public":false,"userContextId":4294967294},{"accessKey":"","color":"","icon":"","name":"userContextIdInternal.webextStorageLocal","public":false,"userContextId":4294967295}],"lastUserContextId":6,"version":4} +{"identities":[{"color":"yellow","icon":"circle","name":"shopping","public":true,"userContextId":0},{"accessKey":"","color":"","icon":"","name":"userContextIdInternal.thumbnail","public":false,"userContextId":4294967294},{"accessKey":"","color":"","icon":"","name":"userContextIdInternal.webextStorageLocal","public":false,"userContextId":4294967295}],"lastUserContextId":0,"version":4} diff --git a/tests/modules/programs/firefox/container-id-out-of-range.nix b/tests/modules/programs/firefox/profiles/containers/id-out-of-range.nix similarity index 86% rename from tests/modules/programs/firefox/container-id-out-of-range.nix rename to tests/modules/programs/firefox/profiles/containers/id-out-of-range.nix index 2ea08e880..f39666723 100644 --- a/tests/modules/programs/firefox/container-id-out-of-range.nix +++ b/tests/modules/programs/firefox/profiles/containers/id-out-of-range.nix @@ -5,7 +5,7 @@ with lib; let - firefoxMockOverlay = import ./setup-firefox-mock-overlay.nix modulePath; + firefoxMockOverlay = import ../../setup-firefox-mock-overlay.nix modulePath; in { imports = [ firefoxMockOverlay ]; diff --git a/tests/modules/programs/firefox/duplicate-profile-ids.nix b/tests/modules/programs/firefox/profiles/duplicate-ids.nix similarity index 87% rename from tests/modules/programs/firefox/duplicate-profile-ids.nix rename to tests/modules/programs/firefox/profiles/duplicate-ids.nix index ad946af10..dc5557b47 100644 --- a/tests/modules/programs/firefox/duplicate-profile-ids.nix +++ b/tests/modules/programs/firefox/profiles/duplicate-ids.nix @@ -7,7 +7,7 @@ let cfg = getAttrFromPath modulePath config; - firefoxMockOverlay = import ./setup-firefox-mock-overlay.nix modulePath; + firefoxMockOverlay = import ../setup-firefox-mock-overlay.nix modulePath; in { imports = [ firefoxMockOverlay ]; diff --git a/tests/modules/programs/firefox/profiles/search/default.nix b/tests/modules/programs/firefox/profiles/search/default.nix new file mode 100644 index 000000000..8a4c98e9b --- /dev/null +++ b/tests/modules/programs/firefox/profiles/search/default.nix @@ -0,0 +1,112 @@ +modulePath: +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = getAttrFromPath modulePath config; + + firefoxMockOverlay = import ../../setup-firefox-mock-overlay.nix modulePath; + +in { + imports = [ firefoxMockOverlay ]; + + config = mkIf config.test.enableBig (setAttrByPath modulePath { + enable = true; + profiles = { + search = { + id = 0; + search = { + force = true; + default = "Google"; + privateDefault = "DuckDuckGo"; + order = [ "Nix Packages" "NixOS Wiki" ]; + engines = { + "Nix Packages" = { + urls = [{ + template = "https://search.nixos.org/packages"; + params = [ + { + name = "type"; + value = "packages"; + } + { + name = "query"; + value = "{searchTerms}"; + } + ]; + }]; + + icon = + "/run/current-system/sw/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; + + definedAliases = [ "@np" ]; + }; + + "NixOS Wiki" = { + urls = [{ + template = + "https://wiki.nixos.org/index.php?search={searchTerms}"; + }]; + iconUpdateURL = "https://wiki.nixos.org/favicon.png"; + updateInterval = 24 * 60 * 60 * 1000; + definedAliases = [ "@nw" ]; + }; + + "Bing".metaData.hidden = true; + "Google".metaData.alias = "@g"; + }; + }; + }; + + searchWithoutDefault = { + id = 1; + search = { + force = true; + order = [ "Google" "Nix Packages" ]; + engines = { + "Nix Packages" = { + urls = [{ + template = "https://search.nixos.org/packages"; + params = [ + { + name = "type"; + value = "packages"; + } + { + name = "query"; + value = "{searchTerms}"; + } + ]; + }]; + + definedAliases = [ "@np" ]; + }; + }; + }; + }; + }; + } // { + nmt.script = '' + function assertFirefoxSearchContent() { + compressedSearch=$(normalizeStorePaths "$1") + + decompressedSearch=$(dirname $compressedSearch)/search.json + ${pkgs.mozlz4a}/bin/mozlz4a -d "$compressedSearch" >(${pkgs.jq}/bin/jq . > "$decompressedSearch") + + assertFileContent \ + $decompressedSearch \ + "$2" + } + + assertFirefoxSearchContent \ + home-files/${cfg.configPath}/search/search.json.mozlz4 \ + ${./expected-search.json} + + assertFirefoxSearchContent \ + home-files/${cfg.configPath}/searchWithoutDefault/search.json.mozlz4 \ + ${./expected-search-without-default.json} + ''; + }); +} diff --git a/tests/modules/programs/firefox/profile-settings-expected-search-without-default.json b/tests/modules/programs/firefox/profiles/search/expected-search-without-default.json similarity index 100% rename from tests/modules/programs/firefox/profile-settings-expected-search-without-default.json rename to tests/modules/programs/firefox/profiles/search/expected-search-without-default.json diff --git a/tests/modules/programs/firefox/profile-settings-expected-search.json b/tests/modules/programs/firefox/profiles/search/expected-search.json similarity index 100% rename from tests/modules/programs/firefox/profile-settings-expected-search.json rename to tests/modules/programs/firefox/profiles/search/expected-search.json diff --git a/tests/modules/programs/firefox/profiles/settings/default.nix b/tests/modules/programs/firefox/profiles/settings/default.nix new file mode 100644 index 000000000..39d329ece --- /dev/null +++ b/tests/modules/programs/firefox/profiles/settings/default.nix @@ -0,0 +1,43 @@ +modulePath: +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = getAttrFromPath modulePath config; + + firefoxMockOverlay = import ../../setup-firefox-mock-overlay.nix modulePath; + +in { + imports = [ firefoxMockOverlay ]; + + config = mkIf config.test.enableBig (setAttrByPath modulePath { + enable = true; + profiles = { + basic.isDefault = true; + test = { + id = 1; + settings = { + "general.smoothScroll" = false; + "browser.newtabpage.pinned" = [{ + title = "NixOS"; + url = "https://nixos.org"; + }]; + }; + }; + }; + } // { + nmt.script = '' + assertFileRegex \ + home-path/bin/${cfg.wrappedPackageName} \ + MOZ_APP_LAUNCHER + + assertDirectoryExists home-files/${cfg.configPath}/basic + + assertFileContent \ + home-files/${cfg.configPath}/test/user.js \ + ${./expected-user.js} + ''; + }); +} diff --git a/tests/modules/programs/firefox/profile-settings-expected-user.js b/tests/modules/programs/firefox/profiles/settings/expected-user.js similarity index 100% rename from tests/modules/programs/firefox/profile-settings-expected-user.js rename to tests/modules/programs/firefox/profiles/settings/expected-user.js From 038630363e7de57c36c417fd2f5d7c14773403e4 Mon Sep 17 00:00:00 2001 From: Timothy Gallion Date: Mon, 7 Oct 2024 17:39:24 -0400 Subject: [PATCH 005/546] xdg-mime type package options (#5920) * xdg-mime: allow overrides to shared-mime-info and desktop-file-utils The `xdg-mime` module now exposes packages to determine what will be run for update-mime-database and update-desktop-database. This allows users to select a different version of these packages if the are incompatible. This should, in combination with an override to the version of `shared-mime-info` (can be found here notalltim/home-manager-config#4), resolve #4955, #5102, #4682, and possibly #4941. The problem seems to stem from a mismatch in the version of `shared-mime-info` with the host. I also switched from using `buildPackages` to `pkgs` to improve cross-compilation compatibility. * xdg-mime: Add tests for xdg-mime module The xdg-mime module was missing tests so I added basic test for all the options and checked the basic behavior. It covers ensuring that the proper files/folders are created and that the package overrides work. --- modules/misc/xdg-mime.nix | 55 ++++++++++++++-------- tests/modules/misc/xdg/default.nix | 3 ++ tests/modules/misc/xdg/mime-disabled.nix | 10 ++++ tests/modules/misc/xdg/mime-expected.cache | 3 ++ tests/modules/misc/xdg/mime-packages.nix | 38 +++++++++++++++ tests/modules/misc/xdg/mime.nix | 24 ++++++++++ 6 files changed, 114 insertions(+), 19 deletions(-) create mode 100644 tests/modules/misc/xdg/mime-disabled.nix create mode 100644 tests/modules/misc/xdg/mime-expected.cache create mode 100644 tests/modules/misc/xdg/mime-packages.nix create mode 100644 tests/modules/misc/xdg/mime.nix diff --git a/modules/misc/xdg-mime.nix b/modules/misc/xdg-mime.nix index 09f62aaff..78b569fa5 100644 --- a/modules/misc/xdg-mime.nix +++ b/modules/misc/xdg-mime.nix @@ -5,33 +5,50 @@ with lib; let cfg = config.xdg.mime; + inherit (lib) getExe getExe'; in { options = { - xdg.mime.enable = mkOption { - type = types.bool; - default = pkgs.stdenv.hostPlatform.isLinux; - defaultText = - literalExpression "true if host platform is Linux, false otherwise"; - description = '' - Whether to install programs and files to support the - XDG Shared MIME-info specification and XDG MIME Applications - specification at - - and - , - respectively. - ''; + xdg.mime = { + enable = mkOption { + type = types.bool; + default = pkgs.stdenv.hostPlatform.isLinux; + defaultText = + literalExpression "true if host platform is Linux, false otherwise"; + description = '' + Whether to install programs and files to support the + XDG Shared MIME-info specification and XDG MIME Applications + specification at + + and + , + respectively. + ''; + }; + + sharedMimeInfoPackage = mkOption { + type = types.package; + default = pkgs.shared-mime-info; + defaultText = literalExpression "pkgs.shared-mime-info"; + description = "The package to use when running update-mime-database."; + }; + + desktopFileUtilsPackage = mkOption { + type = types.package; + default = pkgs.desktop-file-utils; + defaultText = literalExpression "pkgs.desktop-file-utils"; + description = + "The package to use when running update-desktop-database."; + }; }; }; - - config = mkIf config.xdg.mime.enable { + config = mkIf cfg.enable { assertions = [ (hm.assertions.assertPlatform "xdg.mime" pkgs platforms.linux) ]; home.packages = [ # Explicitly install package to provide basic mime types. - pkgs.shared-mime-info + cfg.sharedMimeInfoPackage # Make sure the target directories will be real directories. (pkgs.runCommandLocal "dummy-xdg-mime-dirs1" { } '' @@ -46,12 +63,12 @@ in { if [[ -w $out/share/mime && -w $out/share/mime/packages && -d $out/share/mime/packages ]]; then XDG_DATA_DIRS=$out/share \ PKGSYSTEM_ENABLE_FSYNC=0 \ - ${pkgs.buildPackages.shared-mime-info}/bin/update-mime-database \ + ${getExe cfg.sharedMimeInfoPackage} \ -V $out/share/mime > /dev/null fi if [[ -w $out/share/applications ]]; then - ${pkgs.buildPackages.desktop-file-utils}/bin/update-desktop-database \ + ${getExe' cfg.desktopFileUtilsPackage "update-desktop-database"} \ $out/share/applications fi ''; diff --git a/tests/modules/misc/xdg/default.nix b/tests/modules/misc/xdg/default.nix index bc2f9a9df..87f74e22f 100644 --- a/tests/modules/misc/xdg/default.nix +++ b/tests/modules/misc/xdg/default.nix @@ -6,4 +6,7 @@ xdg-default-locations = ./default-locations.nix; xdg-user-dirs-null = ./user-dirs-null.nix; xdg-portal = ./portal.nix; + xdg-mime = ./mime.nix; + xdg-mime-disabled = ./mime-disabled.nix; + xdg-mime-package = ./mime-packages.nix; } diff --git a/tests/modules/misc/xdg/mime-disabled.nix b/tests/modules/misc/xdg/mime-disabled.nix new file mode 100644 index 000000000..a3df63091 --- /dev/null +++ b/tests/modules/misc/xdg/mime-disabled.nix @@ -0,0 +1,10 @@ +{ ... }: { + config = { + xdg.mime.enable = false; + nmt.script = '' + # assert that neither application is run + assertPathNotExists home-path/share/applications/mimeinfo.cache + assertPathNotExists home-path/share/applications/mime + ''; + }; +} diff --git a/tests/modules/misc/xdg/mime-expected.cache b/tests/modules/misc/xdg/mime-expected.cache new file mode 100644 index 000000000..6907f8f88 --- /dev/null +++ b/tests/modules/misc/xdg/mime-expected.cache @@ -0,0 +1,3 @@ +[MIME Cache] +text/html=mime-test.desktop; +text/xml=mime-test.desktop; diff --git a/tests/modules/misc/xdg/mime-packages.nix b/tests/modules/misc/xdg/mime-packages.nix new file mode 100644 index 000000000..0eaaddcec --- /dev/null +++ b/tests/modules/misc/xdg/mime-packages.nix @@ -0,0 +1,38 @@ +{ config, ... }: +let inherit (config.lib.test) mkStubPackage; +in { + config = { + xdg.mime.enable = true; + xdg.mime.sharedMimeInfoPackage = mkStubPackage { + name = "update-mime-database"; + buildScript = '' + mkdir -p $out/bin + echo '#!/bin/sh' > $out/bin/update-mime-database + echo 'mkdir -p $out/share/mime && touch $out/share/mime/mime.cache' >> $out/bin/update-mime-database + chmod +x $out/bin/update-mime-database + ''; + }; + xdg.mime.desktopFileUtilsPackage = mkStubPackage { + name = "desktop-file-utils"; + buildScript = '' + mkdir -p $out/bin + echo '#!/bin/sh' > $out/bin/update-desktop-database + echo 'mkdir -p $out/share/applications/ && ln -s ${ + ./mime-expected.cache + } $out/share/applications/mimeinfo.cache' >> $out/bin/update-desktop-database + chmod +x $out/bin/update-desktop-database + ''; + }; + nmt.script = '' + assertFileExists home-path/share/applications/mimeinfo.cache # Check that update-desktop-database created file + # Check that update-desktop-database file matches expected + assertFileContent \ + home-path/share/applications/mimeinfo.cache \ + ${./mime-expected.cache} + + assertDirectoryExists home-path/share/mime # Check that update-mime-database created directory + assertFileExists home-path/share/mime/mime.cache # Check that update-mime-database created file + + ''; + }; +} diff --git a/tests/modules/misc/xdg/mime.nix b/tests/modules/misc/xdg/mime.nix new file mode 100644 index 000000000..90d21d567 --- /dev/null +++ b/tests/modules/misc/xdg/mime.nix @@ -0,0 +1,24 @@ +{ ... }: { + config = { + xdg.mime.enable = true; + xdg.desktopEntries = { + mime-test = { # mime info test + name = "mime-test"; + mimeType = [ "text/html" "text/xml" ]; + }; + + }; + + nmt.script = '' + assertFileExists home-path/share/applications/mimeinfo.cache # Check that update-desktop-database created file + # Check that update-desktop-database file matches expected + assertFileContent \ + home-path/share/applications/mimeinfo.cache \ + ${./mime-expected.cache} + + assertDirectoryExists home-path/share/mime # Check that update-mime-database created directory + assertDirectoryNotEmpty home-path/share/mime # Check that update-mime-database created files + + ''; + }; +} From d3ee25c07848725e924a74a4813de2ad0f5d0878 Mon Sep 17 00:00:00 2001 From: Utkarsh Sharma Date: Wed, 9 Oct 2024 16:31:58 +0200 Subject: [PATCH 006/546] Translate using Weblate (Hindi) Currently translated at 5.5% (1 of 18 strings) Translate using Weblate (Hindi) Currently translated at 13.5% (5 of 37 strings) Co-authored-by: Utkarsh Sharma Translate-URL: https://hosted.weblate.org/projects/home-manager/cli/hi/ Translate-URL: https://hosted.weblate.org/projects/home-manager/modules/hi/ Translation: Home Manager/Home Manager CLI Translation: Home Manager/Home Manager Modules --- home-manager/po/hi.po | 8 ++++---- modules/po/hi.po | 11 +++++++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/home-manager/po/hi.po b/home-manager/po/hi.po index 43d873123..3921eff11 100644 --- a/home-manager/po/hi.po +++ b/home-manager/po/hi.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: Home Manager\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" "POT-Creation-Date: 2024-04-17 23:19+0200\n" -"PO-Revision-Date: 2024-09-13 03:09+0000\n" -"Last-Translator: Jay Thomas \n" +"PO-Revision-Date: 2024-10-09 14:31+0000\n" +"Last-Translator: Utkarsh Sharma \n" "Language-Team: Hindi \n" "Language: hi\n" @@ -22,11 +22,11 @@ msgstr "" #. translators: For example: "home-manager: missing argument for --cores" #: home-manager/home-manager:16 msgid "%s: missing argument for %s" -msgstr "" +msgstr "%s: ‌%s के लिए कोई आर्ग्यूमेंट नहीं दिया" #: home-manager/home-manager:64 msgid "No configuration file found at %s" -msgstr "" +msgstr "%s में कोई कन्फि़गरेशन फाइल नहीं मिली" #. translators: The first '%s' specifier will be replaced by either #. 'home.nix' or 'flake.nix'. diff --git a/modules/po/hi.po b/modules/po/hi.po index 02a7f8528..80781aba5 100644 --- a/modules/po/hi.po +++ b/modules/po/hi.po @@ -8,13 +8,16 @@ msgstr "" "Project-Id-Version: Home Manager Modules\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" "POT-Creation-Date: 2024-04-17 23:19+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"PO-Revision-Date: 2024-10-09 14:31+0000\n" +"Last-Translator: Utkarsh Sharma \n" +"Language-Team: Hindi \n" "Language: hi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 5.8-dev\n" #: modules/files.nix:191 msgid "Creating home file links in %s" @@ -22,7 +25,7 @@ msgstr "" #: modules/files.nix:204 msgid "Cleaning up orphan links from %s" -msgstr "" +msgstr "%s से ऑर्फे़न लिंक्स मिटाई जा रही है" #: modules/files.nix:220 msgid "Creating profile generation %s" From d47d33254fbf4fdbdee9f1f14095f689662e479d Mon Sep 17 00:00:00 2001 From: Sandro Date: Thu, 10 Oct 2024 20:29:24 +0200 Subject: [PATCH 007/546] home-manager-manual: expose options.json --- docs/home-manager-manual.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/home-manager-manual.nix b/docs/home-manager-manual.nix index 23b2d1e65..f87803962 100644 --- a/docs/home-manager-manual.nix +++ b/docs/home-manager-manual.nix @@ -59,5 +59,7 @@ in stdenv.mkDerivation { echo "doc manual $dest index.html" >> $out/nix-support/hydra-build-products ''; + passthru = { inherit home-manager-options; }; + meta = { maintainers = [ lib.maintainers.considerate ]; }; } From 8bb5d53c5847d9a9b2ad1bda49f9aa9df0de282a Mon Sep 17 00:00:00 2001 From: Andrew Voynov <37143421+Andrew15-5@users.noreply.github.com> Date: Thu, 10 Oct 2024 22:22:52 +0300 Subject: [PATCH 008/546] docs: add XDG_*_HOME mentions to xdg.*Home options --- modules/misc/xdg.nix | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/modules/misc/xdg.nix b/modules/misc/xdg.nix index a47a33f56..b916e88fb 100644 --- a/modules/misc/xdg.nix +++ b/modules/misc/xdg.nix @@ -30,6 +30,8 @@ in { apply = toString; description = '' Absolute path to directory holding application caches. + + Sets `XDG_CACHE_HOME` for the user if `xdg.enable` is set `true`. ''; }; @@ -48,6 +50,8 @@ in { apply = toString; description = '' Absolute path to directory holding application configurations. + + Sets `XDG_CONFIG_HOME` for the user if `xdg.enable` is set `true`. ''; }; @@ -67,6 +71,8 @@ in { apply = toString; description = '' Absolute path to directory holding application data. + + Sets `XDG_DATA_HOME` for the user if `xdg.enable` is set `true`. ''; }; @@ -86,6 +92,8 @@ in { apply = toString; description = '' Absolute path to directory holding application states. + + Sets `XDG_STATE_HOME` for the user if `xdg.enable` is set `true`. ''; }; }; From 03f8e0b3b3ca4f49d11bf0264dbff465d6ae9aae Mon Sep 17 00:00:00 2001 From: Damien Cassou Date: Fri, 11 Oct 2024 00:14:36 +0200 Subject: [PATCH 009/546] snixembed: add module This is used by SafeEyes (another home-manager) module to show a systemtray icon. See https://git.sr.ht/~steef/snixembed. Fixes #5728 --- modules/misc/news.nix | 12 +++++ modules/modules.nix | 1 + modules/services/snixembed.nix | 50 +++++++++++++++++++ tests/default.nix | 1 + .../snixembed/basic-configuration.desktop | 7 +++ .../snixembed/basic-configuration.nix | 16 ++++++ .../snixembed/basic-configuration.service | 14 ++++++ tests/modules/services/snixembed/default.nix | 1 + 8 files changed, 102 insertions(+) create mode 100644 modules/services/snixembed.nix create mode 100644 tests/modules/services/snixembed/basic-configuration.desktop create mode 100644 tests/modules/services/snixembed/basic-configuration.nix create mode 100644 tests/modules/services/snixembed/basic-configuration.service create mode 100644 tests/modules/services/snixembed/default.nix diff --git a/modules/misc/news.nix b/modules/misc/news.nix index f8786de2f..abd9957cb 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -1748,6 +1748,18 @@ in { add `-w` to your assignment of `services.swayidle.extraArgs`. ''; } + + { + time = "2024-10-09T06:16:23+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'services.snixembed'. + + snixembed proxies StatusNotifierItems as XEmbedded systemtray-spec + icons. This is useful for some tools in some environments, e.g., Safe + Eyes in i3, lxde or mate. + ''; + } ]; }; } diff --git a/modules/modules.nix b/modules/modules.nix index ed2e177f2..c69c66b15 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -361,6 +361,7 @@ let ./services/screen-locker.nix ./services/sctd.nix ./services/signaturepdf.nix + ./services/snixembed.nix ./services/spotifyd.nix ./services/ssh-agent.nix ./services/stalonetray.nix diff --git a/modules/services/snixembed.nix b/modules/services/snixembed.nix new file mode 100644 index 000000000..a470836b0 --- /dev/null +++ b/modules/services/snixembed.nix @@ -0,0 +1,50 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let cfg = config.services.snixembed; +in { + meta.maintainers = [ maintainers.DamienCassou ]; + + options = { + services.snixembed = { + enable = mkEnableOption + "snixembed: proxy StatusNotifierItems as XEmbedded systemtray-spec icons"; + + package = mkPackageOption pkgs "snixembed" { }; + + beforeUnits = mkOption { + type = with types; listOf str; + default = [ ]; + example = [ "safeeyes.service" ]; + description = '' + List of other units that should be started after snixembed. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + assertions = [ + (hm.assertions.assertPlatform "services.snixembed" pkgs platforms.linux) + ]; + + systemd.user.services.snixembed = { + Install.WantedBy = [ "graphical-session.target" ]; + + Unit = { + Description = "snixembed"; + PartOf = [ "graphical-session.target" ]; + StartLimitIntervalSec = 100; + StartLimitBurst = 10; + Before = cfg.beforeUnits; + }; + + Service = { + ExecStart = getExe pkgs.snixembed; + Restart = "on-failure"; + RestartSec = 3; + }; + }; + }; +} diff --git a/tests/default.nix b/tests/default.nix index 4117ea8ea..4cc705b18 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -270,6 +270,7 @@ in import nmtSrc { ./modules/services/remmina ./modules/services/screen-locker ./modules/services/signaturepdf + ./modules/services/snixembed ./modules/services/swayidle ./modules/services/swaync ./modules/services/swayosd diff --git a/tests/modules/services/snixembed/basic-configuration.desktop b/tests/modules/services/snixembed/basic-configuration.desktop new file mode 100644 index 000000000..a606d8f2f --- /dev/null +++ b/tests/modules/services/snixembed/basic-configuration.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Exec=@xdg-utils@/bin/xdg-open http://localhost:9494 +Icon=/snixembed/share/snixembed/public/favicon.ico +Name=Snixembed +Terminal=false +Type=Application +Version=1.4 diff --git a/tests/modules/services/snixembed/basic-configuration.nix b/tests/modules/services/snixembed/basic-configuration.nix new file mode 100644 index 000000000..fd8ec4701 --- /dev/null +++ b/tests/modules/services/snixembed/basic-configuration.nix @@ -0,0 +1,16 @@ +{ ... }: + +{ + services.snixembed = { + enable = true; + beforeUnits = [ "safeeyes.service" ]; + }; + + test.stubs = { snixembed = { outPath = "/snixembed"; }; }; + + nmt.script = '' + assertFileContent \ + home-files/.config/systemd/user/snixembed.service \ + ${./basic-configuration.service} + ''; +} diff --git a/tests/modules/services/snixembed/basic-configuration.service b/tests/modules/services/snixembed/basic-configuration.service new file mode 100644 index 000000000..97e87664b --- /dev/null +++ b/tests/modules/services/snixembed/basic-configuration.service @@ -0,0 +1,14 @@ +[Install] +WantedBy=graphical-session.target + +[Service] +ExecStart=/snixembed/bin/dummy +Restart=on-failure +RestartSec=3 + +[Unit] +Before=safeeyes.service +Description=snixembed +PartOf=graphical-session.target +StartLimitBurst=10 +StartLimitIntervalSec=100 diff --git a/tests/modules/services/snixembed/default.nix b/tests/modules/services/snixembed/default.nix new file mode 100644 index 000000000..b49917197 --- /dev/null +++ b/tests/modules/services/snixembed/default.nix @@ -0,0 +1 @@ +{ snixembed-basic-configuration = ./basic-configuration.nix; } From 342a1d682386d3a1d74f9555cb327f2f311dda6e Mon Sep 17 00:00:00 2001 From: home-manager-bot <106474382+home-manager-bot@users.noreply.github.com> Date: Fri, 11 Oct 2024 00:19:04 +0200 Subject: [PATCH 010/546] flake.lock: Update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flake lock file updates: • Updated input 'nixpkgs': 'github:NixOS/nixpkgs/9357f4f23713673f310988025d9dc261c20e70c6?narHash=sha256-bvGoiQBvponpZh8ClUcmJ6QnsNKw0EMrCQJARK3bI1c%3D' (2024-09-21) → 'github:NixOS/nixpkgs/c31898adf5a8ed202ce5bea9f347b1c6871f32d1?narHash=sha256-yumd4fBc/hi8a9QgA9IT8vlQuLZ2oqhkJXHPKxH/tRw%3D' (2024-10-06) Co-authored-by: github-actions[bot] --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 557a2e855..76920c875 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1726937504, - "narHash": "sha256-bvGoiQBvponpZh8ClUcmJ6QnsNKw0EMrCQJARK3bI1c=", + "lastModified": 1728241625, + "narHash": "sha256-yumd4fBc/hi8a9QgA9IT8vlQuLZ2oqhkJXHPKxH/tRw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "9357f4f23713673f310988025d9dc261c20e70c6", + "rev": "c31898adf5a8ed202ce5bea9f347b1c6871f32d1", "type": "github" }, "original": { From 582830954264080aae93f751c3cdc58df600d2d1 Mon Sep 17 00:00:00 2001 From: aabccd021 Date: Fri, 9 Sep 2022 07:42:53 +0700 Subject: [PATCH 011/546] vifm: add module --- modules/lib/maintainers.nix | 6 ++++ modules/misc/news.nix | 10 ++++++ modules/modules.nix | 3 +- modules/programs/vifm.nix | 33 +++++++++++++++++++ tests/default.nix | 1 + tests/modules/programs/vifm/default.nix | 4 +++ .../modules/programs/vifm/empty-settings.nix | 11 +++++++ .../programs/vifm/example-settings.nix | 21 ++++++++++++ 8 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 modules/programs/vifm.nix create mode 100644 tests/modules/programs/vifm/default.nix create mode 100644 tests/modules/programs/vifm/empty-settings.nix create mode 100644 tests/modules/programs/vifm/example-settings.nix diff --git a/modules/lib/maintainers.nix b/modules/lib/maintainers.nix index 70f480d06..501917ffb 100644 --- a/modules/lib/maintainers.nix +++ b/modules/lib/maintainers.nix @@ -7,6 +7,12 @@ # [1] https://github.com/NixOS/nixpkgs/blob/fca0d6e093c82b31103dc0dacc48da2a9b06e24b/maintainers/maintainer-list.nix#LC1 { + aabccd021 = { + name = "Muhamad Abdurahman"; + email = "aabccd021@gmail.com"; + github = "aabccd021"; + githubId = 33031950; + }; abayomi185 = { name = "Yomi"; email = "yomi+nix@yomitosh.com"; diff --git a/modules/misc/news.nix b/modules/misc/news.nix index abd9957cb..732c92478 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -1760,6 +1760,16 @@ in { Eyes in i3, lxde or mate. ''; } + + { + time = "2024-10-11T08:23:19+00:00"; + message = '' + A new module is available: 'programs.vifm'. + + Vifm is a curses based Vim-like file manager extended with some useful + ideas from mutt. + ''; + } ]; }; } diff --git a/modules/modules.nix b/modules/modules.nix index c69c66b15..72f4adaae 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -241,8 +241,9 @@ let ./programs/translate-shell.nix ./programs/urxvt.nix ./programs/vdirsyncer.nix - ./programs/vim.nix + ./programs/vifm.nix ./programs/vim-vint.nix + ./programs/vim.nix ./programs/vscode.nix ./programs/vscode/haskell.nix ./programs/pywal.nix diff --git a/modules/programs/vifm.nix b/modules/programs/vifm.nix new file mode 100644 index 000000000..2bf31d52d --- /dev/null +++ b/modules/programs/vifm.nix @@ -0,0 +1,33 @@ +{ config, lib, pkgs, ... }: + +let + + inherit (lib) mkIf mkOption types; + + cfg = config.programs.vifm; + +in { + meta.maintainers = [ lib.hm.maintainers.aabccd021 ]; + + options.programs.vifm = { + enable = lib.mkEnableOption "vifm, a Vim-like file manager"; + + package = lib.mkPackageOption pkgs "vifm" { }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + example = "mark h ~/"; + description = '' + Extra lines added to the {file}`$XDG_CONFIG_HOME/vifm/vifmrc` file. + ''; + }; + }; + + config = mkIf cfg.enable { + home.packages = [ cfg.package ]; + + xdg.configFile."vifm/vifmrc" = + mkIf (cfg.extraConfig != "") { text = cfg.extraConfig; }; + }; +} diff --git a/tests/default.nix b/tests/default.nix index 4cc705b18..83ed42a70 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -155,6 +155,7 @@ in import nmtSrc { ./modules/programs/tmux ./modules/programs/topgrade ./modules/programs/translate-shell + ./modules/programs/vifm ./modules/programs/vim-vint ./modules/programs/vscode ./modules/programs/watson diff --git a/tests/modules/programs/vifm/default.nix b/tests/modules/programs/vifm/default.nix new file mode 100644 index 000000000..5a75a54aa --- /dev/null +++ b/tests/modules/programs/vifm/default.nix @@ -0,0 +1,4 @@ +{ + vifm-example-settings = ./example-settings.nix; + vifm-empty-settings = ./empty-settings.nix; +} diff --git a/tests/modules/programs/vifm/empty-settings.nix b/tests/modules/programs/vifm/empty-settings.nix new file mode 100644 index 000000000..4e1df9c18 --- /dev/null +++ b/tests/modules/programs/vifm/empty-settings.nix @@ -0,0 +1,11 @@ +{ ... }: + +{ + programs.vifm.enable = true; + + test.stubs.vifm = { }; + + nmt.script = '' + assertPathNotExists home-files/.config/vifm + ''; +} diff --git a/tests/modules/programs/vifm/example-settings.nix b/tests/modules/programs/vifm/example-settings.nix new file mode 100644 index 000000000..8f562aa62 --- /dev/null +++ b/tests/modules/programs/vifm/example-settings.nix @@ -0,0 +1,21 @@ +{ config, ... }: + +{ + programs.vifm = { + enable = true; + package = config.lib.test.mkStubPackage { }; + extraConfig = '' + mark h ~/ + ''; + }; + + nmt.script = '' + assertFileContent \ + home-files/.config/vifm/vifmrc \ + ${ + builtins.toFile "vifm-expected.conf" '' + mark h ~/ + '' + } + ''; +} From 65ae9c147349829d3df0222151f53f79821c5134 Mon Sep 17 00:00:00 2001 From: Perchun Pak Date: Fri, 11 Oct 2024 14:48:52 +0200 Subject: [PATCH 012/546] git: add module for `git maintenance` (#5772) Adds module for git-scm.com/docs/git-maintenance. --- modules/programs/git.nix | 77 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/modules/programs/git.nix b/modules/programs/git.nix index 07d01ab9d..dfdac2d4b 100644 --- a/modules/programs/git.nix +++ b/modules/programs/git.nix @@ -214,6 +214,41 @@ in { }; }; + maintenance = { + enable = mkEnableOption "" // { + description = '' + Enable the automatic {command}`git maintenance`. + + See . + ''; + }; + + repositories = mkOption { + type = with types; listOf str; + default = [ ]; + description = '' + Repositories on which {command}`git maintenance` should run. + + Should be a list of absolute paths. + ''; + }; + + timers = mkOption { + type = types.attrsOf types.str; + default = { + hourly = "*-*-* 1..23:53:00"; + daily = "Tue..Sun *-*-* 0:53:00"; + weekly = "Mon 0:53:00"; + }; + description = '' + Systemd timers to create for scheduled {command}`git maintenance`. + + Key is passed to `--schedule` argument in {command}`git maintenance run` + and value is passed to `Timer.OnCalendar` in `systemd.user.timers`. + ''; + }; + }; + diff-highlight = { enable = mkEnableOption "" // { description = '' @@ -501,6 +536,48 @@ in { }; }) + (mkIf cfg.maintenance.enable { + programs.git.iniContent.maintenance.repo = cfg.maintenance.repositories; + + systemd.user.services."git-maintenance@" = { + Unit = { + Description = "Optimize Git repositories data"; + Documentation = [ "man:git-maintenance(1)" ]; + }; + + Service = { + Type = "oneshot"; + ExecStart = let exe = lib.getExe cfg.package; + in '' + "${exe}" --exec-path="${exe}" for-each-repo --config=maintenance.repo maintenance run --schedule=%i + ''; + LockPersonality = "yes"; + MemoryDenyWriteExecute = "yes"; + NoNewPrivileges = "yes"; + RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6 AF_VSOCK"; + RestrictNamespaces = "yes"; + RestrictRealtime = "yes"; + RestrictSUIDSGID = "yes"; + SystemCallArchitectures = "native"; + SystemCallFilter = "@system-service"; + }; + }; + + systemd.user.timers = let + toSystemdTimer = name: time: + lib.attrsets.nameValuePair "git-maintenance@${name}" { + Unit.Description = "Optimize Git repositories data"; + + Timer = { + OnCalendar = time; + Persistent = true; + }; + + Install.WantedBy = [ "timers.target" ]; + }; + in lib.attrsets.mapAttrs' toSystemdTimer cfg.maintenance.timers; + }) + (mkIf cfg.diff-highlight.enable { programs.git.iniContent = let dhCommand = From 2b13611eaed8326789f76f70d21d06fbb14e3e47 Mon Sep 17 00:00:00 2001 From: Kilian Mio <86004375+Mikilio@users.noreply.github.com> Date: Sat, 12 Oct 2024 00:21:33 +0200 Subject: [PATCH 013/546] floorp: add module Also fix tests for Firefox module derivatives. --- modules/modules.nix | 1 + modules/programs/floorp.nix | 29 +++ tests/default.nix | 1 + tests/modules/programs/firefox/common.nix | 15 ++ tests/modules/programs/firefox/firefox.nix | 17 +- tests/modules/programs/firefox/floorp.nix | 1 + tests/modules/programs/firefox/policies.nix | 4 +- .../programs/firefox/profile-settings.nix | 241 ++++++++++++++++++ .../firefox/profiles/bookmarks/default.nix | 8 +- .../bookmarks/expected-bookmarks-user.js | 2 +- .../firefox/profiles/search/default.nix | 34 ++- .../expected-search-without-default.json | 2 +- .../profiles/search/expected-search.json | 8 +- 13 files changed, 334 insertions(+), 29 deletions(-) create mode 100644 modules/programs/floorp.nix create mode 100644 tests/modules/programs/firefox/common.nix create mode 100644 tests/modules/programs/firefox/floorp.nix create mode 100644 tests/modules/programs/firefox/profile-settings.nix diff --git a/modules/modules.nix b/modules/modules.nix index 72f4adaae..b6880e62f 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -92,6 +92,7 @@ let ./programs/feh.nix ./programs/firefox.nix ./programs/fish.nix + ./programs/floorp.nix ./programs/foot.nix ./programs/freetube.nix ./programs/fuzzel.nix diff --git a/modules/programs/floorp.nix b/modules/programs/floorp.nix new file mode 100644 index 000000000..0f231bdf4 --- /dev/null +++ b/modules/programs/floorp.nix @@ -0,0 +1,29 @@ +{ lib, ... }: + +with lib; + +let + + modulePath = [ "programs" "floorp" ]; + + mkFirefoxModule = import ./firefox/mkFirefoxModule.nix; + +in { + meta.maintainers = [ hm.maintainers.bricked ]; + + imports = [ + (mkFirefoxModule { + inherit modulePath; + name = "Floorp"; + wrappedPackageName = "floorp"; + unwrappedPackageName = "floorp-unwrapped"; + visible = true; + + platforms.linux = { + configPath = ".floorp"; + vendorPath = ".floorp"; + }; + platforms.darwin = { configPath = "Library/Application Support/Floorp"; }; + }) + ]; +} diff --git a/tests/default.nix b/tests/default.nix index 83ed42a70..90371aafe 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -193,6 +193,7 @@ in import nmtSrc { ./modules/programs/bemenu ./modules/programs/boxxy ./modules/programs/firefox/firefox.nix + ./modules/programs/firefox/floorp.nix ./modules/programs/foot ./modules/programs/freetube ./modules/programs/fuzzel diff --git a/tests/modules/programs/firefox/common.nix b/tests/modules/programs/firefox/common.nix new file mode 100644 index 000000000..7d05382f1 --- /dev/null +++ b/tests/modules/programs/firefox/common.nix @@ -0,0 +1,15 @@ +name: +builtins.mapAttrs (test: module: import module [ "programs" name ]) { + "${name}-deprecated-native-messenger" = ./deprecated-native-messenger.nix; + "${name}-policies" = ./policies.nix; + "${name}-profiles-bookmarks" = ./profiles/bookmarks; + "${name}-profiles-containers" = ./profiles/containers; + "${name}-profiles-containers-duplicate-ids" = + ./profiles/containers/duplicate-ids.nix; + "${name}-profiles-containers-id-out-of-range" = + ./profiles/containers/id-out-of-range.nix; + "${name}-profiles-duplicate-ids" = ./profiles/duplicate-ids.nix; + "${name}-profiles-search" = ./profiles/search; + "${name}-profiles-settings" = ./profiles/settings; + "${name}-state-version-19_09" = ./state-version-19_09.nix; +} diff --git a/tests/modules/programs/firefox/firefox.nix b/tests/modules/programs/firefox/firefox.nix index 6d92a5f49..dd126e260 100644 --- a/tests/modules/programs/firefox/firefox.nix +++ b/tests/modules/programs/firefox/firefox.nix @@ -1,16 +1 @@ -let name = "firefox"; - -in builtins.mapAttrs (test: module: import module [ "programs" name ]) { - "${name}-deprecated-native-messenger" = ./deprecated-native-messenger.nix; - "${name}-policies" = ./policies.nix; - "${name}-profiles-bookmarks" = ./profiles/bookmarks; - "${name}-profiles-containers" = ./profiles/containers; - "${name}-profiles-containers-duplicate-ids" = - ./profiles/containers/duplicate-ids.nix; - "${name}-profiles-containers-id-out-of-range" = - ./profiles/containers/id-out-of-range.nix; - "${name}-profiles-duplicate-ids" = ./profiles/duplicate-ids.nix; - "${name}-profiles-search" = ./profiles/search; - "${name}-profiles-settings" = ./profiles/settings; - "${name}-state-version-19_09" = ./state-version-19_09.nix; -} +import ./common.nix "firefox" diff --git a/tests/modules/programs/firefox/floorp.nix b/tests/modules/programs/firefox/floorp.nix new file mode 100644 index 000000000..67a13659c --- /dev/null +++ b/tests/modules/programs/firefox/floorp.nix @@ -0,0 +1 @@ +import ./common.nix "floorp" diff --git a/tests/modules/programs/firefox/policies.nix b/tests/modules/programs/firefox/policies.nix index 5e02a1916..5cda1406a 100644 --- a/tests/modules/programs/firefox/policies.nix +++ b/tests/modules/programs/firefox/policies.nix @@ -20,7 +20,7 @@ in { package = pkgs.${cfg.wrappedPackageName}.override { extraPolicies = { DownloadDirectory = "/foo"; }; }; - }) // { + } // { nmt.script = '' jq=${lib.getExe pkgs.jq} config_file="${cfg.finalPackage}/lib/${cfg.wrappedPackageName}/distribution/policies.json" @@ -39,5 +39,5 @@ in { fail "Expected '$config_file' to set 'policies.DownloadDirectory' to \"/foo\"" fi ''; - }; + }); } diff --git a/tests/modules/programs/firefox/profile-settings.nix b/tests/modules/programs/firefox/profile-settings.nix new file mode 100644 index 000000000..897067625 --- /dev/null +++ b/tests/modules/programs/firefox/profile-settings.nix @@ -0,0 +1,241 @@ +modulePath: +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = getAttrFromPath modulePath config; + + firefoxMockOverlay = import ./setup-firefox-mock-overlay.nix modulePath; + + withName = path: + pkgs.substituteAll { + src = path; + name = cfg.wrappedPackageName; + }; + +in { + imports = [ firefoxMockOverlay ]; + + config = mkIf config.test.enableBig (setAttrByPath modulePath { + enable = true; + profiles.basic.isDefault = true; + + profiles.test = { + id = 1; + settings = { + "general.smoothScroll" = false; + "browser.newtabpage.pinned" = [{ + title = "NixOS"; + url = "https://nixos.org"; + }]; + }; + }; + + profiles.bookmarks = { + id = 2; + settings = { "general.smoothScroll" = false; }; + bookmarks = [ + { + toolbar = true; + bookmarks = [{ + name = "Home Manager"; + url = "https://wiki.nixos.org/wiki/Home_Manager"; + }]; + } + { + name = "wikipedia"; + tags = [ "wiki" ]; + keyword = "wiki"; + url = "https://en.wikipedia.org/wiki/Special:Search?search=%s&go=Go"; + } + { + name = "kernel.org"; + url = "https://www.kernel.org"; + } + { + name = "Nix sites"; + bookmarks = [ + { + name = "homepage"; + url = "https://nixos.org/"; + } + { + name = "wiki"; + tags = [ "wiki" "nix" ]; + url = "https://wiki.nixos.org/"; + } + { + name = "Nix sites"; + bookmarks = [ + { + name = "homepage"; + url = "https://nixos.org/"; + } + { + name = "wiki"; + url = "https://wiki.nixos.org/"; + } + ]; + } + ]; + } + ]; + }; + + profiles.search = { + id = 3; + search = { + force = true; + default = "Google"; + privateDefault = "DuckDuckGo"; + order = [ "Nix Packages" "NixOS Wiki" ]; + engines = { + "Nix Packages" = { + urls = [{ + template = "https://search.nixos.org/packages"; + params = [ + { + name = "type"; + value = "packages"; + } + { + name = "query"; + value = "{searchTerms}"; + } + ]; + }]; + + icon = + "/run/current-system/sw/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; + + definedAliases = [ "@np" ]; + }; + + "NixOS Wiki" = { + urls = [{ + template = + "https://wiki.nixos.org/index.php?search={searchTerms}"; + }]; + iconUpdateURL = "https://wiki.nixos.org/favicon.png"; + updateInterval = 24 * 60 * 60 * 1000; + definedAliases = [ "@nw" ]; + }; + + "Bing".metaData.hidden = true; + "Google".metaData.alias = "@g"; + }; + }; + }; + + profiles.searchWithoutDefault = { + id = 4; + search = { + force = true; + order = [ "Google" "Nix Packages" ]; + engines = { + "Nix Packages" = { + urls = [{ + template = "https://search.nixos.org/packages"; + params = [ + { + name = "type"; + value = "packages"; + } + { + name = "query"; + value = "{searchTerms}"; + } + ]; + }]; + + definedAliases = [ "@np" ]; + }; + }; + }; + }; + + profiles.containers = { + id = 5; + containers = { + "shopping" = { + id = 6; + icon = "circle"; + color = "yellow"; + }; + }; + }; + } // { + + nmt.script = let + + noHashQuery = '' + 'def walk(f): + . as $in + | if type == "object" then + reduce keys[] as $key + ( {}; . + { ($key): ($in[$key] | walk(f)) } | f ) + elif type == "array" then + map( walk(f) ) + else + f + end; + walk(if type == "object" then + if has("hash") then .hash = null else . end | + if has("privateHash") then .privateHash = null else . end + else + . + end)' ''; + + in '' + assertFileRegex \ + home-path/bin/${cfg.wrappedPackageName} \ + MOZ_APP_LAUNCHER + + assertDirectoryExists home-files/${cfg.configPath}/basic + + assertFileContent \ + home-files/${cfg.configPath}/test/user.js \ + ${withName ./profile-settings-expected-user.js} + + assertFileContent \ + home-files/${cfg.configPath}/containers/containers.json \ + ${withName ./profile-settings-expected-containers.json} + + bookmarksUserJs=$(normalizeStorePaths \ + home-files/${cfg.configPath}/bookmarks/user.js) + + assertFileContent \ + $bookmarksUserJs \ + ${withName ./profile-settings-expected-bookmarks-user.js} + + bookmarksFile="$(sed -n \ + '/browser.bookmarks.file/ {s|^.*\(/nix/store[^"]*\).*|\1|;p}' \ + $TESTED/home-files/${cfg.configPath}/bookmarks/user.js)" + + assertFileContent \ + $bookmarksFile \ + ${withName ./profile-settings-expected-bookmarks.html} + + function assertFirefoxSearchContent() { + compressedSearch=$(normalizeStorePaths "$1") + + decompressedSearch=$(dirname $compressedSearch)/search.json + ${pkgs.mozlz4a}/bin/mozlz4a -d "$compressedSearch" >(${pkgs.jq}/bin/jq ${noHashQuery} > "$decompressedSearch") + + assertFileContent \ + $decompressedSearch \ + "$2" + } + + assertFirefoxSearchContent \ + home-files/${cfg.configPath}/search/search.json.mozlz4 \ + ${withName ./profile-settings-expected-search.json} + + assertFirefoxSearchContent \ + home-files/${cfg.configPath}/searchWithoutDefault/search.json.mozlz4 \ + ${withName ./profile-settings-expected-search-without-default.json} + ''; + }); +} diff --git a/tests/modules/programs/firefox/profiles/bookmarks/default.nix b/tests/modules/programs/firefox/profiles/bookmarks/default.nix index 7bf508ab0..dfbcfbd92 100644 --- a/tests/modules/programs/firefox/profiles/bookmarks/default.nix +++ b/tests/modules/programs/firefox/profiles/bookmarks/default.nix @@ -9,6 +9,12 @@ let firefoxMockOverlay = import ../../setup-firefox-mock-overlay.nix modulePath; + withName = path: + pkgs.substituteAll { + src = path; + name = cfg.wrappedPackageName; + }; + in { imports = [ firefoxMockOverlay ]; @@ -70,7 +76,7 @@ in { assertFileContent \ $bookmarksUserJs \ - ${./expected-bookmarks-user.js} + ${withName ./expected-bookmarks-user.js} bookmarksFile="$(sed -n \ '/browser.bookmarks.file/ {s|^.*\(/nix/store[^"]*\).*|\1|;p}' \ diff --git a/tests/modules/programs/firefox/profiles/bookmarks/expected-bookmarks-user.js b/tests/modules/programs/firefox/profiles/bookmarks/expected-bookmarks-user.js index 922d3651e..47448a6e4 100644 --- a/tests/modules/programs/firefox/profiles/bookmarks/expected-bookmarks-user.js +++ b/tests/modules/programs/firefox/profiles/bookmarks/expected-bookmarks-user.js @@ -1,6 +1,6 @@ // Generated by Home Manager. -user_pref("browser.bookmarks.file", "/nix/store/00000000000000000000000000000000-firefox-bookmarks.html"); +user_pref("browser.bookmarks.file", "/nix/store/00000000000000000000000000000000-@name@-bookmarks.html"); user_pref("browser.places.importBookmarksHTML", true); user_pref("general.smoothScroll", false); diff --git a/tests/modules/programs/firefox/profiles/search/default.nix b/tests/modules/programs/firefox/profiles/search/default.nix index 8a4c98e9b..76acfcd3a 100644 --- a/tests/modules/programs/firefox/profiles/search/default.nix +++ b/tests/modules/programs/firefox/profiles/search/default.nix @@ -9,6 +9,12 @@ let firefoxMockOverlay = import ../../setup-firefox-mock-overlay.nix modulePath; + withName = path: + pkgs.substituteAll { + src = path; + name = cfg.wrappedPackageName; + }; + in { imports = [ firefoxMockOverlay ]; @@ -88,12 +94,32 @@ in { }; }; } // { - nmt.script = '' + nmt.script = let + + noHashQuery = '' + 'def walk(f): + . as $in + | if type == "object" then + reduce keys[] as $key + ( {}; . + { ($key): ($in[$key] | walk(f)) } | f ) + elif type == "array" then + map( walk(f) ) + else + f + end; + walk(if type == "object" then + if has("hash") then .hash = null else . end | + if has("privateHash") then .privateHash = null else . end + else + . + end)' ''; + + in '' function assertFirefoxSearchContent() { compressedSearch=$(normalizeStorePaths "$1") decompressedSearch=$(dirname $compressedSearch)/search.json - ${pkgs.mozlz4a}/bin/mozlz4a -d "$compressedSearch" >(${pkgs.jq}/bin/jq . > "$decompressedSearch") + ${pkgs.mozlz4a}/bin/mozlz4a -d "$compressedSearch" >(${pkgs.jq}/bin/jq ${noHashQuery} > "$decompressedSearch") assertFileContent \ $decompressedSearch \ @@ -102,11 +128,11 @@ in { assertFirefoxSearchContent \ home-files/${cfg.configPath}/search/search.json.mozlz4 \ - ${./expected-search.json} + ${withName ./expected-search.json} assertFirefoxSearchContent \ home-files/${cfg.configPath}/searchWithoutDefault/search.json.mozlz4 \ - ${./expected-search-without-default.json} + ${withName ./expected-search-without-default.json} ''; }); } diff --git a/tests/modules/programs/firefox/profiles/search/expected-search-without-default.json b/tests/modules/programs/firefox/profiles/search/expected-search-without-default.json index b845dad42..ec1ce14c8 100644 --- a/tests/modules/programs/firefox/profiles/search/expected-search-without-default.json +++ b/tests/modules/programs/firefox/profiles/search/expected-search-without-default.json @@ -12,7 +12,7 @@ "@np" ], "_isAppProvided": false, - "_loadPath": "[home-manager]/programs.firefox.profiles.searchWithoutDefault.search.engines.\"Nix Packages\"", + "_loadPath": "[home-manager]/programs.@name@.profiles.searchWithoutDefault.search.engines.\"Nix Packages\"", "_metaData": { "order": 2 }, diff --git a/tests/modules/programs/firefox/profiles/search/expected-search.json b/tests/modules/programs/firefox/profiles/search/expected-search.json index 832b6c09c..a661cf3fe 100644 --- a/tests/modules/programs/firefox/profiles/search/expected-search.json +++ b/tests/modules/programs/firefox/profiles/search/expected-search.json @@ -6,7 +6,7 @@ ], "_iconURL": "file:///run/current-system/sw/share/icons/hicolor/scalable/apps/nix-snowflake.svg", "_isAppProvided": false, - "_loadPath": "[home-manager]/programs.firefox.profiles.search.search.engines.\"Nix Packages\"", + "_loadPath": "[home-manager]/programs.@name@.profiles.search.search.engines.\"Nix Packages\"", "_metaData": { "order": 1 }, @@ -34,7 +34,7 @@ "_iconURL": "https://wiki.nixos.org/favicon.png", "_iconUpdateURL": "https://wiki.nixos.org/favicon.png", "_isAppProvided": false, - "_loadPath": "[home-manager]/programs.firefox.profiles.search.search.engines.\"NixOS Wiki\"", + "_loadPath": "[home-manager]/programs.@name@.profiles.search.search.engines.\"NixOS Wiki\"", "_metaData": { "order": 2 }, @@ -68,9 +68,9 @@ ], "metaData": { "current": "Google", - "hash": "IRmKVSQlAYnvLO8kdZyNUR/g5hzVn4++T0PLPGm+kZk=", + "hash": null, "private": "DuckDuckGo", - "privateHash": "BWvqUiaCuMJ20lbymFf2dqzWyl1cgm1LZhhdWNEp0Cc=", + "privateHash": null, "useSavedOrder": true }, "version": 6 From d57112db877f07387ce7104b5ac346ede556d2d7 Mon Sep 17 00:00:00 2001 From: Nabeen Tiwaree Date: Sat, 12 Oct 2024 05:43:52 -0400 Subject: [PATCH 014/546] pls: fixed perm argument to pass via pls --- modules/programs/pls.nix | 2 +- tests/modules/programs/pls/bash.nix | 2 +- tests/modules/programs/pls/fish.nix | 2 +- tests/modules/programs/pls/zsh.nix | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/programs/pls.nix b/modules/programs/pls.nix index b9f509a76..8abb82618 100644 --- a/modules/programs/pls.nix +++ b/modules/programs/pls.nix @@ -9,7 +9,7 @@ let aliases = { ls = "${cfg.package}/bin/pls"; ll = - "${cfg.package}/bin/pls -d perms -d user -d group -d size -d mtime -d git"; + "${cfg.package}/bin/pls -d perm -d user -d group -d size -d mtime -d git"; }; in { diff --git a/tests/modules/programs/pls/bash.nix b/tests/modules/programs/pls/bash.nix index f7e0429b5..dc1743997 100644 --- a/tests/modules/programs/pls/bash.nix +++ b/tests/modules/programs/pls/bash.nix @@ -23,7 +23,7 @@ with lib; "alias ls=@pls@/bin/pls" assertFileContains \ home-files/.bashrc \ - "alias ll='@pls@/bin/pls -d perms -d user -d group -d size -d mtime -d git'" + "alias ll='@pls@/bin/pls -d perm -d user -d group -d size -d mtime -d git'" ''; }; } diff --git a/tests/modules/programs/pls/fish.nix b/tests/modules/programs/pls/fish.nix index 05dbb10b0..c745cd768 100644 --- a/tests/modules/programs/pls/fish.nix +++ b/tests/modules/programs/pls/fish.nix @@ -27,7 +27,7 @@ with lib; "alias ls @pls@/bin/pls" assertFileContains \ home-files/.config/fish/config.fish \ - "alias ll '@pls@/bin/pls -d perms -d user -d group -d size -d mtime -d git'" + "alias ll '@pls@/bin/pls -d perm -d user -d group -d size -d mtime -d git'" ''; }; } diff --git a/tests/modules/programs/pls/zsh.nix b/tests/modules/programs/pls/zsh.nix index 8f644e753..bbe68abb5 100644 --- a/tests/modules/programs/pls/zsh.nix +++ b/tests/modules/programs/pls/zsh.nix @@ -26,7 +26,7 @@ with lib; "alias -- ls=@pls@/bin/pls" assertFileContains \ home-files/.zshrc \ - "alias -- ll='@pls@/bin/pls -d perms -d user -d group -d size -d mtime -d git'" + "alias -- ll='@pls@/bin/pls -d perm -d user -d group -d size -d mtime -d git'" ''; }; } From 64c6325b28ebd708653dd41d88f306023f296184 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 13 Oct 2024 03:59:22 +0000 Subject: [PATCH 015/546] flake.lock: Update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flake lock file updates: • Updated input 'nixpkgs': 'github:NixOS/nixpkgs/c31898adf5a8ed202ce5bea9f347b1c6871f32d1?narHash=sha256-yumd4fBc/hi8a9QgA9IT8vlQuLZ2oqhkJXHPKxH/tRw%3D' (2024-10-06) → 'github:NixOS/nixpkgs/5633bcff0c6162b9e4b5f1264264611e950c8ec7?narHash=sha256-9UTxR8eukdg%2BXZeHgxW5hQA9fIKHsKCdOIUycTryeVw%3D' (2024-10-09) --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 76920c875..0ce117f43 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1728241625, - "narHash": "sha256-yumd4fBc/hi8a9QgA9IT8vlQuLZ2oqhkJXHPKxH/tRw=", + "lastModified": 1728492678, + "narHash": "sha256-9UTxR8eukdg+XZeHgxW5hQA9fIKHsKCdOIUycTryeVw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "c31898adf5a8ed202ce5bea9f347b1c6871f32d1", + "rev": "5633bcff0c6162b9e4b5f1264264611e950c8ec7", "type": "github" }, "original": { From e1aec543f5caf643ca0d94b6a633101942fd065f Mon Sep 17 00:00:00 2001 From: Kira Bruneau Date: Mon, 14 Oct 2024 07:01:26 -0400 Subject: [PATCH 016/546] thunderbird: support setting search engines (#5697) * firefox: split search into separate submodule file * thunderbird: support setting search engines --- modules/programs/firefox.nix | 3 +- modules/programs/firefox/mkFirefoxModule.nix | 250 ++---------------- modules/programs/firefox/profiles/search.nix | 251 +++++++++++++++++++ modules/programs/thunderbird.nix | 20 ++ 4 files changed, 288 insertions(+), 236 deletions(-) create mode 100644 modules/programs/firefox/profiles/search.nix diff --git a/modules/programs/firefox.nix b/modules/programs/firefox.nix index ac85990ff..2a2667c35 100644 --- a/modules/programs/firefox.nix +++ b/modules/programs/firefox.nix @@ -11,8 +11,7 @@ let mkFirefoxModule = import ./firefox/mkFirefoxModule.nix; in { - meta.maintainers = - [ maintainers.rycee maintainers.kira-bruneau hm.maintainers.bricked ]; + meta.maintainers = [ maintainers.rycee hm.maintainers.bricked ]; imports = [ (mkFirefoxModule { diff --git a/modules/programs/firefox/mkFirefoxModule.nix b/modules/programs/firefox/mkFirefoxModule.nix index 2e4c23cde..dd4920666 100644 --- a/modules/programs/firefox/mkFirefoxModule.nix +++ b/modules/programs/firefox/mkFirefoxModule.nix @@ -547,93 +547,17 @@ in { description = "Whether this is a default profile."; }; - search = { - force = mkOption { - type = with types; bool; - default = false; - description = '' - Whether to force replace the existing search - configuration. This is recommended since ${name} will - replace the symlink for the search configuration on every - launch, but note that you'll lose any existing - configuration by enabling this. - ''; - }; - - default = mkOption { - type = with types; nullOr str; - default = null; - example = "DuckDuckGo"; - description = '' - The default search engine used in the address bar and search bar. - ''; - }; - - privateDefault = mkOption { - type = with types; nullOr str; - default = null; - example = "DuckDuckGo"; - description = '' - The default search engine used in the Private Browsing. - ''; - }; - - order = mkOption { - type = with types; uniq (listOf str); - default = [ ]; - example = [ "DuckDuckGo" "Google" ]; - description = '' - The order the search engines are listed in. Any engines - that aren't included in this list will be listed after - these in an unspecified order. - ''; - }; - - engines = mkOption { - type = with types; attrsOf (attrsOf jsonFormat.type); - default = { }; - example = literalExpression '' - { - "Nix Packages" = { - urls = [{ - template = "https://search.nixos.org/packages"; - params = [ - { name = "type"; value = "packages"; } - { name = "query"; value = "{searchTerms}"; } - ]; - }]; - - icon = "''${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; - definedAliases = [ "@np" ]; - }; - - "NixOS Wiki" = { - urls = [{ template = "https://wiki.nixos.org/index.php?search={searchTerms}"; }]; - iconUpdateURL = "https://wiki.nixos.org/favicon.png"; - updateInterval = 24 * 60 * 60 * 1000; # every day - definedAliases = [ "@nw" ]; - }; - - "Bing".metaData.hidden = true; - "Google".metaData.alias = "@g"; # builtin engines only support specifying one additional alias - } - ''; - description = '' - Attribute set of search engine configurations. Engines - that only have {var}`metaData` specified will - be treated as builtin to ${name}. - - See [SearchEngine.jsm](https://searchfox.org/mozilla-central/rev/669329e284f8e8e2bb28090617192ca9b4ef3380/toolkit/components/search/SearchEngine.jsm#1138-1177) - in Firefox's source for available options. We maintain a - mapping to let you specify all options in the referenced - link without underscores, but it may fall out of date with - future options. - - Note, {var}`icon` is also a special option - added by Home Manager to make it convenient to specify - absolute icon paths. - ''; - }; + search = mkOption { + type = types.submodule (args: + import ./profiles/search.nix { + inherit (args) config; + inherit lib pkgs; + appName = cfg.name; + modulePath = modulePath ++ [ "profiles" name "search" ]; + profilePath = config.path; + }); + default = { }; + description = "Declarative search engine configuration."; }; containersForce = mkOption { @@ -853,152 +777,11 @@ in { force = profile.containersForce; }; - "${profilesPath}/${profile.path}/search.json.mozlz4" = mkIf - (profile.search.default != null || profile.search.privateDefault != null - || profile.search.order != [ ] || profile.search.engines != { }) { - force = profile.search.force; - source = let - settings = { - version = 6; - engines = let - # Map of nice field names to internal field names. - # This is intended to be exhaustive and should be - # updated at every version bump. - internalFieldNames = (genAttrs [ - "name" - "isAppProvided" - "loadPath" - "hasPreferredIcon" - "updateInterval" - "updateURL" - "iconUpdateURL" - "iconURL" - "iconMapObj" - "metaData" - "orderHint" - "definedAliases" - "urls" - ] (name: "_${name}")) // { - searchForm = "__searchForm"; - }; - - processCustomEngineInput = input: - (removeAttrs input [ "icon" ]) - // optionalAttrs (input ? icon) { - # Convenience to specify absolute path to icon - iconURL = "file://${input.icon}"; - } // (optionalAttrs (input ? iconUpdateURL) { - # Convenience to default iconURL to iconUpdateURL so - # the icon is immediately downloaded from the URL - iconURL = input.iconURL or input.iconUpdateURL; - } // { - # Required for custom engine configurations, loadPaths - # are unique identifiers that are generally formatted - # like: [source]/path/to/engine.xml - loadPath = '' - [home-manager]/${moduleName}.profiles.${profile.name}.search.engines."${ - replaceStrings [ "\\" ] [ "\\\\" ] input.name - }"''; - }); - - processEngineInput = name: input: - let - requiredInput = { - inherit name; - isAppProvided = input.isAppProvided or removeAttrs input - [ "metaData" ] == { }; - metaData = input.metaData or { }; - }; - in if requiredInput.isAppProvided then - requiredInput - else - processCustomEngineInput (input // requiredInput); - - buildEngineConfig = name: input: - mapAttrs' (name: value: { - name = internalFieldNames.${name} or name; - inherit value; - }) (processEngineInput name input); - - sortEngineConfigs = configs: - let - buildEngineConfigWithOrder = order: name: - let - config = configs.${name} or { - _name = name; - _isAppProvided = true; - _metaData = { }; - }; - in config // { - _metaData = config._metaData // { inherit order; }; - }; - - engineConfigsWithoutOrder = - attrValues (removeAttrs configs profile.search.order); - - sortedEngineConfigs = - (imap buildEngineConfigWithOrder profile.search.order) - ++ engineConfigsWithoutOrder; - in sortedEngineConfigs; - - engineInput = profile.search.engines // { - # Infer profile.search.default as an app provided - # engine if it's not in profile.search.engines - ${profile.search.default} = - profile.search.engines.${profile.search.default} or { }; - } // { - ${profile.search.privateDefault} = - profile.search.engines.${profile.search.privateDefault} or { }; - }; - in sortEngineConfigs (mapAttrs buildEngineConfig engineInput); - - metaData = optionalAttrs (profile.search.default != null) { - current = profile.search.default; - hash = "@hash@"; - } // optionalAttrs (profile.search.privateDefault != null) { - private = profile.search.privateDefault; - privateHash = "@privateHash@"; - } // { - useSavedOrder = profile.search.order != [ ]; - }; - }; - - # Home Manager doesn't circumvent user consent and isn't acting - # maliciously. We're modifying the search outside of the browser, but - # a claim by Mozilla to remove this would be very anti-user, and - # is unlikely to be an issue for our use case. - disclaimer = appName: - "By modifying this file, I agree that I am doing so " - + "only within ${appName} itself, using official, user-driven search " - + "engine selection processes, and in a way which does not circumvent " - + "user consent. I acknowledge that any attempt to change this file " - + "from outside of ${appName} is a malicious act, and will be responded " - + "to accordingly."; - - salt = if profile.search.default != null then - profile.path + profile.search.default + disclaimer cfg.name - else - null; - - privateSalt = if profile.search.privateDefault != null then - profile.path + profile.search.privateDefault - + disclaimer cfg.name - else - null; - in pkgs.runCommand "search.json.mozlz4" { - nativeBuildInputs = with pkgs; [ mozlz4a openssl ]; - json = builtins.toJSON settings; - inherit salt privateSalt; - } '' - if [[ -n $salt ]]; then - export hash=$(echo -n "$salt" | openssl dgst -sha256 -binary | base64) - export privateHash=$(echo -n "$privateSalt" | openssl dgst -sha256 -binary | base64) - mozlz4a <(substituteStream json search.json.in --subst-var hash --subst-var privateHash) "$out" - else - mozlz4a <(echo "$json") "$out" - fi - ''; - }; + "${profilesPath}/${profile.path}/search.json.mozlz4" = { + enable = profile.search.enable; + force = profile.search.force; + source = profile.search.file; + }; "${profilesPath}/${profile.path}/extensions" = mkIf (profile.extensions != [ ]) { @@ -1025,4 +808,3 @@ in { }; }); } - diff --git a/modules/programs/firefox/profiles/search.nix b/modules/programs/firefox/profiles/search.nix new file mode 100644 index 000000000..69b771aa4 --- /dev/null +++ b/modules/programs/firefox/profiles/search.nix @@ -0,0 +1,251 @@ +{ config, lib, pkgs, appName, modulePath, profilePath }: + +with lib; + +let + jsonFormat = pkgs.formats.json { }; + + # Map of nice field names to internal field names. + # This is intended to be exhaustive and should be + # updated at every version bump. + internalFieldNames = (genAttrs [ + "name" + "isAppProvided" + "loadPath" + "hasPreferredIcon" + "updateInterval" + "updateURL" + "iconUpdateURL" + "iconURL" + "iconMapObj" + "metaData" + "orderHint" + "definedAliases" + "urls" + ] (name: "_${name}")) // { + searchForm = "__searchForm"; + }; + + processCustomEngineInput = input: + (removeAttrs input [ "icon" ]) // optionalAttrs (input ? icon) { + # Convenience to specify absolute path to icon + iconURL = "file://${input.icon}"; + } // (optionalAttrs (input ? iconUpdateURL) { + # Convenience to default iconURL to iconUpdateURL so + # the icon is immediately downloaded from the URL + iconURL = input.iconURL or input.iconUpdateURL; + } // { + # Required for custom engine configurations, loadPaths + # are unique identifiers that are generally formatted + # like: [source]/path/to/engine.xml + loadPath = "[home-manager]/${ + concatStringsSep "." (map strings.escapeNixIdentifier + (modulePath ++ [ "engines" input.name ])) + }"; + }); + + processEngineInput = name: input: + let + requiredInput = { + inherit name; + isAppProvided = input.isAppProvided or removeAttrs input [ "metaData" ] + == { }; + metaData = input.metaData or { }; + }; + in if requiredInput.isAppProvided then + requiredInput + else + processCustomEngineInput (input // requiredInput); + + buildEngineConfig = name: input: + mapAttrs' (name: value: { + name = internalFieldNames.${name} or name; + inherit value; + }) (processEngineInput name input); + + sortEngineConfigs = configs: + let + buildEngineConfigWithOrder = order: name: + let + config = configs.${name} or { + _name = name; + _isAppProvided = true; + _metaData = { }; + }; + in config // { _metaData = config._metaData // { inherit order; }; }; + + engineConfigsWithoutOrder = attrValues (removeAttrs configs config.order); + + sortedEngineConfigs = (imap buildEngineConfigWithOrder config.order) + ++ engineConfigsWithoutOrder; + in sortedEngineConfigs; + + engineInput = config.engines // { + # Infer config.default as an app provided + # engine if it's not in config.engines + ${config.default} = config.engines.${config.default} or { }; + } // { + ${config.privateDefault} = config.engines.${config.privateDefault} or { }; + }; + + settings = { + version = 6; + engines = sortEngineConfigs (mapAttrs buildEngineConfig engineInput); + + metaData = optionalAttrs (config.default != null) { + current = config.default; + hash = "@hash@"; + } // optionalAttrs (config.privateDefault != null) { + private = config.privateDefault; + privateHash = "@privateHash@"; + } // { + useSavedOrder = config.order != [ ]; + }; + }; + + # Home Manager doesn't circumvent user consent and isn't acting + # maliciously. We're modifying the search outside of the browser, but + # a claim by Mozilla to remove this would be very anti-user, and + # is unlikely to be an issue for our use case. + disclaimer = "By modifying this file, I agree that I am doing so " + + "only within ${appName} itself, using official, user-driven search " + + "engine selection processes, and in a way which does not circumvent " + + "user consent. I acknowledge that any attempt to change this file " + + "from outside of ${appName} is a malicious act, and will be responded " + + "to accordingly."; + + salt = if config.default != null then + profilePath + config.default + disclaimer + else + null; + + privateSalt = if config.privateDefault != null then + profilePath + config.privateDefault + disclaimer + else + null; + + file = pkgs.runCommand "search.json.mozlz4" { + nativeBuildInputs = with pkgs; [ mozlz4a openssl ]; + json = builtins.toJSON settings; + inherit salt privateSalt; + } '' + if [[ -n $salt ]]; then + export hash=$(echo -n "$salt" | openssl dgst -sha256 -binary | base64) + export privateHash=$(echo -n "$privateSalt" | openssl dgst -sha256 -binary | base64) + mozlz4a <(substituteStream json search.json.in --subst-var hash --subst-var privateHash) "$out" + else + mozlz4a <(echo "$json") "$out" + fi + ''; +in { + imports = [ (pkgs.path + "/nixos/modules/misc/meta.nix") ]; + + meta.maintainers = with maintainers; [ kira-bruneau ]; + + options = { + enable = mkOption { + type = with types; bool; + default = config.default != null || config.privateDefault != null + || config.order != [ ] || config.engines != { }; + internal = true; + }; + + force = mkOption { + type = with types; bool; + default = false; + description = '' + Whether to force replace the existing search + configuration. This is recommended since ${appName} will + replace the symlink for the search configuration on every + launch, but note that you'll lose any existing configuration + by enabling this. + ''; + }; + + default = mkOption { + type = with types; nullOr str; + default = null; + example = "DuckDuckGo"; + description = '' + The default search engine used in the address bar and search + bar. + ''; + }; + + privateDefault = mkOption { + type = with types; nullOr str; + default = null; + example = "DuckDuckGo"; + description = '' + The default search engine used in the Private Browsing. + ''; + }; + + order = mkOption { + type = with types; uniq (listOf str); + default = [ ]; + example = [ "DuckDuckGo" "Google" ]; + description = '' + The order the search engines are listed in. Any engines that + aren't included in this list will be listed after these in an + unspecified order. + ''; + }; + + engines = mkOption { + type = with types; attrsOf (attrsOf jsonFormat.type); + default = { }; + example = literalExpression '' + { + "Nix Packages" = { + urls = [{ + template = "https://search.nixos.org/packages"; + params = [ + { name = "type"; value = "packages"; } + { name = "query"; value = "{searchTerms}"; } + ]; + }]; + + icon = "''${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; + definedAliases = [ "@np" ]; + }; + + "NixOS Wiki" = { + urls = [{ template = "https://wiki.nixos.org/index.php?search={searchTerms}"; }]; + iconUpdateURL = "https://wiki.nixos.org/favicon.png"; + updateInterval = 24 * 60 * 60 * 1000; # every day + definedAliases = [ "@nw" ]; + }; + + "Bing".metaData.hidden = true; + "Google".metaData.alias = "@g"; # builtin engines only support specifying one additional alias + } + ''; + + description = '' + Attribute set of search engine configurations. Engines that + only have {var}`metaData` specified will be treated as builtin + to ${appName}. + + See [SearchEngine.jsm](https://searchfox.org/mozilla-central/rev/669329e284f8e8e2bb28090617192ca9b4ef3380/toolkit/components/search/SearchEngine.jsm#1138-1177) + in ${appName}'s source for available options. We maintain a + mapping to let you specify all options in the referenced link + without underscores, but it may fall out of date with future + options. + + Note, {var}`icon` is also a special option added by Home + Manager to make it convenient to specify absolute icon paths. + ''; + }; + + file = mkOption { + type = with types; path; + default = file; + internal = true; + readOnly = true; + description = '' + Resulting search.json.mozlz4 file. + ''; + }; + }; +} diff --git a/modules/programs/thunderbird.nix b/modules/programs/thunderbird.nix index 2001e806f..a5ba0e63e 100644 --- a/modules/programs/thunderbird.nix +++ b/modules/programs/thunderbird.nix @@ -225,6 +225,20 @@ in { Extra preferences to add to {file}`user.js`. ''; }; + + search = mkOption { + type = types.submodule (args: + import ./firefox/profiles/search.nix { + inherit (args) config; + inherit lib pkgs; + appName = "Thunderbird"; + modulePath = + [ "programs" "thunderbird" "profiles" name "search" ]; + profilePath = name; + }); + default = { }; + description = "Declarative search engine configuration."; + }; }; })); description = "Attribute set of Thunderbird profiles."; @@ -393,6 +407,12 @@ in { ] ++ (map (a: toThunderbirdAccount a profile) accounts))) profile.extraConfig; }; + + "${thunderbirdProfilesPath}/${name}/search.json.mozlz4" = { + enable = profile.search.enable; + force = profile.search.force; + source = profile.search.file; + }; })); }; } From 2a4fd1cfd8ed5648583dadef86966a8231024221 Mon Sep 17 00:00:00 2001 From: Sergey Date: Tue, 8 Oct 2024 22:34:31 +0100 Subject: [PATCH 017/546] eza: fix icons option Fixes the icons option for eza which was breaking completion in zsh. --- docs/release-notes/rl-2411.md | 5 +++++ modules/programs/eza.nix | 24 ++++++++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/docs/release-notes/rl-2411.md b/docs/release-notes/rl-2411.md index 6f7a6b7b0..626624640 100644 --- a/docs/release-notes/rl-2411.md +++ b/docs/release-notes/rl-2411.md @@ -18,6 +18,11 @@ This release has the following notable changes: add `-w` to your assignment of [services.swayidle.extraArgs](#opt-services.swayidle.extraArgs). +- Support for Boolean values in the option + [programs.eza.icons](#opt-programs.eza.icons) is deprecated for + future removal. The new value for `true` is `"auto"`, and for + `false` it is `null`. + ## State Version Changes {#sec-release-24.11-state-version-changes} The state version in this release includes the changes below. These diff --git a/modules/programs/eza.nix b/modules/programs/eza.nix index d55d6f56e..679f53499 100644 --- a/modules/programs/eza.nix +++ b/modules/programs/eza.nix @@ -49,10 +49,13 @@ with lib; }; icons = mkOption { - type = types.bool; - default = false; + type = types.enum [ null true false "auto" "always" "never" ]; + default = null; description = '' Display icons next to file names ({option}`--icons` argument). + + Note, the support for Boolean values is deprecated. + Setting this option to `true` corresponds to `--icons=auto`. ''; }; @@ -70,8 +73,15 @@ with lib; config = let cfg = config.programs.eza; - args = escapeShellArgs (optional cfg.icons "--icons" - ++ optional cfg.git "--git" ++ cfg.extraOptions); + iconsOption = let + v = if isBool cfg.icons then + (if cfg.icons then "auto" else null) + else + cfg.icons; + in optionals (v != null) [ "--icons" v ]; + + args = escapeShellArgs + (iconsOption ++ optional cfg.git "--git" ++ cfg.extraOptions); optionsAlias = optionalAttrs (args != "") { eza = "eza ${args}"; }; @@ -83,6 +93,12 @@ with lib; lla = "eza -la"; }; in mkIf cfg.enable { + warnings = optional (isBool cfg.icons) '' + Setting programs.eza.icons to a Boolean is deprecated. + Please update your configuration so that + + programs.eza.icons = ${if cfg.icons then ''"auto"'' else "null"}''; + home.packages = [ cfg.package ]; programs.bash.shellAliases = optionsAlias From 994a0baf7be821c6c1487ffb3ab2884a5581a293 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Tri=C3=B1anes?= Date: Sat, 14 Sep 2024 14:48:32 +0200 Subject: [PATCH 018/546] nushell: add joaquintrinanes as maintainer --- modules/programs/nushell.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/programs/nushell.nix b/modules/programs/nushell.nix index 2ebd9554c..b69ec88f0 100644 --- a/modules/programs/nushell.nix +++ b/modules/programs/nushell.nix @@ -39,7 +39,7 @@ let }; }); in { - meta.maintainers = [ maintainers.Philipp-M ]; + meta.maintainers = [ maintainers.Philipp-M maintainers.joaquintrinanes ]; imports = [ (mkRemovedOptionModule [ "programs" "nushell" "settings" ] '' From edf15f1549a2f4e65d704f7d6ab6be715d932976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Tri=C3=B1anes?= Date: Sat, 14 Sep 2024 02:15:02 +0200 Subject: [PATCH 019/546] nushell: create generator helpers --- modules/lib/default.nix | 1 + modules/lib/nushell.nix | 65 +++++++++++++++++++++++++++++++++++++++++ modules/lib/types.nix | 23 +++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 modules/lib/nushell.nix diff --git a/modules/lib/default.nix b/modules/lib/default.nix index 5d732a83f..8014c625e 100644 --- a/modules/lib/default.nix +++ b/modules/lib/default.nix @@ -14,4 +14,5 @@ rec { shell = import ./shell.nix { inherit lib; }; zsh = import ./zsh.nix { inherit lib; }; + nushell = import ./nushell.nix { inherit lib; }; } diff --git a/modules/lib/nushell.nix b/modules/lib/nushell.nix new file mode 100644 index 000000000..e831380cd --- /dev/null +++ b/modules/lib/nushell.nix @@ -0,0 +1,65 @@ +{ lib }: rec { + mkNushellInline = expr: lib.setType "nushell-inline" { inherit expr; }; + + toNushell = { indent ? "", multiline ? true, asBindings ? false }@args: + v: + let + innerIndent = "${indent} "; + introSpace = if multiline then '' + + ${innerIndent}'' else + " "; + outroSpace = if multiline then '' + + ${indent}'' else + " "; + innerArgs = args // { + indent = if asBindings then indent else innerIndent; + asBindings = false; + }; + concatItems = lib.concatStringsSep introSpace; + isNushellInline = lib.isType "nushell-inline"; + + generatedBindings = assert lib.assertMsg (badVarNames == [ ]) + "Bad Nushell variable names: ${ + lib.generators.toPretty { } badVarNames + }"; + lib.concatStrings (lib.mapAttrsToList (key: value: '' + ${indent}let ${key} = ${toNushell innerArgs value} + '') v); + + isBadVarName = name: + # Extracted from https://github.com/nushell/nushell/blob/ebc7b80c23f777f70c5053cca428226b3fe00d30/crates/nu-parser/src/parser.rs#L33 + # Variables with numeric or even empty names are allowed. The only requisite is not containing any of the following characters + let invalidVariableCharacters = ".[({+-*^/=!<>&|"; + in lib.match "^[$]?[^${lib.escapeRegex invalidVariableCharacters}]+$" + name == null; + badVarNames = lib.filter isBadVarName (builtins.attrNames v); + in if asBindings then + generatedBindings + else if v == null then + "null" + else if lib.isInt v || lib.isFloat v || lib.isString v || lib.isBool v then + lib.strings.toJSON v + else if lib.isList v then + (if v == [ ] then + "[]" + else + "[${introSpace}${ + concatItems (map (value: "${toNushell innerArgs value}") v) + }${outroSpace}]") + else if lib.isAttrs v then + (if isNushellInline v then + "(${v.expr})" + else if v == { } then + "{}" + else if lib.isDerivation v then + toString v + else + "{${introSpace}${ + concatItems (lib.mapAttrsToList (key: value: + "${lib.strings.toJSON key}: ${toNushell innerArgs value}") v) + }${outroSpace}}") + else + abort "nushell.toNushell: type ${lib.typeOf v} is unsupported"; +} diff --git a/modules/lib/types.nix b/modules/lib/types.nix index 056d3165b..14d1c2192 100644 --- a/modules/lib/types.nix +++ b/modules/lib/types.nix @@ -107,4 +107,27 @@ in rec { mergeDefaultOption loc defs; }; + nushellValue = let + valueType = types.nullOr (types.oneOf [ + (lib.mkOptionType { + name = "nushell"; + description = "Nushell inline value"; + descriptionClass = "name"; + check = lib.isType "nushell-inline"; + }) + types.bool + types.int + types.float + types.str + types.path + (types.attrsOf valueType // { + description = "attribute set of Nushell values"; + descriptionClass = "name"; + }) + (types.listOf valueType // { + description = "list of Nushell values"; + descriptionClass = "name"; + }) + ]); + in valueType; } From 628b15d275a536fd4d4b9ab4405dd1f0eb34fe18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Tri=C3=B1anes?= Date: Sat, 14 Sep 2024 18:09:15 +0200 Subject: [PATCH 020/546] nushell: allow arbitrary environment variables --- modules/programs/nushell.nix | 27 ++++++++++++++----- .../modules/programs/nushell/env-expected.nu | 15 ++++++++++- .../programs/nushell/example-settings.nix | 14 ++++++++-- 3 files changed, 47 insertions(+), 9 deletions(-) diff --git a/modules/programs/nushell.nix b/modules/programs/nushell.nix index b69ec88f0..6586d1e1a 100644 --- a/modules/programs/nushell.nix +++ b/modules/programs/nushell.nix @@ -145,11 +145,24 @@ in { }; environmentVariables = mkOption { - type = types.attrsOf types.str; + type = types.attrsOf hm.types.nushellValue; default = { }; - example = { FOO = "BAR"; }; + example = literalExpression '' + { + FOO = "BAR"; + LIST_VALUE = [ "foo" "bar" ]; + NU_LIB_DIRS = lib.concatStringsSep ":" [ ./scripts ]; + PROMPT_COMMAND = lib.hm.nushell.mkNushellInline '''{|| "> "}'''; + ENV_CONVERSIONS.PATH = { + from_string = lib.hm.nushell.mkNushellInline "{|s| $s | split row (char esep) }"; + to_string = lib.hm.nushell.mkNushellInline "{|v| $v | str join (char esep) }"; + }; + } + ''; description = '' - An attribute set that maps an environment variable to a shell interpreted string. + Environment variables to be set. + + Inline values can be set with `lib.hm.nushell.mkNushellInline`. ''; }; }; @@ -173,9 +186,11 @@ in { }) (let - envVarsStr = concatStringsSep "\n" - (mapAttrsToList (k: v: "$env.${k} = ${v}") cfg.environmentVariables); - in mkIf (cfg.envFile != null || cfg.extraEnv != "" || envVarsStr != "") { + hasEnvVars = cfg.environmentVariables != { }; + envVarsStr = '' + load-env ${hm.nushell.toNushell { } cfg.environmentVariables} + ''; + in mkIf (cfg.envFile != null || cfg.extraEnv != "" || hasEnvVars) { "${configDir}/env.nu".text = mkMerge [ (mkIf (cfg.envFile != null) cfg.envFile.text) cfg.extraEnv diff --git a/tests/modules/programs/nushell/env-expected.nu b/tests/modules/programs/nushell/env-expected.nu index 07105fc54..50f6f767b 100644 --- a/tests/modules/programs/nushell/env-expected.nu +++ b/tests/modules/programs/nushell/env-expected.nu @@ -1,4 +1,17 @@ $env.FOO = 'BAR' -$env.BAR = $'(echo BAZ)' \ No newline at end of file +load-env { + "ENV_CONVERSIONS": { + "PATH": { + "from_string": ({|s| $s | split row (char esep) }) + "to_string": ({|v| $v | str join (char esep) }) + } + } + "FOO": "BAR" + "LIST_VALUE": [ + "foo" + "bar" + ] + "PROMPT_COMMAND": ({|| "> "}) +} diff --git a/tests/modules/programs/nushell/example-settings.nix b/tests/modules/programs/nushell/example-settings.nix index d870eb9db..4fc1402a4 100644 --- a/tests/modules/programs/nushell/example-settings.nix +++ b/tests/modules/programs/nushell/example-settings.nix @@ -1,4 +1,4 @@ -{ pkgs, config, ... }: +{ pkgs, config, lib, ... }: { programs.nushell = { @@ -28,7 +28,17 @@ "ll" = "ls -a"; }; - environmentVariables = { BAR = "$'(echo BAZ)'"; }; + environmentVariables = { + FOO = "BAR"; + LIST_VALUE = [ "foo" "bar" ]; + PROMPT_COMMAND = lib.hm.nushell.mkNushellInline ''{|| "> "}''; + ENV_CONVERSIONS.PATH = { + from_string = + lib.hm.nushell.mkNushellInline "{|s| $s | split row (char esep) }"; + to_string = + lib.hm.nushell.mkNushellInline "{|v| $v | str join (char esep) }"; + }; + }; }; test.stubs.nushell = { }; From b53427656655174c50c050b50c497d0e91405ab7 Mon Sep 17 00:00:00 2001 From: AtomicDude Date: Thu, 17 Oct 2024 02:20:16 +0200 Subject: [PATCH 021/546] Translate using Weblate (Romanian) Currently translated at 100.0% (18 of 18 strings) Co-authored-by: AtomicDude Translate-URL: https://hosted.weblate.org/projects/home-manager/modules/ro/ Translation: Home Manager/Home Manager Modules --- modules/po/ro.po | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/po/ro.po b/modules/po/ro.po index d817496a7..71e9243c9 100644 --- a/modules/po/ro.po +++ b/modules/po/ro.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: Home Manager Modules\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" "POT-Creation-Date: 2024-04-17 23:19+0200\n" -"PO-Revision-Date: 2023-08-11 19:51+0000\n" -"Last-Translator: HeartBlin913861820c094e37 \n" +"PO-Revision-Date: 2024-10-13 22:15+0000\n" +"Last-Translator: AtomicDude \n" "Language-Team: Romanian \n" "Language: ro\n" @@ -18,7 +18,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < " "20)) ? 1 : 2;\n" -"X-Generator: Weblate 5.0-dev\n" +"X-Generator: Weblate 5.8-dev\n" #: modules/files.nix:191 msgid "Creating home file links in %s" @@ -26,7 +26,7 @@ msgstr "Se creează legături ale fișierelor personale în %s" #: modules/files.nix:204 msgid "Cleaning up orphan links from %s" -msgstr "Se curăță legăturiile orfane din %s" +msgstr "Se curăță legăturile orfane din %s" #: modules/files.nix:220 msgid "Creating profile generation %s" From f81be125ff5a47b2f0a2289ccb6d4c752083659b Mon Sep 17 00:00:00 2001 From: Viktor Illmer Date: Thu, 17 Oct 2024 02:20:16 +0200 Subject: [PATCH 022/546] Translate using Weblate (German) Currently translated at 100.0% (18 of 18 strings) Co-authored-by: Viktor Illmer Translate-URL: https://hosted.weblate.org/projects/home-manager/modules/de/ Translation: Home Manager/Home Manager Modules --- modules/po/de.po | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/po/de.po b/modules/po/de.po index 5783cd7d7..d9cdbc944 100644 --- a/modules/po/de.po +++ b/modules/po/de.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: Home Manager Modules\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" "POT-Creation-Date: 2024-04-17 23:19+0200\n" -"PO-Revision-Date: 2023-12-29 02:09+0000\n" -"Last-Translator: Peter Pfeufer \n" +"PO-Revision-Date: 2024-10-15 21:37+0000\n" +"Last-Translator: Viktor Illmer \n" "Language-Team: German \n" "Language: de\n" @@ -17,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.4-dev\n" +"X-Generator: Weblate 5.8-rc\n" #: modules/files.nix:191 msgid "Creating home file links in %s" @@ -120,7 +120,7 @@ msgstr "Fehler: HOME ist auf \"%s\" gesetzt, aber wir erwarten \"%s\"" #: modules/lib-bash/activation-init.sh:153 msgid "Starting Home Manager activation" -msgstr "Starte Home Manager Aktivierung" +msgstr "Starte Home-Manager-Aktivierung" #: modules/lib-bash/activation-init.sh:157 msgid "Sanity checking Nix" From 5bb057a7b527f8061f5b3dfaaf06650a23034f18 Mon Sep 17 00:00:00 2001 From: Julius Marozas Date: Thu, 17 Oct 2024 02:20:16 +0200 Subject: [PATCH 023/546] Translate using Weblate (Lithuanian) Currently translated at 97.2% (36 of 37 strings) Co-authored-by: Julius Marozas Translate-URL: https://hosted.weblate.org/projects/home-manager/cli/lt/ Translation: Home Manager/Home Manager CLI --- home-manager/po/lt.po | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/home-manager/po/lt.po b/home-manager/po/lt.po index 458ac14a7..c635d93a6 100644 --- a/home-manager/po/lt.po +++ b/home-manager/po/lt.po @@ -8,22 +8,22 @@ msgstr "" "Project-Id-Version: Home Manager\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" "POT-Creation-Date: 2024-04-17 23:19+0200\n" -"PO-Revision-Date: 2024-02-16 22:01+0000\n" -"Last-Translator: Robert Helgesson \n" +"PO-Revision-Date: 2024-10-17 00:20+0000\n" +"Last-Translator: Julius Marozas \n" "Language-Team: Lithuanian \n" "Language: lt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " -"(n%100<10 || n%100>=20) ? 1 : 2);\n" -"X-Generator: Weblate 5.4\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (" +"n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Weblate 5.8-rc\n" #. translators: For example: "home-manager: missing argument for --cores" #: home-manager/home-manager:16 msgid "%s: missing argument for %s" -msgstr "" +msgstr "%s: trūksta argumento %s" #: home-manager/home-manager:64 msgid "No configuration file found at %s" @@ -55,6 +55,8 @@ msgid "" "The fallback Home Manager path %s has been deprecated and a file/directory " "was found there." msgstr "" +"Atsarginis kelias %s į Home Manager jau nebenaudojamas, tačiau jame buvo " +"rastas failas/katalogas." #. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated. #: home-manager/home-manager:118 @@ -77,6 +79,24 @@ msgid "" "\n" " $ rm -r \"%s\"" msgstr "" +"Norėdami pašalinti šį įspėjimą, atlikite vieną iš šių veiksmų.\n" +"\n" +"1. Aiškiai nurodykite kelią į Home Manager, pavyzdžiui, pridėdami\n" +"\n" +" { programs.home-manager.path = \"%s\"; }\n" +"\n" +" prie jūsų konfigūracijos.\n" +"\n" +" Jei importuojate Home Manager tiesiogiai, galite naudoti parametrą `path`." +"\n" +"\n" +" pkgs.callPackage /path/to/home-manager-package { path = \"%s\"; }\n" +"\n" +" kviečiant į Home Manager paketą.\n" +"\n" +"2. Pašalinkite nebenaudojamą kelią.\n" +"\n" +" $ rm -r \"%s\"" #: home-manager/home-manager:146 msgid "Sanity checking Nix" @@ -175,10 +195,9 @@ msgstr "Nežinomas \"news.display\" nustatymas \"%s\"." #: home-manager/home-manager:594 #, sh-format msgid "Please set the $EDITOR or $VISUAL environment variable" -msgstr "" +msgstr "Nustatykite $EDITOR arba $VISUAL aplinkos kintamuosius" #: home-manager/home-manager:612 -#, fuzzy msgid "Cannot run build in read-only directory" msgstr "Negalima vykdyti kompiliavimo read-only kataloge" From 1d9b4a3e60398572f4a760bc93f89ebeebbdb3e2 Mon Sep 17 00:00:00 2001 From: "Jeffrey C. Ollie" Date: Mon, 5 Feb 2024 19:34:52 -0600 Subject: [PATCH 024/546] fish: make generation of completions optional Add a config option to optionally disable the generation of command completions based upon man pages. --- modules/programs/fish.nix | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index 8cd7f9f92..02141042d 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -253,6 +253,12 @@ in { ''; }; + generateCompletions = mkEnableOption + "the automatic generation of completions based upon installed man pages" + // { + default = true; + }; + shellAliases = mkOption { type = with types; attrsOf str; default = { }; @@ -390,9 +396,9 @@ in { }; config = mkIf cfg.enable (mkMerge [ - { - home.packages = [ cfg.package ]; + { home.packages = [ cfg.package ]; } + (mkIf cfg.generateCompletions { # Support completion for `man` by building a cache for `apropos`. programs.man.generateCaches = mkDefault true; @@ -456,7 +462,9 @@ in { set fish_complete_path $prev "${config.xdg.dataHome}/fish/home-manager_generated_completions" $post end ''; + }) + { xdg.configFile."fish/config.fish".source = fishIndent "config.fish" '' # ~/.config/fish/config.fish: DO NOT EDIT -- this file has been generated # automatically by home-manager. From 800a191f33ce7311e5070ff10d6fb5030b55fdde Mon Sep 17 00:00:00 2001 From: xwjqv <35635774+xwjqv@users.noreply.github.com> Date: Sat, 5 Oct 2024 20:26:47 +0200 Subject: [PATCH 025/546] broot: allow multiple keyboard keys per verb To allow multiple keys the verb options need to accept listOf str. --- modules/programs/broot.nix | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/programs/broot.nix b/modules/programs/broot.nix index 6a1680e07..b4cd6d620 100644 --- a/modules/programs/broot.nix +++ b/modules/programs/broot.nix @@ -15,7 +15,7 @@ let modal = mkEnableOption "modal (vim) mode"; verbs = mkOption { - type = with types; listOf (attrsOf (either bool str)); + type = with types; listOf (attrsOf (oneOf [ bool str (listOf str) ])); default = [ ]; example = literalExpression '' [ @@ -46,6 +46,9 @@ let `key` (optional) : a keyboard key triggering execution + `keys` (optional) + : multiple keyboard keys each triggering execution + `shortcut` (optional) : an alternate way to call the verb (without the arguments part) From e43902a7d6df1ce25063d59fa35ab786fa9f7704 Mon Sep 17 00:00:00 2001 From: Robert Helgesson Date: Thu, 17 Oct 2024 13:51:49 +0200 Subject: [PATCH 026/546] broot: fix minor documentation bug --- modules/programs/broot.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/programs/broot.nix b/modules/programs/broot.nix index b4cd6d620..c1ce94776 100644 --- a/modules/programs/broot.nix +++ b/modules/programs/broot.nix @@ -57,7 +57,7 @@ let : whether to quit broot on execution (default: `true`) - `from_shell` (optional) + `from_shell` (optional) : whether the verb must be executed from the parent shell (default: `false`) ''; From 78a7a070bbcc3b37cc36080c2a3514207d427b3b Mon Sep 17 00:00:00 2001 From: home-manager-bot <106474382+home-manager-bot@users.noreply.github.com> Date: Thu, 17 Oct 2024 13:53:03 +0200 Subject: [PATCH 027/546] flake.lock: Update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flake lock file updates: • Updated input 'nixpkgs': 'github:NixOS/nixpkgs/5633bcff0c6162b9e4b5f1264264611e950c8ec7?narHash=sha256-9UTxR8eukdg%2BXZeHgxW5hQA9fIKHsKCdOIUycTryeVw%3D' (2024-10-09) → 'github:NixOS/nixpkgs/a3c0b3b21515f74fd2665903d4ce6bc4dc81c77c?narHash=sha256-nsNdSldaAyu6PE3YUA%2BYQLqUDJh%2BgRbBooMMekZJwvI%3D' (2024-10-14) Co-authored-by: github-actions[bot] --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 0ce117f43..6837fdba2 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1728492678, - "narHash": "sha256-9UTxR8eukdg+XZeHgxW5hQA9fIKHsKCdOIUycTryeVw=", + "lastModified": 1728888510, + "narHash": "sha256-nsNdSldaAyu6PE3YUA+YQLqUDJh+gRbBooMMekZJwvI=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "5633bcff0c6162b9e4b5f1264264611e950c8ec7", + "rev": "a3c0b3b21515f74fd2665903d4ce6bc4dc81c77c", "type": "github" }, "original": { From 9c1a1c7df49a9b28539ccb509b36d0b81e41391c Mon Sep 17 00:00:00 2001 From: Robert Helgesson Date: Thu, 17 Oct 2024 15:29:43 +0200 Subject: [PATCH 028/546] activitywatch: reduce test closure This also reduces test flakiness. --- tests/modules/services/activitywatch/basic-setup.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/modules/services/activitywatch/basic-setup.nix b/tests/modules/services/activitywatch/basic-setup.nix index d3a14ae87..a8ba1cb49 100644 --- a/tests/modules/services/activitywatch/basic-setup.nix +++ b/tests/modules/services/activitywatch/basic-setup.nix @@ -5,6 +5,7 @@ let stubPackage = config.lib.test.mkStubPackage { }; in { services.activitywatch = { enable = true; + package = stubPackage; settings = { port = 3012; custom_static = { custom-watcher = stubPackage; }; From e78cbb20276f09c1802e62d2f77fc93ec32da268 Mon Sep 17 00:00:00 2001 From: libewa Date: Sun, 26 May 2024 11:41:16 +0200 Subject: [PATCH 029/546] zed-editor: add module Add a simple module for zed-editor, a simple editor written in Rust. --- modules/lib/maintainers.nix | 5 ++ modules/misc/news.nix | 10 +++ modules/modules.nix | 1 + modules/programs/zed-editor.nix | 89 +++++++++++++++++++ tests/default.nix | 1 + tests/modules/programs/zed-editor/default.nix | 5 ++ .../programs/zed-editor/extensions.nix | 24 +++++ tests/modules/programs/zed-editor/keymap.nix | 39 ++++++++ .../modules/programs/zed-editor/settings.nix | 36 ++++++++ 9 files changed, 210 insertions(+) create mode 100644 modules/programs/zed-editor.nix create mode 100644 tests/modules/programs/zed-editor/default.nix create mode 100644 tests/modules/programs/zed-editor/extensions.nix create mode 100644 tests/modules/programs/zed-editor/keymap.nix create mode 100644 tests/modules/programs/zed-editor/settings.nix diff --git a/modules/lib/maintainers.nix b/modules/lib/maintainers.nix index 501917ffb..5916024b0 100644 --- a/modules/lib/maintainers.nix +++ b/modules/lib/maintainers.nix @@ -349,6 +349,11 @@ githubId = 12465195; name = "Bruno BELANYI"; }; + libewa = { + email = "libewa-git@icloud.com"; + github = "libewa"; + githubId = 67926131; + }; malvo = { email = "malte@malvo.org"; github = "malte-v"; diff --git a/modules/misc/news.nix b/modules/misc/news.nix index 732c92478..bf5e4be76 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -1770,6 +1770,16 @@ in { ideas from mutt. ''; } + + { + time = "2024-10-17T13:07:55+00:00"; + message = '' + A new module is available: 'programs.zed-editor'. + + Zed is a fast text editor for macOS and Linux. + See https://zed.dev for more. + ''; + } ]; }; } diff --git a/modules/modules.nix b/modules/modules.nix index b6880e62f..b2b98e231 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -262,6 +262,7 @@ let ./programs/yt-dlp.nix ./programs/z-lua.nix ./programs/zathura.nix + ./programs/zed-editor.nix ./programs/zellij.nix ./programs/zk.nix ./programs/zoxide.nix diff --git a/modules/programs/zed-editor.nix b/modules/programs/zed-editor.nix new file mode 100644 index 000000000..250d891bb --- /dev/null +++ b/modules/programs/zed-editor.nix @@ -0,0 +1,89 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.zed-editor; + jsonFormat = pkgs.formats.json { }; + + mergedSettings = cfg.userSettings // { + # this part by @cmacrae + auto_install_extensions = lib.genAttrs cfg.extensions (_: true); + }; +in { + meta.maintainers = [ hm.maintainers.libewa ]; + + options = { + # TODO: add vscode option parity (installing extensions, configuring + # keybinds with nix etc.) + programs.zed-editor = { + enable = mkEnableOption + "Zed, the high performance, multiplayer code editor from the creators of Atom and Tree-sitter"; + + package = mkPackageOption pkgs "zed-editor" { }; + + userSettings = mkOption { + type = jsonFormat.type; + default = { }; + example = literalExpression '' + { + features = { + copilot = false; + }; + telemetry = { + metrics = false; + }; + vim_mode = false; + ui_font_size = 16; + buffer_font_size = 16; + } + ''; + description = '' + Configuration written to Zed's {file}`settings.json`. + ''; + }; + + userKeymaps = mkOption { + type = jsonFormat.type; + default = { }; + example = literalExpression '' + [ + { + context = "Workspace"; + bindings = { + ctrl-shift-t = "workspace::NewTerminal"; + }; + }; + ] + ''; + description = '' + Configuration written to Zed's {file}`keymap.json`. + ''; + }; + + extensions = mkOption { + type = types.listOf types.str; + default = [ ]; + example = literalExpression '' + [ "swift" "nix" "xy-zed" ] + ''; + description = '' + A list of the extensions Zed should install on startup. + Use the name of a repository in the [extension list](https://github.com/zed-industries/extensions/tree/main/extensions). + ''; + }; + }; + }; + + config = mkIf cfg.enable { + home.packages = [ cfg.package ]; + + xdg.configFile."zed/settings.json" = (mkIf (mergedSettings != { }) { + source = jsonFormat.generate "zed-user-settings" mergedSettings; + }); + + xdg.configFile."zed/keymap.json" = (mkIf (cfg.userKeymaps != { }) { + source = jsonFormat.generate "zed-user-keymaps" cfg.userKeymaps; + }); + }; +} diff --git a/tests/default.nix b/tests/default.nix index 90371aafe..9e431e473 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -161,6 +161,7 @@ in import nmtSrc { ./modules/programs/watson ./modules/programs/wezterm ./modules/programs/yazi + ./modules/programs/zed-editor ./modules/programs/zellij ./modules/programs/zk ./modules/programs/zplug diff --git a/tests/modules/programs/zed-editor/default.nix b/tests/modules/programs/zed-editor/default.nix new file mode 100644 index 000000000..3c5c894fe --- /dev/null +++ b/tests/modules/programs/zed-editor/default.nix @@ -0,0 +1,5 @@ +{ + zed-extensions = ./extensions.nix; + zed-keymap = ./keymap.nix; + zed-settings = ./settings.nix; +} diff --git a/tests/modules/programs/zed-editor/extensions.nix b/tests/modules/programs/zed-editor/extensions.nix new file mode 100644 index 000000000..82b79aed8 --- /dev/null +++ b/tests/modules/programs/zed-editor/extensions.nix @@ -0,0 +1,24 @@ +{ config, ... }: + +{ + programs.zed-editor = { + enable = true; + package = config.lib.test.mkStubPackage { }; + extensions = [ "swift" "html" "xy-zed" ]; + }; + + nmt.script = let + expectedContent = builtins.toFile "expected.json" '' + { + "auto_install_extensions": { + "html": true, + "swift": true, + "xy-zed": true + } + } + ''; + in '' + assertFileExists "home-files/.config/zed/settings.json" + assertFileContent "home-files/.config/zed/settings.json" "${expectedContent}" + ''; +} diff --git a/tests/modules/programs/zed-editor/keymap.nix b/tests/modules/programs/zed-editor/keymap.nix new file mode 100644 index 000000000..df6abebdf --- /dev/null +++ b/tests/modules/programs/zed-editor/keymap.nix @@ -0,0 +1,39 @@ +# Test custom keymap functionality +{ config, ... }: + +{ + programs.zed-editor = { + enable = true; + package = config.lib.test.mkStubPackage { }; + userKeymaps = [ + { bindings = { up = "menu::SelectPrev"; }; } + { + context = "Editor"; + bindings = { escape = "editor::Cancel"; }; + } + ]; + }; + + nmt.script = let + expectedContent = builtins.toFile "expected.json" '' + [ + { + "bindings": { + "up": "menu::SelectPrev" + } + }, + { + "bindings": { + "escape": "editor::Cancel" + }, + "context": "Editor" + } + ] + ''; + + keymapPath = ".config/zed/keymap.json"; + in '' + assertFileExists "home-files/${keymapPath}" + assertFileContent "home-files/${keymapPath}" "${expectedContent}" + ''; +} diff --git a/tests/modules/programs/zed-editor/settings.nix b/tests/modules/programs/zed-editor/settings.nix new file mode 100644 index 000000000..701caab13 --- /dev/null +++ b/tests/modules/programs/zed-editor/settings.nix @@ -0,0 +1,36 @@ +# Test custom keymap functionality +{ config, ... }: + +{ + programs.zed-editor = { + enable = true; + package = config.lib.test.mkStubPackage { }; + userSettings = { + theme = "XY-Zed"; + features = { copilot = false; }; + vim_mode = false; + ui_font_size = 16; + buffer_font_size = 16; + }; + }; + + nmt.script = let + expectedContent = builtins.toFile "expected.json" '' + { + "auto_install_extensions": {}, + "buffer_font_size": 16, + "features": { + "copilot": false + }, + "theme": "XY-Zed", + "ui_font_size": 16, + "vim_mode": false + } + ''; + + settingsPath = ".config/zed/settings.json"; + in '' + assertFileExists "home-files/${settingsPath}" + assertFileContent "home-files/${settingsPath}" "${expectedContent}" + ''; +} From 1834304bc3849bfec635cab408e6090d536a549f Mon Sep 17 00:00:00 2001 From: K900 Date: Thu, 17 Oct 2024 22:10:39 +0300 Subject: [PATCH 030/546] direnv: simplify, work around nushell/nushell#14112 nushell 0.99 does not like early returns in hooks. So, what if we just didn't? Rewrite the entire hook to work as one single pipeline. --- modules/programs/direnv.nix | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/modules/programs/direnv.nix b/modules/programs/direnv.nix index 4d4862afb..228430c24 100644 --- a/modules/programs/direnv.nix +++ b/modules/programs/direnv.nix @@ -162,28 +162,20 @@ in { $env.config.hooks.pre_prompt? | default [] | append {|| - let direnv = ( - ${direnvWrapped} - | from json --strict - | default {} - ) - if ($direnv | is-empty) { - return - } - $direnv + ${direnvWrapped} + | from json --strict + | default {} | items {|key, value| - { - key: $key - value: (do ( - $env.ENV_CONVERSIONS? - | default {} - | get -i $key - | get -i from_string - | default {|x| $x} - ) $value) - } + let value = do ( + $env.ENV_CONVERSIONS? + | default {} + | get -i $key + | get -i from_string + | default {|x| $x} + ) $value + return [ $key $value ] } - | transpose -ird + | into record | load-env } ) From cb93ab1c990c5719ec199e8c397e688de06cb46d Mon Sep 17 00:00:00 2001 From: K900 Date: Fri, 18 Oct 2024 07:54:12 +0300 Subject: [PATCH 031/546] direnv: remove nushell hack --- modules/programs/direnv.nix | 31 +++-------------------- tests/modules/programs/direnv/nushell.nix | 2 +- 2 files changed, 5 insertions(+), 28 deletions(-) diff --git a/modules/programs/direnv.nix b/modules/programs/direnv.nix index 228430c24..6d0af3ac1 100644 --- a/modules/programs/direnv.nix +++ b/modules/programs/direnv.nix @@ -130,39 +130,16 @@ in { ${getExe cfg.package} hook fish | source ''); - programs.nushell.extraConfig = mkIf cfg.enableNushellIntegration (let - # We want to get the stdout from direnv even if it exits with non-zero, - # because it will have the DIRENV_ internal variables defined. - # - # However, nushell's current implementation of try-catch is subtly - # broken with external commands in pipelines[0]. - # - # This means we don't have a good way to ignore the exit code - # without using do | complete, which has a side effect of also - # capturing stderr, which we don't want. - # - # So, as a workaround, we wrap nushell in a second script that - # just ignores the exit code and does nothing else, allowing - # nushell to capture our stdout, but letting stderr go through - # and not causing a spurious "command failed" message. - # - # [0]: https://github.com/nushell/nushell/issues/13868 - # - # FIXME: remove the wrapper once the upstream issue is fixed - - direnvWrapped = pkgs.writeShellScript "direnv-wrapped" '' - ${getExe cfg.package} export json || true - ''; - # Using mkAfter to make it more likely to appear after other - # manipulations of the prompt. - in mkAfter '' + # Using mkAfter to make it more likely to appear after other + # manipulations of the prompt. + programs.nushell.extraConfig = mkIf cfg.enableNushellIntegration (mkAfter '' $env.config = ($env.config? | default {}) $env.config.hooks = ($env.config.hooks? | default {}) $env.config.hooks.pre_prompt = ( $env.config.hooks.pre_prompt? | default [] | append {|| - ${direnvWrapped} + ${getExe cfg.package} export json | from json --strict | default {} | items {|key, value| diff --git a/tests/modules/programs/direnv/nushell.nix b/tests/modules/programs/direnv/nushell.nix index 86293e1d7..502b325d5 100644 --- a/tests/modules/programs/direnv/nushell.nix +++ b/tests/modules/programs/direnv/nushell.nix @@ -13,6 +13,6 @@ "home-files/.config/nushell/config.nu"; in '' assertFileExists "${configFile}" - assertFileRegex "${configFile}" '/nix/store/.*direnv-wrapped' + assertFileRegex "${configFile}" '/nix/store/.*direnv.*/bin/direnv export json' ''; } From d4a3186de0eeb37d1e43ed65791b0af677e440a1 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Thu, 17 Oct 2024 09:19:51 -0500 Subject: [PATCH 032/546] firefox: conditional search file --- modules/programs/firefox/mkFirefoxModule.nix | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/programs/firefox/mkFirefoxModule.nix b/modules/programs/firefox/mkFirefoxModule.nix index dd4920666..f7403e59a 100644 --- a/modules/programs/firefox/mkFirefoxModule.nix +++ b/modules/programs/firefox/mkFirefoxModule.nix @@ -777,11 +777,12 @@ in { force = profile.containersForce; }; - "${profilesPath}/${profile.path}/search.json.mozlz4" = { - enable = profile.search.enable; - force = profile.search.force; - source = profile.search.file; - }; + "${profilesPath}/${profile.path}/search.json.mozlz4" = + mkIf (profile.search.enable) { + enable = profile.search.enable; + force = profile.search.force; + source = profile.search.file; + }; "${profilesPath}/${profile.path}/extensions" = mkIf (profile.extensions != [ ]) { From 2ffb68e20981d78bfcc73b2271f2dfa003df182c Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Thu, 17 Oct 2024 09:29:42 -0500 Subject: [PATCH 033/546] thunderbird: conditional search file --- modules/programs/thunderbird.nix | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/programs/thunderbird.nix b/modules/programs/thunderbird.nix index a5ba0e63e..ad7a1360f 100644 --- a/modules/programs/thunderbird.nix +++ b/modules/programs/thunderbird.nix @@ -408,11 +408,12 @@ in { profile.extraConfig; }; - "${thunderbirdProfilesPath}/${name}/search.json.mozlz4" = { - enable = profile.search.enable; - force = profile.search.force; - source = profile.search.file; - }; + "${thunderbirdProfilesPath}/${name}/search.json.mozlz4" = + mkIf (profile.search.enable) { + enable = profile.search.enable; + force = profile.search.force; + source = profile.search.file; + }; })); }; } From 346973b338365240090eded0de62f7edce4ce3d1 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Thu, 17 Oct 2024 10:03:51 -0500 Subject: [PATCH 034/546] tests/firefox: add shared path test Used to make sure that profiles that share a common generated path still build properly. --- tests/modules/programs/firefox/common.nix | 1 + .../programs/firefox/profiles/shared-path.nix | 53 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 tests/modules/programs/firefox/profiles/shared-path.nix diff --git a/tests/modules/programs/firefox/common.nix b/tests/modules/programs/firefox/common.nix index 7d05382f1..a3af6d4ab 100644 --- a/tests/modules/programs/firefox/common.nix +++ b/tests/modules/programs/firefox/common.nix @@ -12,4 +12,5 @@ builtins.mapAttrs (test: module: import module [ "programs" name ]) { "${name}-profiles-search" = ./profiles/search; "${name}-profiles-settings" = ./profiles/settings; "${name}-state-version-19_09" = ./state-version-19_09.nix; + "${name}-profiles-shared-path" = ./profiles/shared-path.nix; } diff --git a/tests/modules/programs/firefox/profiles/shared-path.nix b/tests/modules/programs/firefox/profiles/shared-path.nix new file mode 100644 index 000000000..e6d4a06d4 --- /dev/null +++ b/tests/modules/programs/firefox/profiles/shared-path.nix @@ -0,0 +1,53 @@ +modulePath: +{ config, lib, ... }: + +with lib; + +let firefoxMockOverlay = import ../setup-firefox-mock-overlay.nix modulePath; +in { + imports = [ firefoxMockOverlay ]; + + config = mkIf config.test.enableBig (setAttrByPath modulePath { + enable = true; + + profiles = { + main = { + isDefault = true; + id = 1; + bookmarks = [{ + toolbar = true; + bookmarks = [{ + name = "Home Manager"; + url = "https://wiki.nixos.org/wiki/Home_Manager"; + }]; + }]; + containers = { + "shopping" = { + icon = "circle"; + color = "yellow"; + }; + }; + search = { + force = true; + default = "Google"; + privateDefault = "DuckDuckGo"; + engines = { + "Bing".metaData.hidden = true; + "Google".metaData.alias = "@g"; + }; + }; + settings = { + "general.smoothScroll" = false; + "browser.newtabpage.pinned" = [{ + title = "NixOS"; + url = "https://nixos.org"; + }]; + }; + }; + "dev-edition-default" = { + id = 2; + path = "main"; + }; + }; + }); +} From 09a0c0c02953318bf94425738c7061ffdc4cba75 Mon Sep 17 00:00:00 2001 From: joygnu Date: Thu, 10 Oct 2024 00:08:02 +0200 Subject: [PATCH 035/546] cmus: add module PR #5951 --- modules/lib/maintainers.nix | 6 ++++ modules/misc/news.nix | 9 +++++ modules/modules.nix | 1 + modules/programs/cmus.nix | 44 +++++++++++++++++++++++++ tests/default.nix | 1 + tests/modules/programs/cmus/cmus.nix | 20 +++++++++++ tests/modules/programs/cmus/default.nix | 1 + 7 files changed, 82 insertions(+) create mode 100644 modules/programs/cmus.nix create mode 100644 tests/modules/programs/cmus/cmus.nix create mode 100644 tests/modules/programs/cmus/default.nix diff --git a/modules/lib/maintainers.nix b/modules/lib/maintainers.nix index 5916024b0..ce88b1cf0 100644 --- a/modules/lib/maintainers.nix +++ b/modules/lib/maintainers.nix @@ -604,6 +604,12 @@ github = "zorrobert"; githubId = 118135271; }; + joygnu = { + name = "joygnu"; + email = "contact@joygnu.org"; + github = "joygnu"; + githubId = 152063003; + }; callumio = { name = "Callum Leslie"; email = "git+nix@cleslie.uk"; diff --git a/modules/misc/news.nix b/modules/misc/news.nix index bf5e4be76..6c1b9b89b 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -1780,6 +1780,15 @@ in { See https://zed.dev for more. ''; } + + { + time = "2024-10-18T14:01:07+00:00"; + message = '' + A new module is available: 'programs.cmus'. + + cmus is a small, fast and powerful console music player. + ''; + } ]; }; } diff --git a/modules/modules.nix b/modules/modules.nix index b2b98e231..133a0dfff 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -77,6 +77,7 @@ let ./programs/carapace.nix ./programs/cava.nix ./programs/chromium.nix + ./programs/cmus.nix ./programs/command-not-found/command-not-found.nix ./programs/comodoro.nix ./programs/darcs.nix diff --git a/modules/programs/cmus.nix b/modules/programs/cmus.nix new file mode 100644 index 000000000..ac3e46ee1 --- /dev/null +++ b/modules/programs/cmus.nix @@ -0,0 +1,44 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.programs.cmus; + +in { + meta.maintainers = [ hm.maintainers.joygnu ]; + + options.programs.cmus = { + enable = mkEnableOption "Enable cmus, the music player."; + + theme = mkOption { + type = types.lines; + default = ""; + example = "gruvbox"; + description = '' + Select color theme. A list of available color themes can be found + here: . + ''; + }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + example = '' + set audio_backend = "mpd" + set status_display = "default" + ''; + description = "Extra configuration to add to cmus {file}`rc`."; + }; + }; + + config = mkIf cfg.enable { + home.packages = [ pkgs.cmus ]; + + home.file.".config/cmus/rc".text = '' + ${optionalString (cfg.theme != "") "colorscheme ${cfg.theme}"} + ${cfg.extraConfig} + ''; + }; +} diff --git a/tests/default.nix b/tests/default.nix index 9e431e473..f4b03275b 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -67,6 +67,7 @@ in import nmtSrc { ./modules/programs/btop ./modules/programs/carapace ./modules/programs/cava + ./modules/programs/cmus ./modules/programs/comodoro ./modules/programs/darcs ./modules/programs/dircolors diff --git a/tests/modules/programs/cmus/cmus.nix b/tests/modules/programs/cmus/cmus.nix new file mode 100644 index 000000000..8d1bbbd3a --- /dev/null +++ b/tests/modules/programs/cmus/cmus.nix @@ -0,0 +1,20 @@ +{ ... }: + +{ + programs.cmus = { + enable = true; + theme = "gruvbox"; + extraConfig = "test"; + }; + + nmt.script = '' + assertFileContent \ + home-files/.config/cmus/rc \ + ${ + builtins.toFile "cmus-expected-rc" '' + colorscheme gruvbox + test + '' + } + ''; +} diff --git a/tests/modules/programs/cmus/default.nix b/tests/modules/programs/cmus/default.nix new file mode 100644 index 000000000..1b606bab3 --- /dev/null +++ b/tests/modules/programs/cmus/default.nix @@ -0,0 +1 @@ +{ cmus = ./cmus.nix; } From 802b3cb2d45ad66619ea8ad19b280baa460556d2 Mon Sep 17 00:00:00 2001 From: Muhammad Talal Anwar Date: Sat, 19 Oct 2024 09:01:11 +0200 Subject: [PATCH 036/546] espanso: use `launcher` command on Linux The source uses `launcher` instead of `daemon`. Additionally we remove `Type` and add `RestartSec` as defined in the source: https://github.com/espanso/espanso/blob/b421bcf73fa13506938d62425459d6c16c6a8d0a/espanso/src/res/linux/systemd.service#L5-L7C1 --- modules/services/espanso.nix | 4 ++-- tests/modules/services/espanso/basic-configuration.service | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/services/espanso.nix b/modules/services/espanso.nix index f6e27e796..dbfa05875 100644 --- a/modules/services/espanso.nix +++ b/modules/services/espanso.nix @@ -121,9 +121,9 @@ in { systemd.user.services.espanso = { Unit = { Description = "Espanso: cross platform text expander in Rust"; }; Service = { - Type = "exec"; - ExecStart = "${cfg.package}/bin/espanso daemon"; + ExecStart = "${cfg.package}/bin/espanso launcher"; Restart = "on-failure"; + RestartSec = 3; }; Install = { WantedBy = [ "default.target" ]; }; }; diff --git a/tests/modules/services/espanso/basic-configuration.service b/tests/modules/services/espanso/basic-configuration.service index 593196e59..2c07465a0 100644 --- a/tests/modules/services/espanso/basic-configuration.service +++ b/tests/modules/services/espanso/basic-configuration.service @@ -2,9 +2,9 @@ WantedBy=default.target [Service] -ExecStart=@espanso@/bin/espanso daemon +ExecStart=@espanso@/bin/espanso launcher Restart=on-failure -Type=exec +RestartSec=3 [Unit] Description=Espanso: cross platform text expander in Rust From 122f70545b29ccb922e655b08acfe05bfb44ec68 Mon Sep 17 00:00:00 2001 From: Scharada Date: Fri, 18 Oct 2024 21:24:18 +0200 Subject: [PATCH 037/546] firefox: change container.json version to 5 --- modules/programs/firefox/mkFirefoxModule.nix | 2 +- .../firefox/profiles/containers/expected-containers.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/programs/firefox/mkFirefoxModule.nix b/modules/programs/firefox/mkFirefoxModule.nix index f7403e59a..8ef3f12d3 100644 --- a/modules/programs/firefox/mkFirefoxModule.nix +++ b/modules/programs/firefox/mkFirefoxModule.nix @@ -101,7 +101,7 @@ let }; in '' ${builtins.toJSON { - version = 4; + version = 5; lastUserContextId = foldlAttrs (acc: _: value: if value.id > acc then value.id else acc) 0 containers; diff --git a/tests/modules/programs/firefox/profiles/containers/expected-containers.json b/tests/modules/programs/firefox/profiles/containers/expected-containers.json index d957b0c50..28d8143d0 100644 --- a/tests/modules/programs/firefox/profiles/containers/expected-containers.json +++ b/tests/modules/programs/firefox/profiles/containers/expected-containers.json @@ -1 +1 @@ -{"identities":[{"color":"yellow","icon":"circle","name":"shopping","public":true,"userContextId":0},{"accessKey":"","color":"","icon":"","name":"userContextIdInternal.thumbnail","public":false,"userContextId":4294967294},{"accessKey":"","color":"","icon":"","name":"userContextIdInternal.webextStorageLocal","public":false,"userContextId":4294967295}],"lastUserContextId":0,"version":4} +{"identities":[{"color":"yellow","icon":"circle","name":"shopping","public":true,"userContextId":0},{"accessKey":"","color":"","icon":"","name":"userContextIdInternal.thumbnail","public":false,"userContextId":4294967294},{"accessKey":"","color":"","icon":"","name":"userContextIdInternal.webextStorageLocal","public":false,"userContextId":4294967295}],"lastUserContextId":0,"version":5} From 892a6443b7676207490c83d181367ba3abcb1f23 Mon Sep 17 00:00:00 2001 From: John Titor <50095635+JohnRTitor@users.noreply.github.com> Date: Tue, 23 Apr 2024 23:07:08 +0530 Subject: [PATCH 038/546] nh: add module --- modules/misc/news.nix | 12 ++++++ modules/modules.nix | 1 + modules/programs/nh.nix | 94 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 modules/programs/nh.nix diff --git a/modules/misc/news.nix b/modules/misc/news.nix index 6c1b9b89b..8f9a77cfa 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -1789,6 +1789,18 @@ in { cmus is a small, fast and powerful console music player. ''; } + + { + time = "2024-10-20T07:53:54+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'programs.nh'. + + nh is yet another Nix CLI helper. Adding functionality on top of the + existing solutions, like nixos-rebuild, home-manager cli or nix + itself. + ''; + } ]; }; } diff --git a/modules/modules.nix b/modules/modules.nix index 133a0dfff..ba8414721 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -172,6 +172,7 @@ let ./programs/neovide.nix ./programs/neovim.nix ./programs/newsboat.nix + ./programs/nh.nix ./programs/nheko.nix ./programs/nix-index.nix ./programs/nnn.nix diff --git a/modules/programs/nh.nix b/modules/programs/nh.nix new file mode 100644 index 000000000..a5e8dcfaf --- /dev/null +++ b/modules/programs/nh.nix @@ -0,0 +1,94 @@ +{ config, osConfig, lib, pkgs, ... }: + +let + + cfg = config.programs.nh; + +in { + meta.maintainers = with lib.maintainers; [ johnrtitor ]; + + options.programs.nh = { + enable = lib.mkEnableOption "nh, yet another Nix CLI helper"; + + package = lib.mkPackageOption pkgs "nh" { }; + + flake = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + description = '' + The path that will be used for the {env}`FLAKE` environment variable. + + {env}`FLAKE` is used by nh as the default flake for performing actions, + like {command}`nh os switch`. + ''; + }; + + clean = { + enable = lib.mkEnableOption '' + periodic garbage collection for user profile and nix store with nh clean + user''; + + dates = lib.mkOption { + type = lib.types.singleLineStr; + default = "weekly"; + description = '' + How often cleanup is performed. + + The format is described in {manpage}`systemd.time(7)`. + ''; + }; + + extraArgs = lib.mkOption { + type = lib.types.singleLineStr; + default = ""; + example = "--keep 5 --keep-since 3d"; + description = '' + Options given to nh clean when the service is run automatically. + + See `nh clean all --help` for more information. + ''; + }; + }; + }; + + config = { + warnings = lib.optionals (!(cfg.clean.enable -> !osConfig.nix.gc.automatic)) + [ + "programs.nh.clean.enable and nix.gc.automatic (system-wide in configuration.nix) are both enabled. Please use one or the other to avoid conflict." + ]; + + assertions = [{ + assertion = (cfg.flake != null) -> !(lib.hasSuffix ".nix" cfg.flake); + message = "nh.flake must be a directory, not a nix file"; + }]; + + home = lib.mkIf cfg.enable { + packages = [ cfg.package ]; + sessionVariables = lib.mkIf (cfg.flake != null) { FLAKE = cfg.flake; }; + }; + + systemd.user = lib.mkIf cfg.clean.enable { + services.nh-clean = { + Unit.Description = "Nh clean (user)"; + + Service = { + Type = "oneshot"; + ExecStart = + "exec ${lib.getExe cfg.package} clean user ${cfg.clean.extraArgs}"; + Environment = "PATH=$PATH:${config.nix.package}"; + }; + }; + + timers.nh-clean = { + Unit.Description = "Run nh clean"; + + Timer = { + OnCalendar = cfg.clean.dates; + Persistent = true; + }; + + Install.WantedBy = [ "timers.target" ]; + }; + }; + }; +} From fe56302339bb28e3471632379d733547caec8103 Mon Sep 17 00:00:00 2001 From: Talha Can Havadar Date: Fri, 11 Oct 2024 21:19:14 +0000 Subject: [PATCH 039/546] zoxide: fix fzf bash-completion conflict When zoxide initializes after fzf it causes fzf " ** " trigger to not work. To fix the issue we needed to make zoxide initialize earlier than fzf but after bash-completion. PR #5955 --- modules/programs/zoxide.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/programs/zoxide.nix b/modules/programs/zoxide.nix index cab75cecf..f5e258af9 100644 --- a/modules/programs/zoxide.nix +++ b/modules/programs/zoxide.nix @@ -68,9 +68,9 @@ in { config = mkIf cfg.enable { home.packages = [ cfg.package ]; - programs.bash.initExtra = mkIf cfg.enableBashIntegration '' + programs.bash.initExtra = mkIf cfg.enableBashIntegration (mkOrder 150 '' eval "$(${cfg.package}/bin/zoxide init bash ${cfgOptions})" - ''; + ''); programs.zsh.initExtra = mkIf cfg.enableZshIntegration '' eval "$(${cfg.package}/bin/zoxide init zsh ${cfgOptions})" From 1e27f213d77fc842603628bcf2df6681d7d08f7e Mon Sep 17 00:00:00 2001 From: home-manager-bot <106474382+home-manager-bot@users.noreply.github.com> Date: Sun, 20 Oct 2024 23:21:28 +0200 Subject: [PATCH 040/546] flake.lock: Update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flake lock file updates: • Updated input 'nixpkgs': 'github:NixOS/nixpkgs/a3c0b3b21515f74fd2665903d4ce6bc4dc81c77c?narHash=sha256-nsNdSldaAyu6PE3YUA%2BYQLqUDJh%2BgRbBooMMekZJwvI%3D' (2024-10-14) → 'github:NixOS/nixpkgs/4c2fcb090b1f3e5b47eaa7bd33913b574a11e0a0?narHash=sha256-/uilDXvCIEs3C9l73JTACm4quuHUsIHcns1c%2BcHUJwA%3D' (2024-10-18) Co-authored-by: github-actions[bot] --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 6837fdba2..d052ebff2 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1728888510, - "narHash": "sha256-nsNdSldaAyu6PE3YUA+YQLqUDJh+gRbBooMMekZJwvI=", + "lastModified": 1729256560, + "narHash": "sha256-/uilDXvCIEs3C9l73JTACm4quuHUsIHcns1c+cHUJwA=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "a3c0b3b21515f74fd2665903d4ce6bc4dc81c77c", + "rev": "4c2fcb090b1f3e5b47eaa7bd33913b574a11e0a0", "type": "github" }, "original": { From 5ec753a1fc4454df9285d8b3ec0809234defb975 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Mon, 21 Oct 2024 17:58:46 -0500 Subject: [PATCH 041/546] modules/neovim: fix config generation (#5976) --- modules/programs/neovim.nix | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/modules/programs/neovim.nix b/modules/programs/neovim.nix index 8632a7ec8..e8be25f92 100644 --- a/modules/programs/neovim.nix +++ b/modules/programs/neovim.nix @@ -398,6 +398,13 @@ in { customRC = cfg.extraConfig; }; + wrappedNeovim' = pkgs.wrapNeovimUnstable cfg.package (neovimConfig // { + wrapperArgs = + (lib.escapeShellArgs (neovimConfig.wrapperArgs ++ cfg.extraWrapperArgs)) + + " " + extraMakeWrapperArgs + " " + extraMakeWrapperLuaCArgs + " " + + extraMakeWrapperLuaArgs; + wrapRc = false; + }); in mkIf cfg.enable { programs.neovim.generatedConfigViml = neovimConfig.neovimRcContent; @@ -422,11 +429,10 @@ in { # writes runtime (map (x: x.runtime) pluginsNormalized) ++ [{ "nvim/init.lua" = let - luaRcContent = - lib.optionalString (neovimConfig.neovimRcContent != "") + luaRcContent = lib.optionalString (wrappedNeovim'.initRc != "") "vim.cmd [[source ${ pkgs.writeText "nvim-init-home-manager.vim" - neovimConfig.neovimRcContent + wrappedNeovim'.initRc }]]" + config.programs.neovim.extraLuaConfig + lib.optionalString hasLuaConfig config.programs.neovim.generatedConfigs.lua; @@ -437,13 +443,6 @@ in { }; }]); - programs.neovim.finalPackage = pkgs.wrapNeovimUnstable cfg.package - (neovimConfig // { - wrapperArgs = (lib.escapeShellArgs - (neovimConfig.wrapperArgs ++ cfg.extraWrapperArgs)) + " " - + extraMakeWrapperArgs + " " + extraMakeWrapperLuaCArgs + " " - + extraMakeWrapperLuaArgs; - wrapRc = false; - }); + programs.neovim.finalPackage = wrappedNeovim'; }; } From 5765fe4feb78092cf3cbe2aa5cd523513eea7769 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20J=C3=A4ckel?= Date: Wed, 23 Oct 2024 22:55:42 +0200 Subject: [PATCH 042/546] accounts/calendar: fix defaultText rendering --- modules/accounts/calendar.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/accounts/calendar.nix b/modules/accounts/calendar.nix index bfbc3e124..86f1b38c5 100644 --- a/modules/accounts/calendar.nix +++ b/modules/accounts/calendar.nix @@ -12,7 +12,8 @@ let path = mkOption { type = types.str; default = "${cfg.basePath}/${name}"; - defaultText = "‹accounts.calendar.basePath›/‹name›"; + defaultText = + lib.literalExpression "‹accounts.calendar.basePath›/‹name›"; description = "The path of the storage."; }; From a4353cc43d1b4dd6bdeacea90eb92a8b7b78a9d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20J=C3=A4ckel?= Date: Wed, 23 Oct 2024 22:55:53 +0200 Subject: [PATCH 043/546] accounts/contacts: fix defaultText rendering --- modules/accounts/contacts.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/accounts/contacts.nix b/modules/accounts/contacts.nix index 272594b18..d00f5d071 100644 --- a/modules/accounts/contacts.nix +++ b/modules/accounts/contacts.nix @@ -12,7 +12,8 @@ let path = mkOption { type = types.str; default = "${cfg.basePath}/${name}"; - defaultText = "‹accounts.contact.basePath›/‹name›"; + defaultText = + lib.literalExpression "‹accounts.contact.basePath›/‹name›"; description = "The path of the storage."; }; From 0a0b1b18bdd16d3f810178c7aec9eca730699631 Mon Sep 17 00:00:00 2001 From: Omer Naveed Date: Thu, 24 Oct 2024 23:41:24 -0500 Subject: [PATCH 044/546] maintainers: remove omernaveedxyz --- modules/lib/maintainers.nix | 6 ------ modules/programs/bemenu.nix | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/modules/lib/maintainers.nix b/modules/lib/maintainers.nix index ce88b1cf0..6b7dc8b42 100644 --- a/modules/lib/maintainers.nix +++ b/modules/lib/maintainers.nix @@ -432,12 +432,6 @@ github = "nurelin"; githubId = 5276274; }; - omernaveedxyz = { - name = "Omer Naveed"; - email = "omer@omernaveed.dev"; - github = "omernaveedxyz"; - githubId = 112912585; - }; otavio = { email = "otavio.salvador@ossystems.com.br"; github = "otavio"; diff --git a/modules/programs/bemenu.nix b/modules/programs/bemenu.nix index 58d24dcc2..f90067216 100644 --- a/modules/programs/bemenu.nix +++ b/modules/programs/bemenu.nix @@ -7,7 +7,7 @@ let cfg = config.programs.bemenu; in { - meta.maintainers = [ hm.maintainers.omernaveedxyz ]; + meta.maintainers = [ ]; options.programs.bemenu = { enable = mkEnableOption "bemenu"; From 454e8d6b15aafb02fd22bba0edc4cc0b06dd0f41 Mon Sep 17 00:00:00 2001 From: Willi Carlsen Date: Wed, 23 Oct 2024 14:07:07 +0200 Subject: [PATCH 045/546] granted: use assume directly The `.assume-wrapped` path is not available since the merge of https://github.com/NixOS/nixpkgs/pull/347816 Use assume directly instead. PR #5994 --- modules/programs/granted.nix | 2 +- tests/modules/programs/granted/integration-disabled.nix | 2 +- tests/modules/programs/granted/integration-enabled.nix | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/programs/granted.nix b/modules/programs/granted.nix index a09169250..93cdb97df 100644 --- a/modules/programs/granted.nix +++ b/modules/programs/granted.nix @@ -28,7 +28,7 @@ in { programs.zsh.initExtra = mkIf cfg.enableZshIntegration '' function assume() { export GRANTED_ALIAS_CONFIGURED="true" - source ${package}/bin/.assume-wrapped "$@" + source ${package}/bin/assume "$@" unset GRANTED_ALIAS_CONFIGURED } ''; diff --git a/tests/modules/programs/granted/integration-disabled.nix b/tests/modules/programs/granted/integration-disabled.nix index 6e43b4777..90f8d494a 100644 --- a/tests/modules/programs/granted/integration-disabled.nix +++ b/tests/modules/programs/granted/integration-disabled.nix @@ -19,7 +19,7 @@ 'export GRANTED_ALIAS_CONFIGURED="true"' assertFileNotRegex \ home-files/.zshrc \ - 'source @granted@/bin/.assume-wrapped "$@"' + 'source @granted@/bin/assume "$@"' assertFileNotRegex \ home-files/.zshrc \ 'unset GRANTED_ALIAS_CONFIGURED' diff --git a/tests/modules/programs/granted/integration-enabled.nix b/tests/modules/programs/granted/integration-enabled.nix index daf843676..5bb903aae 100644 --- a/tests/modules/programs/granted/integration-enabled.nix +++ b/tests/modules/programs/granted/integration-enabled.nix @@ -18,7 +18,7 @@ 'export GRANTED_ALIAS_CONFIGURED="true"' assertFileContains \ home-files/.zshrc \ - 'source @granted@/bin/.assume-wrapped "$@"' + 'source @granted@/bin/assume "$@"' assertFileContains \ home-files/.zshrc \ 'unset GRANTED_ALIAS_CONFIGURED' From eea1bc607249f0b79fb437b5e9709aa6d2218bac Mon Sep 17 00:00:00 2001 From: DrymarchonShaun <40149778+DrymarchonShaun@users.noreply.github.com> Date: Thu, 24 Oct 2024 15:15:43 -0700 Subject: [PATCH 046/546] gpg-agent: use $TTY parameter in zsh integration --- modules/services/gpg-agent.nix | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/services/gpg-agent.nix b/modules/services/gpg-agent.nix index 7af58c8df..8bfe68aae 100644 --- a/modules/services/gpg-agent.nix +++ b/modules/services/gpg-agent.nix @@ -18,6 +18,10 @@ let export GPG_TTY '' + optionalString cfg.enableSshSupport gpgSshSupportStr; + gpgZshInitStr = '' + export GPG_TTY=$TTY + '' + optionalString cfg.enableSshSupport gpgSshSupportStr; + gpgFishInitStr = '' set -gx GPG_TTY (tty) '' + optionalString cfg.enableSshSupport gpgSshSupportStr; @@ -287,7 +291,7 @@ in { ''; programs.bash.initExtra = mkIf cfg.enableBashIntegration gpgInitStr; - programs.zsh.initExtra = mkIf cfg.enableZshIntegration gpgInitStr; + programs.zsh.initExtra = mkIf cfg.enableZshIntegration gpgZshInitStr; programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration gpgFishInitStr; From c7cfdb386430b01fd9748139a0e9cfa40e36c265 Mon Sep 17 00:00:00 2001 From: diniamo Date: Sun, 29 Sep 2024 14:55:46 +0200 Subject: [PATCH 047/546] spotify-player: add support for actions Actions were added in the v0.19.1 release. --- modules/programs/spotify-player.nix | 44 ++++++++++++++++--- .../programs/spotify-player/keymap.toml | 13 ++++++ .../programs/spotify-player/settings.nix | 16 +++++++ 3 files changed, 66 insertions(+), 7 deletions(-) diff --git a/modules/programs/spotify-player.nix b/modules/programs/spotify-player.nix index 83eefe12d..35d3933bc 100644 --- a/modules/programs/spotify-player.nix +++ b/modules/programs/spotify-player.nix @@ -1,12 +1,12 @@ { config, lib, pkgs, ... }: let - inherit (lib) - mkEnableOption mkPackageOption mkOption types literalExpression mkIf; + inherit (lib) mkEnableOption mkPackageOption mkOption literalExpression mkIf; + inherit (lib.types) listOf; cfg = config.programs.spotify-player; tomlFormat = pkgs.formats.toml { }; - + tomlType = tomlFormat.type; in { meta.maintainers = with lib.hm.maintainers; [ diniamo ]; @@ -16,7 +16,7 @@ in { package = mkPackageOption pkgs "spotify-player" { }; settings = mkOption { - type = tomlFormat.type; + type = tomlType; default = { }; example = literalExpression '' { @@ -43,7 +43,7 @@ in { }; themes = mkOption { - type = types.listOf tomlFormat.type; + type = listOf tomlType; default = [ ]; example = literalExpression '' [ @@ -94,7 +94,7 @@ in { }; keymaps = mkOption { - type = types.listOf tomlFormat.type; + type = listOf tomlType; default = [ ]; example = literalExpression '' [ @@ -129,6 +129,36 @@ in { for the full list of options. ''; }; + + actions = mkOption { + type = listOf tomlType; + default = [ ]; + example = literalExpression '' + [ + { + action = "GoToArtist"; + key_sequence = "g A"; + } + { + action = "GoToAlbum"; + key_sequence = "g B"; + target = "PlayingTrack"; + } + { + action = "ToggleLiked"; + key_sequence = "C-l"; + } + ] + ''; + description = '' + Configuration written to the `actions` field of + {file}`$XDG_CONFIG_HOME/spotify-player/keymap.toml`. + + See + + for the full list of options. + ''; + }; }; config = mkIf cfg.enable { @@ -146,7 +176,7 @@ in { "spotify-player/keymap.toml" = mkIf (cfg.keymaps != [ ]) { source = tomlFormat.generate "spotify-player-keymap" { - inherit (cfg) keymaps; + inherit (cfg) keymaps actions; }; }; }; diff --git a/tests/modules/programs/spotify-player/keymap.toml b/tests/modules/programs/spotify-player/keymap.toml index d11c86e41..29cac4781 100644 --- a/tests/modules/programs/spotify-player/keymap.toml +++ b/tests/modules/programs/spotify-player/keymap.toml @@ -1,3 +1,16 @@ +[[actions]] +action = "GoToArtist" +key_sequence = "g A" + +[[actions]] +action = "GoToAlbum" +key_sequence = "g B" +target = "PlayingTrack" + +[[actions]] +action = "ToggleLiked" +key_sequence = "C-l" + [[keymaps]] command = "NextTrack" key_sequence = "g n" diff --git a/tests/modules/programs/spotify-player/settings.nix b/tests/modules/programs/spotify-player/settings.nix index dc7fe8c6a..e0442360b 100644 --- a/tests/modules/programs/spotify-player/settings.nix +++ b/tests/modules/programs/spotify-player/settings.nix @@ -87,6 +87,22 @@ key_sequence = "q"; } ]; + + actions = [ + { + action = "GoToArtist"; + key_sequence = "g A"; + } + { + action = "GoToAlbum"; + key_sequence = "g B"; + target = "PlayingTrack"; + } + { + action = "ToggleLiked"; + key_sequence = "C-l"; + } + ]; }; test.stubs.spotify-player = { }; From 82378b3f7f8c12ecfab8539df780e495e6ba4cb6 Mon Sep 17 00:00:00 2001 From: Luflosi Date: Fri, 21 Jun 2024 17:30:18 +0200 Subject: [PATCH 048/546] htop: use attrsOf instead of attrs as settings type --- modules/programs/htop.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/programs/htop.nix b/modules/programs/htop.nix index 1c569c404..b4004942c 100644 --- a/modules/programs/htop.nix +++ b/modules/programs/htop.nix @@ -113,7 +113,8 @@ in { enable = mkEnableOption "htop"; settings = mkOption { - type = types.attrs; + type = with types; + attrsOf (oneOf [ bool int str (listOf (oneOf [ int str ])) ]); default = { }; example = literalExpression '' { From 446293584f10d56b91368f500c022f7a93edbe2c Mon Sep 17 00:00:00 2001 From: Mel Bourgeois Date: Mon, 29 Apr 2024 19:37:24 -0500 Subject: [PATCH 049/546] nixgl: add module This module enables wrapping programs which require access to libGL with nixGL on non-NixOS systems. --- modules/misc/news.nix | 12 ++++++++ modules/misc/nixgl.nix | 64 ++++++++++++++++++++++++++++++++++++++++++ modules/modules.nix | 1 + 3 files changed, 77 insertions(+) create mode 100644 modules/misc/nixgl.nix diff --git a/modules/misc/news.nix b/modules/misc/news.nix index 8f9a77cfa..801391cc2 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -1801,6 +1801,18 @@ in { itself. ''; } + + { + time = "2024-10-25T08:18:30+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'nixGL'. + + NixGL solve the "OpenGL" problem with nix. The 'nixGL' module provides + integration of NixGL into Home Manager. See the "GPU on non-NixOS + systems" section in the Home Manager mantual for more. + ''; + } ]; }; } diff --git a/modules/misc/nixgl.nix b/modules/misc/nixgl.nix new file mode 100644 index 000000000..b6cff7cc0 --- /dev/null +++ b/modules/misc/nixgl.nix @@ -0,0 +1,64 @@ +{ config, lib, pkgs, ... }: + +let cfg = config.nixGL; +in { + meta.maintainers = [ lib.maintainers.smona ]; + + options.nixGL.prefix = lib.mkOption { + type = lib.types.str; + default = ""; + example = lib.literalExpression + ''"''${inputs.nixGL.packages.x86_64-linux.nixGLIntel}/bin/nixGLIntel"''; + description = '' + The nixGL command that `lib.nixGL.wrap` should wrap packages with. + This can be used to provide libGL access to applications on non-NixOS systems. + + Some packages are wrapped by default (e.g. kitty, firefox), but you can wrap other packages + as well, with `(config.lib.nixGL.wrap )`. If this option is empty (the default), + then `lib.nixGL.wrap` is a no-op. + ''; + }; + + config = { + lib.nixGL.wrap = # Wrap a single package with the configured nixGL wrapper + pkg: + + if cfg.prefix == "" then + pkg + else + # Wrap the package's binaries with nixGL, while preserving the rest of + # the outputs and derivation attributes. + (pkg.overrideAttrs (old: { + name = "nixGL-${pkg.name}"; + + # Make sure this is false for the wrapper derivation, so nix doesn't expect + # a new debug output to be produced. We won't be producing any debug info + # for the original package. + separateDebugInfo = false; + + buildCommand = '' + set -eo pipefail + + ${ + # Heavily inspired by https://stackoverflow.com/a/68523368/6259505 + pkgs.lib.concatStringsSep "\n" (map (outputName: '' + echo "Copying output ${outputName}" + set -x + cp -rs --no-preserve=mode "${ + pkg.${outputName} + }" "''$${outputName}" + set +x + '') (old.outputs or [ "out" ]))} + + rm -rf $out/bin/* + shopt -s nullglob # Prevent loop from running if no files + for file in ${pkg.out}/bin/*; do + echo "#!${pkgs.bash}/bin/bash" > "$out/bin/$(basename $file)" + echo "exec -a \"\$0\" ${cfg.prefix} $file \"\$@\"" >> "$out/bin/$(basename $file)" + chmod +x "$out/bin/$(basename $file)" + done + shopt -u nullglob # Revert nullglob back to its normal default state + ''; + })); + }; +} diff --git a/modules/modules.nix b/modules/modules.nix index ba8414721..3b4985083 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -31,6 +31,7 @@ let ./misc/gtk.nix ./misc/lib.nix ./misc/news.nix + ./misc/nixgl.nix ./misc/numlock.nix ./misc/pam.nix ./misc/qt.nix From bbd4254d00e8c69c4c958ddb51fb18637ca7f9b8 Mon Sep 17 00:00:00 2001 From: Mel Bourgeois Date: Wed, 19 Jun 2024 18:25:56 -0500 Subject: [PATCH 050/546] nixgl: make desktop files point to wrapped exe Some desktop files will refer to the absolute path of the original derivation, which would bypass nixGL wrapping. So we need to replace the path with the path to the wrapper derivation to ensure the wrapped version is always launched. --- modules/misc/nixgl.nix | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/modules/misc/nixgl.nix b/modules/misc/nixgl.nix index b6cff7cc0..16a00a755 100644 --- a/modules/misc/nixgl.nix +++ b/modules/misc/nixgl.nix @@ -57,6 +57,17 @@ in { echo "exec -a \"\$0\" ${cfg.prefix} $file \"\$@\"" >> "$out/bin/$(basename $file)" chmod +x "$out/bin/$(basename $file)" done + + # If .desktop files refer to the old package, replace the references + for dsk in "$out/share/applications"/*.desktop ; do + if ! grep "${pkg.out}" "$dsk" > /dev/null; then + continue + fi + src="$(readlink "$dsk")" + rm "$dsk" + sed "s|${pkg.out}|$out|g" "$src" > "$dsk" + done + shopt -u nullglob # Revert nullglob back to its normal default state ''; })); From b9fe747915d95c3ea37539cccea67d3df39526a9 Mon Sep 17 00:00:00 2001 From: Mel Bourgeois Date: Wed, 19 Jun 2024 18:35:53 -0500 Subject: [PATCH 051/546] nixgl: use makeWrapper and update docs makeWrapper is more consistent with the rest of nixpkgs & home-manager, so it should be a little more maintainable. It can also validate that the wrapper command is executable at build time. --- modules/misc/nixgl.nix | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/modules/misc/nixgl.nix b/modules/misc/nixgl.nix index 16a00a755..c84397fc5 100644 --- a/modules/misc/nixgl.nix +++ b/modules/misc/nixgl.nix @@ -13,9 +13,9 @@ in { The nixGL command that `lib.nixGL.wrap` should wrap packages with. This can be used to provide libGL access to applications on non-NixOS systems. - Some packages are wrapped by default (e.g. kitty, firefox), but you can wrap other packages - as well, with `(config.lib.nixGL.wrap )`. If this option is empty (the default), - then `lib.nixGL.wrap` is a no-op. + Wrap individual packages like so: `(config.lib.nixGL.wrap )`. The returned package + can be used just like the original one, but will have access to libGL. If this option is empty (the default), + then `lib.nixGL.wrap` is a no-op. This is useful on NixOS, where the wrappers are unnecessary. ''; }; @@ -53,9 +53,12 @@ in { rm -rf $out/bin/* shopt -s nullglob # Prevent loop from running if no files for file in ${pkg.out}/bin/*; do - echo "#!${pkgs.bash}/bin/bash" > "$out/bin/$(basename $file)" - echo "exec -a \"\$0\" ${cfg.prefix} $file \"\$@\"" >> "$out/bin/$(basename $file)" - chmod +x "$out/bin/$(basename $file)" + local prog="$(basename "$file")" + makeWrapper \ + "${cfg.prefix}" \ + "$out/bin/$prog" \ + --argv0 "$prog" \ + --add-flags "$file" done # If .desktop files refer to the old package, replace the references From 199cf5634c2ed39fceae0da3b1d0a76f7d47e1b1 Mon Sep 17 00:00:00 2001 From: Mel Bourgeois Date: Wed, 26 Jun 2024 21:14:08 -0500 Subject: [PATCH 052/546] nixgl: use -q to silence grep Co-authored-by: V. <150687949+vigress8@users.noreply.github.com> --- modules/misc/nixgl.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/misc/nixgl.nix b/modules/misc/nixgl.nix index c84397fc5..76b05296b 100644 --- a/modules/misc/nixgl.nix +++ b/modules/misc/nixgl.nix @@ -63,7 +63,7 @@ in { # If .desktop files refer to the old package, replace the references for dsk in "$out/share/applications"/*.desktop ; do - if ! grep "${pkg.out}" "$dsk" > /dev/null; then + if ! grep -q "${pkg.out}" "$dsk"; then continue fi src="$(readlink "$dsk")" From d0c036ca4904701289e0a779253f241feeacbf40 Mon Sep 17 00:00:00 2001 From: Mel Bourgeois Date: Wed, 26 Jun 2024 21:16:22 -0500 Subject: [PATCH 053/546] nixgl: ensure makeWrapper is present during build Co-authored-by: V. <150687949+vigress8@users.noreply.github.com> --- modules/misc/nixgl.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/misc/nixgl.nix b/modules/misc/nixgl.nix index 76b05296b..90bd1f3aa 100644 --- a/modules/misc/nixgl.nix +++ b/modules/misc/nixgl.nix @@ -35,7 +35,7 @@ in { # a new debug output to be produced. We won't be producing any debug info # for the original package. separateDebugInfo = false; - + nativeBuildInputs = old.nativeBuildInputs or [ ] ++ [ pkgs.makeWrapper ]; buildCommand = '' set -eo pipefail From 7dee0dc8f0c7d4f174c481f36d04b9edadba3b7e Mon Sep 17 00:00:00 2001 From: Mel Bourgeois Date: Mon, 1 Jul 2024 15:42:10 -0500 Subject: [PATCH 054/546] nixgl: reference lib directly Co-authored-by: V. <150687949+vigress8@users.noreply.github.com> --- modules/misc/nixgl.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/misc/nixgl.nix b/modules/misc/nixgl.nix index 90bd1f3aa..ca674ff13 100644 --- a/modules/misc/nixgl.nix +++ b/modules/misc/nixgl.nix @@ -41,7 +41,7 @@ in { ${ # Heavily inspired by https://stackoverflow.com/a/68523368/6259505 - pkgs.lib.concatStringsSep "\n" (map (outputName: '' + lib.concatStringsSep "\n" (map (outputName: '' echo "Copying output ${outputName}" set -x cp -rs --no-preserve=mode "${ From e61f87969ae179139164c7fb5e0bb76b791144e5 Mon Sep 17 00:00:00 2001 From: Mel Bourgeois Date: Fri, 9 Aug 2024 19:40:33 -0500 Subject: [PATCH 055/546] nixgl: Improve option documentation --- modules/misc/nixgl.nix | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/modules/misc/nixgl.nix b/modules/misc/nixgl.nix index ca674ff13..47314b9c2 100644 --- a/modules/misc/nixgl.nix +++ b/modules/misc/nixgl.nix @@ -10,12 +10,28 @@ in { example = lib.literalExpression ''"''${inputs.nixGL.packages.x86_64-linux.nixGLIntel}/bin/nixGLIntel"''; description = '' - The nixGL command that `lib.nixGL.wrap` should wrap packages with. - This can be used to provide libGL access to applications on non-NixOS systems. + The [nixGL](https://github.com/nix-community/nixGL) command that `lib.nixGL.wrap` should prefix + package binaries with. nixGL provides your system's version of libGL to applications, enabling + them to access the GPU on non-NixOS systems. - Wrap individual packages like so: `(config.lib.nixGL.wrap )`. The returned package - can be used just like the original one, but will have access to libGL. If this option is empty (the default), - then `lib.nixGL.wrap` is a no-op. This is useful on NixOS, where the wrappers are unnecessary. + Wrap individual packages which require GPU access with the function like so: `(config.lib.nixGL.wrap )`. + The returned package can be used just like the original one, but will have access to libGL. For example: + + ```nix + # If you're using a Home Manager module to configure the package, + # pass it into the module's package argument: + programs.kitty = { + enable = true; + package = (config.lib.nixGL.wrap pkgs.kitty); + }; + + # Otherwise, pass it to any option where a package is expected: + home.packages = [ (config.lib.nixGL.wrap pkgs.hello) ]; + ``` + + If this option is empty (the default), then `lib.nixGL.wrap` is a no-op. This is useful for sharing your Home Manager + configurations between NixOS and non-NixOS systems, since NixOS already provides libGL to applications without the + need for nixGL. ''; }; @@ -35,7 +51,8 @@ in { # a new debug output to be produced. We won't be producing any debug info # for the original package. separateDebugInfo = false; - nativeBuildInputs = old.nativeBuildInputs or [ ] ++ [ pkgs.makeWrapper ]; + nativeBuildInputs = old.nativeBuildInputs or [ ] + ++ [ pkgs.makeWrapper ]; buildCommand = '' set -eo pipefail From 7a5879707bb49c350aee7ab270c917584d430193 Mon Sep 17 00:00:00 2001 From: Jure Varlec Date: Wed, 10 Jul 2024 10:51:32 +0200 Subject: [PATCH 056/546] nixgl: API rework for flexibility and dual-GPU --- docs/manual/usage.md | 1 + docs/manual/usage/gpu-non-nixos.md | 70 ++++++++ modules/misc/nixgl.nix | 252 +++++++++++++++++++++++++---- 3 files changed, 288 insertions(+), 35 deletions(-) create mode 100644 docs/manual/usage/gpu-non-nixos.md diff --git a/docs/manual/usage.md b/docs/manual/usage.md index 2a569aaf9..88e884546 100644 --- a/docs/manual/usage.md +++ b/docs/manual/usage.md @@ -59,5 +59,6 @@ usage/configuration.md usage/rollbacks.md usage/dotfiles.md usage/graphical.md +usage/gpu-non-nixos.md usage/updating.md ``` diff --git a/docs/manual/usage/gpu-non-nixos.md b/docs/manual/usage/gpu-non-nixos.md new file mode 100644 index 000000000..7b7cfbaea --- /dev/null +++ b/docs/manual/usage/gpu-non-nixos.md @@ -0,0 +1,70 @@ +# GPU on non-NixOS systems {#sec-usage-gpu-non-nixos} + +To access the GPU, programs need access to OpenGL and Vulkan libraries. While +this works transparently on NixOS, it does not on other Linux systems. A +solution is provided by [NixGL](https://github.com/nix-community/nixGL), which +can be integrated into Home Manager. + +To enable the integration, import NixGL into your home configuration, either as +a channel, or as a flake input passed via `extraSpecialArgs`. Then, set the +`nixGL.packages` option to the package set provided by NixGL. + +Once integration is enabled, it can be used in two ways: as Nix functions for +wrapping programs installed via Home Manager, and as shell commands for running +programs installed by other means (such as `nix shell`). In either case, there +are several wrappers available. They can be broadly categorized + +- by vendor: as Mesa (for Free drivers of all vendors) and Nvidia (for + Nvidia-specific proprietary drivers). +- by GPU selection: as primary and secondary (offloading). + +For example, the `mesa` wrapper provides support for running programs on the +primary GPU for Intel, AMD and Nouveau drivers, while the `mesaPrime` wrapper +does the same for the secondary GPU. + +**Note:** when using Nvidia wrappers together with flakes, your home +configuration will not be pure and needs to be built using `home-manager switch +--impure`. Otherwise, the build will fail, complaining about missing attribute +`currentTime`. + +Wrapper functions are available under `config.lib.nixGL.wrappers`. However, it +can be more convenient to use the `config.lib.nixGL.wrap` alias, which can be +configured to use any of the wrappers. It is intended to provide a customization +point when the same home configuration is used across several machines with +different hardware. There is also the `config.lib.nixGL.wrapOffload` alias for +two-GPU systems. + +Another convenience is that all wrapper functions are always available. However, +when `nixGL.packages` option is unset, they are no-ops. This allows them to be +used even when the home configuration is used on NixOS machines. The exception +is the `prime-offload` script which ignores `nixGL.packages` and is installed +into the environment whenever `nixGL.prime.installScript` is set. This script, +which can be used to start a program on a secondary GPU, does not depend on +NixGL and is useful on NixOS systems as well. + +Below is an abbreviated example for an Optimus laptop that makes use of both +Mesa and Nvidia wrappers, where the latter is used in dGPU offloading mode. It +demonstrates how to wrap `mpv` to run on the integrated Intel GPU, wrap FreeCAD +to run on the Nvidia dGPU, and how to install the wrapper scripts. It also wraps +Xonotic to run on the dGPU, but uses the wrapper function directly for +demonstration purposes. + +```nix +{ config, lib, pkgs, nixGL, ... }: +{ + nixGL.packages = nixGL.packages; + nixGL.defaultWrapper = "mesa"; + nixGL.offloadWrapper = "nvidiaPrime"; + nixGL.installScripts = [ "mesa" "nvidiaPrime" ]; + + programs.mpv = { + enable = true; + package = config.lib.nixGL.wrap pkgs.mpv; + }; + + home.packages = [ + (config.lib.nixGL.wrapOffload pkgs.freecad) + (config.lib.nixGL.wrappers.nvidiaPrime pkgs.xonotic) + ]; +} +``` diff --git a/modules/misc/nixgl.nix b/modules/misc/nixgl.nix index 47314b9c2..f45c483bc 100644 --- a/modules/misc/nixgl.nix +++ b/modules/misc/nixgl.nix @@ -1,45 +1,166 @@ { config, lib, pkgs, ... }: -let cfg = config.nixGL; +let + cfg = config.nixGL; + wrapperListMarkdown = with builtins; + foldl' (list: name: + list + '' + - ${name} + '') "" (attrNames config.lib.nixGL.wrappers); in { meta.maintainers = [ lib.maintainers.smona ]; - options.nixGL.prefix = lib.mkOption { - type = lib.types.str; - default = ""; - example = lib.literalExpression - ''"''${inputs.nixGL.packages.x86_64-linux.nixGLIntel}/bin/nixGLIntel"''; - description = '' - The [nixGL](https://github.com/nix-community/nixGL) command that `lib.nixGL.wrap` should prefix - package binaries with. nixGL provides your system's version of libGL to applications, enabling - them to access the GPU on non-NixOS systems. + options.nixGL = { + packages = lib.mkOption { + type = with lib.types; nullOr attrs; + default = null; + example = lib.literalExpression "inputs.nixGL.packages"; + description = '' + The nixGL package set containing GPU library wrappers. This can be used + to provide OpenGL and Vulkan access to applications on non-NixOS systems + by using `(config.lib.nixGL.wrap )` for the default wrapper, or + `(config.lib.nixGL.wrappers. )` for any available + wrapper. - Wrap individual packages which require GPU access with the function like so: `(config.lib.nixGL.wrap )`. - The returned package can be used just like the original one, but will have access to libGL. For example: + The wrapper functions are always available. If this option is empty (the + default), they are a no-op. This is useful on NixOS where the wrappers + are unnecessary. - ```nix - # If you're using a Home Manager module to configure the package, - # pass it into the module's package argument: - programs.kitty = { - enable = true; - package = (config.lib.nixGL.wrap pkgs.kitty); - }; + Note that using any Nvidia wrapper requires building the configuration + with the `--impure` option. + ''; + }; - # Otherwise, pass it to any option where a package is expected: - home.packages = [ (config.lib.nixGL.wrap pkgs.hello) ]; - ``` + defaultWrapper = lib.mkOption { + type = lib.types.enum (builtins.attrNames config.lib.nixGL.wrappers); + default = "mesa"; + description = '' + The package wrapper function available for use as `(config.lib.nixGL.wrap + )`. Intended to start programs on the main GPU. - If this option is empty (the default), then `lib.nixGL.wrap` is a no-op. This is useful for sharing your Home Manager - configurations between NixOS and non-NixOS systems, since NixOS already provides libGL to applications without the - need for nixGL. - ''; + Wrapper functions can be found under `config.lib.nixGL.wrappers`. They + can be used directly, however, setting this option provides a convenient + shorthand. + + The following wrappers are available: + ${wrapperListMarkdown} + ''; + }; + + offloadWrapper = lib.mkOption { + type = lib.types.enum (builtins.attrNames config.lib.nixGL.wrappers); + default = "mesaPrime"; + description = '' + The package wrapper function available for use as + `(config.lib.nixGL.wrapOffload )`. Intended to start programs + on the secondary GPU. + + Wrapper functions can be found under `config.lib.nixGL.wrappers`. They + can be used directly, however, setting this option provides a convenient + shorthand. + + The following wrappers are available: + ${wrapperListMarkdown} + ''; + }; + + prime.card = lib.mkOption { + type = lib.types.str; + default = "1"; + example = "pci-0000_06_00_0"; + description = '' + Selects the non-default graphics card used for PRIME render offloading. + The value can be: + + - a number, selecting the n-th non-default GPU; + - a PCI bus id in the form `pci-XXX_YY_ZZ_U`; + - a PCI id in the form `vendor_id:device_id` + + For more information, consult the Mesa documentation on the `DRI_PRIME` + environment variable. + ''; + }; + + prime.nvidiaProvider = lib.mkOption { + type = with lib.types; nullOr str; + default = null; + example = "NVIDIA-G0"; + description = '' + If this option is set, it overrides the offload provider for Nvidia + PRIME offloading. Consult the proprietary Nvidia driver documentation + on the `__NV_PRIME_RENDER_OFFLOAD_PROVIDER` environment variable. + ''; + }; + + prime.installScript = lib.mkOption { + type = with lib.types; nullOr (enum [ "mesa" "nvidia" ]); + default = null; + example = "mesa"; + description = '' + If this option is set, the wrapper script `prime-offload` is installed + into the environment. It allows starting programs on the secondary GPU + selected by the `nixGL.prime.card` option. This makes sense when the + program is not already using one of nixGL PRIME wrappers, or for + programs not installed from Nixpkgs. + + This option can be set to either "mesa" or "nvidia", making the script + use one or the other graphics library. + ''; + }; + + installScripts = lib.mkOption { + type = with lib.types; + nullOr (listOf (enum (builtins.attrNames config.lib.nixGL.wrappers))); + default = null; + example = [ "mesa" "mesaPrime" ]; + description = '' + For each wrapper `wrp` named in the provided list, a wrapper script + named `nixGLWrp` is installed into the environment. These scripts are + useful for running programs not installed via Home Manager. + + The following wrappers are available: + ${wrapperListMarkdown} + ''; + }; + + vulkan.enable = lib.mkOption { + type = lib.types.bool; + default = false; + example = true; + description = '' + Whether to enable Vulkan in nixGL wrappers. + + This is disabled by default bacause Vulkan brings in several libraries + that can cause symbol version conflicts in wrapped programs. Your + mileage may vary. + ''; + }; }; - config = { - lib.nixGL.wrap = # Wrap a single package with the configured nixGL wrapper - pkg: + config = let + getWrapperExe = vendor: + let + glPackage = cfg.packages.${pkgs.system}."nixGL${vendor}"; + glExe = lib.getExe glPackage; + vulkanPackage = cfg.packages.${pkgs.system}."nixVulkan${vendor}"; + vulkanExe = if cfg.vulkan.enable then lib.getExe vulkanPackage else ""; + in "${glExe} ${vulkanExe}"; - if cfg.prefix == "" then + mesaOffloadEnv = { "DRI_PRIME" = "${cfg.prime.card}"; }; + + nvOffloadEnv = { + "DRI_PRIME" = "${cfg.prime.card}"; + "__NV_PRIME_RENDER_OFFLOAD" = "1"; + "__GLX_VENDOR_LIBRARY_NAME" = "nvidia"; + "__VK_LAYER_NV_optimus" = "NVIDIA_only"; + } // (let provider = cfg.prime.nvidiaProvider; + in if !isNull provider then { + "__NV_PRIME_RENDER_OFFLOAD_PROVIDER" = "${provider}"; + } else + { }); + + makePackageWrapper = vendor: environment: pkg: + if builtins.isNull cfg.packages then pkg else # Wrap the package's binaries with nixGL, while preserving the rest of @@ -53,11 +174,17 @@ in { separateDebugInfo = false; nativeBuildInputs = old.nativeBuildInputs or [ ] ++ [ pkgs.makeWrapper ]; - buildCommand = '' + buildCommand = let + # We need an intermediate wrapper package because makeWrapper + # requires a single executable as the wrapper. + combinedWrapperPkg = + pkgs.writeShellScriptBin "nixGLCombinedWrapper-${vendor}" '' + exec ${getWrapperExe vendor} "$@" + ''; + in '' set -eo pipefail - ${ - # Heavily inspired by https://stackoverflow.com/a/68523368/6259505 + ${ # Heavily inspired by https://stackoverflow.com/a/68523368/6259505 lib.concatStringsSep "\n" (map (outputName: '' echo "Copying output ${outputName}" set -x @@ -72,10 +199,14 @@ in { for file in ${pkg.out}/bin/*; do local prog="$(basename "$file")" makeWrapper \ - "${cfg.prefix}" \ + "${lib.getExe combinedWrapperPkg}" \ "$out/bin/$prog" \ --argv0 "$prog" \ - --add-flags "$file" + --add-flags "$file" \ + ${ + lib.concatStringsSep " " (lib.attrsets.mapAttrsToList + (var: val: "--set '${var}' '${val}'") environment) + } done # If .desktop files refer to the old package, replace the references @@ -91,5 +222,56 @@ in { shopt -u nullglob # Revert nullglob back to its normal default state ''; })); + + wrappers = { + mesa = makePackageWrapper "Intel" { }; + mesaPrime = makePackageWrapper "Intel" mesaOffloadEnv; + nvidia = makePackageWrapper "Nvidia" { }; + nvidiaPrime = makePackageWrapper "Nvidia" nvOffloadEnv; + }; + in { + lib.nixGL.wrap = wrappers.${cfg.defaultWrapper}; + lib.nixGL.wrapOffload = wrappers.${cfg.offloadWrapper}; + lib.nixGL.wrappers = wrappers; + + home.packages = let + wantsPrimeWrapper = (!isNull cfg.prime.installScript); + wantsWrapper = wrapper: + (!isNull cfg.packages) && (!isNull cfg.installScripts) + && (builtins.elem wrapper cfg.installScripts); + envVarsAsScript = environment: + lib.concatStringsSep "\n" + (lib.attrsets.mapAttrsToList (var: val: "export ${var}=${val}") + environment); + in [ + (lib.mkIf wantsPrimeWrapper (pkgs.writeShellScriptBin "prime-offload" '' + ${if cfg.prime.installScript == "mesa" then + (envVarsAsScript mesaOffloadEnv) + else + (envVarsAsScript nvOffloadEnv)} + exec "$@" + '')) + + (lib.mkIf (wantsWrapper "mesa") (pkgs.writeShellScriptBin "nixGLMesa" '' + exec ${getWrapperExe "Intel"} "$@" + '')) + + (lib.mkIf (wantsWrapper "mesaPrime") + (pkgs.writeShellScriptBin "nixGLMesaPrime" '' + ${envVarsAsScript mesaOffloadEnv} + exec ${getWrapperExe "Intel"} "$@" + '')) + + (lib.mkIf (wantsWrapper "nvidia") + (pkgs.writeShellScriptBin "nixGLNvidia" '' + exec ${getWrapperExe "Nvidia"} "$@" + '')) + + (lib.mkIf (wantsWrapper "nvidia") + (pkgs.writeShellScriptBin "nixGLNvidiaPrime" '' + ${envVarsAsScript nvOffloadEnv} + exec ${getWrapperExe "Nvidia"} "$@" + '')) + ]; }; } From 8bd6e0a1a805c373686e21678bb07f23293d357b Mon Sep 17 00:00:00 2001 From: Jure Varlec Date: Wed, 2 Oct 2024 20:19:53 +0200 Subject: [PATCH 057/546] nixgl: add support for channel-based configuration --- docs/manual/usage/gpu-non-nixos.md | 15 +++++++++++++-- modules/misc/nixgl.nix | 23 +++++++++++++++++++++-- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/docs/manual/usage/gpu-non-nixos.md b/docs/manual/usage/gpu-non-nixos.md index 7b7cfbaea..0aefa4ae3 100644 --- a/docs/manual/usage/gpu-non-nixos.md +++ b/docs/manual/usage/gpu-non-nixos.md @@ -50,9 +50,9 @@ Xonotic to run on the dGPU, but uses the wrapper function directly for demonstration purposes. ```nix -{ config, lib, pkgs, nixGL, ... }: +{ config, lib, pkgs, nixgl, ... }: { - nixGL.packages = nixGL.packages; + nixGL.packages = nixgl.packages; nixGL.defaultWrapper = "mesa"; nixGL.offloadWrapper = "nvidiaPrime"; nixGL.installScripts = [ "mesa" "nvidiaPrime" ]; @@ -68,3 +68,14 @@ demonstration purposes. ]; } ``` + +The above example assumes a flake-based setup where `nixgl` was passed from the +flake. When using channels, the example would instead begin with + +```nix +{ config, lib, pkgs, ... }: +{ + nixGL.packages = import { inherit pkgs; }; + # The rest is the same as above + ... +``` diff --git a/modules/misc/nixgl.nix b/modules/misc/nixgl.nix index f45c483bc..2c7fcaffc 100644 --- a/modules/misc/nixgl.nix +++ b/modules/misc/nixgl.nix @@ -138,11 +138,30 @@ in { }; config = let + findWrapperPackage = packageAttr: + # NixGL has wrapper packages in different places depending on how you + # access it. We want HM configuration to be the same, regardless of how + # NixGL is imported. + # + # First, let's see if we have a flake. + if builtins.hasAttr pkgs.system cfg.packages then + cfg.packages.${pkgs.system}.${packageAttr} + else + # Next, let's see if we have a channel. + if builtins.hasAttr packageAttr cfg.packages then + cfg.packages.${packageAttr} + else + # Lastly, with channels, some wrappers are grouped under "auto". + if builtins.hasAttr "auto" cfg.packages then + cfg.packages.auto.${packageAttr} + else + throw "Incompatible NixGL package layout"; + getWrapperExe = vendor: let - glPackage = cfg.packages.${pkgs.system}."nixGL${vendor}"; + glPackage = findWrapperPackage "nixGL${vendor}"; glExe = lib.getExe glPackage; - vulkanPackage = cfg.packages.${pkgs.system}."nixVulkan${vendor}"; + vulkanPackage = findWrapperPackage "nixVulkan${vendor}"; vulkanExe = if cfg.vulkan.enable then lib.getExe vulkanPackage else ""; in "${glExe} ${vulkanExe}"; From c77c3bb23390a9ba91860e721edde54856fc5f7a Mon Sep 17 00:00:00 2001 From: "Giovanni Nicosia (mood)" <74420740+no-mood@users.noreply.github.com> Date: Mon, 21 Oct 2024 19:04:00 +0200 Subject: [PATCH 058/546] yazi: enable shell integration values by default Previously, - `programs.yazi.enableNushellIntegration`, - `programs.yazi.enableFishIntegration`, and - `programs.yazi.enableZshIntegration` were set to false by default. It seems more appropriate to enable these integrations by default. --- modules/programs/yazi.nix | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/modules/programs/yazi.nix b/modules/programs/yazi.nix index d7b880200..0f5117dbd 100644 --- a/modules/programs/yazi.nix +++ b/modules/programs/yazi.nix @@ -56,13 +56,21 @@ in { ''; }; - enableBashIntegration = mkEnableOption "Bash integration"; + enableBashIntegration = mkEnableOption "Bash integration" // { + default = true; + }; - enableZshIntegration = mkEnableOption "Zsh integration"; + enableZshIntegration = mkEnableOption "Zsh integration" // { + default = true; + }; - enableFishIntegration = mkEnableOption "Fish integration"; + enableFishIntegration = mkEnableOption "Fish integration" // { + default = true; + }; - enableNushellIntegration = mkEnableOption "Nushell integration"; + enableNushellIntegration = mkEnableOption "Nushell integration" // { + default = true; + }; keymap = mkOption { type = tomlFormat.type; From 6cc03e337aa1d0222e5942f58839d965075a9781 Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Mon, 21 Oct 2024 10:29:57 +0000 Subject: [PATCH 059/546] nix-gc: add `randomizedDelaySec` option There's no launchd equivalent to this option, so this is a no-op on Darwin. --- modules/services/nix-gc.nix | 13 +++++++++++++ tests/modules/services/nix-gc/basic.nix | 1 + tests/modules/services/nix-gc/expected.timer | 1 + 3 files changed, 15 insertions(+) diff --git a/modules/services/nix-gc.nix b/modules/services/nix-gc.nix index 50e8b6351..7789aeffb 100644 --- a/modules/services/nix-gc.nix +++ b/modules/services/nix-gc.nix @@ -81,6 +81,18 @@ in { ''; }; + randomizedDelaySec = lib.mkOption { + default = "0"; + type = lib.types.singleLineStr; + example = "45min"; + description = '' + Add a randomized delay before each garbage collection. + The delay will be chosen between zero and this value. + This value must be a time span in the format specified by + {manpage}`systemd.time(7)` + ''; + }; + options = mkOption { type = types.nullOr types.str; default = null; @@ -121,6 +133,7 @@ in { Unit = { Description = "Nix Garbage Collector"; }; Timer = { OnCalendar = "${cfg.frequency}"; + RandomizedDelaySec = cfg.randomizedDelaySec; Persistent = cfg.persistent; Unit = "nix-gc.service"; }; diff --git a/tests/modules/services/nix-gc/basic.nix b/tests/modules/services/nix-gc/basic.nix index a06b67238..1fc019da7 100644 --- a/tests/modules/services/nix-gc/basic.nix +++ b/tests/modules/services/nix-gc/basic.nix @@ -4,6 +4,7 @@ nix.gc = { automatic = true; frequency = "monthly"; + randomizedDelaySec = "42min"; options = "--delete-older-than 30d --max-freed $((64 * 1024**3))"; }; diff --git a/tests/modules/services/nix-gc/expected.timer b/tests/modules/services/nix-gc/expected.timer index ef30df435..70232bb47 100644 --- a/tests/modules/services/nix-gc/expected.timer +++ b/tests/modules/services/nix-gc/expected.timer @@ -4,6 +4,7 @@ WantedBy=timers.target [Timer] OnCalendar=monthly Persistent=true +RandomizedDelaySec=42min Unit=nix-gc.service [Unit] From c0e23159872e2e2135c7eb5cf96cd36cfe6ee1f4 Mon Sep 17 00:00:00 2001 From: Tomo Date: Fri, 25 Oct 2024 06:56:37 -0700 Subject: [PATCH 060/546] git-credential-oauth: add extraFlags option This facilitates a legitimate use-case for browserless systems. From the README: > On systems without a web browser, set the -device flag to authenticate > on another device using [OAuth device flow]: > ```ini [credential] helper = cache --timeout 7200 # two hours helper = oauth -device ``` [OAuth device flow]: https://www.rfc-editor.org/rfc/rfc8628 Please note that, for the documentation about the man-page to be accurate, https://github.com/NixOS/nixpkgs/pull/302922 must be merged. --- modules/programs/git-credential-oauth.nix | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/modules/programs/git-credential-oauth.nix b/modules/programs/git-credential-oauth.nix index 4833e8068..1f4b99247 100644 --- a/modules/programs/git-credential-oauth.nix +++ b/modules/programs/git-credential-oauth.nix @@ -12,13 +12,26 @@ in { enable = lib.mkEnableOption "Git authentication handler for OAuth"; package = lib.mkPackageOption pkgs "git-credential-oauth" { }; + + extraFlags = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ ]; + example = lib.literalExpression ''[ "-device" ]''; + description = '' + Extra command-line arguments passed to git-credential-oauth. + + For valid arguments, see {manpage}`git-credential-oauth(1)`. + ''; + }; }; }; config = lib.mkIf cfg.enable { home.packages = [ cfg.package ]; - programs.git.extraConfig.credential.helper = - [ "${cfg.package}/bin/git-credential-oauth" ]; + programs.git.extraConfig.credential.helper = [ + ("${cfg.package}/bin/git-credential-oauth" + lib.mkIf cfg.extraFlags + " ${lib.strings.concatStringsSep " " cfg.extraFlags}") + ]; }; } From 0c0268a3c80d30b989d0aadbd65f38d4fa27a9a0 Mon Sep 17 00:00:00 2001 From: nyadiia Date: Wed, 23 Oct 2024 16:35:08 -0500 Subject: [PATCH 061/546] eza: add color option --- modules/programs/eza.nix | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/modules/programs/eza.nix b/modules/programs/eza.nix index 679f53499..f35912b8c 100644 --- a/modules/programs/eza.nix +++ b/modules/programs/eza.nix @@ -59,6 +59,14 @@ with lib; ''; }; + colors = mkOption { + type = types.enum [ null "auto" "always" "never" ]; + default = null; + description = '' + Use terminal colors in output ({option}`--color` argument). + ''; + }; + git = mkOption { type = types.bool; default = false; @@ -80,8 +88,9 @@ with lib; cfg.icons; in optionals (v != null) [ "--icons" v ]; - args = escapeShellArgs - (iconsOption ++ optional cfg.git "--git" ++ cfg.extraOptions); + args = escapeShellArgs (iconsOption + ++ optionals (cfg.colors != null) [ "--color" cfg.colors ] + ++ optional cfg.git "--git" ++ cfg.extraOptions); optionsAlias = optionalAttrs (args != "") { eza = "eza ${args}"; }; From 93435d27d250fa986bfec6b2ff263161ff8288cb Mon Sep 17 00:00:00 2001 From: William Phetsinorath Date: Fri, 25 Oct 2024 17:06:02 +0200 Subject: [PATCH 062/546] direnv: add support for mise integration --- modules/programs/direnv.nix | 16 +++++++++++++++- tests/modules/programs/direnv/default.nix | 1 + tests/modules/programs/direnv/mise.nix | 17 +++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 tests/modules/programs/direnv/mise.nix diff --git a/modules/programs/direnv.nix b/modules/programs/direnv.nix index 6d0af3ac1..37899c4a2 100644 --- a/modules/programs/direnv.nix +++ b/modules/programs/direnv.nix @@ -19,7 +19,7 @@ in { "Flake support is now always enabled.") ]; - meta.maintainers = [ lib.maintainers.rycee ]; + meta.maintainers = [ lib.maintainers.rycee lib.maintainers.shikanime ]; options.programs.direnv = { enable = mkEnableOption "direnv, the environment switcher"; @@ -95,6 +95,14 @@ in { package = mkPackageOption pkgs "nix-direnv" { }; }; + mise = { + enable = mkEnableOption '' + [mise](https://mise.jdx.dev/direnv.html), + integration of use_mise for direnv''; + + package = mkPackageOption pkgs "mise" { }; + }; + silent = mkEnableOption "silent mode, that is, disabling direnv logging"; }; @@ -112,6 +120,12 @@ in { xdg.configFile."direnv/direnvrc" = lib.mkIf (cfg.stdlib != "") { text = cfg.stdlib; }; + xdg.configFile."direnv/lib/hm-mise.sh" = mkIf cfg.mise.enable { + text = '' + eval "$(${getExe cfg.mise.package} direnv activate)" + ''; + }; + programs.bash.initExtra = mkIf cfg.enableBashIntegration ( # Using mkAfter to make it more likely to appear after other # manipulations of the prompt. diff --git a/tests/modules/programs/direnv/default.nix b/tests/modules/programs/direnv/default.nix index a0e618481..b61fb1e33 100644 --- a/tests/modules/programs/direnv/default.nix +++ b/tests/modules/programs/direnv/default.nix @@ -1,5 +1,6 @@ { direnv-bash = ./bash.nix; + direnv-mise = ./mise.nix; direnv-nix-direnv = ./nix-direnv.nix; direnv-nushell = ./nushell.nix; direnv-stdlib = ./stdlib.nix; diff --git a/tests/modules/programs/direnv/mise.nix b/tests/modules/programs/direnv/mise.nix new file mode 100644 index 000000000..b205df627 --- /dev/null +++ b/tests/modules/programs/direnv/mise.nix @@ -0,0 +1,17 @@ +{ config, ... }: + +{ + programs.bash.enable = true; + programs.direnv = { + enable = true; + mise = { + enable = true; + package = config.lib.test.mkStubPackage { name = "mise"; }; + }; + }; + + nmt.script = '' + assertFileExists home-files/.bashrc + assertFileExists home-files/.config/direnv/lib/hm-mise.sh + ''; +} From 05d9bee4a5155758aec3c3807c0e342b9f253522 Mon Sep 17 00:00:00 2001 From: Tomo Date: Sat, 26 Oct 2024 23:45:32 -0700 Subject: [PATCH 063/546] git-credential-oauth: fix use of mkIf and add tests Closes #6005 --- modules/programs/git-credential-oauth.nix | 3 ++- tests/default.nix | 1 + .../programs/git-credential-oauth/basic.nix | 16 ++++++++++++++++ .../programs/git-credential-oauth/default.nix | 4 ++++ .../git-credential-oauth/extra-flags.nix | 19 +++++++++++++++++++ 5 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 tests/modules/programs/git-credential-oauth/basic.nix create mode 100644 tests/modules/programs/git-credential-oauth/default.nix create mode 100644 tests/modules/programs/git-credential-oauth/extra-flags.nix diff --git a/modules/programs/git-credential-oauth.nix b/modules/programs/git-credential-oauth.nix index 1f4b99247..5fa54276c 100644 --- a/modules/programs/git-credential-oauth.nix +++ b/modules/programs/git-credential-oauth.nix @@ -30,7 +30,8 @@ in { home.packages = [ cfg.package ]; programs.git.extraConfig.credential.helper = [ - ("${cfg.package}/bin/git-credential-oauth" + lib.mkIf cfg.extraFlags + ("${cfg.package}/bin/git-credential-oauth" + + lib.optionalString (cfg.extraFlags != [ ]) " ${lib.strings.concatStringsSep " " cfg.extraFlags}") ]; }; diff --git a/tests/default.nix b/tests/default.nix index f4b03275b..3271d3052 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -81,6 +81,7 @@ in import nmtSrc { ./modules/programs/gh-dash ./modules/programs/git ./modules/programs/git-cliff + ./modules/programs/git-credential-oauth ./modules/programs/gpg ./modules/programs/gradle ./modules/programs/granted diff --git a/tests/modules/programs/git-credential-oauth/basic.nix b/tests/modules/programs/git-credential-oauth/basic.nix new file mode 100644 index 000000000..741adfbfb --- /dev/null +++ b/tests/modules/programs/git-credential-oauth/basic.nix @@ -0,0 +1,16 @@ +{ config, pkgs, ... }: + +{ + programs.git-credential-oauth = { enable = true; }; + + programs.git = { enable = true; }; + + test.stubs.git-credential-oauth = { }; + + nmt.script = '' + assertFileExists home-files/.config/git/config + assertFileContains \ + home-files/.config/git/config \ + "${config.programs.git-credential-oauth.package}/bin/git-credential-oauth" + ''; +} diff --git a/tests/modules/programs/git-credential-oauth/default.nix b/tests/modules/programs/git-credential-oauth/default.nix new file mode 100644 index 000000000..63ecb183a --- /dev/null +++ b/tests/modules/programs/git-credential-oauth/default.nix @@ -0,0 +1,4 @@ +{ + git-credential-oauth-basic = ./basic.nix; + git-credential-oauth-extra-flags = ./extra-flags.nix; +} diff --git a/tests/modules/programs/git-credential-oauth/extra-flags.nix b/tests/modules/programs/git-credential-oauth/extra-flags.nix new file mode 100644 index 000000000..7a586ede6 --- /dev/null +++ b/tests/modules/programs/git-credential-oauth/extra-flags.nix @@ -0,0 +1,19 @@ +{ config, pkgs, ... }: + +{ + programs.git-credential-oauth = { + enable = true; + extraFlags = [ "-device" ]; + }; + + programs.git = { enable = true; }; + + test.stubs.git-credential-oauth = { }; + + nmt.script = '' + assertFileExists home-files/.config/git/config + assertFileContains \ + home-files/.config/git/config \ + "${config.programs.git-credential-oauth.package}/bin/git-credential-oauth -device" + ''; +} From e83414058edd339148dc142a8437edb9450574c8 Mon Sep 17 00:00:00 2001 From: home-manager-bot <106474382+home-manager-bot@users.noreply.github.com> Date: Sun, 27 Oct 2024 09:15:08 +0100 Subject: [PATCH 064/546] flake.lock: Update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flake lock file updates: • Updated input 'nixpkgs': 'github:NixOS/nixpkgs/4c2fcb090b1f3e5b47eaa7bd33913b574a11e0a0?narHash=sha256-/uilDXvCIEs3C9l73JTACm4quuHUsIHcns1c%2BcHUJwA%3D' (2024-10-18) → 'github:NixOS/nixpkgs/18536bf04cd71abd345f9579158841376fdd0c5a?narHash=sha256-RP%2BOQ6koQQLX5nw0NmcDrzvGL8HDLnyXt/jHhL1jwjM%3D' (2024-10-25) Co-authored-by: github-actions[bot] --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index d052ebff2..b03cf135b 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1729256560, - "narHash": "sha256-/uilDXvCIEs3C9l73JTACm4quuHUsIHcns1c+cHUJwA=", + "lastModified": 1729880355, + "narHash": "sha256-RP+OQ6koQQLX5nw0NmcDrzvGL8HDLnyXt/jHhL1jwjM=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "4c2fcb090b1f3e5b47eaa7bd33913b574a11e0a0", + "rev": "18536bf04cd71abd345f9579158841376fdd0c5a", "type": "github" }, "original": { From 8ca921e5a806b5b6171add542defe7bdac79d189 Mon Sep 17 00:00:00 2001 From: Kosta Gorodetsky Date: Fri, 1 Nov 2024 10:46:22 +0200 Subject: [PATCH 065/546] git-credential-oauth: fix ordering of git extraConfig Added `mkAfter` to `git.extraConfig` to ensure our oauth is last, as required to work with additional helpers. --- modules/programs/git-credential-oauth.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/programs/git-credential-oauth.nix b/modules/programs/git-credential-oauth.nix index 5fa54276c..499c7c4c1 100644 --- a/modules/programs/git-credential-oauth.nix +++ b/modules/programs/git-credential-oauth.nix @@ -29,7 +29,7 @@ in { config = lib.mkIf cfg.enable { home.packages = [ cfg.package ]; - programs.git.extraConfig.credential.helper = [ + programs.git.extraConfig.credential.helper = lib.mkAfter [ ("${cfg.package}/bin/git-credential-oauth" + lib.optionalString (cfg.extraFlags != [ ]) " ${lib.strings.concatStringsSep " " cfg.extraFlags}") From 1743615b61c7285976f85b303a36cdf88a556503 Mon Sep 17 00:00:00 2001 From: Nicholas Hassan Date: Fri, 22 Dec 2023 10:54:18 +1030 Subject: [PATCH 066/546] podman: add module Adds a new Podman module for creating user containers and networks as systemd services. These are installed to the user's `$XDG_CONFIG/systemd/user` directory. --- modules/lib/maintainers.nix | 16 + modules/misc/news.nix | 14 + modules/modules.nix | 1 + modules/services/podman-linux/activation.nix | 99 ++++++ modules/services/podman-linux/containers.nix | 313 ++++++++++++++++++ modules/services/podman-linux/default.nix | 17 + .../services/podman-linux/install-quadlet.nix | 88 +++++ modules/services/podman-linux/networks.nix | 168 ++++++++++ modules/services/podman-linux/options.nix | 52 +++ modules/services/podman-linux/podman-lib.nix | 136 ++++++++ modules/services/podman-linux/services.nix | 65 ++++ tests/default.nix | 1 + .../podman-linux/container-expected.service | 51 +++ .../services/podman-linux/container.nix | 60 ++++ .../modules/services/podman-linux/default.nix | 6 + .../integration-container-expected.service | 41 +++ .../integration-network-expected.service | 29 ++ .../services/podman-linux/integration.nix | 29 ++ .../services/podman-linux/manifest.nix | 64 ++++ .../podman-linux/network-expected.service | 33 ++ .../modules/services/podman-linux/network.nix | 44 +++ 21 files changed, 1327 insertions(+) create mode 100644 modules/services/podman-linux/activation.nix create mode 100644 modules/services/podman-linux/containers.nix create mode 100644 modules/services/podman-linux/default.nix create mode 100644 modules/services/podman-linux/install-quadlet.nix create mode 100644 modules/services/podman-linux/networks.nix create mode 100644 modules/services/podman-linux/options.nix create mode 100644 modules/services/podman-linux/podman-lib.nix create mode 100644 modules/services/podman-linux/services.nix create mode 100644 tests/modules/services/podman-linux/container-expected.service create mode 100644 tests/modules/services/podman-linux/container.nix create mode 100644 tests/modules/services/podman-linux/default.nix create mode 100644 tests/modules/services/podman-linux/integration-container-expected.service create mode 100644 tests/modules/services/podman-linux/integration-network-expected.service create mode 100644 tests/modules/services/podman-linux/integration.nix create mode 100644 tests/modules/services/podman-linux/manifest.nix create mode 100644 tests/modules/services/podman-linux/network-expected.service create mode 100644 tests/modules/services/podman-linux/network.nix diff --git a/modules/lib/maintainers.nix b/modules/lib/maintainers.nix index 6b7dc8b42..91ecb47be 100644 --- a/modules/lib/maintainers.nix +++ b/modules/lib/maintainers.nix @@ -43,6 +43,12 @@ github = "Avimitin"; githubId = 30021675; }; + bamhm182 = { + name = "bamhm182"; + email = "bamhm182@gmail.com"; + github = "bamhm182"; + githubId = 920269; + }; blmhemu = { name = "blmhemu"; email = "19410501+blmhemu@users.noreply.github.com"; @@ -288,6 +294,16 @@ github = "NitroSniper"; githubId = 44097331; }; + n-hass = { + name = "Nicholas Hassan"; + email = "nick@hassan.host"; + github = "n-hass"; + githubId = 72363381; + keys = [{ + longkeyid = "rsa4096/0xFC95AB946A781EE7"; + fingerprint = "FDEE 6116 DBA7 8840 7323 4466 A371 5973 2728 A6A6"; + }]; + }; seylerius = { email = "sable@seyleri.us"; name = "Sable Seyler"; diff --git a/modules/misc/news.nix b/modules/misc/news.nix index 801391cc2..aeec8f9a0 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -1813,6 +1813,20 @@ in { systems" section in the Home Manager mantual for more. ''; } + + { + time = "2024-11-01T19:44:59+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'services.podman'. + + Podman is a daemonless container engine that lets you manage + containers, pods, and images. + + This Home Manager module allows you to define containers that will run + as systemd services. + ''; + } ]; }; } diff --git a/modules/modules.nix b/modules/modules.nix index 3b4985083..75f8ac461 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -352,6 +352,7 @@ let ./services/plan9port.nix ./services/playerctld.nix ./services/plex-mpv-shim.nix + ./services/podman-linux ./services/polybar.nix ./services/poweralertd.nix ./services/psd.nix diff --git a/modules/services/podman-linux/activation.nix b/modules/services/podman-linux/activation.nix new file mode 100644 index 000000000..5791f19b0 --- /dev/null +++ b/modules/services/podman-linux/activation.nix @@ -0,0 +1,99 @@ +{ config, podman-lib, ... }: + +{ + cleanup = '' + PATH=$PATH:${podman-lib.newuidmapPaths} + export VERBOSE=true + + DRYRUN_ENABLED() { + return $([ -n "''${DRY_RUN:-}" ] && echo 0 || echo 1) + } + + VERBOSE_ENABLED() { + return $([ -n "''${VERBOSE:-}" ] && echo 0 || echo 1) + } + + cleanup() { + local resourceType=$1 + local manifestFile="${config.xdg.configHome}/podman/$2" + local extraListCommands="''${3:-}" + [[ $resourceType = "container" ]] && extraListCommands+=" -a" + + [ ! -f "$manifestFile" ] && VERBOSE_ENABLED && echo "Manifest does not exist: $manifestFile" && return 0 + + VERBOSE_ENABLED && echo "Cleaning up ''${resourceType}s not in manifest..." || true + + loadManifest "$manifestFile" + + formatString="{{.Name}}" + [[ $resourceType = "container" ]] && formatString="{{.Names}}" + + local listOutput=$(${config.services.podman.package}/bin/podman $resourceType ls $extraListCommands --filter 'label=nix.home-manager.managed=true' --format "$formatString") + + IFS=$'\n' read -r -d "" -a podmanResources <<< "$listOutput" || true + + if [ ''${#podmanResources[@]} -eq 0 ]; then + VERBOSE_ENABLED && echo "No ''${resourceType}s available to process." || true + else + for resource in "''${podmanResources[@]}"; do + if ! isResourceInManifest "$resource"; then + removeResource "$resourceType" "$resource" + else + VERBOSE_ENABLED && echo "Keeping managed $resourceType: $resource" || true + fi + done + fi + } + + isResourceInManifest() { + local resource="$1" + for manifestEntry in "''${resourceManifest[@]}"; do + if [ "$resource" = "$manifestEntry" ]; then + return 0 # Resource found in manifest + fi + done + return 1 # Resource not found in manifest + } + + # Function to fill resourceManifest from the manifest file + loadManifest() { + local manifestFile="$1" + VERBOSE_ENABLED && echo "Loading manifest from $manifestFile..." || true + IFS=$'\n' read -r -d "" -a resourceManifest <<< "$(cat "$manifestFile")" || true + } + + removeResource() { + local resourceType="$1" + local resource="$2" + echo "Removing orphaned $resourceType: $resource" + commands=() + case "$resourceType" in + "container") + commands+="${config.services.podman.package}/bin/podman $resourceType stop $resource" + commands+="${config.services.podman.package}/bin/podman $resourceType rm -f $resource" + ;; + "network") + commands+="${config.services.podman.package}/bin/podman $resourceType rm $resource" + ;; + esac + for command in "''${commands[@]}"; do + command=$(echo $command | tr -d ';&|`') + DRYRUN_ENABLED && echo "Would run: $command" && continue || true + VERBOSE_ENABLED && echo "Running: $command" || true + if [[ "$(eval "$command")" != "$resource" ]]; then + echo -e "\tCommand failed: ''${command}" + usedByContainers=$(${config.services.podman.package}/bin/podman container ls -a --filter "$resourceType=$resource" --format "{{.Names}}") + echo -e "\t$resource in use by containers: $usedByContainers" + fi + done + } + + resourceManifest=() + [[ "$@" == *"--verbose"* ]] && VERBOSE="true" + [[ "$@" == *"--dry-run"* ]] && DRY_RUN="true" + + for type in "container" "network"; do + cleanup "$type" "''${type}s.manifest" + done + ''; +} diff --git a/modules/services/podman-linux/containers.nix b/modules/services/podman-linux/containers.nix new file mode 100644 index 000000000..41ab29130 --- /dev/null +++ b/modules/services/podman-linux/containers.nix @@ -0,0 +1,313 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.podman; + + podman-lib = import ./podman-lib.nix { inherit lib config; }; + + createQuadletSource = name: containerDef: + let + mapHmNetworks = network: + if builtins.hasAttr network cfg.networks then + "podman-${network}-network.service" + else + null; + + finalConfig = let + managedNetworks = if lib.isList containerDef.network then + map mapHmNetworks containerDef.network + else if containerDef.network != null then + map mapHmNetworks [ containerDef.network ] + else + [ ]; + in (podman-lib.deepMerge { + Container = { + AddCapability = containerDef.addCapabilities; + AddDevice = containerDef.devices; + AutoUpdate = containerDef.autoUpdate; + ContainerName = name; + DropCapability = containerDef.dropCapabilities; + Entrypoint = containerDef.entrypoint; + Environment = containerDef.environment; + EnvironmentFile = containerDef.environmentFile; + Exec = containerDef.exec; + Group = containerDef.group; + Image = containerDef.image; + IP = containerDef.ip4; + IP6 = containerDef.ip6; + Label = + (containerDef.labels // { "nix.home-manager.managed" = true; }); + Network = containerDef.network; + NetworkAlias = containerDef.networkAlias; + PodmanArgs = containerDef.extraPodmanArgs; + PublishPort = containerDef.ports; + UserNS = containerDef.userNS; + User = containerDef.user; + Volume = containerDef.volumes; + }; + Install = { + WantedBy = (if containerDef.autoStart then [ + "default.target" + "multi-user.target" + ] else + [ ]); + }; + Service = { + Environment = { + PATH = (builtins.concatStringsSep ":" [ + "/run/wrappers/bin" + "/run/current-system/sw/bin" + "${config.home.homeDirectory}/.nix-profile/bin" + ]); + }; + Restart = "always"; + TimeoutStopSec = 30; + }; + Unit = { + After = [ "network.target" ] ++ managedNetworks; + Requires = managedNetworks; + Description = (if (builtins.isString containerDef.description) then + containerDef.description + else + "Service for container ${name}"); + }; + } containerDef.extraConfig); + in '' + # Automatically generated by home-manager podman container configuration + # DO NOT EDIT THIS FILE DIRECTLY + # + # ${name}.container + ${podman-lib.toQuadletIni finalConfig} + ''; + + toQuadletInternal = name: containerDef: { + assertions = podman-lib.buildConfigAsserts name containerDef.extraConfig; + resourceType = "container"; + serviceName = + "podman-${name}"; # quadlet service name: 'podman-.service' + source = + podman-lib.removeBlankLines (createQuadletSource name containerDef); + }; + + # Define the container user type as the user interface + containerDefinitionType = types.submodule { + options = { + + addCapabilities = mkOption { + type = with types; listOf str; + default = [ ]; + example = [ "CAP_DAC_OVERRIDE" "CAP_IPC_OWNER" ]; + description = "The capabilities to add to the container."; + }; + + autoStart = mkOption { + type = types.bool; + default = true; + description = '' + Whether to start the container on boot (requires user lingering). + ''; + }; + + autoUpdate = mkOption { + type = types.enum [ null "registry" "local" ]; + default = null; + example = "registry"; + description = "The autoupdate policy for the container."; + }; + + description = mkOption { + type = with types; nullOr str; + default = null; + example = "My Container"; + description = "The description of the container."; + }; + + devices = mkOption { + type = with types; listOf str; + default = [ ]; + example = [ "/dev/:/dev/" ]; + description = "The devices to mount into the container"; + }; + + dropCapabilities = mkOption { + type = with types; listOf str; + default = [ ]; + example = [ "CAP_DAC_OVERRIDE" "CAP_IPC_OWNER" ]; + description = "The capabilities to drop from the container."; + }; + + entrypoint = mkOption { + type = with types; nullOr str; + default = null; + example = "/foo.sh"; + description = "The container entrypoint."; + }; + + environment = mkOption { + type = podman-lib.primitiveAttrs; + default = { }; + example = literalExpression '' + { + VAR1 = "0:100"; + VAR2 = true; + VAR3 = 5; + } + ''; + description = "Environment variables to set in the container."; + }; + + environmentFile = mkOption { + type = with types; listOf str; + default = [ ]; + example = [ "/etc/environment" "/etc/other-env" ]; + description = '' + Paths to files containing container environment variables. + ''; + }; + + exec = mkOption { + type = with types; nullOr str; + default = null; + example = "sleep inf"; + description = "The command to run after the container start."; + }; + + extraPodmanArgs = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ + "--security-opt=no-new-privileges" + "--security-opt=seccomp=unconfined" + ]; + description = "Extra arguments to pass to the podman run command."; + }; + + extraConfig = mkOption { + type = podman-lib.extraConfigType; + default = { }; + example = literalExpression '' + { + Container = { + User = 1000; + }; + Service = { + TimeoutStartSec = 15; + }; + } + ''; + description = '' + INI sections and values to populate the Container Quadlet. + ''; + }; + + group = mkOption { + type = with types; nullOr (either int str); + default = null; + description = "The group ID inside the container."; + }; + + image = mkOption { + type = types.str; + example = "registry.access.redhat.com/ubi9-minimal:latest"; + description = "The container image."; + }; + + ip4 = mkOption { + type = with types; nullOr str; + default = null; + description = "Set an IPv4 address for the container."; + }; + + ip6 = mkOption { + type = with types; nullOr str; + default = null; + description = "Set an IPv6 address for the container."; + }; + + labels = mkOption { + type = with types; attrsOf str; + default = { }; + example = { + app = "myapp"; + some-label = "somelabel"; + }; + description = "The labels to apply to the container."; + }; + + network = mkOption { + type = with types; either str (listOf str); + default = [ ]; + apply = value: if isString value then [ value ] else value; + example = literalMD '' + `"host"` + or + `"bridge_network_1"` + or + `[ "bridge_network_1" "bridge_network_2" ]` + ''; + description = '' + The network mode or network/s to connect the container to. Equivalent + to `podman run --network=