From: Tino Calancha <[email protected]> Git option -C requires version >= 1.8.5. Add a wrapper function exec_git_command, to run the Git commands. If the system Git supports -C option, then use it; otherwise, emulate that option inside the wrapper.
The options --matchdirs/--ignore-case, used by cmd_find, require tree version >= v1.7.0. For lower versions, print a message to stderr and run tree without the unsupported options. See: https://bugzilla.redhat.com/show_bug.cgi?id=1639806 * src/password-store.sh (exec_git_command): New function. (cmd_find): Use --matchdirs/--ignore-case options if they are available; otherwise, warn user and run tree without the unsupported options. * tests/t0500-find.sh: Update find test to cover tree versions < 1.7.0. * tests/t0300-reencryption.sh: Tweak test to pass on git v1.8.3. --- src/password-store.sh | 57 +++++++++++++++++++++++++++---------- tests/t0300-reencryption.sh | 4 +-- tests/t0500-find.sh | 35 ++++++++++++++++------- 3 files changed, 69 insertions(+), 27 deletions(-) diff --git a/src/password-store.sh b/src/password-store.sh index 1d119f2..a44282f 100755 --- a/src/password-store.sh +++ b/src/password-store.sh @@ -26,24 +26,40 @@ export GIT_CEILING_DIRECTORIES="$PREFIX/.." # BEGIN helper functions # +# If the system Git doesn't support the -C option, then emulate +# it with pushd/popd. +exec_git_command() { + if git --help | grep -q '\[-C <path>\]'; then + git -C "$INNER_GIT_DIR" "$@" + return $? + fi + # Emulate Git -C option. + pushd "$INNER_GIT_DIR" > /dev/null + git "$@" + local result=$? + popd > /dev/null + return $result +} + + set_git() { INNER_GIT_DIR="${1%/*}" while [[ ! -d $INNER_GIT_DIR && ${INNER_GIT_DIR%/*}/ == "${PREFIX%/}/"* ]]; do INNER_GIT_DIR="${INNER_GIT_DIR%/*}" done - [[ $(git -C "$INNER_GIT_DIR" rev-parse --is-inside-work-tree 2>/dev/null) == true ]] || INNER_GIT_DIR="" + [[ $(exec_git_command rev-parse --is-inside-work-tree 2>/dev/null) == true ]] || INNER_GIT_DIR="" } git_add_file() { [[ -n $INNER_GIT_DIR ]] || return - git -C "$INNER_GIT_DIR" add "$1" || return - [[ -n $(git -C "$INNER_GIT_DIR" status --porcelain "$1") ]] || return + exec_git_command add "$1" || return + [[ -n $(exec_git_command status --porcelain "$1") ]] || return git_commit "$2" } git_commit() { local sign="" [[ -n $INNER_GIT_DIR ]] || return - [[ $(git -C "$INNER_GIT_DIR" config --bool --get pass.signcommits) == "true" ]] && sign="-S" - git -C "$INNER_GIT_DIR" commit $sign -m "$1" + [[ $(exec_git_command config --bool --get pass.signcommits) == "true" ]] && sign="-S" + exec_git_command commit $sign -m "$1" } yesno() { [[ -t 0 ]] || return 0 @@ -336,7 +352,7 @@ cmd_init() { [[ ! -f "$gpg_id" ]] && die "Error: $gpg_id does not exist and so cannot be removed." rm -v -f "$gpg_id" || exit 1 if [[ -n $INNER_GIT_DIR ]]; then - git -C "$INNER_GIT_DIR" rm -qr "$gpg_id" + exec_git_command rm -qr "$gpg_id" git_commit "Deinitialize ${gpg_id}${id_path:+ ($id_path)}." fi rmdir -p "${gpg_id%/*}" 2>/dev/null @@ -411,7 +427,18 @@ cmd_find() { [[ $# -eq 0 ]] && die "Usage: $PROGRAM $COMMAND pass-names..." IFS="," eval 'echo "Search Terms: $*"' local terms="*$(printf '%s*|*' "$@")" - tree -C -l --noreport -P "${terms%|*}" --prune --matchdirs --ignore-case "$PREFIX" | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g' + local tree_version=$(tree --version | sed 's/tree \([^[:space:]]\+\).*/\1/g') + # Use --matchdirs and --ignore-case options only when available. + if tree --help |& grep -q -e --matchdirs; then + tree -C -l --noreport -P "${terms%|*}" --prune --matchdirs --ignore-case "$PREFIX" | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g' + else + cat >&2 <<-_EOF + Your tree version ($tree_version) doesn't support --ignore-case/--matchdirs options. + Upgrade tree to version >= 1.7.0 if you wish to use them. + +_EOF + tree -C -l --noreport -P "${terms%|*}" --prune "$PREFIX" | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g' + fi } cmd_grep() { @@ -584,7 +611,7 @@ cmd_delete() { rm $recursive -f -v "$passfile" set_git "$passfile" if [[ -n $INNER_GIT_DIR && ! -e $passfile ]]; then - git -C "$INNER_GIT_DIR" rm -qr "$passfile" + exec_git_command rm -qr "$passfile" set_git "$passfile" git_commit "Remove $path from store." fi @@ -628,15 +655,15 @@ cmd_copy_move() { set_git "$new_path" if [[ -n $INNER_GIT_DIR && ! -e $old_path ]]; then - git -C "$INNER_GIT_DIR" rm -qr "$old_path" 2>/dev/null + exec_git_command rm -qr "$old_path" 2>/dev/null set_git "$new_path" git_add_file "$new_path" "Rename ${1} to ${2}." fi set_git "$old_path" if [[ -n $INNER_GIT_DIR && ! -e $old_path ]]; then - git -C "$INNER_GIT_DIR" rm -qr "$old_path" 2>/dev/null + exec_git_command rm -qr "$old_path" 2>/dev/null set_git "$old_path" - [[ -n $(git -C "$INNER_GIT_DIR" status --porcelain "$old_path") ]] && git_commit "Remove ${1}." + [[ -n $(exec_git_command status --porcelain "$old_path") ]] && git_commit "Remove ${1}." fi rmdir -p "$old_dir" 2>/dev/null else @@ -650,17 +677,17 @@ cmd_git() { set_git "$PREFIX/" if [[ $1 == "init" ]]; then INNER_GIT_DIR="$PREFIX" - git -C "$INNER_GIT_DIR" "$@" || exit 1 + exec_git_command "$@" || exit 1 git_add_file "$PREFIX" "Add current contents of password store." echo '*.gpg diff=gpg' > "$PREFIX/.gitattributes" git_add_file .gitattributes "Configure git repository for gpg file diff." - git -C "$INNER_GIT_DIR" config --local diff.gpg.binary true - git -C "$INNER_GIT_DIR" config --local diff.gpg.textconv "$GPG -d ${GPG_OPTS[*]}" + exec_git_command config --local diff.gpg.binary true + exec_git_command config --local diff.gpg.textconv "$GPG -d ${GPG_OPTS[*]}" elif [[ -n $INNER_GIT_DIR ]]; then tmpdir nowarn #Defines $SECURE_TMPDIR. We don't warn, because at most, this only copies encrypted files. export TMPDIR="$SECURE_TMPDIR" - git -C "$INNER_GIT_DIR" "$@" + exec_git_command "$@" else die "Error: the password store is not a git repository. Try \"$PROGRAM git init\"." fi diff --git a/tests/t0300-reencryption.sh b/tests/t0300-reencryption.sh index 3c88987..4729f58 100755 --- a/tests/t0300-reencryption.sh +++ b/tests/t0300-reencryption.sh @@ -90,8 +90,8 @@ test_expect_success 'Reencryption subfolder multiple keys, move, deinit' ' test_expect_success 'Reencryption skips links' ' ln -s "$PASSWORD_STORE_DIR/folder/cred1.gpg" "$PASSWORD_STORE_DIR/folder/linked_cred.gpg" && [[ -L $PASSWORD_STORE_DIR/folder/linked_cred.gpg ]] && - git add "$PASSWORD_STORE_DIR/folder/linked_cred.gpg" && - git commit "$PASSWORD_STORE_DIR/folder/linked_cred.gpg" -m "Added linked cred" && + git add "folder/linked_cred.gpg" && + git commit -m "Added linked cred" && "$PASS" init -p folder $KEY3 && [[ -L $PASSWORD_STORE_DIR/folder/linked_cred.gpg ]] ' diff --git a/tests/t0500-find.sh b/tests/t0500-find.sh index 3cf6815..9727b35 100755 --- a/tests/t0500-find.sh +++ b/tests/t0500-find.sh @@ -4,15 +4,30 @@ test_description='Find check' cd "$(dirname "$0")" . ./setup.sh -test_expect_success 'Make sure find resolves correct files' ' - "$PASS" init $KEY1 && - "$PASS" generate Something/neat 19 && - "$PASS" generate Anotherthing/okay 38 && - "$PASS" generate Fish 12 && - "$PASS" generate Fishthings 122 && - "$PASS" generate Fishies/stuff 21 && - "$PASS" generate Fishies/otherstuff 1234 && - [[ $("$PASS" find fish | sed "s/^[ \`|-]*//g;s/$(printf \\x1b)\\[[0-9;]*[a-zA-Z]//g" | tr "\\n" -) == "Search Terms: fish-Fish-Fishies-otherstuff-stuff-Fishthings-" ]] -' +if tree --help 2>&1 | grep -q -e --ignore-case -e --matchdirs; then + test_expect_success 'Make sure find resolves correct files' ' + "$PASS" init $KEY1 && + "$PASS" generate Something/neat 19 && + "$PASS" generate Anotherthing/okay 38 && + "$PASS" generate Fish 12 && + "$PASS" generate Fishthings 122 && + "$PASS" generate Fishies/stuff 21 && + "$PASS" generate Fishies/otherstuff 1234 && + [[ $("$PASS" find fish | sed "s/^[ \`|-]*//g;s/$(printf \\x1b)\\[[0-9;]*[a-zA-Z]//g" | tr "\\n" -) == "Search Terms: fish-Fish-Fishies-otherstuff-stuff-Fishthings-" ]] + ' +else + # Redirect stderr to /dev/null to drop the warning message. + test_expect_success 'Make sure find resolves correct files' ' + "$PASS" init $KEY1 && + "$PASS" generate Something/neat 19 && + "$PASS" generate Anotherthing/okay 38 && + "$PASS" generate Fish 12 && + "$PASS" generate myfish 12 && + "$PASS" generate Fishthings 122 && + "$PASS" generate Fishies/stuff 21 && + "$PASS" generate Fishies/otherstuff 1234 && + [[ $("$PASS" find fish 2>/dev/null | sed "s/^[ \`|-]*//g;s/$(printf \\x1b)\\[[0-9;]*[a-zA-Z]//g" | tr "\\n" -) == "Search Terms: fish-myfish-" ]] + ' +fi test_done -- 2.20.1 _______________________________________________ Password-Store mailing list [email protected] https://lists.zx2c4.com/mailman/listinfo/password-store
