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:
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.