From 4af3336c451c3770b41dd868b8906e84f12cc722 Mon Sep 17 00:00:00 2001 From: Erik Flodin Date: Sun, 24 Nov 2024 22:56:07 +0100 Subject: [PATCH] Use git ls-files to list files to encrypt By using git ls-files instead of bash we can support ** also on macOS where the included bash version (3) doesn't support globstar. --- test/test_unit_parse_encrypt.py | 7 ++-- yadm | 65 ++++++++------------------------- yadm.1 | 12 +++--- 3 files changed, 24 insertions(+), 60 deletions(-) diff --git a/test/test_unit_parse_encrypt.py b/test/test_unit_parse_encrypt.py index 6a5c23b..d7db41a 100644 --- a/test/test_unit_parse_encrypt.py +++ b/test/test_unit_parse_encrypt.py @@ -105,7 +105,8 @@ def create_test_encrypt_data(paths): edata += "dirwild*\n" paths.work.join("dirwildcard/file1").write("", ensure=True) paths.work.join("dirwildcard/file2").write("", ensure=True) - expected.add("dirwildcard") + expected.add("dirwildcard/file1") + expected.add("dirwildcard/file2") # excludes edata += "exclude*\n" @@ -186,9 +187,7 @@ def run_parse_encrypt(runner, paths, skip_parse=False, twice=False): YADM_WORK={paths.work} export YADM_WORK {parse_cmd} - export ENCRYPT_INCLUDE_FILES - export PARSE_ENCRYPT_SHORT - env + echo PARSE_ENCRYPT_SHORT=$PARSE_ENCRYPT_SHORT echo EIF_COUNT:${{#ENCRYPT_INCLUDE_FILES[@]}} for value in "${{ENCRYPT_INCLUDE_FILES[@]}}"; do echo "EIF:$value" diff --git a/yadm b/yadm index 547121b..7455d25 100755 --- a/yadm +++ b/yadm @@ -1940,65 +1940,30 @@ function parse_encrypt() { fi ENCRYPT_INCLUDE_FILES=() - ENCRYPT_EXCLUDE_FILES=() - FINAL_INCLUDE=() [ -f "$YADM_ENCRYPT" ] || return cd_work "Parsing encrypt" || return - # setting globstar to allow ** in encrypt patterns - # (only supported on Bash >= 4) - local unset_globstar - if ! shopt globstar &> /dev/null; then - unset_globstar=1 - fi - shopt -s globstar &> /dev/null + local -a exclude + local -a include - exclude_pattern="^!(.+)" - # parse both included/excluded - while IFS='' read -r line || [ -n "$line" ]; do - if [[ ! $line =~ ^# && ! $line =~ ^[[:blank:]]*$ ]] ; then - local IFS=$'\n' - for pattern in $line; do - if [[ "$pattern" =~ $exclude_pattern ]]; then - for ex_file in ${BASH_REMATCH[1]}; do - if [ -e "$ex_file" ]; then - ENCRYPT_EXCLUDE_FILES+=("$ex_file") - fi - done - else - for in_file in $pattern; do - if [ -e "$in_file" ]; then - ENCRYPT_INCLUDE_FILES+=("$in_file") - fi - done - fi - done - fi + while IFS= read -r pattern; do + if [[ $pattern =~ ^# || $pattern =~ ^[[:blank:]]*$ ]]; then + continue + fi + if [[ $pattern =~ ^!(.*)$ ]]; then + exclude+=(--exclude "${pattern:1}") + else + include+=("$pattern") + fi done < "$YADM_ENCRYPT" - # remove excludes from the includes - #(SC2068 is disabled because in this case, we desire globbing) - #shellcheck disable=SC2068 - for included in "${ENCRYPT_INCLUDE_FILES[@]}"; do - skip= - #shellcheck disable=SC2068 - for ex_file in ${ENCRYPT_EXCLUDE_FILES[@]}; do - [ "$included" == "$ex_file" ] && { skip=1; break; } - done - [ -n "$skip" ] || FINAL_INCLUDE+=("$included") - done - - # sort the encrypted files - #shellcheck disable=SC2207 - IFS=$'\n' ENCRYPT_INCLUDE_FILES=($(LC_ALL=C sort <<<"${FINAL_INCLUDE[*]}")) - unset IFS - - if [ "$unset_globstar" = "1" ]; then - shopt -u globstar &> /dev/null + if [[ ${#include} -gt 0 ]]; then + while IFS= read -r filename; do + ENCRYPT_INCLUDE_FILES+=("$filename") + done < <("$GIT_PROGRAM" ls-files --others "${exclude[@]}" -- "${include[@]}") fi - } function builtin_dirname() { diff --git a/yadm.1 b/yadm.1 index e79ac06..d3fe100 100644 --- a/yadm.1 +++ b/yadm.1 @@ -750,7 +750,8 @@ gpg is used by default, but openssl can be configured with the .I yadm.cipher configuration. -To use this feature, a list of patterns must be created and saved as +To use this feature, a list of patterns (one per line) must be created and +saved as .IR $HOME/.config/yadm/encrypt . This list of patterns should be relative to the configured .IR work-tree \ (usually\ $HOME ). @@ -761,11 +762,10 @@ For example: .gnupg/*.gpg .RE -Standard filename expansions (*, ?, [) are supported. -If you have Bash version 4, you may use "**" to match all subdirectories. -Other shell expansions like brace and tilde are not supported. -Spaces in paths are supported, and should not be quoted. -If a directory is specified, its contents will be included, but not recursively. +Standard filename expansions (*, ?, [) are supported. Two consecutive asterisks +"**" can be used to match all subdirectories. Other shell expansions like +brace and tilde are not supported. Spaces in paths are supported, and should +not be quoted. If a directory is specified, its contents will be included. Paths beginning with a "!" will be excluded. The