mirror of
https://github.com/nix-community/home-manager.git
synced 2026-10-03 20:19:19 +00:00
Replace the module-local `impureConfigMerger` with `lib.hm.generators.mkImpureConfigMerger`, keeping the JSON5 reader for settings that may contain comments. Behavior is preserved but two rough edges are fixed along the way: - A corrupted existing file now fails activation loudly instead of silently replacing the user's settings with the generated defaults. - An existing file keeps its permissions and symlink target instead of being replaced with a fresh mode-644 file. Add a test that runs the generated activation snippet with `$DRY_RUN` and `$VERBOSE` set, covering a dry-run that leaves existing settings untouched, a live merge on top of preexisting settings, verbose logging, silent quiet mode, permission preservation, and loud failure on a corrupted file. Assisted-by: Goose + GLM 5.3 Flash
96 lines
2.7 KiB
Nix
96 lines
2.7 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}:
|
|
|
|
{
|
|
programs.zed-editor = {
|
|
enable = true;
|
|
package = config.lib.test.mkStubPackage { };
|
|
userSettings = {
|
|
theme = "XY-Zed";
|
|
vim_mode = false;
|
|
};
|
|
};
|
|
|
|
home.homeDirectory = lib.mkForce "/@TMPDIR@/hm-user";
|
|
|
|
nmt.script =
|
|
let
|
|
preexistingSettings = builtins.toFile "preexisting.json" ''
|
|
{
|
|
"theme": "Default"
|
|
}
|
|
'';
|
|
|
|
expectedContent = builtins.toFile "expected.json" ''
|
|
{
|
|
"theme": "XY-Zed",
|
|
"vim_mode": false
|
|
}
|
|
'';
|
|
|
|
settingsPath = ".config/zed/settings.json";
|
|
corruptedSettings = builtins.toFile "corrupted.json" ''
|
|
{ not valid json
|
|
'';
|
|
activationScript = pkgs.writeScript "activation" config.home.activation.zedSettingsActivation.data;
|
|
mkActivation = name: ''
|
|
substitute ${activationScript} $TMPDIR/${name} --subst-var TMPDIR
|
|
chmod +x $TMPDIR/${name}
|
|
'';
|
|
in
|
|
''
|
|
export HOME=$TMPDIR/hm-user
|
|
|
|
# Simulate preexisting settings
|
|
mkdir -p $HOME/.config/zed
|
|
cat ${preexistingSettings} > $HOME/${settingsPath}
|
|
|
|
${mkActivation "activate"}
|
|
|
|
# Dry-run must leave the existing settings untouched and must not fail
|
|
# with an unbound variable error.
|
|
export DRY_RUN=1
|
|
$TMPDIR/activate > $TMPDIR/dry-output
|
|
unset DRY_RUN
|
|
assertFileContent "$HOME/${settingsPath}" "${preexistingSettings}"
|
|
grep 'Would merge Nix-generated config into' $TMPDIR/dry-output
|
|
|
|
# A live run applies the Nix-generated settings on top.
|
|
$TMPDIR/activate
|
|
assertFileContent "$HOME/${settingsPath}" "${expectedContent}"
|
|
|
|
# Verbose mode logs the merge message.
|
|
${mkActivation "activate-verbose"}
|
|
export VERBOSE=1
|
|
$TMPDIR/activate-verbose > $TMPDIR/verbose-output
|
|
unset VERBOSE
|
|
grep 'Merging Nix-generated config into' $TMPDIR/verbose-output
|
|
|
|
# Without verbose, no merge message is logged.
|
|
$TMPDIR/activate > $TMPDIR/quiet-output
|
|
test ! -s $TMPDIR/quiet-output
|
|
|
|
# A live run must preserve the permissions of an existing file.
|
|
chmod 600 $HOME/${settingsPath}
|
|
$TMPDIR/activate
|
|
currentMode="$(stat -c '%a' $HOME/${settingsPath})"
|
|
test "$currentMode" = 600 || {
|
|
echo "Expected mode 600, got $currentMode"
|
|
exit 1
|
|
}
|
|
|
|
# A corrupted existing file must fail activation loudly instead of
|
|
# silently overwriting it with the generated defaults.
|
|
echo '{ not valid json' > $HOME/${settingsPath}
|
|
if $TMPDIR/activate > /dev/null 2>&1; then
|
|
echo "Activation unexpectedly succeeded on a corrupted config file"
|
|
exit 1
|
|
fi
|
|
assertFileContent "$HOME/${settingsPath}" "${corruptedSettings}"
|
|
'';
|
|
}
|