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 ad78faa2d4563c92b0543865d69231e3d4ebb632
parent d0644d652237abc8c41aeb400c36f4c65e0fc5c4
Author: Natasha Kerensikova <natgh@instinctive.eu>
Date:   Sun,  9 Nov 2025 18:39:45 +0000

Empty directories are optionally included in raw list output
Diffstat:
Mspec/action_spec.sh | 16++++++++++++++++
Mspec/pashage_extra_spec.sh | 20++++++++++++++++++++
Msrc/pashage.sh | 12+++++++++++-
3 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/spec/action_spec.sh b/spec/action_spec.sh @@ -1810,6 +1810,22 @@ Describe 'Action Functions' The output should equal "$(result)" End + It 'displays everything, including empty directories' + result() { + %text + #|empty/ + #|other/lower + #|other/lower.gpg + #|root + #|subdir/subsub/old + #|subdir.gpg + } + LIST_EMPTY=yes + When call do_list '' + The status should be success + The output should equal "$(result)" + End + It 'displays only matching files' result() { %text diff --git a/spec/pashage_extra_spec.sh b/spec/pashage_extra_spec.sh @@ -1291,6 +1291,26 @@ Describe 'Integrated Command Functions' The output should equal "$(expected_out)" End + It 'displays the whole store and empty directories as a raw list' + LIST_EMPTY=yes + When call cmd_list_or_show --raw + The status should be success + The error should be blank + expected_out() { %text + #|extra/subdir/file + #|extra/subdir.gpg + #|fluff/one + #|fluff/three + #|fluff/two + #|old + #|shared/ + #|stale + #|stale.gpg + #|subdir/file + } + The output should equal "$(expected_out)" + End + It 'displays a subdirectory as a raw list' When call cmd_list_or_show -r fluff The status should be success diff --git a/src/pashage.sh b/src/pashage.sh @@ -852,7 +852,10 @@ do_insert() { # ...: (optional) grep arguments to filter # BEGIN_GPG_NAME: (optional) marker before gpg secret name # END_GPG_NAME: (optional) marker after gpg secret name -# Note that this function is recrusive and cannot use variables to hold state. +# HAS_ITEMS: (output) set to `yes` when something has been printed +# LIST_EMPTY: include empty directories in output when set to `yes` +# Note that this function is recrusive and cannot use variables to hold state +# (except for HAS_ITEMS which is carefully designed with this constraint). do_list() { for FULL_ENTRY in "${PREFIX}/$1${1:+/}"*; do ENTRY="${FULL_ENTRY#"${PREFIX}/"}" @@ -860,7 +863,12 @@ do_list() { if [ -d "${FULL_ENTRY}" ]; then shift set -- "${ENTRY}" "$@" + HAS_ITEMS=no do_list "$@" + if [ "${LIST_EMPTY-}${HAS_ITEMS}" = 'yesno' ]; then + printf '%s/\n' "$1" + fi + HAS_ITEMS=yes elif [ "${ENTRY%.age}.age" = "${ENTRY}" ]; then shift set -- "-q" "$@" @@ -868,6 +876,7 @@ do_list() { || printf '%s\n' "${ITEM_NAME%.age}" | grep "$@" then printf '%s\n' "${ENTRY%.age}" + HAS_ITEMS=yes fi elif [ "${ENTRY%.gpg}.gpg" = "${ENTRY}" ]; then shift @@ -887,6 +896,7 @@ do_list() { "${BEGIN_GPG_NAME-}" \ "${ITEM_NAME}" \ "${END_GPG_NAME-}" + HAS_ITEMS=yes fi fi unset ENTRY