1
0
mirror of https://github.com/TheLocehiliosan/yadm synced 2026-03-02 03:49:29 +00:00

parse_encrypt: Don't let e.g. "*.ext" match files in subdirs

This matches the behavior before 3.4.0.

Silent errors from ls-files to avoid warnings about e.g. directories that
aren't readable and also list files that would have been encrypted had they not
been tracked in git (#521).

Fix the patterns written to info/exclude so that they match the same files as
are encrypted (e.g. *.key should only match .key files in the topdir, not in
subdirs).
This commit is contained in:
Erik Flodin
2025-02-10 20:58:01 +01:00
parent 5648f8b337
commit 6726730701
5 changed files with 87 additions and 36 deletions

98
yadm
View File

@@ -61,6 +61,7 @@ PROC_VERSION="/proc/version"
OPERATING_SYSTEM="Unknown"
ENCRYPT_INCLUDE_FILES="unparsed"
NO_ENCRYPT_TRACKED_FILES=()
LEGACY_WARNING_ISSUED=0
INVALID_ALT=()
@@ -1042,6 +1043,12 @@ function encrypt() {
printf '%s\n' "${ENCRYPT_INCLUDE_FILES[@]}"
echo
if [ ${#NO_ENCRYPT_TRACKED_FILES[@]} -gt 0 ]; then
echo "Warning: The following files are tracked and will NOT be encrypted:"
printf '%s\n' "${NO_ENCRYPT_TRACKED_FILES[@]}"
echo
fi
# encrypt all files which match the globs
if tar -f - -c "${ENCRYPT_INCLUDE_FILES[@]}" | _encrypt_to "$YADM_ARCHIVE"; then
echo "Wrote new file: $YADM_ARCHIVE"
@@ -1468,38 +1475,59 @@ function version() {
function exclude_encrypted() {
local auto_exclude
auto_exclude=$(config --bool yadm.auto-exclude)
[ "$auto_exclude" == "false" ] && return 0
exclude_path="${YADM_REPO}/info/exclude"
newline=$'\n'
exclude_flag="# yadm-auto-excludes"
exclude_header="${exclude_flag}${newline}"
# do nothing if there is no YADM_ENCRYPT
[ -e "$YADM_ENCRYPT" ] || return 0
readonly exclude_path="${YADM_REPO}/info/exclude"
readonly newline=$'\n'
readonly exclude_flag="# yadm-auto-excludes"
local exclude_header="${exclude_flag}${newline}"
exclude_header="${exclude_header}# This section is managed by yadm."
exclude_header="${exclude_header}${newline}"
exclude_header="${exclude_header}# Any edits below will be lost."
exclude_header="${exclude_header}${newline}"
# do nothing if there is no YADM_ENCRYPT
[ -e "$YADM_ENCRYPT" ] || return 0
# read encrypt
encrypt_data=""
while IFS='' read -r line || [ -n "$line" ]; do
encrypt_data="${encrypt_data}${line}${newline}"
local encrypt_data=""
local pattern
while IFS='' read -r pattern || [ -n "$pattern" ]; do
case ${pattern:0:1} in
\#)
pattern=""
;;
!)
# Prepend / to the pattern so that it matches the same files as in
# parse_encrypt (i.e. only from the root)
pattern="!/${pattern:1}$newline"
;;
*)
if ! [[ $pattern =~ ^[[:blank:]]*(#|$) ]]; then
pattern="/$pattern$newline"
else
pattern=""
fi
;;
esac
encrypt_data="${encrypt_data}${pattern}"
done <"$YADM_ENCRYPT"
# read info/exclude
unmanaged=""
managed=""
local unmanaged=""
local managed=""
if [ -e "$exclude_path" ]; then
flag_seen=0
local -i flag_seen=0
local line
while IFS='' read -r line || [ -n "$line" ]; do
[ "$line" = "$exclude_flag" ] && flag_seen=1
if [ "$flag_seen" -eq 0 ]; then
unmanaged="${unmanaged}${line}${newline}"
else
if ((flag_seen)); then
managed="${managed}${line}${newline}"
else
unmanaged="${unmanaged}${line}${newline}"
fi
done <"$exclude_path"
fi
@@ -1926,26 +1954,44 @@ function parse_encrypt() {
local -a exclude
local -a include
while IFS= read -r pattern; do
case $pattern in
\#*)
local pattern
while IFS='' read -r pattern || [ -n "$pattern" ]; do
case ${pattern:0:1} in
\#)
# Ignore comments
;;
!*)
exclude+=("--exclude=${pattern:1}")
!)
exclude+=("--exclude=/${pattern:1}")
;;
*)
if ! [[ $pattern =~ ^[[:blank:]]*$ ]]; then
if ! [[ $pattern =~ ^[[:blank:]]*(#|$) ]]; then
include+=("$pattern")
fi
;;
esac
done <"$YADM_ENCRYPT"
if [[ ${#include} -gt 0 ]]; then
while IFS= read -r filename; do
ENCRYPT_INCLUDE_FILES+=("${filename%/}")
done <<<"$("$GIT_PROGRAM" ls-files --others "${exclude[@]}" -- "${include[@]}")"
if [ ${#include[@]} -gt 0 ]; then
while IFS='' read -r filename; do
if [ -n "$filename" ]; then
ENCRYPT_INCLUDE_FILES+=("${filename%/}")
fi
done <<<"$(
"$GIT_PROGRAM" --glob-pathspecs ls-files --others \
"${exclude[@]}" -- "${include[@]}" 2>/dev/null
)"
[ "$YADM_COMMAND" = "encrypt" ] || return
# List files that matches encryption pattern but is tracked
while IFS='' read -r filename; do
if [ -n "$filename" ]; then
NO_ENCRYPT_TRACKED_FILES+=("${filename%/}")
fi
done <<<"$(
"$GIT_PROGRAM" --glob-pathspecs ls-files \
"${exclude[@]}" -- "${include[@]}"
)"
fi
}