diff --git a/.github/workflows/github_pages.yml b/.github/workflows/github_pages.yml index 7c5d7e91acb7..1e0a0f9a9f81 100644 --- a/.github/workflows/github_pages.yml +++ b/.github/workflows/github_pages.yml @@ -10,8 +10,8 @@ jobs: os: [ubuntu-latest] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 - - uses: cachix/install-nix-action@v15 + - uses: actions/checkout@v3 + - uses: cachix/install-nix-action@v17 with: nix_path: nixpkgs=channel:nixos-unstable - uses: cachix/cachix-action@v10 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 423ad9e7abe6..510fa9cfe503 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,10 +11,10 @@ jobs: os: [ubuntu-latest, macos-latest] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 - - uses: cachix/install-nix-action@v15 + - uses: actions/checkout@v3 + - uses: cachix/install-nix-action@v17 with: - nix_path: nixpkgs=channel:nixos-unstable + nix_path: nixpkgs=channel:nixos-21.11 - uses: cachix/cachix-action@v10 with: name: nix-community diff --git a/README.md b/README.md index f5f010d54849..9cffe4ef3560 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ will write to your dconf store and cannot tell whether a configuration that it is about to be overwritten was from a previous Home Manager generation or from manual configuration. -Home Manager targets [NixOS][] unstable and NixOS version 21.05 (the +Home Manager targets [NixOS][] unstable and NixOS version 21.11 (the current stable version), it may or may not work on other Linux distributions and NixOS versions. @@ -152,7 +152,7 @@ Home Manager is developed against `nixpkgs-unstable` branch, which often causes it to contain tweaks for changes/packages not yet released in stable NixOS. To avoid breaking users' configurations, Home Manager is released in branches corresponding to NixOS releases -(e.g. `release-21.05`). These branches get fixes, but usually not new +(e.g. `release-21.11`). These branches get fixes, but usually not new modules. If you need a module to be backported, then feel free to open an issue. diff --git a/docs/release-notes/rl-2111.adoc b/docs/release-notes/rl-2111.adoc index fdd1220c1465..4287ade1376b 100644 --- a/docs/release-notes/rl-2111.adoc +++ b/docs/release-notes/rl-2111.adoc @@ -1,8 +1,7 @@ [[sec-release-21.11]] == Release 21.11 -This is the current unstable branch and the information in this -section is therefore not final. +The 21.11 release branch became the stable branch in November, 2021. [[sec-release-21.11-highlights]] === Highlights diff --git a/format b/format index 0fa620c1acf3..1a961e919e4a 100755 --- a/format +++ b/format @@ -24,7 +24,6 @@ find . -name '*.nix' \ ! -path ./modules/manual.nix \ ! -path ./modules/misc/news.nix \ ! -path ./modules/programs/bash.nix \ - ! -path ./modules/programs/gpg.nix \ ! -path ./modules/programs/ssh.nix \ ! -path ./modules/programs/zsh.nix \ ! -path ./modules/services/gpg-agent.nix \ diff --git a/home-manager/home-manager b/home-manager/home-manager index 990e1e5e8d74..42210ed10578 100644 --- a/home-manager/home-manager +++ b/home-manager/home-manager @@ -10,6 +10,23 @@ function errorEcho() { echo $* >&2 } +function removeByName() { + nix profile list \ + | { grep "$1" || test $? = 1; } \ + | cut -d ' ' -f 4 \ + | xargs -t $DRY_RUN_CMD nix profile remove $VERBOSE_ARG +} + +function setNixProfileCommands() { + if [[ -e ~/.nix-profile/manifest.json ]] ; then + LIST_OUTPATH_CMD="nix profile list" + REMOVE_CMD="removeByName" + else + LIST_OUTPATH_CMD="nix-env -q --outpath" + REMOVE_CMD="nix-env -q" + fi +} + function setVerboseAndDryRun() { if [[ -v VERBOSE ]]; then export VERBOSE_ARG="--verbose" @@ -263,9 +280,9 @@ function doBuild() { setFlakeAttribute if [[ -v FLAKE_CONFIG_URI ]]; then doBuildFlake \ - "${DRY_RUN+--dry-run} \ - "${NO_OUT_LINK+--no-link} \ "$FLAKE_CONFIG_URI.activationPackage" \ + ${DRY_RUN+--dry-run} \ + ${NO_OUT_LINK+--no-link} \ || return else doBuildAttr \ @@ -294,8 +311,8 @@ function doSwitch() { setFlakeAttribute if [[ -v FLAKE_CONFIG_URI ]]; then doBuildFlake \ - --out-link "$generation" \ "$FLAKE_CONFIG_URI.activationPackage" \ + --out-link "$generation" \ && "$generation/activate" || return else doBuildAttr \ @@ -371,8 +388,9 @@ function doExpireGenerations() { } function doListPackages() { + setNixProfileCommands local outPath - outPath="$(nix-env -q --out-path | grep -o '/.*home-manager-path$')" + outPath="$($LIST_OUTPATH_CMD | grep -o '/.*home-manager-path$')" if [[ -n "$outPath" ]] ; then nix-store -q --references "$outPath" | sed 's/[^-]*-//' else @@ -447,6 +465,7 @@ function doShowNews() { function doUninstall() { setVerboseAndDryRun + setNixProfileCommands echo "This will remove Home Manager from your system." @@ -464,7 +483,7 @@ function doUninstall() { HOME_MANAGER_CONFIG="$(mktemp --tmpdir home-manager.XXXXXXXXXX)" echo "{ lib, ... }: { home.file = lib.mkForce {}; }" > "$HOME_MANAGER_CONFIG" doSwitch - $DRY_RUN_CMD nix-env -e home-manager-path || true + $DRY_RUN_CMD $REMOVE_CMD home-manager-path || true rm "$HOME_MANAGER_CONFIG" $DRY_RUN_CMD rm $VERBOSE_ARG -r \ "${XDG_DATA_HOME:-$HOME/.local/share}/home-manager" diff --git a/modules/files.nix b/modules/files.nix index d6b5eb64335f..8e8d26a5f6cd 100644 --- a/modules/files.nix +++ b/modules/files.nix @@ -239,7 +239,7 @@ in } function cleanOldGen() { - if [[ ! -v oldGenPath ]] ; then + if [[ ! -v oldGenPath || ! -e "$oldGenPath/home-files" ]] ; then return fi @@ -260,7 +260,17 @@ in if [[ ! -v oldGenPath || "$oldGenPath" != "$newGenPath" ]] ; then echo "Creating profile generation $newGenNum" - $DRY_RUN_CMD nix-env $VERBOSE_ARG --profile "$genProfilePath" --set "$newGenPath" + if [[ -e "$genProfilePath"/manifest.json ]] ; then + # Remove all packages from "$genProfilePath" + # `nix profile remove '.*' --profile "$genProfilePath"` was not working, so here is a workaround: + nix profile list --profile "$genProfilePath" \ + | cut -d ' ' -f 4 \ + | xargs -t $DRY_RUN_CMD nix profile remove $VERBOSE_ARG --profile "$genProfilePath" + $DRY_RUN_CMD nix profile install $VERBOSE_ARG --profile "$genProfilePath" "$newGenPath" + else + $DRY_RUN_CMD nix-env $VERBOSE_ARG --profile "$genProfilePath" --set "$newGenPath" + fi + $DRY_RUN_CMD ln -Tsf $VERBOSE_ARG "$newGenPath" "$newGenGcPath" else echo "No change so reusing latest profile generation $oldGenNum" diff --git a/modules/home-environment.nix b/modules/home-environment.nix index dd8b9817f15f..6d880818af71 100644 --- a/modules/home-environment.nix +++ b/modules/home-environment.nix @@ -578,30 +578,49 @@ in if config.submoduleSupport.externalPackageInstall then '' - if nix-env -q | grep '^home-manager-path$'; then - $DRY_RUN_CMD nix-env -e home-manager-path + if [[ -e "$nixProfilePath"/manifest.json ]] ; then + nix profile list \ + | { grep 'home-manager-path$' || test $? = 1; } \ + | awk -F ' ' '{ print $4 }' \ + | cut -d ' ' -f 4 \ + | xargs -t $DRY_RUN_CMD nix profile remove $VERBOSE_ARG + else + if nix-env -q | grep '^home-manager-path$'; then + $DRY_RUN_CMD nix-env -e home-manager-path + fi fi '' else '' - if ! $DRY_RUN_CMD nix-env -i ${cfg.path} ; then + if [[ -e "$nixProfilePath"/manifest.json ]] ; then + INSTALL_CMD="nix profile install" + LIST_CMD="nix profile list" + REMOVE_CMD_SYNTAX='nix profile remove {number | store path}' + else + INSTALL_CMD="nix-env -i" + LIST_CMD="nix-env -q" + REMOVE_CMD_SYNTAX='nix-env -e {package name}' + fi + + if ! $DRY_RUN_CMD $INSTALL_CMD ${cfg.path} ; then cat <" ]); getSubModules = elemType.getSubModules; substSubModules = m: dagOf (elemType.substSubModules m); functor = (defaultFunctor name) // { wrapped = elemType; }; + nestedTypes.elemType = elemType; }; # A directed acyclic graph of some inner type OR a list of that diff --git a/modules/programs/direnv.nix b/modules/programs/direnv.nix index ad4c49934690..9974a28fb3a6 100644 --- a/modules/programs/direnv.nix +++ b/modules/programs/direnv.nix @@ -15,8 +15,6 @@ in { "direnv" "enableNixDirenvIntegration" ] [ "programs" "direnv" "nix-direnv" "enable" ]) - (mkRemovedOptionModule [ "programs" "direnv" "nix-direnv" "enableFlakes" ] - "Flake support is now always enabled.") ]; meta.maintainers = [ maintainers.rycee ]; @@ -81,6 +79,7 @@ in { nix-direnv, a fast, persistent use_nix implementation for direnv''; + enableFlakes = mkEnableOption "Flake support in nix-direnv"; }; }; @@ -93,9 +92,11 @@ in { }; xdg.configFile."direnv/direnvrc" = let + package = + pkgs.nix-direnv.override { inherit (cfg.nix-direnv) enableFlakes; }; text = concatStringsSep "\n" (optional (cfg.stdlib != "") cfg.stdlib ++ optional cfg.nix-direnv.enable - "source ${pkgs.nix-direnv}/share/nix-direnv/direnvrc"); + "source ${package}/share/nix-direnv/direnvrc"); in mkIf (text != "") { inherit text; }; programs.bash.initExtra = mkIf cfg.enableBashIntegration ( diff --git a/modules/programs/gpg.nix b/modules/programs/gpg.nix index d32a819243b9..4b233dc6b59b 100644 --- a/modules/programs/gpg.nix +++ b/modules/programs/gpg.nix @@ -6,9 +6,7 @@ let cfg = config.programs.gpg; mkKeyValue = key: value: - if isString value - then "${key} ${value}" - else optionalString value key; + if isString value then "${key} ${value}" else optionalString value key; cfgText = generators.toKeyValue { inherit mkKeyValue; @@ -21,8 +19,132 @@ let } cfg.scdaemonSettings; primitiveType = types.oneOf [ types.str types.bool ]; -in -{ + + publicKeyOpts = { config, ... }: { + options = { + text = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Text of an OpenPGP public key. + ''; + }; + + source = mkOption { + type = types.path; + description = '' + Path of an OpenPGP public key file. + ''; + }; + + trust = mkOption { + type = types.nullOr (types.enum [ + "unknown" + 1 + "never" + 2 + "marginal" + 3 + "full" + 4 + "ultimate" + 5 + ]); + default = null; + apply = v: + if isString v then + { + unknown = 1; + never = 2; + marginal = 3; + full = 4; + ultimate = 5; + }.${v} + else + v; + description = '' + The amount of trust you have in the key ownership and the care the + owner puts into signing other keys. The available levels are + + + unknown or 1 + I don't know or won't say. + + + never or 2 + I do NOT trust. + + + marginal or 3 + I trust marginally. + + + full or 4 + I trust fully. + + + ultimate or 5 + I trust ultimately. + + + + See + for more. + ''; + }; + }; + + config = { + source = + mkIf (config.text != null) (pkgs.writeText "gpg-pubkey" config.text); + }; + }; + + importTrustBashFunctions = let gpg = "${cfg.package}/bin/gpg"; + in '' + function gpgKeyId() { + ${gpg} --show-key --with-colons "$1" \ + | grep ^pub: \ + | cut -d: -f5 + } + + function importTrust() { + local keyIds trust + IFS='\n' read -ra keyIds <<< "$(gpgKeyId "$1")" + trust="$2" + for id in "''${keyIds[@]}" ; do + { echo trust; echo "$trust"; (( trust == 5 )) && echo y; echo quit; } \ + | ${gpg} --no-tty --command-fd 0 --edit-key "$id" + done + } + + ''; + + keyringFiles = let + gpg = "${cfg.package}/bin/gpg"; + + importKey = { source, trust, ... }: '' + ${gpg} --import ${source} + ${optionalString (trust != null) + ''importTrust "${source}" ${toString trust}''} + ''; + + importKeys = concatMapStringsSep "\n" importKey cfg.publicKeys; + in pkgs.runCommand "gpg-pubring" { buildInputs = [ cfg.package ]; } '' + export GNUPGHOME + GNUPGHOME=$(mktemp -d) + + ${importTrustBashFunctions} + ${importKeys} + + mkdir $out + cp $GNUPGHOME/pubring.kbx $out/pubring.kbx + if [[ -e $GNUPGHOME/trustdb.gpg ]] ; then + cp $GNUPGHOME/trustdb.gpg $out/trustdb.gpg + fi + ''; + +in { options.programs.gpg = { enable = mkEnableOption "GnuPG"; @@ -31,11 +153,13 @@ in default = pkgs.gnupg; defaultText = literalExpression "pkgs.gnupg"; example = literalExpression "pkgs.gnupg23"; - description = "The Gnupg package to use (also used the gpg-agent service)."; + description = + "The Gnupg package to use (also used the gpg-agent service)."; }; settings = mkOption { - type = types.attrsOf (types.either primitiveType (types.listOf types.str)); + type = + types.attrsOf (types.either primitiveType (types.listOf types.str)); example = literalExpression '' { no-comments = false; @@ -53,7 +177,8 @@ in }; scdaemonSettings = mkOption { - type = types.attrsOf (types.either primitiveType (types.listOf types.str)); + type = + types.attrsOf (types.either primitiveType (types.listOf types.str)); example = literalExpression '' { disable-ccid = true; @@ -68,11 +193,54 @@ in homedir = mkOption { type = types.path; - example = literalExpression "\"\${config.xdg.dataHome}/gnupg\""; + example = literalExpression ''"''${config.xdg.dataHome}/gnupg"''; default = "${config.home.homeDirectory}/.gnupg"; - defaultText = literalExpression "\"\${config.home.homeDirectory}/.gnupg\""; + defaultText = + literalExpression ''"''${config.home.homeDirectory}/.gnupg"''; description = "Directory to store keychains and configuration."; }; + + mutableKeys = mkOption { + type = types.bool; + default = true; + description = '' + If set to true, you may manage your keyring as a user + using the gpg command. Upon activation, the keyring + will have managed keys added without overwriting unmanaged keys. + + If set to false, the path + $GNUPGHOME/pubring.kbx will become an immutable + link to the Nix store, denying modifications. + ''; + }; + + mutableTrust = mkOption { + type = types.bool; + default = true; + description = '' + If set to true, you may manage trust as a user using + the gpg command. Upon activation, trusted keys have + their trust set without overwriting unmanaged keys. + + If set to false, the path + $GNUPGHOME/trustdb.gpg will be + overwritten on each activation, removing trust for + any unmanaged keys. Be careful to make a backup of your old + trustdb.gpg before switching to immutable trust! + ''; + }; + + publicKeys = mkOption { + type = types.listOf (types.submodule publicKeyOpts); + example = literalExpression '' + [ { source = ./pubkeys.txt; } ] + ''; + default = [ ]; + description = '' + A list of public keys to be imported into GnuPG. Note, these key files + will be copied into the world-readable Nix store. + ''; + }; }; config = mkIf cfg.enable { @@ -80,7 +248,8 @@ in personal-cipher-preferences = mkDefault "AES256 AES192 AES"; personal-digest-preferences = mkDefault "SHA512 SHA384 SHA256"; personal-compress-preferences = mkDefault "ZLIB BZIP2 ZIP Uncompressed"; - default-preference-list = mkDefault "SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed"; + default-preference-list = mkDefault + "SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed"; cert-digest-algo = mkDefault "SHA512"; s2k-digest-algo = mkDefault "SHA512"; s2k-cipher-algo = mkDefault "AES256"; @@ -102,12 +271,56 @@ in }; home.packages = [ cfg.package ]; - home.sessionVariables = { - GNUPGHOME = cfg.homedir; - }; + home.sessionVariables = { GNUPGHOME = cfg.homedir; }; home.file."${cfg.homedir}/gpg.conf".text = cfgText; home.file."${cfg.homedir}/scdaemon.conf".text = scdaemonCfgText; + + # Link keyring if keys are not mutable + home.file."${cfg.homedir}/pubring.kbx" = + mkIf (!cfg.mutableKeys && cfg.publicKeys != [ ]) { + source = "${keyringFiles}/pubring.kbx"; + }; + + home.activation = { + createGpgHomedir = + hm.dag.entryBetween [ "linkGeneration" ] [ "writeBoundary" ] '' + $DRY_RUN_CMD mkdir -m700 -p $VERBOSE_ARG ${escapeShellArg cfg.homedir} + ''; + + importGpgKeys = let + gpg = "${cfg.package}/bin/gpg"; + + importKey = { source, trust, ... }: + # Import mutable keys + optional cfg.mutableKeys + "$DRY_RUN_CMD ${gpg} $QUIET_ARG --import ${source}" + + # Import mutable trust + ++ optional (trust != null && cfg.mutableTrust) + ''$DRY_RUN_CMD importTrust "${source}" ${toString trust}''; + + anyTrust = any (k: k.trust != null) cfg.publicKeys; + + importKeys = concatStringsSep "\n" (concatMap importKey cfg.publicKeys); + + # If any key/trust should be imported then create the block. Otherwise + # leave it empty. + block = concatStringsSep "\n" (optional (importKeys != "") '' + export GNUPGHOME=${escapeShellArg cfg.homedir} + if [[ ! -v VERBOSE ]]; then + QUIET_ARG="--quiet" + else + QUIET_ARG="" + fi + ${importTrustBashFunctions} + ${importKeys} + unset GNUPGHOME QUIET_ARG keyId importTrust + '' ++ optional (!cfg.mutableTrust && anyTrust) '' + install -m 0700 ${keyringFiles}/trustdb.gpg "${cfg.homedir}/trustdb.gpg"''); + in mkIf (cfg.publicKeys != [ ]) + (lib.hm.dag.entryAfter [ "linkGeneration" ] block); + }; }; } diff --git a/modules/programs/irssi.nix b/modules/programs/irssi.nix index a8f8a22ff703..ea74986339b6 100644 --- a/modules/programs/irssi.nix +++ b/modules/programs/irssi.nix @@ -44,14 +44,15 @@ let } '')); - channelString = concatStringsSep cnl (flip mapAttrsToList cfg.networks (k: v: - concatStringsSep cnl (flip mapAttrsToList v.channels (c: cv: '' - { - chatnet = "${k}"; - name = "${c}"; - autojoin = "${boolStr cv.autoJoin}"; - } - '')))); + channelString = concatStringsSep cnl (concatLists + (flip mapAttrsToList cfg.networks (k: v: + (flip mapAttrsToList v.channels (c: cv: '' + { + chatnet = "${k}"; + name = "${c}"; + autojoin = "${boolStr cv.autoJoin}"; + } + ''))))); channelType = types.submodule { options = { diff --git a/modules/programs/kakoune.nix b/modules/programs/kakoune.nix index 49f259d012b9..bf332a7a843b 100644 --- a/modules/programs/kakoune.nix +++ b/modules/programs/kakoune.nix @@ -530,20 +530,20 @@ let uiOptions = with cfg.config.ui; concatStringsSep " " [ - "ncurses_set_title=${if setTitle then "true" else "false"}" - "ncurses_status_on_top=${ + "terminal_set_title=${if setTitle then "true" else "false"}" + "terminal_status_on_top=${ if (statusLine == "top") then "true" else "false" }" - "ncurses_assistant=${assistant}" - "ncurses_enable_mouse=${if enableMouse then "true" else "false"}" - "ncurses_change_colors=${if changeColors then "true" else "false"}" + "terminal_assistant=${assistant}" + "terminal_enable_mouse=${if enableMouse then "true" else "false"}" + "terminal_change_colors=${if changeColors then "true" else "false"}" "${optionalString (wheelDownButton != null) - "ncurses_wheel_down_button=${wheelDownButton}"}" + "terminal_wheel_down_button=${wheelDownButton}"}" "${optionalString (wheelUpButton != null) - "ncurses_wheel_up_button=${wheelUpButton}"}" + "terminal_wheel_up_button=${wheelUpButton}"}" "${optionalString (shiftFunctionKeys != null) - "ncurses_shift_function_key=${toString shiftFunctionKeys}"}" - "ncurses_builtin_key_parser=${ + "terminal_shift_function_key=${toString shiftFunctionKeys}"}" + "terminal_builtin_key_parser=${ if useBuiltinKeyParser then "true" else "false" }" ]; diff --git a/modules/programs/rofi.nix b/modules/programs/rofi.nix index 1ae7016bc11d..0c4bc3d897b9 100644 --- a/modules/programs/rofi.nix +++ b/modules/programs/rofi.nix @@ -35,10 +35,10 @@ let ${configStr}} '' else - mkKeyValue { + (mkKeyValue { sep = " "; end = ""; - } name value; + } name value) + "\n"; toRasi = attrs: concatStringsSep "\n" (mapAttrsToList mkRasiSection attrs); @@ -266,9 +266,9 @@ in { location = (getAttr cfg.location locationsMap); xoffset = cfg.xoffset; yoffset = cfg.yoffset; - theme = themeName; } // cfg.extraConfig); - }; + # @theme must go after configuration but attrs are output in alphabetical order ('@' first) + } + (optionalString (themeName != null) (toRasi { "@theme" = themeName; })); xdg.dataFile = mkIf (themePath != null) (if themePath == "custom" then { "rofi/themes/${themeName}.rasi".text = toRasi cfg.theme; diff --git a/modules/services/gpg-agent.nix b/modules/services/gpg-agent.nix index 785f11141c1c..5270af394eb0 100644 --- a/modules/services/gpg-agent.nix +++ b/modules/services/gpg-agent.nix @@ -170,6 +170,18 @@ in now. ''; }; + + enableBashIntegration = mkEnableOption "Bash integration" // { + default = true; + }; + + enableZshIntegration = mkEnableOption "Zsh integration" // { + default = true; + }; + + enableFishIntegration = mkEnableOption "Fish integration" // { + default = true; + }; }; }; @@ -206,9 +218,9 @@ in fi ''; - programs.bash.initExtra = gpgInitStr; - programs.zsh.initExtra = gpgInitStr; - programs.fish.interactiveShellInit = '' + programs.bash.initExtra = mkIf cfg.enableBashIntegration gpgInitStr; + programs.zsh.initExtra = mkIf cfg.enableZshIntegration gpgInitStr; + programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration '' set -gx GPG_TTY (tty) ''; } diff --git a/modules/targets/generic-linux.nix b/modules/targets/generic-linux.nix index 9132d8898b04..8347cd6bfbdc 100644 --- a/modules/targets/generic-linux.nix +++ b/modules/targets/generic-linux.nix @@ -8,6 +8,8 @@ let profileDirectory = config.home.profileDirectory; + nixPkg = if config.nix.package == null then pkgs.nix else config.nix.package; + in { imports = [ (mkRenamedOptionModule [ "targets" "genericLinux" "extraXdgDataDirs" ] [ @@ -44,7 +46,7 @@ in { ]; home.sessionVariablesExtra = '' - . "${pkgs.nix}/etc/profile.d/nix.sh" + . "${nixPkg}/etc/profile.d/nix.sh" # reset TERM with new TERMINFO available (if any) export TERM="$TERM" @@ -53,7 +55,7 @@ in { # We need to source both nix.sh and hm-session-vars.sh as noted in # https://github.com/nix-community/home-manager/pull/797#issuecomment-544783247 programs.bash.initExtra = '' - . "${pkgs.nix}/etc/profile.d/nix.sh" + . "${nixPkg}/etc/profile.d/nix.sh" . "${profileDirectory}/etc/profile.d/hm-session-vars.sh" ''; diff --git a/nix-darwin/default.nix b/nix-darwin/default.nix index 8d354a1d5dc3..007e2de3886a 100644 --- a/nix-darwin/default.nix +++ b/nix-darwin/default.nix @@ -29,6 +29,10 @@ let home.username = config.users.users.${name}.name; home.homeDirectory = config.users.users.${name}.home; + + # Make activation script use same version of Nix as system as a whole. + # This avoids problems with Nix not being in PATH. + home.extraActivationPath = [ config.nix.package ]; }; }) ] ++ cfg.sharedModules; @@ -130,7 +134,7 @@ in system.activationScripts.postActivation.text = concatStringsSep "\n" (mapAttrsToList (username: usercfg: '' echo Activating home-manager configuration for ${username} - sudo -u ${username} -i ${pkgs.writeShellScript "activation-${username}" '' + sudo -u ${username} -s --set-home ${pkgs.writeShellScript "activation-${username}" '' ${lib.optionalString (cfg.backupFileExtension != null) "export HOME_MANAGER_BACKUP_EXT=${lib.escapeShellArg cfg.backupFileExtension}"} ${lib.optionalString cfg.verbose "export VERBOSE=1"} diff --git a/tests/lib/types/dag-merge.nix b/tests/lib/types/dag-merge.nix index 5e361cd7e7f5..0b41ec8a0c49 100644 --- a/tests/lib/types/dag-merge.nix +++ b/tests/lib/types/dag-merge.nix @@ -1,7 +1,7 @@ { config, lib, pkgs, ... }: let - inherit (lib) concatStringsSep hm mkMerge mkOption types; + inherit (lib) concatStringsSep hm mkIf mkMerge mkOption types; dag = lib.hm.dag; @@ -14,10 +14,14 @@ in { options.tested.dag = mkOption { type = hm.types.dagOf types.str; }; config = { - tested = mkMerge [ - { dag.after = "after"; } - { dag.before = dag.entryBefore [ "after" ] "before"; } - { dag.between = dag.entryBetween [ "after" ] [ "before" ] "between"; } + tested.dag = mkMerge [ + { never = mkIf false "never"; } + { after = mkMerge [ "after" (mkIf false "neither") ]; } + { before = dag.entryBefore [ "after" ] (mkIf true "before"); } + { + between = + mkIf true (dag.entryBetween [ "after" ] [ "before" ] "between"); + } ]; home.file."result.txt".text = result; diff --git a/tests/modules/programs/gpg/default.nix b/tests/modules/programs/gpg/default.nix index 7fed2cdcc69c..a3949b186013 100644 --- a/tests/modules/programs/gpg/default.nix +++ b/tests/modules/programs/gpg/default.nix @@ -1 +1,5 @@ -{ gpg-override-defaults = ./override-defaults.nix; } +{ + gpg-immutable-keyfiles = ./immutable-keyfiles.nix; + gpg-mutable-keyfiles = ./mutable-keyfiles.nix; + gpg-override-defaults = ./override-defaults.nix; +} diff --git a/tests/modules/programs/gpg/immutable-keyfiles.nix b/tests/modules/programs/gpg/immutable-keyfiles.nix new file mode 100644 index 000000000000..b66d770f19bf --- /dev/null +++ b/tests/modules/programs/gpg/immutable-keyfiles.nix @@ -0,0 +1,52 @@ +{ config, lib, pkgs, ... }: + +{ + programs.gpg = { + enable = true; + + mutableKeys = false; + mutableTrust = false; + + publicKeys = [ + { + source = pkgs.fetchurl { + url = + "https://keybase.io/rycee/pgp_keys.asc?fingerprint=36cacf52d098cc0e78fb0cb13573356c25c424d4"; + sha256 = "082mjy6llvrdry6i9r5gx97nw9d89blnam7bghza4ynsjk1mmx6c"; + }; + trust = 1; # "unknown" + } + { + source = pkgs.fetchurl { + url = "https://www.rsync.net/resources/pubkey.txt"; + sha256 = "16nzqfb1kvsxjkq919hxsawx6ydvip3md3qyhdmw54qx6drnxckl"; + }; + trust = "never"; + } + ]; + }; + + nmt.script = '' + assertFileNotRegex activate "^export GNUPGHOME='/home/hm-user/.gnupg'$" + + assertFileRegex activate \ + '^install -m 0700 /nix/store/[0-9a-z]*-gpg-pubring/trustdb.gpg "/home/hm-user/.gnupg/trustdb.gpg"$' + + # Setup GPGHOME + export GNUPGHOME=$(mktemp -d) + cp -r $TESTED/home-files/.gnupg/* $GNUPGHOME + TRUSTDB=$(grep -o '/nix/store/[0-9a-z]*-gpg-pubring/trustdb.gpg' $TESTED/activate) + install -m 0700 $TRUSTDB $GNUPGHOME/trustdb.gpg + + # Export Trust + export WORKDIR=$(mktemp -d) + ${pkgs.gnupg}/bin/gpg -q --export-ownertrust > $WORKDIR/gpgtrust.txt + + # Check Trust + assertFileRegex $WORKDIR/gpgtrust.txt \ + '^36CACF52D098CC0E78FB0CB13573356C25C424D4:2:$' + + assertFileRegex $WORKDIR/gpgtrust.txt \ + '^BB847B5A69EF343CEF511B29073C282D7D6F806C:3:$' + ''; +} diff --git a/tests/modules/programs/gpg/mutable-keyfiles.nix b/tests/modules/programs/gpg/mutable-keyfiles.nix new file mode 100644 index 000000000000..588c90704884 --- /dev/null +++ b/tests/modules/programs/gpg/mutable-keyfiles.nix @@ -0,0 +1,30 @@ +{ config, lib, pkgs, ... }: + +{ + programs.gpg = { + enable = true; + + publicKeys = [ + { + source = builtins.toFile "key1" "key1"; + trust = 1; + } + { source = builtins.toFile "key2" "key2"; } + ]; + }; + + test.stubs.gnupg = { }; + + nmt.script = '' + assertFileContains activate "export GNUPGHOME='/home/hm-user/.gnupg'" + + assertFileContains activate "unset GNUPGHOME QUIET_ARG keyId importTrust" + + assertFileRegex activate \ + '^\$DRY_RUN_CMD @gnupg@/bin/gpg \$QUIET_ARG --import /nix/store/[0-9a-z]*-key1$' + assertFileRegex activate \ + '^\$DRY_RUN_CMD importTrust "/nix/store/[0-9a-z]*-key1" 1$' + assertFileRegex activate \ + '^\$DRY_RUN_CMD @gnupg@/bin/gpg \$QUIET_ARG --import /nix/store/[0-9a-z]*-key2$' + ''; +} diff --git a/tests/modules/programs/gpg/override-defaults.nix b/tests/modules/programs/gpg/override-defaults.nix index 3b00e451bccb..62fe50dc2adf 100644 --- a/tests/modules/programs/gpg/override-defaults.nix +++ b/tests/modules/programs/gpg/override-defaults.nix @@ -23,6 +23,8 @@ with lib; nmt.script = '' assertFileExists home-files/bar/foopg/gpg.conf assertFileContent home-files/bar/foopg/gpg.conf ${./override-defaults-expected.conf} + + assertFileNotRegex activate "^unset GNUPGHOME keyId importTrust$" ''; }; } diff --git a/tests/modules/programs/i3status-rust/with-custom.nix b/tests/modules/programs/i3status-rust/with-custom.nix index b53963ddba87..d89e2ddcb829 100644 --- a/tests/modules/programs/i3status-rust/with-custom.nix +++ b/tests/modules/programs/i3status-rust/with-custom.nix @@ -175,7 +175,7 @@ with lib; [[block]] block = "battery" - '' + '' } ''; }; diff --git a/tests/modules/programs/i3status-rust/with-default.nix b/tests/modules/programs/i3status-rust/with-default.nix index 4a0d4a4c4d22..c8ff4195ed30 100644 --- a/tests/modules/programs/i3status-rust/with-default.nix +++ b/tests/modules/programs/i3status-rust/with-default.nix @@ -47,7 +47,7 @@ with lib; block = "time" format = "%a %d/%m %R" interval = 60 - '' + '' } ''; }; diff --git a/tests/modules/programs/i3status-rust/with-extra-settings.nix b/tests/modules/programs/i3status-rust/with-extra-settings.nix index 4a0442732bc9..114edb993096 100644 --- a/tests/modules/programs/i3status-rust/with-extra-settings.nix +++ b/tests/modules/programs/i3status-rust/with-extra-settings.nix @@ -191,7 +191,7 @@ with lib; [theme.overrides] idle_bg = "#123456" idle_fg = "#abcdef" - '' + '' } ''; }; diff --git a/tests/modules/programs/rofi/custom-theme-config.rasi b/tests/modules/programs/rofi/custom-theme-config.rasi index 639336d98313..6b4d5b8a0479 100644 --- a/tests/modules/programs/rofi/custom-theme-config.rasi +++ b/tests/modules/programs/rofi/custom-theme-config.rasi @@ -1,6 +1,6 @@ configuration { location: 0; -theme: "custom"; xoffset: 0; yoffset: 0; } +@theme "custom" diff --git a/tests/modules/programs/rofi/custom-theme.rasi b/tests/modules/programs/rofi/custom-theme.rasi index b018843feb0d..8ec097099141 100644 --- a/tests/modules/programs/rofi/custom-theme.rasi +++ b/tests/modules/programs/rofi/custom-theme.rasi @@ -16,4 +16,4 @@ foreground-color: rgba ( 250, 251, 252, 100 % ); width: 512; } -@import "~/.cache/wal/colors-rofi-dark" \ No newline at end of file +@import "~/.cache/wal/colors-rofi-dark"