From 07ad6a4f76d9402ae8af1507b4158b52aa59fcea Mon Sep 17 00:00:00 2001 From: Robert Helgesson Date: Thu, 20 May 2021 22:12:45 +0200 Subject: [PATCH] files: fix use of onChange with directory source Previously, the comparison would not handle directory comparison correctly, always finding that the source and target differed. This would trigger the `onChange` script on each activation. Fixes #2004 --- modules/files.nix | 23 ++++++++++++++++++++++- modules/lib/file-type.nix | 3 +++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/modules/files.nix b/modules/files.nix index 09ecf715..9eb4fd05 100644 --- a/modules/files.nix +++ b/modules/files.nix @@ -39,6 +39,17 @@ in }; config = { + assertions = [( + let + conflicts = mapAttrsToList (n: v: n) + (filterAttrs (n: v: v.recursive && v.onChange != "") cfg); + in { + assertion = conflicts == []; + message = '' + Cannot use 'home.file..onChange' when 'home.file..recursive' is enabled: + ${concatStringsSep ", " conflicts}''; + })]; + lib.file.mkOutOfStoreSymlink = path: let pathStr = toString path; @@ -236,12 +247,22 @@ in home.activation.checkFilesChanged = hm.dag.entryBefore ["linkGeneration"] ( '' + function _cmp() { + if [[ -d $1 && -d $2 ]]; then + diff -rq "$1" "$2" &> /dev/null + else + cmp --quiet "$1" "$2" + fi + } declare -A changedFiles '' + concatMapStrings (v: '' - cmp --quiet "${sourceStorePath v}" "${homeDirectory}/${v.target}" \ + _cmp "${sourceStorePath v}" "${homeDirectory}/${v.target}" \ && changedFiles["${v.target}"]=0 \ || changedFiles["${v.target}"]=1 '') (filter (v: v.onChange != "") (attrValues cfg)) + + '' + unset -f _cmp + '' ); home.activation.onFilesChange = hm.dag.entryAfter ["linkGeneration"] ( diff --git a/modules/lib/file-type.nix b/modules/lib/file-type.nix index 56a3a128..d0ae1f31 100644 --- a/modules/lib/file-type.nix +++ b/modules/lib/file-type.nix @@ -82,6 +82,9 @@ with lib; generations. The script will be run after the new files have been linked into place. + + Note, this option cannot be used when recursive + is enabled. ''; };