add better diff ignores

This commit is contained in:
RingOfStorms (Joshua Bell) 2026-01-05 23:44:18 -06:00
parent 2f96b52b6f
commit d04f855874
4 changed files with 204 additions and 2 deletions

View file

@ -7,9 +7,64 @@
let
cfg = config.impermanence.tools;
bcacheImpermanenceBin = pkgs.writeShellScriptBin "bcache-impermanence" (
persistence = config.environment.persistence or { };
normalizePath = v:
if builtins.isString v then
v
else if v ? dirPath then
v.dirPath
else if v ? filePath then
v.filePath
else
null;
pathsFromList = f: xs: lib.filter (p: p != null) (map f xs);
userPersistencePaths = users:
lib.flatten (
lib.mapAttrsToList (
userName: userCfg:
let
home = (config.users.users.${userName} or { }).home or "/home/${userName}";
normalizeUserPath = v:
if builtins.isString v then
if lib.hasPrefix "/" v then v else "${home}/${v}"
else
normalizePath v;
in
(pathsFromList normalizeUserPath (userCfg.directories or [ ]))
++ (pathsFromList normalizeUserPath (userCfg.files or [ ]))
) users
);
ignorePaths =
lib.unique (
lib.filter (p: p != null && p != "" && p != "/") (
lib.flatten (
lib.mapAttrsToList (
persistRoot: persistCfg:
[ persistRoot ]
++ (pathsFromList normalizePath (persistCfg.directories or [ ]))
++ (pathsFromList normalizePath (persistCfg.files or [ ]))
++ (userPersistencePaths (persistCfg.users or { }))
) persistence
)
)
);
ignoreFile = pkgs.writeText "bcache-impermanence-ignore-paths" (
lib.concatStringsSep "\n" ignorePaths + "\n"
);
scriptFile = pkgs.writeText "bcache-impermanence.sh" (
builtins.readFile ./impermanence-tools.sh
);
bcacheImpermanenceBin = pkgs.writeShellScriptBin "bcache-impermanence" ''
export BCACHE_IMPERMANENCE_IGNORE_FILE="${ignoreFile}"
exec ${pkgs.bash}/bin/bash "${scriptFile}" "$@"
'';
in
{
options.impermanence.tools = {

View file

@ -7,6 +7,7 @@ KEEP_RECENT_WEEKS=4
KEEP_RECENT_COUNT=5
DRY_RUN=0
DIFF_MAX_DEPTH=0
IGNORE_FILE="${BCACHE_IMPERMANENCE_IGNORE_FILE-}"
usage() {
cat <<EOF
@ -466,6 +467,13 @@ cmd_diff() {
local persist_mounts
persist_mounts=$(awk '$2 ~ "^/persist(/|$)" { print $2 }' /proc/self/mounts || true)
# Optional ignore list file generated from `environment.persistence`.
local ignore_list
ignore_list=""
if [ -n "$IGNORE_FILE" ] && [ -f "$IGNORE_FILE" ]; then
ignore_list=$(grep -vE '^[[:space:]]*($|#)' "$IGNORE_FILE" | sed 's/[[:space:]]*$//' || true)
fi
is_persist_backed() {
local p
p="$1"
@ -484,6 +492,34 @@ cmd_diff() {
return 1
}
is_ignored_path() {
local p
p="$1"
if [ -z "$p" ] || [ "$p" = "/" ]; then
return 1
fi
if [ -z "$ignore_list" ]; then
return 1
fi
local ign
while read -r ign; do
[ -n "$ign" ] || continue
case "$ign" in
/*) : ;;
*) continue ;;
esac
case "$p" in
"$ign"|"$ign"/*) return 0 ;;
esac
done <<<"$ignore_list"
return 1
}
local prefixes
prefixes=("$@")
@ -504,6 +540,11 @@ cmd_diff() {
continue
fi
# Skip prefixes explicitly persisted via `environment.persistence`.
if is_ignored_path "$prefix"; then
continue
fi
local rel
rel="${prefix#/}"
[ -z "$rel" ] && rel="."
@ -550,6 +591,11 @@ cmd_diff() {
continue
fi
# Skip paths explicitly persisted via `environment.persistence`.
if is_ignored_path "$b_path"; then
continue
fi
local status
if [ ! -e "$a_path" ] && [ -e "$b_path" ]; then
status="added"

View file

@ -7,9 +7,64 @@
let
cfg = config.impermanence.tools;
bcacheImpermanenceBin = pkgs.writeShellScriptBin "bcache-impermanence" (
persistence = config.environment.persistence or { };
normalizePath = v:
if builtins.isString v then
v
else if v ? dirPath then
v.dirPath
else if v ? filePath then
v.filePath
else
null;
pathsFromList = f: xs: lib.filter (p: p != null) (map f xs);
userPersistencePaths = users:
lib.flatten (
lib.mapAttrsToList (
userName: userCfg:
let
home = (config.users.users.${userName} or { }).home or "/home/${userName}";
normalizeUserPath = v:
if builtins.isString v then
if lib.hasPrefix "/" v then v else "${home}/${v}"
else
normalizePath v;
in
(pathsFromList normalizeUserPath (userCfg.directories or [ ]))
++ (pathsFromList normalizeUserPath (userCfg.files or [ ]))
) users
);
ignorePaths =
lib.unique (
lib.filter (p: p != null && p != "" && p != "/") (
lib.flatten (
lib.mapAttrsToList (
persistRoot: persistCfg:
[ persistRoot ]
++ (pathsFromList normalizePath (persistCfg.directories or [ ]))
++ (pathsFromList normalizePath (persistCfg.files or [ ]))
++ (userPersistencePaths (persistCfg.users or { }))
) persistence
)
)
);
ignoreFile = pkgs.writeText "bcache-impermanence-ignore-paths" (
lib.concatStringsSep "\n" ignorePaths + "\n"
);
scriptFile = pkgs.writeText "bcache-impermanence.sh" (
builtins.readFile ./impermanence-tools.sh
);
bcacheImpermanenceBin = pkgs.writeShellScriptBin "bcache-impermanence" ''
export BCACHE_IMPERMANENCE_IGNORE_FILE="${ignoreFile}"
exec ${pkgs.bash}/bin/bash "${scriptFile}" "$@"
'';
in
{
options.impermanence.tools = {

View file

@ -7,6 +7,7 @@ KEEP_RECENT_WEEKS=4
KEEP_RECENT_COUNT=5
DRY_RUN=0
DIFF_MAX_DEPTH=0
IGNORE_FILE="${BCACHE_IMPERMANENCE_IGNORE_FILE-}"
usage() {
cat <<EOF
@ -466,6 +467,13 @@ cmd_diff() {
local persist_mounts
persist_mounts=$(awk '$2 ~ "^/persist(/|$)" { print $2 }' /proc/self/mounts || true)
# Optional ignore list file generated from `environment.persistence`.
local ignore_list
ignore_list=""
if [ -n "$IGNORE_FILE" ] && [ -f "$IGNORE_FILE" ]; then
ignore_list=$(grep -vE '^[[:space:]]*($|#)' "$IGNORE_FILE" | sed 's/[[:space:]]*$//' || true)
fi
is_persist_backed() {
local p
p="$1"
@ -484,6 +492,34 @@ cmd_diff() {
return 1
}
is_ignored_path() {
local p
p="$1"
if [ -z "$p" ] || [ "$p" = "/" ]; then
return 1
fi
if [ -z "$ignore_list" ]; then
return 1
fi
local ign
while read -r ign; do
[ -n "$ign" ] || continue
case "$ign" in
/*) : ;;
*) continue ;;
esac
case "$p" in
"$ign"|"$ign"/*) return 0 ;;
esac
done <<<"$ignore_list"
return 1
}
local prefixes
prefixes=("$@")
@ -504,6 +540,11 @@ cmd_diff() {
continue
fi
# Skip prefixes explicitly persisted via `environment.persistence`.
if is_ignored_path "$prefix"; then
continue
fi
local rel
rel="${prefix#/}"
[ -z "$rel" ] && rel="."
@ -550,6 +591,11 @@ cmd_diff() {
continue
fi
# Skip paths explicitly persisted via `environment.persistence`.
if is_ignored_path "$b_path"; then
continue
fi
local status
if [ ! -e "$a_path" ] && [ -e "$b_path" ]; then
status="added"