pashage

Yet Another Opinionated Re-engineering of the Unix Password Store
git clone https://git.instinctive.eu/pashage.git
Log | Files | Refs | README | LICENSE

commit b15c13f6c8167bb55c988f3695445ebecab9915c
parent a048cf471d230e7e9bef91b6a76e7ab95335d562
Author: Natasha Kerensikova <natgh@instinctive.eu>
Date:   Sat, 21 Sep 2024 06:50:26 +0000

Delete command skips directories without recursive flag
Diffstat:
Mspec/action_spec.sh | 17+++++++++++++++++
Mspec/usage_spec.sh | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Msrc/pashage.sh | 27+++++++++++++++++++++++----
3 files changed, 113 insertions(+), 6 deletions(-)

diff --git a/spec/action_spec.sh b/spec/action_spec.sh @@ -453,6 +453,7 @@ Describe 'Action Functions' Describe 'do_delete' DECISION=force + RECURSIVE=yes PREFIX="${SHELLSPEC_WORKDIR}/prefix" dirname() { @dirname "$@"; } @@ -543,6 +544,22 @@ Describe 'Action Functions' The error should equal "$(result)" End + It 'does not delete an explicit directory without RECURSIVE' + RECURSIVE=no + When run do_delete sub/ + The output should be blank + The error should equal 'Error: sub/ is a directory' + The status should equal 1 + End + + It 'does not delete an implicit directory without RECURSIVE' + RECURSIVE=no + When run do_delete empty + The output should be blank + The error should equal 'Error: empty/ is a directory' + The status should equal 1 + End + It 'does not delete a non-encrypted file' When run do_delete non-encrypted The output should be blank diff --git a/spec/usage_spec.sh b/spec/usage_spec.sh @@ -68,6 +68,7 @@ Describe 'Command-Line Parsing' mocklog do_delete "$@" %text:expand >&2 #|DECISION=${DECISION} + #|RECURSIVE=${RECURSIVE} } do_edit() { mocklog do_edit "$@" @@ -244,12 +245,14 @@ Describe 'Command-Line Parsing' Describe 'cmd_delete' COMMAND=delete + RECURSIVE=no It 'removes a file forcefully with a long option' result() { %text #|$ do_delete arg1 #|DECISION=force + #|RECURSIVE=no } When call cmd_delete --force arg1 The output should be blank @@ -261,21 +264,85 @@ Describe 'Command-Line Parsing' %text #|$ do_delete arg1 #|DECISION=force + #|RECURSIVE=no } When call cmd_delete -f arg1 The output should be blank The error should equal "$(result)" End + It 'removes a directory recursively with a long option' + result() { + %text + #|$ do_delete arg1 + #|DECISION=default + #|RECURSIVE=yes + } + When call cmd_delete --recursive arg1 + The output should be blank + The error should equal "$(result)" + End + + It 'removes a directory recursively with a short option' + result() { + %text + #|$ do_delete arg1 + #|DECISION=default + #|RECURSIVE=yes + } + When call cmd_delete -r arg1 + The output should be blank + The error should equal "$(result)" + End + + It 'removes a directory recursively and forcefully with long options' + result() { + %text + #|$ do_delete arg1 + #|DECISION=force + #|RECURSIVE=yes + } + When call cmd_delete --recursive --force arg1 + The output should be blank + The error should equal "$(result)" + End + + It 'removes a directory recursively and forcefully with short options' + result() { + %text + #|$ do_delete arg1 + #|DECISION=force + #|RECURSIVE=yes + } + When call cmd_delete -rf arg1 + The output should be blank + The error should equal "$(result)" + End + + It 'removes a directory forcefully and recursively with short options' + result() { + %text + #|$ do_delete arg1 + #|DECISION=force + #|RECURSIVE=yes + } + When call cmd_delete -fr arg1 + The output should be blank + The error should equal "$(result)" + End + It 'removes multiple files' result() { %text #|$ do_delete arg1 #|DECISION=default + #|RECURSIVE=no #|$ do_delete arg2 #|DECISION=default + #|RECURSIVE=no #|$ do_delete arg3 #|DECISION=default + #|RECURSIVE=no } When call cmd_delete arg1 arg2 arg3 The output should be blank @@ -287,8 +354,10 @@ Describe 'Command-Line Parsing' %text #|$ do_delete -f #|DECISION=default + #|RECURSIVE=no #|$ do_delete arg2 #|DECISION=default + #|RECURSIVE=no } When call cmd_delete -- -f arg2 The output should be blank @@ -299,7 +368,8 @@ Describe 'Command-Line Parsing' cat() { @cat; } When run cmd_delete -u arg The output should be blank - The error should equal 'Usage: prg delete [--force,-f] pass-name' + The error should equal \ + 'Usage: prg delete [--recursive,-r] [--force,-f] pass-name' The status should equal 1 End @@ -307,7 +377,8 @@ Describe 'Command-Line Parsing' cat() { @cat; } When run cmd_delete The output should be blank - The error should equal 'Usage: prg delete [--force,-f] pass-name' + The error should equal \ + 'Usage: prg delete [--recursive,-r] [--force,-f] pass-name' The status should equal 1 End End diff --git a/src/pashage.sh b/src/pashage.sh @@ -177,7 +177,7 @@ scm_commit() { # $1: source # $2: destination scm_cp() { - cp -r -- "${PREFIX}/$1" "${PREFIX}/$2" + cp -rf -- "${PREFIX}/$1" "${PREFIX}/$2" scm_add "$2" } @@ -193,9 +193,9 @@ scm_del() { # $2: destination scm_mv() { if [ -d "${PREFIX}/.git" ]; then - git -C "${PREFIX}" mv -- "$1" "$2" + git -C "${PREFIX}" mv -f -- "$1" "$2" else - mv -- "${PREFIX}/$1" "${PREFIX}/$2" + mv -f -- "${PREFIX}/$1" "${PREFIX}/$2" fi } @@ -473,6 +473,7 @@ do_deinit() { # Delete a file or directory from the password store # $1: file or directory name # DECISION: whether to ask before deleting +# RECURSIVE: whether to delete directories do_delete() { # Distinguish between file or directory if [ "$1" = "${1%/}/" ]; then @@ -484,10 +485,16 @@ do_delete() { if ! [ -d "${PREFIX}/${NAME%/}" ]; then die "Error: $1 is not a directory." fi + if ! [ "${RECURSIVE}" = yes ]; then + die "Error: $1 is a directory" + fi elif [ -f "${PREFIX}/$1.age" ]; then NAME="$1" TARGET="$1.age" elif [ -d "${PREFIX}/$1" ]; then + if ! [ "${RECURSIVE}" = yes ]; then + die "Error: $1/ is a directory" + fi NAME="$1/" TARGET="$1/" else @@ -1045,11 +1052,23 @@ cmd_delete() { check_sneaky_paths "$@" PARSE_ERROR=no + RECURSIVE=no while [ $# -ge 1 ]; do case "$1" in -f|--force) DECISION=force shift ;; + -r|--recursive) + RECURSIVE=yes + shift ;; + -[fr]?*) + REST="${1#??}" + FIRST="${1%"${REST}"}" + shift + set -- "${FIRST}" "-${REST}" "$@" + unset FIRST + unset REST + ;; --) shift break ;; @@ -1492,7 +1511,7 @@ EOF ;; delete) cat <<EOF -${F}${PROGRAM} delete [--force,-f] pass-name +${F}${PROGRAM} delete [--recursive,-r] [--force,-f] pass-name EOF [ "${VERBOSE}" = yes ] && cat <<EOF ${I} Remove existing passwords or directories, optionally forcefully.