Files
home-manager/tests/lib/generators/mkImpureConfigMerger-mode.nix
Austin Horstman 3378835aa9 generators: add mode input to mkImpureConfigMerger
Some applications store tokens in the files these merges manage, such
as gh's hosts.yml or Docker's config.json, so callers need a way to
create them as 600.

The new optional `mode` input applies only when the target does not
exist yet; existing files keep their mode. By default it is null and a
new file gets the permissions shell redirection would give it under the
activation's umask, as the hand-written mergers this helper replaces
did, instead of a fixed 644. A value that is not an octal string fails
evaluation, rather than the first activation on a machine where the
file does not exist yet.
2026-10-02 10:30:05 -05:00

66 lines
1.9 KiB
Nix

{ lib, pkgs, ... }:
let
mkMerger =
options:
lib.hm.generators.mkImpureConfigMerger (
{
inherit pkgs;
format = "json";
empty = "{}";
jqOperation = "$dynamic * $static";
path = "/@TMPDIR@/merger-mode/settings.json";
staticSettings = builtins.toFile "settings.json" ''{"managed":true}'';
}
// options
);
mkScript =
name: options:
pkgs.writeScript name ''
set -euo pipefail
errorEcho() { echo "$*" >&2; }
${mkMerger options}
'';
defaultMode = mkScript "merge-default-mode" { };
privateMode = mkScript "merge-private-mode" { mode = "600"; };
# An integer such as 600 must fail the same assertion, not a type error.
invalidModeRejected =
lib.all
(
mode:
!(builtins.tryEval (mkMerger {
inherit mode;
})).success
)
[
"u=rw"
600
];
in
{
nmt.script = ''
substitute ${defaultMode} "$TMPDIR/default-mode" --subst-var TMPDIR
substitute ${privateMode} "$TMPDIR/private-mode" --subst-var TMPDIR
chmod +x "$TMPDIR/default-mode" "$TMPDIR/private-mode"
settings="$TMPDIR/merger-mode/settings.json"
(umask 022 && "$TMPDIR/default-mode")
[[ "$(stat -c '%a' "$settings")" == 644 ]] || fail "Expected umask mode 644"
rm "$settings"
(umask 077 && "$TMPDIR/default-mode")
[[ "$(stat -c '%a' "$settings")" == 600 ]] || fail "Expected umask mode 600"
rm "$settings"
"$TMPDIR/private-mode"
[[ "$(stat -c '%a' "$settings")" == 600 ]] || fail "Expected configured mode 600"
chmod 640 "$settings"
"$TMPDIR/private-mode"
[[ "$(stat -c '%a' "$settings")" == 640 ]] || fail "Existing mode must be preserved"
${lib.getExe pkgs.jaq} -e '.managed == true' "$settings" > /dev/null
${lib.optionalString (!invalidModeRejected) ''
fail "A non-octal mode must be rejected during evaluation"
''}
'';
}