From 9b46037136cade0f590b83871e20020c0c18e952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Wed, 8 Apr 2015 09:56:11 +0200 Subject: [PATCH 01/55] allow parameters / options in default action --- todo.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/todo.sh b/todo.sh index 1aa72934..b7c36d5c 100755 --- a/todo.sh +++ b/todo.sh @@ -982,6 +982,13 @@ elif [ -d "$TODO_ACTIONS_DIR" -a -x "$TODO_ACTIONS_DIR/$action" ] then "$TODO_ACTIONS_DIR/$action" "$@" exit $? +else + actionarray=($action) + if [ -d "$TODO_ACTIONS_DIR" -a -x "$TODO_ACTIONS_DIR/${actionarray[0]}" ] + then + "$TODO_ACTIONS_DIR/${actionarray[0]}" $action + exit $? + fi fi ## Only run if $action isn't found in .todo.actions.d From 779200685366e173b29f62f6a3837b704363f85b Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Thu, 16 Sep 2021 19:44:48 +0200 Subject: [PATCH 02/55] Tests: Refactoring: Extract make_dummy_action() The action script creation in both test helper functions is pretty similar; extract a function for that so that the invocation is a single command. --- tests/actions-test-lib.sh | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/tests/actions-test-lib.sh b/tests/actions-test-lib.sh index 51d4eefc..2530fb8a 100644 --- a/tests/actions-test-lib.sh +++ b/tests/actions-test-lib.sh @@ -1,20 +1,26 @@ #!/bin/bash -make_action() +make_dummy_action() { - unset TODO_ACTIONS_DIR - [ -d .todo.actions.d ] || mkdir .todo.actions.d - cat > ".todo.actions.d/$1" < "$1" < ".todo.actions.d/$1/$1" < Date: Thu, 16 Sep 2021 21:38:47 +0200 Subject: [PATCH 03/55] Refactoring: Extract hasCustomAction() --- todo.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/todo.sh b/todo.sh index fb8d4bce..37eca5e2 100755 --- a/todo.sh +++ b/todo.sh @@ -1036,6 +1036,11 @@ listWordsWithSigil() | sort -u } +hasCustomAction() +{ + [ -d "${1:?}" ] && [ -x "${1:?}/${2:?}" ] +} + export -f cleaninput getPrefix getTodo getNewtodo shellquote filtercommand _list listWordsWithSigil getPadding _format die # == HANDLE ACTION == @@ -1051,11 +1056,11 @@ then shift ## Reset action to new first argument action=$( printf "%s\n" "$1" | tr '[:upper:]' '[:lower:]' ) -elif [ -d "$TODO_ACTIONS_DIR/$action" ] && [ -x "$TODO_ACTIONS_DIR/$action/$action" ] +elif hasCustomAction "$TODO_ACTIONS_DIR/$action" "$action" then "$TODO_ACTIONS_DIR/$action/$action" "$@" exit $? -elif [ -d "$TODO_ACTIONS_DIR" ] && [ -x "$TODO_ACTIONS_DIR/$action" ] +elif hasCustomAction "$TODO_ACTIONS_DIR" "$action" then "$TODO_ACTIONS_DIR/$action" "$@" exit $? From e1c1c328a21e4c077688b4a50dbdc622f84d587e Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Thu, 16 Sep 2021 22:15:00 +0200 Subject: [PATCH 04/55] Robustness: Check for broken symlinks to custom actions and complain Instead of potentially falling back to the built-in action that a custom action was intended to override, but (e.g. due to file system reorganizations) now results in a broken link. The extension functionality that is then skipped may result in undesired results, but this may not be immedately obvious to the user (if the extension is not particularly verbose), so some data corruption could occur if this remains undetected. To avoid duplicating (or somehow extracting) all the built-in actions, simply detect _any_ broken symlink; i.e. offer a superset of the required functionality. So this would also complain about a broken symlink to a non-executable custom (auxiliary) file (rarely used) if that is mistakenly passed as a custom action (unlikely). Fixes #359 --- tests/actions-test-lib.sh | 4 ++-- tests/t8000-actions.sh | 46 +++++++++++++++++++++++++++++++++++++++ todo.sh | 8 ++++++- 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/tests/actions-test-lib.sh b/tests/actions-test-lib.sh index 2530fb8a..71cd4fdf 100644 --- a/tests/actions-test-lib.sh +++ b/tests/actions-test-lib.sh @@ -20,7 +20,7 @@ make_action() { unset TODO_ACTIONS_DIR [ -d .todo.actions.d ] || mkdir .todo.actions.d - make_dummy_action ".todo.actions.d/$1" + [ -z "$1" ] || make_dummy_action ".todo.actions.d/$1" } make_action_in_folder() @@ -28,5 +28,5 @@ make_action_in_folder() unset TODO_ACTIONS_DIR [ -d .todo.actions.d ] || mkdir .todo.actions.d mkdir ".todo.actions.d/$1" - make_dummy_action ".todo.actions.d/$1/$1" "in folder $1" + [ -z "$1" ] || make_dummy_action ".todo.actions.d/$1/$1" "in folder $1" } diff --git a/tests/t8000-actions.sh b/tests/t8000-actions.sh index 763c4e92..2facc8f6 100755 --- a/tests/t8000-actions.sh +++ b/tests/t8000-actions.sh @@ -44,4 +44,50 @@ custom action bad === 42 EOF +make_action +ln -s /actionsdir/doesnotexist/badlink .todo.actions.d/badlink +# On Cygwin, the Windows ACL may still grant execution rights. In this case, we +# skip the test. +if [ -x .todo.actions.d/badlink ]; then + SKIP_TESTS="${SKIP_TESTS}${SKIP_TESTS+ }t8000.6 t8000.7" +fi +test_todo_session 'broken symlink' <>> todo.sh badlink | sed "s#'[^']*\(\\.todo\\.actions\\.d/[^']\{1,\}\)'#'\1'#g" +Fatal Error: Broken link to custom action: '.todo.actions.d/badlink' + +>>> todo.sh do >/dev/null +=== 1 +EOF + +make_action +mkdir .todo.actions.d/badfolderlink +ln -s /actionsdir/doesnotexist/badfolderlink .todo.actions.d/badfolderlink/badfolderlink +# On Cygwin, the Windows ACL may still grant execution rights. In this case, we +# skip the test. +if [ -x .todo.actions.d/badfolderlink/badfolderlink ]; then + SKIP_TESTS="${SKIP_TESTS}${SKIP_TESTS+ }t8000.8 t8000.9" +fi +test_todo_session 'broken symlink in folder' <>> todo.sh badfolderlink | sed "s#'[^']*\(\\.todo\\.actions\\.d/[^']\{1,\}\)'#'\1'#g" +Fatal Error: Broken link to custom action: '.todo.actions.d/badfolderlink/badfolderlink' + +>>> todo.sh do >/dev/null +=== 1 +EOF + +make_action +ln -s /actionsdir/doesnotexist/do .todo.actions.d/do +# On Cygwin, the Windows ACL may still grant execution rights. In this case, we +# skip the test. +if [ -x .todo.actions.d/do ]; then + SKIP_TESTS="${SKIP_TESTS}${SKIP_TESTS+ }t8000.10 t8000.11" +fi +test_todo_session 'broken symlink overrides built-in action' <>> todo.sh do | sed "s#'[^']*\(\\.todo\\.actions\\.d/[^']\{1,\}\)'#'\1'#g" +Fatal Error: Broken link to custom action: '.todo.actions.d/do' + +>>> todo.sh do >/dev/null +=== 1 +EOF + test_done diff --git a/todo.sh b/todo.sh index 37eca5e2..f128e67f 100755 --- a/todo.sh +++ b/todo.sh @@ -1038,7 +1038,13 @@ listWordsWithSigil() hasCustomAction() { - [ -d "${1:?}" ] && [ -x "${1:?}/${2:?}" ] + [ -d "${1:?}" ] || return 1 + [ -x "$1/${2:?}" ] && return 0 + if [ -h "$1/$2" ] && [ ! -e "$1/$2" ] + then + dieWithHelp "$2" "Fatal Error: Broken link to custom action: '$1/$2'" + fi + return 1 } export -f cleaninput getPrefix getTodo getNewtodo shellquote filtercommand _list listWordsWithSigil getPadding _format die From bd88c20cabcae91bc634c27811599c7d88cb7566 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Sat, 9 Oct 2021 19:57:47 +0200 Subject: [PATCH 05/55] Add TODOTXT_VERBOSE to the configuration There's no command-line option to reduce verbosity (just -v to increase it), so users who would like to remove the additional messages (cp. https://github.com/todotxt/todo.txt-cli/discussions/364) have to configure this, but the variable is hard to find. Include the default value in commented-out form and some documentation of the possible values. --- todo.cfg | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/todo.cfg b/todo.cfg index 0ab7d9bb..3ccd2181 100644 --- a/todo.cfg +++ b/todo.cfg @@ -76,6 +76,13 @@ export REPORT_FILE="$TODO_DIR/report.txt" # === BEHAVIOR === +## verbosity +# +# By default, additional information and confirmation of actions (like +# "TODO: 1 added") are printed. You can suppress this via 0 or add extra +# verbosity via 2. +# export TODOTXT_VERBOSE=1 + ## customize list output # # TODOTXT_SORT_COMMAND will filter after line numbers are From d0075e4d578422f6a7143026b8b906eed0bc4a97 Mon Sep 17 00:00:00 2001 From: Lawrence Liu Date: Fri, 19 Nov 2021 21:48:16 +0800 Subject: [PATCH 06/55] Different folder to copy ~/.todo.cfg for macOS on arm/x86 CPU (#369) --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 4fc5128c..925afc8f 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,12 @@ Download the latest stable [release][release] for use on your desktop or server. ```shell brew install todo-txt + +# For macOS on x86 CPU cp -n /usr/local/opt/todo-txt/todo.cfg ~/.todo.cfg + +# For macOS on arm CPU +cp -n /opt/homebrew/opt/todo-txt/todo.cfg ~/.todo.cfg ``` **Note**: The `-n` flag for `cp` makes sure you do not overwrite an existing file. From ea32af34e6a0efef59bdf9acaa1c38d5d32bef0d Mon Sep 17 00:00:00 2001 From: Ali Karbassi Date: Thu, 2 Dec 2021 15:49:42 -0600 Subject: [PATCH 07/55] Updated GitHub Actions Environments (#372) Rather than `*-latest`, I'm specifying specific environments. --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index eeea980c..27fbeb54 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,7 +10,7 @@ jobs: test: strategy: matrix: - platform: [ubuntu-latest, macos-latest, ubuntu-18.04] + platform: [ubuntu-20.04, ubuntu-18.04, macos-11, macos-10.15] runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v2 From 7a4da603744f7907e56363c4437fa9f858231789 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Mon, 28 Mar 2022 22:23:17 +0200 Subject: [PATCH 08/55] Documentation: Clarify that CONFIG_DIR is for the configuration template And only coincidentally picked up as the global configuration (if CONFIG_DIR=/etc). Fixes #377 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 925afc8f..8cd987d0 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ make test *NOTE:* Makefile defaults to several default paths for installed files. Adjust to your system: - `INSTALL_DIR`: PATH for executables (default /usr/local/bin) -- `CONFIG_DIR`: PATH for todo.txt config +- `CONFIG_DIR`: PATH for the todo.txt configuration template - `BASH_COMPLETION`: PATH for autocompletion scripts (default to /etc/bash_completion.d) ```shell From 273c465af050ac26456e0c29d05ec401a3cc2af7 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Mon, 28 Mar 2022 22:24:49 +0200 Subject: [PATCH 09/55] Documentation: Add Configuration section with overview and recommendation to copy the template --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 8cd987d0..594cb9e4 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,11 @@ make install CONFIG_DIR=/etc INSTALL_DIR=/usr/bin BASH_COMPLETION=/usr/share/bas https://aur.archlinux.org/packages/todotxt/ +## Configuration + +No configuration is required; however, most users tweak the default settings (e.g. relocating the todo.txt directory to a subdirectory of the user's home directory, or onto a cloud drive (via the `TODO_DIR` variable)), modify the colors, add additional highlighting of projects, contexts, dates, and so on. A configuration template with a commented-out list of all available options is included. +It is recommended to _copy_ that template into one of the locations listed by `todo.sh help` on `-d CONFIG_FILE`, even if it is installed in the global configuration location (`/etc/todo/config`). + ## Usage ```shell todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description] From aef7d8b9e580b13d58e39a37f139803f207c464f Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Tue, 12 Apr 2022 07:53:07 +0200 Subject: [PATCH 10/55] Refactoring: Replace shellquote() with printf %q I didn't know about printf's capability when I introduced quoting 10 years ago. The %q format will do the quoting, and "-v VAR" can be used to reassign to the variable. Note: The shellquote() function has been exported for reuse by add-ons. I don't think anyone has ever used that (it was mostly intended for my own, extensive extensions, and I never used it), and is trivial to move away from, anyway. --- todo.sh | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/todo.sh b/todo.sh index fb8d4bce..d084d58d 100755 --- a/todo.sh +++ b/todo.sh @@ -824,11 +824,6 @@ _addto() { fi } -shellquote() -{ - typeset -r qq=\'; printf %s\\n "'${1//\'/${qq}\\${qq}${qq}}'"; -} - filtercommand() { filter=${1:-} @@ -843,13 +838,13 @@ filtercommand() then ## First character isn't a dash: hide lines that don't match ## this $search_term - filter="${filter:-}${filter:+ | }grep -i $(shellquote "$search_term")" + printf -v filter '%sgrep -i %q' "${filter:-}${filter:+ | }" "$search_term" else ## First character is a dash: hide lines that match this ## $search_term # ## Remove the first character (-) before adding to our filter command - filter="${filter:-}${filter:+ | }grep -v -i $(shellquote "${search_term:1}")" + printf -v filter '%sgrep -v -i %q' "${filter:-}${filter:+ | }" "${search_term:1}" fi done @@ -1036,7 +1031,7 @@ listWordsWithSigil() | sort -u } -export -f cleaninput getPrefix getTodo getNewtodo shellquote filtercommand _list listWordsWithSigil getPadding _format die +export -f cleaninput getPrefix getTodo getNewtodo filtercommand _list listWordsWithSigil getPadding _format die # == HANDLE ACTION == action=$( printf "%s\n" "$ACTION" | tr '[:upper:]' '[:lower:]' ) From 491979b76a9505b098b57fb042a510f9e89feb5b Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Sat, 7 May 2022 20:03:48 +0200 Subject: [PATCH 11/55] Renaming: Add .sh extension to completion script This doesn't matter if (as currently recommended) the script is placed into a eagerly loaded location (like /etc/bash_completion.d/) - any name will do. However, there's now lazy loading of completion scripts (in /usr/share/bash-completion/completions/), and that only works when the completion script is named exactly like the command the completion is for. As our command is todo.sh (ignoring aliases, which become more complex with lazy loading), the corresponding completion needs to be todo.sh (with the .sh extension) as well. Renaming does not do any harm for our recommended location, but makes it easier for users (and packagers who prepare a todo.sh package) that want to use lazy loading. See https://github.com/todotxt/todo.txt-cli/issues/383 for the complete discussion. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b6056bc6..d498004c 100644 --- a/Makefile +++ b/Makefile @@ -64,7 +64,7 @@ clean: test-pre-clean install: installdirs $(INSTALL_PROGRAM) todo.sh $(DESTDIR)$(bindir)/todo.sh - $(INSTALL_DATA) todo_completion $(DESTDIR)$(datarootdir)/todo + $(INSTALL_DATA) todo_completion $(DESTDIR)$(datarootdir)/todo.sh [ -e $(DESTDIR)$(sysconfdir)/todo/config ] || \ sed "s/^\(export[ \t]*TODO_DIR=\).*/\1~\/.todo/" todo.cfg > $(DESTDIR)$(sysconfdir)/todo/config From 28523851d0517fc613df9a9796e21a51ff20f429 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Fri, 17 Jun 2022 23:12:35 +0200 Subject: [PATCH 12/55] replace: Completely merge given priority / date with existing So that any combination of priority / date entered in the replacement will replace the corresponding original ones, but if they are left out, the original ones will be kept. In essence, omitted stuff will be kept, added stuff will override, only deletion of existing stuff is not possible (but this is replace, after all). Fixes #386 --- tests/t1100-replace.sh | 41 +++++++++++++++++++++++++++++++++++++++++ todo.sh | 23 +++++++++++++++++------ 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/tests/t1100-replace.sh b/tests/t1100-replace.sh index bfec5e68..67112d41 100755 --- a/tests/t1100-replace.sh +++ b/tests/t1100-replace.sh @@ -140,6 +140,18 @@ TODO: Replaced task with: 1 2010-07-04 this also has a new date EOF +cat /dev/null > todo.txt +test_todo_session 'replace handling prepended priority on add' <>> todo.sh -t add "new task" +1 2009-02-13 new task +TODO: 1 added. + +>>> todo.sh replace 1 '(B) this also has a priority now' +1 2009-02-13 new task +TODO: Replaced task with: +1 (B) 2009-02-13 this also has a priority now +EOF + cat /dev/null > todo.txt test_todo_session 'replace handling priority and prepended date on add' <>> todo.sh -t add "new task" @@ -156,6 +168,18 @@ TODO: Replaced task with: 1 (A) 2009-02-13 this is just a new one EOF +cat /dev/null > todo.txt +test_todo_session 'replace handling prepended priority and date on add' <>> todo.sh -t add "new task" +1 2009-02-13 new task +TODO: 1 added. + +>>> todo.sh replace 1 '(C) 2010-07-04 this also has a priority and new date' +1 2009-02-13 new task +TODO: Replaced task with: +1 (C) 2010-07-04 this also has a priority and new date +EOF + echo '(A) 2009-02-13 this is just a new one' > todo.txt test_todo_session 'replace with prepended date replaces existing date' <>> todo.sh replace 1 2010-07-04 this also has a new date @@ -164,6 +188,14 @@ TODO: Replaced task with: 1 (A) 2010-07-04 this also has a new date EOF +echo '(A) 2009-02-13 this is just a new one' > todo.txt +test_todo_session 'replace with prepended priority replaces existing priority' <>> todo.sh replace 1 '(B) this also has a new priority' +1 (A) 2009-02-13 this is just a new one +TODO: Replaced task with: +1 (B) 2009-02-13 this also has a new priority +EOF + echo '2009-02-13 this is just a new one' > todo.txt test_todo_session 'replace with prepended priority and date replaces existing date' <>> todo.sh replace 1 '(B) 2010-07-04 this also has a new date' @@ -172,4 +204,13 @@ TODO: Replaced task with: 1 (B) 2010-07-04 this also has a new date EOF + +echo '(A) 2009-02-13 this is just a new one' > todo.txt +test_todo_session 'replace with prepended priority and date replaces existing priority and date' <>> todo.sh replace 1 '(B) 2010-07-04 this also has a new prio+date' +1 (A) 2009-02-13 this is just a new one +TODO: Replaced task with: +1 (B) 2010-07-04 this also has a new prio+date +EOF + test_done diff --git a/todo.sh b/todo.sh index fb8d4bce..1887b29a 100755 --- a/todo.sh +++ b/todo.sh @@ -459,20 +459,31 @@ replaceOrPrepend() # Retrieve existing priority and prepended date local -r priAndDateExpr='^\((.) \)\{0,1\}\([0-9]\{2,4\}-[0-9]\{2\}-[0-9]\{2\} \)\{0,1\}' - priority=$(sed -e "$item!d" -e "${item}s/${priAndDateExpr}.*/\\1/" "$TODO_FILE") - prepdate=$(sed -e "$item!d" -e "${item}s/${priAndDateExpr}.*/\\2/" "$TODO_FILE") - - if [ "$prepdate" ] && [ "$action" = "replace" ] && [ "$(echo "$input"|sed -e "s/${priAndDateExpr}.*/\\1\\2/")" ]; then + originalPriority=$(sed -e "$item!d" -e "${item}s/${priAndDateExpr}.*/\\1/" "$TODO_FILE") + priority="$originalPriority" + originalPrepdate=$(sed -e "$item!d" -e "${item}s/${priAndDateExpr}.*/\\2/" "$TODO_FILE") + prepdate="$originalPrepdate" + if [ "$action" = "replace" ]; then + replacementPrepdate="$(echo "$input"|sed -e "s/${priAndDateExpr}.*/\\2/")" + if [ "$replacementPrepdate" ]; then # If the replaced text starts with a [priority +] date, it will replace # the existing date, too. - prepdate= + prepdate="$replacementPrepdate" + fi + replacementPriority="$(echo "$input"|sed -e "s/${priAndDateExpr}.*/\\1/")" + if [ "$replacementPriority" ]; then + # If the replaced text starts with a priority, it will replace + # the existing priority, too. + priority="$replacementPriority" + fi + input="$(echo "$input"|sed -e "s/${priAndDateExpr}//")" fi # Temporarily remove any existing priority and prepended date, perform the # change (replace/prepend) and re-insert the existing priority and prepended # date again. cleaninput "for sed" - sed -i.bak -e "$item s/^${priority}${prepdate}//" -e "$item s|^.*|${priority}${prepdate}${input}${backref}|" "$TODO_FILE" + sed -i.bak -e "$item s/^${originalPriority}${originalPrepdate}//" -e "$item s|^.*|${priority}${prepdate}${input}${backref}|" "$TODO_FILE" if [ "$TODOTXT_VERBOSE" -gt 0 ]; then getNewtodo "$item" case "$action" in From 1a5600c79cd7c586ef4d98abfd010e016dbff7be Mon Sep 17 00:00:00 2001 From: Pegasust Date: Thu, 16 Jun 2022 16:28:05 -0700 Subject: [PATCH 13/55] test listaddons: Make pass on Cygwin If a custom action cannot be made non-executable, it needs to be removed as well (and the test skipped); otherwise its existence will break following tests that assume it's inactive. --- tests/t8010-listaddons.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/t8010-listaddons.sh b/tests/t8010-listaddons.sh index b4e89aa9..cf212e86 100755 --- a/tests/t8010-listaddons.sh +++ b/tests/t8010-listaddons.sh @@ -30,9 +30,11 @@ EOF chmod -x .todo.actions.d/foo # On Cygwin, clearing the executable flag may have no effect, as the Windows ACL -# may still grant execution rights. In this case, we skip the test. +# may still grant execution rights. In this case, we skip the test, and remove +# the (still valid) custom action so that it doesn't break following tests. if [ -x .todo.actions.d/foo ]; then SKIP_TESTS="${SKIP_TESTS}${SKIP_TESTS+ }t8010.4" + rm .todo.actions.d/foo fi test_todo_session 'nonexecutable action' <>> todo.sh listaddons @@ -69,9 +71,11 @@ EOF # nthorne: shamelessly stolen from above.. chmod -x .todo.actions.d/norris/norris # On Cygwin, clearing the executable flag may have no effect, as the Windows ACL -# may still grant execution rights. In this case, we skip the test. +# may still grant execution rights. In this case, we skip the test, and remove +# the (still valid) custom action so that it doesn't break following tests. if [ -x .todo.actions.d/norris/norris ]; then SKIP_TESTS="${SKIP_TESTS}${SKIP_TESTS+ }t8010.8" + rm .todo.actions.d/norris/norris fi test_todo_session 'nonexecutable action in subfolder' <>> todo.sh listaddons From bab2af950186380d6106702768a5a7cce7d84de0 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Sat, 18 Jun 2022 10:55:04 +0200 Subject: [PATCH 14/55] Tests: Refactoring: Extract invalidate_action() into actions-test-lib We don't "shamelessly steal" code, we refactoring it ;-) --- tests/actions-test-lib.sh | 16 ++++++++++++++++ tests/t8010-listaddons.sh | 19 ++----------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/tests/actions-test-lib.sh b/tests/actions-test-lib.sh index 51d4eefc..daf18a9a 100644 --- a/tests/actions-test-lib.sh +++ b/tests/actions-test-lib.sh @@ -34,3 +34,19 @@ echo "custom action $1 in folder $1" EOF chmod +x ".todo.actions.d/$1/$1" } + +invalidate_action() +{ + local customActionFilespec="${1:?}"; shift + local testName="${1:?}"; shift + + chmod -x "$customActionFilespec" + # On Cygwin, clearing the executable flag may have no effect, as the Windows + # ACL may still grant execution rights. In this case, we skip the test, and + # remove the (still valid) custom action so that it doesn't break following + # tests. + if [ -x "$customActionFilespec" ]; then + SKIP_TESTS="${SKIP_TESTS}${SKIP_TESTS+ }${testName}" + rm -- "$customActionFilespec" + fi +} diff --git a/tests/t8010-listaddons.sh b/tests/t8010-listaddons.sh index cf212e86..ee0495a9 100755 --- a/tests/t8010-listaddons.sh +++ b/tests/t8010-listaddons.sh @@ -28,14 +28,7 @@ ls quux EOF -chmod -x .todo.actions.d/foo -# On Cygwin, clearing the executable flag may have no effect, as the Windows ACL -# may still grant execution rights. In this case, we skip the test, and remove -# the (still valid) custom action so that it doesn't break following tests. -if [ -x .todo.actions.d/foo ]; then - SKIP_TESTS="${SKIP_TESTS}${SKIP_TESTS+ }t8010.4" - rm .todo.actions.d/foo -fi +invalidate_action .todo.actions.d/foo t8010.4 test_todo_session 'nonexecutable action' <>> todo.sh listaddons bar @@ -68,15 +61,7 @@ norris quux EOF -# nthorne: shamelessly stolen from above.. -chmod -x .todo.actions.d/norris/norris -# On Cygwin, clearing the executable flag may have no effect, as the Windows ACL -# may still grant execution rights. In this case, we skip the test, and remove -# the (still valid) custom action so that it doesn't break following tests. -if [ -x .todo.actions.d/norris/norris ]; then - SKIP_TESTS="${SKIP_TESTS}${SKIP_TESTS+ }t8010.8" - rm .todo.actions.d/norris/norris -fi +invalidate_action .todo.actions.d/norris/norris t8010.8 test_todo_session 'nonexecutable action in subfolder' <>> todo.sh listaddons bar From 466265175bdb119f1dbe1ecb5dd78af37d4528f3 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Fri, 17 Jun 2022 23:39:42 +0200 Subject: [PATCH 15/55] Refactoring: Use read -p MSG instead of doing echo -n MSG separately I've seen strange readline editing behavior when the editing doesn't start at the first column: I can actually backspace into the prepended message (with Del, Ctrl-W or Ctrl-U), and then the whole edit becomes messed up. read can output a prompt on its own (hopefully in all versions of Bash that we aim to support - the tests will tell), and that doesn't have this problem, and it's also a bit cleaner and shorter. The prompt is only displayed if input is coming from a terminal. For the tests (currently only deletion and move confirmations are covered), this means that the prompt itself cannot be covered, and an empty line instead has to be expected. (On the positive side, this removes the ugly trick with $SPACE.) --- tests/t1800-del.sh | 10 ++++------ tests/t1850-move.sh | 4 +--- todo.sh | 15 +++++---------- 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/tests/t1800-del.sh b/tests/t1800-del.sh index 6d96e89c..2529a933 100755 --- a/tests/t1800-del.sh +++ b/tests/t1800-del.sh @@ -4,8 +4,6 @@ test_description='basic del functionality ' . ./test-lib.sh -SPACE=' ' - test_todo_session 'del usage' <>> todo.sh del B usage: todo.sh del ITEM# [TERM] @@ -60,7 +58,7 @@ test_todo_session 'del with confirmation' <>> printf n | todo.sh del 1 -Delete '(B) smell the uppercase Roses +flowers @outside'? (y/n)$SPACE +\\ TODO: No tasks were deleted. >>> todo.sh -p list @@ -71,15 +69,15 @@ TODO: No tasks were deleted. TODO: 3 of 3 tasks shown >>> printf x | todo.sh del 1 -Delete '(B) smell the uppercase Roses +flowers @outside'? (y/n)$SPACE +\\ TODO: No tasks were deleted. >>> echo | todo.sh del 1 -Delete '(B) smell the uppercase Roses +flowers @outside'? (y/n)$SPACE +\\ TODO: No tasks were deleted. >>> printf y | todo.sh del 1 -Delete '(B) smell the uppercase Roses +flowers @outside'? (y/n)$SPACE +\\ 1 (B) smell the uppercase Roses +flowers @outside TODO: 1 deleted. diff --git a/tests/t1850-move.sh b/tests/t1850-move.sh index 9fbdc0b6..2a9e6ea3 100755 --- a/tests/t1850-move.sh +++ b/tests/t1850-move.sh @@ -4,8 +4,6 @@ test_description='basic move functionality ' . ./test-lib.sh -SPACE=' ' - cat > todo.txt <>> printf y | todo.sh move 1 done.txt 2>&1 | sed -e "s#'[^']\{1,\}/\([^/']\{1,\}\)'#'\1'#g" -e 's#from .\{1,\}/\([^/]\{1,\}\) to .\{1,\}/\([^/]\{1,\}\)?#from \1 to \2?#g' -Move '(B) smell the uppercase Roses +flowers @outside' from todo.txt to done.txt? (y/n)$SPACE +\\ 1 (B) smell the uppercase Roses +flowers @outside TODO: 1 moved from 'todo.txt' to 'done.txt'. diff --git a/todo.sh b/todo.sh index fb8d4bce..c3d46750 100755 --- a/todo.sh +++ b/todo.sh @@ -364,12 +364,11 @@ confirm() { [ $TODOTXT_FORCE = 0 ] || return 0 - printf %s "${1:?}? (y/n) " local readArgs=(-e -r) [ -n "${BASH_VERSINFO:-}" ] && [ \( ${BASH_VERSINFO[0]} -eq 4 -a ${BASH_VERSINFO[1]} -ge 1 \) -o ${BASH_VERSINFO[0]} -gt 4 ] && readArgs+=(-N 1) # Bash 4.1+ supports -N nchars local answer - read "${readArgs[@]}" answer + read -p "${1:?}? (y/n) " "${readArgs[@]}" answer echo [ "$answer" = "y" ] } @@ -451,8 +450,7 @@ replaceOrPrepend() getTodo "$item" if [[ -z "$1" && $TODOTXT_FORCE = 0 ]]; then - echo -n "$querytext" - read -r -i "$todo" -e input + read -p "$querytext" -r -i "$todo" -e input else input=$* fi @@ -1065,8 +1063,7 @@ fi case $action in "add" | "a") if [[ -z "$2" && $TODOTXT_FORCE = 0 ]]; then - echo -n "Add: " - read -e -r input + read -p "Add: " -e -r input else [ -z "$2" ] && die "usage: $TODO_SH add \"TODO ITEM\"" shift @@ -1077,8 +1074,7 @@ case $action in "addm") if [[ -z "$2" && $TODOTXT_FORCE = 0 ]]; then - echo -n "Add: " - read -e -r input + read -p "Add: " -e -r input else [ -z "$2" ] && die "usage: $TODO_SH addm \"TODO ITEM\"" shift @@ -1118,8 +1114,7 @@ case $action in getTodo "$item" if [[ -z "$1" && $TODOTXT_FORCE = 0 ]]; then - echo -n "Append: " - read -e -r input + read -p "Append: " -e -r input else input=$* fi From 803881998fed3b34a0f219bd28a03d247183c204 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Sat, 21 Jan 2023 18:59:32 +0100 Subject: [PATCH 16/55] FIX: Use standard error for die() and dieWithHelp() By convention, error output should be printed to standard error, not standard out. Same for the usage help that may accompany the error message. --- todo.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/todo.sh b/todo.sh index fb8d4bce..49d16556 100755 --- a/todo.sh +++ b/todo.sh @@ -349,14 +349,14 @@ dieWithHelp() case "$1" in help) help;; shorthelp) shorthelp;; - esac + esac >&2 shift die "$@" } die() { - echo "$*" + echo >&2 "$*" exit 1 } From ef419f3594c79f329f7f156ade9a2a767a58ee62 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Sat, 21 Jan 2023 19:01:24 +0100 Subject: [PATCH 17/55] Use die() / print to stderr for error conditions To indicate that something went wrong (e.g. the task already was unprioritized). Note: For actions that handle multiple ITEMs in a loop, we cannot use die() as that would abort processing of any following ITEM(s). Instead, use a status variable and set it to 1 on error, then exit at the end. --- tests/t1200-pri.sh | 1 + tests/t1500-do.sh | 1 + tests/t1700-depri.sh | 1 + tests/t1800-del.sh | 3 +++ tests/t1910-deduplicate.sh | 1 + tests/t2120-shorthelp.sh | 6 +++--- todo.sh | 23 ++++++++++++++++------- 7 files changed, 26 insertions(+), 10 deletions(-) diff --git a/tests/t1200-pri.sh b/tests/t1200-pri.sh index fd8bd10c..54b610fd 100755 --- a/tests/t1200-pri.sh +++ b/tests/t1200-pri.sh @@ -90,6 +90,7 @@ TODO: 2 re-prioritized from (C) to (A). TODO: 3 of 3 tasks shown >>> todo.sh pri 2 a +=== 1 2 (A) notice the sunflowers TODO: 2 already prioritized (A). diff --git a/tests/t1500-do.sh b/tests/t1500-do.sh index 79994980..d359a49d 100755 --- a/tests/t1500-do.sh +++ b/tests/t1500-do.sh @@ -81,6 +81,7 @@ test_todo_session 'fail multiple do attempts' <>> todo.sh -a do 3 +=== 1 TODO: 3 is already marked done. EOF diff --git a/tests/t1700-depri.sh b/tests/t1700-depri.sh index 7ec7e7f9..f459ef10 100755 --- a/tests/t1700-depri.sh +++ b/tests/t1700-depri.sh @@ -82,6 +82,7 @@ test_todo_session 'depriority of unprioritized task' <>> todo.sh depri 3 2 +=== 1 TODO: 3 is not prioritized. 2 notice the sunflowers TODO: 2 deprioritized. diff --git a/tests/t1800-del.sh b/tests/t1800-del.sh index 6d96e89c..bdf66705 100755 --- a/tests/t1800-del.sh +++ b/tests/t1800-del.sh @@ -60,6 +60,7 @@ test_todo_session 'del with confirmation' <>> printf n | todo.sh del 1 +=== 1 Delete '(B) smell the uppercase Roses +flowers @outside'? (y/n)$SPACE TODO: No tasks were deleted. @@ -71,10 +72,12 @@ TODO: No tasks were deleted. TODO: 3 of 3 tasks shown >>> printf x | todo.sh del 1 +=== 1 Delete '(B) smell the uppercase Roses +flowers @outside'? (y/n)$SPACE TODO: No tasks were deleted. >>> echo | todo.sh del 1 +=== 1 Delete '(B) smell the uppercase Roses +flowers @outside'? (y/n)$SPACE TODO: No tasks were deleted. diff --git a/tests/t1910-deduplicate.sh b/tests/t1910-deduplicate.sh index 3617807d..67217864 100755 --- a/tests/t1910-deduplicate.sh +++ b/tests/t1910-deduplicate.sh @@ -32,6 +32,7 @@ EOF test_todo_session 'deduplicate without duplicates' <>> todo.sh deduplicate +=== 1 TODO: No duplicate tasks found EOF diff --git a/tests/t2120-shorthelp.sh b/tests/t2120-shorthelp.sh index f0123b72..82275db5 100755 --- a/tests/t2120-shorthelp.sh +++ b/tests/t2120-shorthelp.sh @@ -47,7 +47,7 @@ echo 'export TODO_ACTIONS_DIR=$HOME/custom.actions' >> custom.cfg export TODOTXT_GLOBAL_CFG_FILE=global.cfg test_todo_session '-h and fatal error without config' <>> todo.sh -h | sed '/^ \\{0,2\\}[A-Z]/!d' +>>> todo.sh -h 2>&1 | sed '/^ \\{0,2\\}[A-Z]/!d' Usage: todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description] Actions: Actions can be added and overridden using scripts in the actions @@ -58,7 +58,7 @@ EOF # Config option comes too late; "Add-on Actions" is *not* mentioned here. test_todo_session '-h and fatal error with trailing custom config' <>> todo.sh -h -d custom.cfg | sed '/^ \\{0,2\\}[A-Z]/!d' +>>> todo.sh -h -d custom.cfg 2>&1 | sed '/^ \\{0,2\\}[A-Z]/!d' Usage: todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description] Actions: Actions can be added and overridden using scripts in the actions @@ -69,7 +69,7 @@ EOF # Config option processed; "Add-on Actions" is mentioned here. test_todo_session '-h output with preceding custom config' <>> todo.sh -d custom.cfg -h | sed '/^ \\{0,2\\}[A-Z]/!d' +>>> todo.sh -d custom.cfg -h 2>&1 | sed '/^ \\{0,2\\}[A-Z]/!d' Usage: todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description] Actions: Actions can be added and overridden using scripts in the actions diff --git a/todo.sh b/todo.sh index 49d16556..50297f2c 100755 --- a/todo.sh +++ b/todo.sh @@ -1170,7 +1170,7 @@ case $action in echo "TODO: $item deleted." fi else - echo "TODO: No tasks were deleted." + die "TODO: No tasks were deleted." fi else sed -i.bak \ @@ -1200,6 +1200,7 @@ case $action in # Split multiple depri's, if comma separated change to whitespace separated # Loop the 'depri' function for each item + status=0 for item in ${*//,/ }; do getTodo "$item" @@ -1211,9 +1212,11 @@ case $action in echo "TODO: $item deprioritized." fi else - echo "TODO: $item is not prioritized." + echo >&2 "TODO: $item is not prioritized." + status=1 fi done + exit $status ;; "do" | "done" ) @@ -1224,6 +1227,7 @@ case $action in # Split multiple do's, if comma separated change to whitespace separated # Loop the 'do' function for each item + status=0 for item in ${*//,/ }; do getTodo "$item" @@ -1239,15 +1243,17 @@ case $action in echo "TODO: $item marked as done." fi else - echo "TODO: $item is already marked done." + echo >&2 "TODO: $item is already marked done." + status=1 fi done if [ $TODOTXT_AUTO_ARCHIVE = 1 ]; then # Recursively invoke the script to allow overriding of the archive # action. - "$TODO_FULL_SH" archive + "$TODO_FULL_SH" archive || status=$? fi + exit $status ;; "help" ) @@ -1363,7 +1369,7 @@ case $action in echo "TODO: $item moved from '$src' to '$dest'." fi else - echo "TODO: No tasks moved." + die "TODO: No tasks moved." fi ;; @@ -1374,6 +1380,7 @@ case $action in "pri" | "p" ) shift + status=0 while [ "$#" -gt 0 ] ; do item=$1 newpri=$( printf "%s\n" "$2" | tr '[:lower:]' '[:upper:]' ) @@ -1405,10 +1412,12 @@ note: PRIORITY must be anywhere from A to Z." fi fi if [ "$oldpri" = "$newpri" ]; then - echo "TODO: $item already prioritized ($newpri)." + echo >&2 "TODO: $item already prioritized ($newpri)." + status=1 fi shift; shift done + exit $status ;; "replace" ) @@ -1476,7 +1485,7 @@ note: PRIORITY must be anywhere from A to Z." newTaskNum=$( sed -e '/./!d' "$TODO_FILE" | sed -n '$ =' ) deduplicateNum=$(( originalTaskNum - newTaskNum )) if [ $deduplicateNum -eq 0 ]; then - echo "TODO: No duplicate tasks found" + die "TODO: No duplicate tasks found" else echo "TODO: $deduplicateNum duplicate task(s) removed" fi From c9583196a9a4ad6a0fd35d4800dfddf5c96695ed Mon Sep 17 00:00:00 2001 From: chrysle Date: Mon, 6 Mar 2023 07:35:37 +0100 Subject: [PATCH 18/55] Added test and docstring --- tests/t0002-actions.sh | 14 ++++++++++++++ todo.sh | 1 + 2 files changed, 15 insertions(+) diff --git a/tests/t0002-actions.sh b/tests/t0002-actions.sh index 533a3e06..c9fd3e1c 100755 --- a/tests/t0002-actions.sh +++ b/tests/t0002-actions.sh @@ -16,6 +16,13 @@ echo "TODO: foo" EOF chmod +x foo +cat > foo2 << EOF +if [ "$#" -eq 0 ]; then + echo "TODO: foo" +fi +EOF +chmod +x foo2 + test_expect_success 'custom action (default location 1)' ' mkdir .todo.actions.d cp foo .todo.actions.d/ @@ -37,4 +44,11 @@ test_expect_success 'custom action (env variable)' ' test_cmp expect output && rm -rf myactions ' +test_expect_success 'custom action (default action)' ' + mkdir .todo.actions.d + cp foo2 .todo.actions.d/ + TODOTXT_DEFAULT_ACTION="foo2 bar" todo.sh > output; + test_cmp expect output && rm -rf .todo.actions.d +' + test_done diff --git a/todo.sh b/todo.sh index b7c36d5c..b26d659c 100755 --- a/todo.sh +++ b/todo.sh @@ -983,6 +983,7 @@ then "$TODO_ACTIONS_DIR/$action" "$@" exit $? else + ## Use eventually given parameters actionarray=($action) if [ -d "$TODO_ACTIONS_DIR" -a -x "$TODO_ACTIONS_DIR/${actionarray[0]}" ] then From 7b04315315092cd2520eba2e07cb23eced84f2a6 Mon Sep 17 00:00:00 2001 From: chrysle Date: Mon, 6 Mar 2023 07:40:00 +0100 Subject: [PATCH 19/55] Added `TODOTXT_DEFAULT_ACTION` to the config --- todo.cfg | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/todo.cfg b/todo.cfg index 078c04ff..b99f8765 100644 --- a/todo.cfg +++ b/todo.cfg @@ -82,3 +82,8 @@ export REPORT_FILE="$TODO_DIR/report.txt" # just before the list output is displayed. # # export TODOTXT_FINAL_FILTER='cat' + +## default actions +# Set a default action for calling todo.sh without parameters. +# Also allows for parameters for the action. +# export TODOTXT_DEFAULT_ACTION='' From 6cc821705797c40be1bc7f40a7d27ddad4500357 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Mon, 6 Mar 2023 22:20:34 +0100 Subject: [PATCH 20/55] Actually test (and fix) that the default action parameter is received by the action The foo2 action needs to print its parameters (minus the first which is the action name, instead of hard-coding "foo" if no parameters are passed (which also is broken because the $# is already expanded in the here-doc)), and the test needs to include "foo" (instead of "bar") to match the (reused) expected output. --- tests/t0002-actions.sh | 9 ++++----- todo.sh | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/t0002-actions.sh b/tests/t0002-actions.sh index c9fd3e1c..9d23671d 100755 --- a/tests/t0002-actions.sh +++ b/tests/t0002-actions.sh @@ -16,10 +16,9 @@ echo "TODO: foo" EOF chmod +x foo -cat > foo2 << EOF -if [ "$#" -eq 0 ]; then - echo "TODO: foo" -fi +cat > foo2 << 'EOF' +shift +echo "TODO: $*" EOF chmod +x foo2 @@ -47,7 +46,7 @@ test_expect_success 'custom action (env variable)' ' test_expect_success 'custom action (default action)' ' mkdir .todo.actions.d cp foo2 .todo.actions.d/ - TODOTXT_DEFAULT_ACTION="foo2 bar" todo.sh > output; + TODOTXT_DEFAULT_ACTION="foo2 foo" todo.sh > output; test_cmp expect output && rm -rf .todo.actions.d ' diff --git a/todo.sh b/todo.sh index b26d659c..36f858b7 100755 --- a/todo.sh +++ b/todo.sh @@ -987,7 +987,7 @@ else actionarray=($action) if [ -d "$TODO_ACTIONS_DIR" -a -x "$TODO_ACTIONS_DIR/${actionarray[0]}" ] then - "$TODO_ACTIONS_DIR/${actionarray[0]}" $action + "$TODO_ACTIONS_DIR/${actionarray[0]}" "${actionarray[@]}" exit $? fi fi From 3ed6b48a12e5596e3f9b7e20d3e07a878d96e897 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Mon, 3 Apr 2023 20:50:42 +0200 Subject: [PATCH 21/55] Also handle special characters (that need escaping) in the default action Spaces, quotes, $, and other special shell characters need to be escaped inside the TODOTXT_DEFAULT_ACTION, and consequently eval() used to parse that back into individual arguments. --- tests/t0002-actions.sh | 18 +++++++++++++++++- todo.sh | 7 ++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/tests/t0002-actions.sh b/tests/t0002-actions.sh index 9d23671d..fecc9050 100755 --- a/tests/t0002-actions.sh +++ b/tests/t0002-actions.sh @@ -18,7 +18,8 @@ chmod +x foo cat > foo2 << 'EOF' shift -echo "TODO: $*" +IFS=- # Print arguments separated with dashes to recognize the individual arguments. +printf 'TODO: %s\n' "$*" EOF chmod +x foo2 @@ -50,4 +51,19 @@ test_expect_success 'custom action (default action)' ' test_cmp expect output && rm -rf .todo.actions.d ' +test_todo_session 'default custom action with multiple arguments' <>> mkdir -p .todo.actions.d && cp foo2 .todo.actions.d/ + +>>> TODOTXT_DEFAULT_ACTION='foo2 foo bar baz' todo.sh +TODO: foo-bar-baz +EOF + +export TODOTXT_DEFAULT_ACTION="foo2 foo\\ bar \\\$HOSTNAME O\\'Really\\? \\\"quoted\\\"" +test_todo_session 'default custom action with arguments that have special characters' <>> mkdir -p .todo.actions.d && cp foo2 .todo.actions.d/ + +>>> todo.sh +TODO: foo bar-\$HOSTNAME-O'Really?-"quoted" +EOF + test_done diff --git a/todo.sh b/todo.sh index 36f858b7..0794ddc8 100755 --- a/todo.sh +++ b/todo.sh @@ -984,10 +984,11 @@ then exit $? else ## Use eventually given parameters - actionarray=($action) - if [ -d "$TODO_ACTIONS_DIR" -a -x "$TODO_ACTIONS_DIR/${actionarray[0]}" ] + eval "actionarray=($ACTION)" # Note: Need to use original $ACTION to avoid that arguments are getting lowercased, too. + action=$( printf "%s\n" "${actionarray[0]}" | tr 'A-Z' 'a-z' ) + if [ -d "$TODO_ACTIONS_DIR" -a -x "$TODO_ACTIONS_DIR/$action" ] then - "$TODO_ACTIONS_DIR/${actionarray[0]}" "${actionarray[@]}" + "$TODO_ACTIONS_DIR/$action" "${actionarray[@]}" exit $? fi fi From 05324853018dc24214cf5c6ffc3215dca73c41fb Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Mon, 3 Apr 2023 20:56:18 +0200 Subject: [PATCH 22/55] FIX: Default action with arguments does not consider built-in commands Only $TODO_ACTIONS_DIR/$action, not even the $TODO_ACTIONS_DIR/$action/$action variant. A totally different approach is needed: Instead of parsing off the first argument and treating that as the custom action, do a recursive invocation with the default action parsed as a command-line. A new isDefaultAction flag is needed so that we only do this when the default action actually applies (otherwise, strange invocations like todo.sh "add +project here" would also be possible). The condition for non-empty $TODOTXT_DEFAULT_ACTION avoids an endless loop. --- tests/t0002-actions.sh | 15 +++++++++++++++ todo.sh | 21 +++++++++++---------- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/tests/t0002-actions.sh b/tests/t0002-actions.sh index fecc9050..02269b97 100755 --- a/tests/t0002-actions.sh +++ b/tests/t0002-actions.sh @@ -51,6 +51,12 @@ test_expect_success 'custom action (default action)' ' test_cmp expect output && rm -rf .todo.actions.d ' +test_todo_session 'default built-in action with multiple arguments' <>> TODOTXT_DEFAULT_ACTION='add +foo @bar baz' todo.sh +1 +foo @bar baz +TODO: 1 added. +EOF + test_todo_session 'default custom action with multiple arguments' <>> mkdir -p .todo.actions.d && cp foo2 .todo.actions.d/ @@ -58,6 +64,15 @@ test_todo_session 'default custom action with multiple arguments' < todo.txt +export TODOTXT_DEFAULT_ACTION="add foo\\ bar \\\$HOSTNAME O\\'Really\\? \\\"quoted\\\"" +test_todo_session 'default built-in action with arguments that have special characters' <>> todo.sh +1 foo bar \$HOSTNAME O'Really? "quoted" +TODO: 1 added. +EOF + +: > todo.txt export TODOTXT_DEFAULT_ACTION="foo2 foo\\ bar \\\$HOSTNAME O\\'Really\\? \\\"quoted\\\"" test_todo_session 'default custom action with arguments that have special characters' <>> mkdir -p .todo.actions.d && cp foo2 .todo.actions.d/ diff --git a/todo.sh b/todo.sh index 0794ddc8..27682e1e 100755 --- a/todo.sh +++ b/todo.sh @@ -727,7 +727,13 @@ if [ -n "$OVR_TODOTXT_FINAL_FILTER" ] ; then TODOTXT_FINAL_FILTER="$OVR_TODOTXT_FINAL_FILTER" fi -ACTION=${1:-$TODOTXT_DEFAULT_ACTION} +isDefaultAction= +if [ -n "$1" ]; then + ACTION=$1 +else + ACTION=$TODOTXT_DEFAULT_ACTION + isDefaultAction=t +fi [ -z "$ACTION" ] && usage [ -d "$TODO_DIR" ] || mkdir -p $TODO_DIR 2> /dev/null || dieWithHelp "$1" "Fatal Error: $TODO_DIR is not a directory" @@ -982,15 +988,10 @@ elif [ -d "$TODO_ACTIONS_DIR" -a -x "$TODO_ACTIONS_DIR/$action" ] then "$TODO_ACTIONS_DIR/$action" "$@" exit $? -else - ## Use eventually given parameters - eval "actionarray=($ACTION)" # Note: Need to use original $ACTION to avoid that arguments are getting lowercased, too. - action=$( printf "%s\n" "${actionarray[0]}" | tr 'A-Z' 'a-z' ) - if [ -d "$TODO_ACTIONS_DIR" -a -x "$TODO_ACTIONS_DIR/$action" ] - then - "$TODO_ACTIONS_DIR/$action" "${actionarray[@]}" - exit $? - fi +elif [ "$isDefaultAction" ] && [ -n "$TODOTXT_DEFAULT_ACTION" ]; then + # Recursive invocation with the contents of the default action parsed as a + # command-line. + eval "exec \"\${BASH_SOURCE[0]}\" $TODOTXT_DEFAULT_ACTION" fi ## Only run if $action isn't found in .todo.actions.d From e71eb46d93397383958ce0904a6d6250a5f7997f Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Tue, 4 Apr 2023 17:15:38 +0200 Subject: [PATCH 23/55] Robustness: Use mkdir -p and copy only on success --- tests/t0002-actions.sh | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/tests/t0002-actions.sh b/tests/t0002-actions.sh index 02269b97..4d2d7edf 100755 --- a/tests/t0002-actions.sh +++ b/tests/t0002-actions.sh @@ -24,29 +24,25 @@ EOF chmod +x foo2 test_expect_success 'custom action (default location 1)' ' - mkdir .todo.actions.d - cp foo .todo.actions.d/ + mkdir -p .todo.actions.d && cp foo .todo.actions.d/ todo.sh foo > output; test_cmp expect output && rm -rf .todo.actions.d ' test_expect_success 'custom action (default location 2)' ' - mkdir -p .todo/actions - cp foo .todo/actions/ + mkdir -p .todo/actions && cp foo .todo/actions/ todo.sh foo > output; test_cmp expect output && rm -rf .todo/actions ' test_expect_success 'custom action (env variable)' ' - mkdir myactions - cp foo myactions/ + mkdir -p myactions && cp foo myactions/ TODO_ACTIONS_DIR=myactions todo.sh foo > output; test_cmp expect output && rm -rf myactions ' test_expect_success 'custom action (default action)' ' - mkdir .todo.actions.d - cp foo2 .todo.actions.d/ + mkdir -p .todo.actions.d && cp foo2 .todo.actions.d/ TODOTXT_DEFAULT_ACTION="foo2 foo" todo.sh > output; test_cmp expect output && rm -rf .todo.actions.d ' From ef5b71496d73beec54a8005b5ec9f0837610a45e Mon Sep 17 00:00:00 2001 From: chrysle Date: Tue, 27 Jun 2023 09:49:02 +0200 Subject: [PATCH 24/55] Fix macOS tests --- todo.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/todo.sh b/todo.sh index fb8d4bce..437cfee4 100755 --- a/todo.sh +++ b/todo.sh @@ -491,7 +491,14 @@ replaceOrPrepend() fixMissingEndOfLine() { # Parameters: $1: todo file; empty means $TODO_FILE. - sed -i.bak -e '$a\' "${1:-$TODO_FILE}" + #if [ "$OSTYPE" == "linux-gnu" ]; then + # sed -i.bak -e '$a\' "${1:-$TODO_FILE}" + #else + # sed -i '' -n p "${1:-$TODO_FILE}" + #f + todo_path="${1:-$TODO_FILE}" + [[ -f $todo_path ]] || echo "Not existing: $todo_path" + [[ -f $todo_path && $(tail -c1 "$todo_path") ]] && echo "" >> "$todo_path" } uppercasePriority() From b10904bb206948c5bc009180a201cccae4fd96b0 Mon Sep 17 00:00:00 2001 From: chrysle Date: Fri, 30 Jun 2023 15:11:44 +0200 Subject: [PATCH 25/55] Remove hacks --- todo.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/todo.sh b/todo.sh index 437cfee4..f6844219 100755 --- a/todo.sh +++ b/todo.sh @@ -491,13 +491,7 @@ replaceOrPrepend() fixMissingEndOfLine() { # Parameters: $1: todo file; empty means $TODO_FILE. - #if [ "$OSTYPE" == "linux-gnu" ]; then - # sed -i.bak -e '$a\' "${1:-$TODO_FILE}" - #else - # sed -i '' -n p "${1:-$TODO_FILE}" - #f todo_path="${1:-$TODO_FILE}" - [[ -f $todo_path ]] || echo "Not existing: $todo_path" [[ -f $todo_path && $(tail -c1 "$todo_path") ]] && echo "" >> "$todo_path" } From aa381535863288912acfca1b62db40a8bd031616 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Fri, 30 Jun 2023 16:59:44 +0200 Subject: [PATCH 26/55] Housekeeping: Remove obsolete build platforms GitHub runners for Ubuntu 18.04 and MacOS 10.15 are not available any longer. --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 27fbeb54..4b173a09 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,7 +10,7 @@ jobs: test: strategy: matrix: - platform: [ubuntu-20.04, ubuntu-18.04, macos-11, macos-10.15] + platform: [ubuntu-20.04, macos-11] runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v2 From fd753c6c2e8e661d9882eb41af4ec3a2429b6484 Mon Sep 17 00:00:00 2001 From: Edwin Kofler Date: Wed, 16 Aug 2023 12:09:15 -0700 Subject: [PATCH 27/55] style: Fix typo in pull request template (#420) --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 114b94a7..68e6fd3d 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -3,7 +3,7 @@ - [ ] Fork [the repository](https://github.com/todotxt/todo.txt-cli) and create your branch from `master`. - [ ] If you've added code that should be tested, add tests! - [ ] Ensure the test suite passes. -- [ ] Format your code with [ShellCheck](https://www.shellcheck.net/). +- [ ] Lint your code with [ShellCheck](https://www.shellcheck.net/). - [ ] Include a human-readable description of what the pull request is trying to accomplish. - [ ] Steps for the reviewer(s) on how they can manually QA the changes. - [ ] Have a `fixes #XX` reference to the issue that this pull request fixes. From ca444e40009efc28f50c9a9002e07c4cc1668955 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Mon, 16 Sep 2024 08:24:07 +0200 Subject: [PATCH 28/55] ENH: Allow concatenation of multiple priorities [-ranges] for listpri It can be useful to filter for non-consecutive priority ranges. By enforcing uppercase in that added syntax, overlap with general TERM(s) (e.g. "foo-bar") can be mostly avoided (and in the rare case of having to filter by all-uppercase TERM(s) one can always pass the default A-Z filter, anyway). --- tests/t1250-listpri.sh | 20 ++++++++++++++++++++ todo.sh | 6 +++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/tests/t1250-listpri.sh b/tests/t1250-listpri.sh index ff374e2f..26303cbc 100755 --- a/tests/t1250-listpri.sh +++ b/tests/t1250-listpri.sh @@ -96,6 +96,26 @@ TODO: 0 of 5 tasks shown -- TODO: 1 of 5 tasks shown EOF +test_todo_session 'listpri filtering concatenation of priorities and -ranges' <>> todo.sh -p listpri CX +3 (C) notice the sunflowers +2 (X) clean the house from A-Z +4 (X) listen to music +-- +TODO: 3 of 5 tasks shown + +>>> todo.sh -p listpri ABR-Y +1 (B) smell the uppercase Roses +flowers @outside +2 (X) clean the house from A-Z +4 (X) listen to music +-- +TODO: 3 of 5 tasks shown + +>>> todo.sh -p listpri A- +2 (X) clean the house from A-Z +-- +TODO: 1 of 5 tasks shown +EOF cat > todo.txt < Date: Sat, 21 Sep 2024 11:48:49 +0200 Subject: [PATCH 29/55] Bump: Build platforms to latest available: Ubuntu 24.04, MacOS 14 MacOS 11 is unsupported and the builds are just hanging due to the missing image. --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4b173a09..df2109dd 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,7 +10,7 @@ jobs: test: strategy: matrix: - platform: [ubuntu-20.04, macos-11] + platform: [ubuntu-24.04, macos-14] runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v2 From 75dc8cdaed89748e0ed4f8707e8201d062e8ff56 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Sat, 21 Sep 2024 11:52:23 +0200 Subject: [PATCH 30/55] Bump: checkout action to v4 To silence this warning: > The following actions uses node12 which is deprecated and will be forced to run on node16: actions/checkout@v2 --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index df2109dd..53e1ce71 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,7 +13,7 @@ jobs: platform: [ubuntu-24.04, macos-14] runs-on: ${{ matrix.platform }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - run: make - run: make dist - run: make test From 26a82c3c2fda3c4285706b4684c060aadb6a5797 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Sat, 21 Sep 2024 11:56:10 +0200 Subject: [PATCH 31/55] Build: ENH: Enable manual workflow run Helpful for testing. --- .github/workflows/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 53e1ce71..0d73c835 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -5,6 +5,7 @@ on: branches: [ master ] pull_request: branches: [ master ] + workflow_dispatch: # Allows you to run this workflow manually from the Actions tab jobs: test: From c2b3d01024bc6aa8d3c9142bc25140713e9a155f Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Sat, 21 Sep 2024 11:59:33 +0200 Subject: [PATCH 32/55] Build: ENH: Add dependabot configuration to offer updates to outdated GitHub actions This will automatically scan our workflow once a week and open PR(s) with updates to GitHub actions. --- .github/dependabot.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..ca79ca5b --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly From b00c212fcc585e8927c0aa9e561935a6ca9fe586 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Sat, 21 Sep 2024 12:31:16 +0200 Subject: [PATCH 33/55] FIX: Regression: Compatibility: Bash on MacOS 12 does not support ${var^^} (after ca444e4) This went undetected because the CI/CD pipeline was broken again due to an outdated MacOS image. Continue to use tr for uppercasing. Enable pipefail so that grep (which needs to happen before the uppercasing) result is still considered. (This corrects commit ca444e40009efc28f50c9a9002e07c4cc1668955) --- todo.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/todo.sh b/todo.sh index 7c43c1eb..026739a5 100755 --- a/todo.sh +++ b/todo.sh @@ -1346,8 +1346,8 @@ case $action in "listpri" | "lsp" ) shift ## was "listpri", new $1 is priority to list or first TERM - pri=$(printf "%s\n" "$1" | grep '^\([A-Za-z]\|[A-Za-z]-[A-Za-z]\|[A-Z][A-Z-]*[A-Z]\)$') && shift || pri="A-Z" - post_filter_command="${post_filter_command:-}${post_filter_command:+ | }grep '^ *[0-9]\+ ([${pri^^}]) '" + pri=$(set -o pipefail; printf "%s\n" "$1" | grep '^\([A-Za-z]\|[A-Za-z]-[A-Za-z]\|[A-Z][A-Z-]*[A-Z]\)$' | tr '[:lower:]' '[:upper:]') && shift || pri="A-Z" + post_filter_command="${post_filter_command:-}${post_filter_command:+ | }grep '^ *[0-9]\+ ([${pri}]) '" _list "$TODO_FILE" "$@" ;; From 9623f77af842f2ac974830292c8cc98d6f81e374 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Wed, 30 Oct 2024 08:28:09 +0100 Subject: [PATCH 34/55] ENH: Reuse the todo.sh alias for completion Having to define a completion function wrapper is cumbersome. I had seen the trick of simply using ${COMP_WORDS[0]} (i.e. the used todo.sh command itself) from Paul Mansfield (https://github.com/the1ts/todo.txt-plugins/blob/develop/bash_completion/todo.txt#L7), which neatly avoids this. By keeping the _todo_sh variable, this is a one-line change and it still allows the old way of using the override in a wrapper function. (So users aren't forced to change their customizations when upgrading.) Tests are adapted to verify that the alias is used, and still verify the wrapper function as well. The documentation is simplified because there's normally no need for the completion wrapper function. --- tests/t6090-completion-aliases.sh | 13 ++++++++++--- todo_completion | 26 +++++++++----------------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/tests/t6090-completion-aliases.sh b/tests/t6090-completion-aliases.sh index 7e9f00f3..f136ee74 100755 --- a/tests/t6090-completion-aliases.sh +++ b/tests/t6090-completion-aliases.sh @@ -46,15 +46,22 @@ test_todo_session 'todo 1 and 2 contexts' < Date: Wed, 18 Dec 2024 17:06:08 +0100 Subject: [PATCH 35/55] Build: Tests: "make test" now fails if there are failing or broken tests aggregate-results.sh just reports the execution status, but succeeds in all cases. The build should fail if there are errors. (This also means that no cleanup runs and the failures can be investigated in more detail.) --- tests/aggregate-results.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/aggregate-results.sh b/tests/aggregate-results.sh index cbf64f64..9716accb 100755 --- a/tests/aggregate-results.sh +++ b/tests/aggregate-results.sh @@ -85,3 +85,5 @@ say_color "$(get_color "$success" 'pass')" "$(printf "%-8s%d\n" success $success say_color "$(get_color "$failed" 'error')" "$(printf "%-8s%d\n" failed $failed)" say_color "$(get_color "$broken" 'error')" "$(printf "%-8s%d\n" broken $broken)" say_color 'info' "$(printf "%-8s%d\n" total $total)" + +[ $broken -eq 0 -a $failed -eq 0 ] From 20bdfbf0dd4d7c38d1909ef23c0f6c7f72011358 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Sat, 21 Dec 2024 08:59:48 +0100 Subject: [PATCH 36/55] aggregate-results: Style: Address shellcheck warnings --- tests/aggregate-results.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/aggregate-results.sh b/tests/aggregate-results.sh index 9716accb..0b769dc0 100755 --- a/tests/aggregate-results.sh +++ b/tests/aggregate-results.sh @@ -44,7 +44,7 @@ get_color() # Only use the supplied color if there are actually instances of that # type, so that a clean test run does not distract the user by the # appearance of the error highlighting. - if [ ${1:?} -eq 0 ] + if [ "${1:?}" -eq 0 ] then echo 'info' else @@ -61,21 +61,21 @@ total=0 for file do - while read type value + while read -r type value do case $type in '') continue ;; fixed) - fixed=$((fixed + $value)) ;; + fixed=$((fixed + value)) ;; success) - success=$((success + $value)) ;; + success=$((success + value)) ;; failed) - failed=$((failed + $value)) ;; + failed=$((failed + value)) ;; broken) - broken=$((broken + $value)) ;; + broken=$((broken + value)) ;; total) - total=$((total + $value)) ;; + total=$((total + value)) ;; esac done <"$file" done @@ -86,4 +86,4 @@ say_color "$(get_color "$failed" 'error')" "$(printf "%-8s%d\n" failed $failed)" say_color "$(get_color "$broken" 'error')" "$(printf "%-8s%d\n" broken $broken)" say_color 'info' "$(printf "%-8s%d\n" total $total)" -[ $broken -eq 0 -a $failed -eq 0 ] +[ $broken -eq 0 ] && [ $failed -eq 0 ] From 68ea0b8dc1484d133b0262151f7598aeadf67f3a Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Sat, 21 Dec 2024 09:05:57 +0100 Subject: [PATCH 37/55] aggregate-results: Cleanup: Remove unused $quiet It's not parsed here (from --quiet, as in test-lib.sh), and even exporting it doesn't have any effect, as it's only used when say_color()'s first argument is invalid / empty, which cannot happen due to the defaulting in get_color(). --- tests/aggregate-results.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/aggregate-results.sh b/tests/aggregate-results.sh index 0b769dc0..e16fdd69 100755 --- a/tests/aggregate-results.sh +++ b/tests/aggregate-results.sh @@ -18,12 +18,11 @@ if test -n "$color"; then say_color() { ( export TERM - case "$1" in + case "${1:?}" in error) tput bold; tput setaf 1;; # bold red skip) tput bold; tput setaf 2;; # bold green pass) tput setaf 2;; # green info) tput setaf 3;; # brown - *) test -n "$quiet" && return;; esac shift printf "* %s" "$*" @@ -33,7 +32,6 @@ if test -n "$color"; then } else say_color() { - test -z "$1" && test -n "$quiet" && return shift echo "* $*" } From c2dddb0d94fc31cca8ae5f80bb25ad440f62d78b Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Thu, 19 Dec 2024 10:37:50 +0100 Subject: [PATCH 38/55] Documentation: Update changelog with changes since 2.12.0 It's been over four years now; there should be another release. These are the relevant changes that have happened. --- CHANGELOG.md | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e10522ba..73cf4d45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +## [2.13.0] - 2024-12-25 + +### Added +- listpri action allows concatenation of multiple priorities [-ranges] +- replace action completely merges any combination of priority / date with existing ([#386]) +- Check for broken symlinks to custom actions and complain ([#359]) + +### Changed + +- Add .sh extension to completion script +- Reuse the todo.sh alias for completion +- Return from user prompt without requiring Enter ([#354]) +- Default to user writable directory in config ([#148]) + +### Fixed +- Fix problem with spaces in directory path ([#276]) +- pri action takes multiple items + priorities on single run ([#346]) + ## [2.12.0] - 2020-08-11 ### Added @@ -461,7 +479,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Consolidated into one master script with usage notes and released. -[Unreleased]: https://github.com/todotxt/todo.txt-cli/compare/v2.12.0...HEAD +[Unreleased]: https://github.com/todotxt/todo.txt-cli/compare/v2.13.0...HEAD +[2.13.0]: https://github.com/todotxt/todo.txt-cli/compare/v2.12.0...v2.13.0 [2.12.0]: https://github.com/todotxt/todo.txt-cli/compare/v2.11.0...v2.12.0 [2.11.0]: https://github.com/todotxt/todo.txt-cli/compare/v2.10.0...v2.11.0 [2.10.0]: https://github.com/todotxt/todo.txt-cli/compare/v2.9.0...v2.10.0 @@ -492,6 +511,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. [1.2.0]: https://github.com/todotxt/todo.txt-cli/compare/v1.1.0...v1.2.0 [1.1.0]: https://github.com/todotxt/todo.txt-cli/compare/v1.0.0...v1.1.0 [#8]: https://github.com/todotxt/todo.txt-cli/pull/8 +[#148]: https://github.com/todotxt/todo.txt-cli/pull/148 [#156]: https://github.com/todotxt/todo.txt-cli/pull/156 [#160]: https://github.com/todotxt/todo.txt-cli/pull/160 [#169]: https://github.com/todotxt/todo.txt-cli/pull/169 @@ -501,11 +521,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. [#228]: https://github.com/todotxt/todo.txt-cli/pull/228 [#230]: https://github.com/todotxt/todo.txt-cli/pull/230 [#246]: https://github.com/todotxt/todo.txt-cli/pull/246 +[#246]: https://github.com/todotxt/todo.txt-cli/pull/246 [#249]: https://github.com/todotxt/todo.txt-cli/pull/249 +[#254]: https://github.com/todotxt/todo.txt-cli/pull/254 [#264]: https://github.com/todotxt/todo.txt-cli/pull/264 [#270]: https://github.com/todotxt/todo.txt-cli/pull/270 [#271]: https://github.com/todotxt/todo.txt-cli/pull/271 +[#276]: https://github.com/todotxt/todo.txt-cli/pull/276 [#289]: https://github.com/todotxt/todo.txt-cli/pull/289 [#295]: https://github.com/todotxt/todo.txt-cli/pull/295 [#300]: https://github.com/todotxt/todo.txt-cli/pull/300 [#301]: https://github.com/todotxt/todo.txt-cli/pull/301 +[#346]: https://github.com/todotxt/todo.txt-cli/pull/346 +[#354]: https://github.com/todotxt/todo.txt-cli/pull/354 +[#359]: https://github.com/todotxt/todo.txt-cli/pull/359 +[#386]: https://github.com/todotxt/todo.txt-cli/pull/386 From 8cc23677804fda0ce99bc4eb1485da8787d6b5e9 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Wed, 25 Dec 2024 11:39:20 +0100 Subject: [PATCH 39/55] Tests: Cleanup: Remove unused test_external[_without_stderr]() These make sense in the original context of testing Git commands (that may have external test scripts), but for todo.sh we've never used them, nor are they likely to be useful for this project. --- tests/test-lib.sh | 58 ----------------------------------------------- 1 file changed, 58 deletions(-) diff --git a/tests/test-lib.sh b/tests/test-lib.sh index 4640c207..121fa9a5 100644 --- a/tests/test-lib.sh +++ b/tests/test-lib.sh @@ -316,64 +316,6 @@ expected exit code $1, actual ${eval_ret}" echo >&3 "" } -# test_external runs external test scripts that provide continuous -# test output about their progress, and succeeds/fails on -# zero/non-zero exit code. It outputs the test output on stdout even -# in non-verbose mode, and announces the external script with "* run -# : ..." before running it. When providing relative paths, keep in -# mind that all scripts run in "trash directory". -# Usage: test_external description command arguments... -# Example: test_external 'Perl API' perl ../path/to/test.pl -test_external () { - test "$#" -eq 3 || - error >&5 "bug in the test script: not 3 parameters to test_external" - descr="$1" - shift - if ! test_skip "$descr" "$@" - then - # Announce the script to reduce confusion about the - # test output that follows. - say_color "" " run $test_count: $descr ($*)" - # Run command; redirect its stderr to &4 as in - # test_run_, but keep its stdout on our stdout even in - # non-verbose mode. - "$@" 2>&4 - if [ "$?" = 0 ] - then - test_ok_ "$descr" - else - test_failure_ "$descr" "$@" - fi - fi -} - -# Like test_external, but in addition tests that the command generated -# no output on stderr. -test_external_without_stderr () { - # The temporary file has no (and must have no) security - # implications. - tmp="$TMPDIR"; if [ -z "$tmp" ]; then tmp=/tmp; fi - stderr="$tmp/todotxt-external-stderr.$$.tmp" - test_external "$@" 4> "$stderr" - [ -f "$stderr" ] || error "Internal error: $stderr disappeared." - descr="no stderr: $1" - shift - say >&3 "expecting no stderr from previous command" - if [ ! -s "$stderr" ]; then - rm "$stderr" - test_ok_ "$descr" - else - if [ "$verbose" = t ]; then - output=$(echo; echo Stderr is:; cat "$stderr") - else - output= - fi - # rm first in case test_failure exits. - rm "$stderr" - test_failure_ "$descr" "$@" "$output" - fi -} - # This is not among top-level (test_expect_success | test_expect_failure) # but is a prefix that can be used in the test script, like: # From f00ee905cacf5556b1cf6d3cfef8f41a89f0a782 Mon Sep 17 00:00:00 2001 From: AgumasD <150914292+AgumasD@users.noreply.github.com> Date: Wed, 25 Dec 2024 22:02:17 +0300 Subject: [PATCH 40/55] added some basic usage example on readme (#446) --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 594cb9e4..2601c7d9 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,18 @@ For example, to add a todo item, you can do: ```shell todo.sh add "THING I NEED TO DO +project @context" ``` +### `replace` +Replaces task on line ITEM# with UPDATED TODO. + +```shell +todo.sh replace ITEM# "UPDATED TODO" +``` +### `report` +Adds the number of open tasks and done tasks to report.txt. + +```shell +todo.sh report +``` Read about all the possible commands in the [USAGE][USAGE] file. From e15ad8248f73832660d4093088eef7092cc18489 Mon Sep 17 00:00:00 2001 From: Edwin Kofler Date: Thu, 26 Dec 2024 01:42:45 -0800 Subject: [PATCH 41/55] lint: Fix all ShellCheck errors and most warnings (#419) --- todo.sh | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/todo.sh b/todo.sh index 026739a5..34b9c60f 100755 --- a/todo.sh +++ b/todo.sh @@ -362,13 +362,14 @@ die() confirm() { - [ $TODOTXT_FORCE = 0 ] || return 0 + [ "$TODOTXT_FORCE" = 0 ] || return 0 local readArgs=(-e -r) - [ -n "${BASH_VERSINFO:-}" ] && [ \( ${BASH_VERSINFO[0]} -eq 4 -a ${BASH_VERSINFO[1]} -ge 1 \) -o ${BASH_VERSINFO[0]} -gt 4 ] && + if [ -n "${BASH_VERSINFO:-}" ] && ((BASH_VERSINFO[0] > 4 || (BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] >= 1) )); then readArgs+=(-N 1) # Bash 4.1+ supports -N nchars + fi local answer - read -p "${1:?}? (y/n) " "${readArgs[@]}" answer + read -rp "${1:?}? (y/n) " "${readArgs[@]}" answer echo [ "$answer" = "y" ] } @@ -739,6 +740,7 @@ done # === SANITY CHECKS (thanks Karl!) === [ -r "$TODOTXT_CFG_FILE" ] || dieWithHelp "$1" "Fatal Error: Cannot read configuration file ${TODOTXT_CFG_FILE:-${configFileLocations[0]}}" +# shellcheck source=./todo.cfg . "$TODOTXT_CFG_FILE" # === APPLY OVERRIDES @@ -922,16 +924,18 @@ _format() fi items=$( if [ "$FILE" ]; then + # shellcheck disable=SC2283 sed = "$FILE" else + # shellcheck disable=SC2283 sed = fi \ - | sed -e ''' + | sed -e ' N s/^/ / s/ *\([ 0-9]\{'"$PADDING"',\}\)\n/\1 / /^[ 0-9]\{1,\} *$/d - ''' + ' ) ## Build and apply the filter. @@ -1007,12 +1011,12 @@ _format() printf "%s\n", end_clr } ''' \ - | sed ''' + | sed ' s/'"${HIDE_PROJECTS_SUBSTITUTION:-^}"'//g s/'"${HIDE_CONTEXTS_SUBSTITUTION:-^}"'//g s/'"${HIDE_CUSTOM_SUBSTITUTION:-^}"'//g - ''' \ - | eval ${TODOTXT_FINAL_FILTER} \ + ' \ + | eval ${TODOTXT_FINAL_FILTER} \ ) [ "$filtered_items" ] && echo "$filtered_items" From 5d2727f4ec3bb5654ede97ab97617f0d6cef301b Mon Sep 17 00:00:00 2001 From: Edwin Kofler Date: Thu, 26 Dec 2024 01:54:53 -0800 Subject: [PATCH 42/55] fix: Use shebang `#!/usr/bin/env bash` (#418) --- tests/README | 4 ++-- tests/actions-test-lib.sh | 2 +- tests/aggregate-results.sh | 2 +- tests/t0000-config.sh | 2 +- tests/t0001-null.sh | 2 +- tests/t0002-actions.sh | 2 +- tests/t0100-code-nobacktick.sh | 2 +- tests/t1000-addlist.sh | 2 +- tests/t1010-add-date.sh | 2 +- tests/t1020-addtolistfile.sh | 2 +- tests/t1030-addto-date.sh | 2 +- tests/t1040-add-priority.sh | 2 +- tests/t1100-replace.sh | 2 +- tests/t1200-pri.sh | 2 +- tests/t1250-listpri.sh | 2 +- tests/t1300-ls.sh | 2 +- tests/t1310-listcon.sh | 2 +- tests/t1320-listproj.sh | 2 +- tests/t1330-ls-highlighting.sh | 2 +- tests/t1340-listescapes.sh | 2 +- tests/t1350-listall.sh | 2 +- tests/t1360-ls-project-context-highlighting.sh | 2 +- tests/t1380-ls-date-number-metadata-highlighting.sh | 2 +- tests/t1400-prepend.sh | 2 +- tests/t1500-do.sh | 2 +- tests/t1600-append.sh | 2 +- tests/t1700-depri.sh | 2 +- tests/t1800-del.sh | 2 +- tests/t1850-move.sh | 2 +- tests/t1900-archive.sh | 2 +- tests/t1910-deduplicate.sh | 2 +- tests/t1950-report.sh | 2 +- tests/t2000-multiline.sh | 2 +- tests/t2100-help.sh | 2 +- tests/t2110-help-action.sh | 2 +- tests/t2120-shorthelp.sh | 2 +- tests/t2200-no-done-report-files.sh | 2 +- tests/t6000-completion.sh | 2 +- tests/t6010-completion-contexts.sh | 2 +- tests/t6020-completion-projects.sh | 2 +- tests/t6030-completion-tasks.sh | 2 +- tests/t6040-completion-files.sh | 2 +- tests/t6050-completion-addons.sh | 2 +- tests/t6060-completion-addon-files.sh | 2 +- tests/t6080-completion-path.sh | 2 +- tests/t6090-completion-aliases.sh | 2 +- tests/t6100-completion-help.sh | 2 +- tests/t8000-actions.sh | 2 +- tests/t8010-listaddons.sh | 2 +- tests/t8020-actions-help.sh | 2 +- tests/t9999-testsuite_example.sh | 2 +- tests/test-lib.sh | 2 +- tests/testshell.sh | 2 +- 53 files changed, 54 insertions(+), 54 deletions(-) diff --git a/tests/README b/tests/README index 3f1740d2..b2025f86 100644 --- a/tests/README +++ b/tests/README @@ -125,10 +125,10 @@ Writing Tests ------------- The test script is written as a shell script. It should start -with the standard "#!/bin/bash" with copyright notices, and an +with the standard "#!/usr/bin/env bash" with copyright notices, and an assignment to variable 'test_description', like this: - #!/bin/bash + #!/usr/bin/env bash # # Copyright (c) 2005 Junio C Hamano # diff --git a/tests/actions-test-lib.sh b/tests/actions-test-lib.sh index 42185f24..541babb3 100644 --- a/tests/actions-test-lib.sh +++ b/tests/actions-test-lib.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash make_dummy_action() { diff --git a/tests/aggregate-results.sh b/tests/aggregate-results.sh index e16fdd69..ae632ed5 100755 --- a/tests/aggregate-results.sh +++ b/tests/aggregate-results.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash [ "x$TERM" != "xdumb" ] && ( export TERM && diff --git a/tests/t0000-config.sh b/tests/t0000-config.sh index 1aced0cb..b82a867e 100755 --- a/tests/t0000-config.sh +++ b/tests/t0000-config.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='todo.sh configuration file location diff --git a/tests/t0001-null.sh b/tests/t0001-null.sh index 58f16e6a..14b2224f 100755 --- a/tests/t0001-null.sh +++ b/tests/t0001-null.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='todo.sh basic null functionality test. diff --git a/tests/t0002-actions.sh b/tests/t0002-actions.sh index 402ae6eb..5cacb068 100755 --- a/tests/t0002-actions.sh +++ b/tests/t0002-actions.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='todo.sh actions.d diff --git a/tests/t0100-code-nobacktick.sh b/tests/t0100-code-nobacktick.sh index eb42fbc8..931c56cf 100755 --- a/tests/t0100-code-nobacktick.sh +++ b/tests/t0100-code-nobacktick.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='no old-style backtick command substitution diff --git a/tests/t1000-addlist.sh b/tests/t1000-addlist.sh index c20d257d..50f0a8b4 100755 --- a/tests/t1000-addlist.sh +++ b/tests/t1000-addlist.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='basic add and list functionality diff --git a/tests/t1010-add-date.sh b/tests/t1010-add-date.sh index 74f5917d..38260983 100755 --- a/tests/t1010-add-date.sh +++ b/tests/t1010-add-date.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='test the date on add feature diff --git a/tests/t1020-addtolistfile.sh b/tests/t1020-addtolistfile.sh index 5d827db2..87d7b930 100755 --- a/tests/t1020-addtolistfile.sh +++ b/tests/t1020-addtolistfile.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='basic addto and list functionality diff --git a/tests/t1030-addto-date.sh b/tests/t1030-addto-date.sh index 2cb7400f..88743b5c 100755 --- a/tests/t1030-addto-date.sh +++ b/tests/t1030-addto-date.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='test the date on addto feature diff --git a/tests/t1040-add-priority.sh b/tests/t1040-add-priority.sh index 3adaec61..329485fe 100755 --- a/tests/t1040-add-priority.sh +++ b/tests/t1040-add-priority.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='test the priority on add feature' . ./test-lib.sh diff --git a/tests/t1100-replace.sh b/tests/t1100-replace.sh index 67112d41..2416a5df 100755 --- a/tests/t1100-replace.sh +++ b/tests/t1100-replace.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='basic replace functionality diff --git a/tests/t1200-pri.sh b/tests/t1200-pri.sh index 54b610fd..08ce029f 100755 --- a/tests/t1200-pri.sh +++ b/tests/t1200-pri.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='basic priority functionality ' diff --git a/tests/t1250-listpri.sh b/tests/t1250-listpri.sh index 26303cbc..8cce291a 100755 --- a/tests/t1250-listpri.sh +++ b/tests/t1250-listpri.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='list priority functionality ' diff --git a/tests/t1300-ls.sh b/tests/t1300-ls.sh index 1ba25885..c862a9ed 100755 --- a/tests/t1300-ls.sh +++ b/tests/t1300-ls.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='list functionality diff --git a/tests/t1310-listcon.sh b/tests/t1310-listcon.sh index edf3bd91..0c878514 100755 --- a/tests/t1310-listcon.sh +++ b/tests/t1310-listcon.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='listcon functionality diff --git a/tests/t1320-listproj.sh b/tests/t1320-listproj.sh index 7fa9f10f..13d28b15 100755 --- a/tests/t1320-listproj.sh +++ b/tests/t1320-listproj.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='listproj functionality diff --git a/tests/t1330-ls-highlighting.sh b/tests/t1330-ls-highlighting.sh index 339b4ae5..ab652084 100755 --- a/tests/t1330-ls-highlighting.sh +++ b/tests/t1330-ls-highlighting.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='list highlighting diff --git a/tests/t1340-listescapes.sh b/tests/t1340-listescapes.sh index 32a1a76c..c6a7ff81 100755 --- a/tests/t1340-listescapes.sh +++ b/tests/t1340-listescapes.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='list with escape sequences diff --git a/tests/t1350-listall.sh b/tests/t1350-listall.sh index 72af1355..40c0ee5f 100755 --- a/tests/t1350-listall.sh +++ b/tests/t1350-listall.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='listall functionality ' diff --git a/tests/t1360-ls-project-context-highlighting.sh b/tests/t1360-ls-project-context-highlighting.sh index 019c75df..d13c786f 100755 --- a/tests/t1360-ls-project-context-highlighting.sh +++ b/tests/t1360-ls-project-context-highlighting.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='highlighting projects and contexts diff --git a/tests/t1380-ls-date-number-metadata-highlighting.sh b/tests/t1380-ls-date-number-metadata-highlighting.sh index e14bef25..1adbe91d 100755 --- a/tests/t1380-ls-date-number-metadata-highlighting.sh +++ b/tests/t1380-ls-date-number-metadata-highlighting.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='highlighting date, item numbers and metadata diff --git a/tests/t1400-prepend.sh b/tests/t1400-prepend.sh index 44d8f0e3..c45a04ae 100755 --- a/tests/t1400-prepend.sh +++ b/tests/t1400-prepend.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='basic prepend functionality ' diff --git a/tests/t1500-do.sh b/tests/t1500-do.sh index d359a49d..20b2bccf 100755 --- a/tests/t1500-do.sh +++ b/tests/t1500-do.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='do functionality ' diff --git a/tests/t1600-append.sh b/tests/t1600-append.sh index af25896c..0d350882 100755 --- a/tests/t1600-append.sh +++ b/tests/t1600-append.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='basic append functionality diff --git a/tests/t1700-depri.sh b/tests/t1700-depri.sh index f459ef10..33f65fab 100755 --- a/tests/t1700-depri.sh +++ b/tests/t1700-depri.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='basic depriority functionality ' diff --git a/tests/t1800-del.sh b/tests/t1800-del.sh index 356596fa..b9058ce5 100755 --- a/tests/t1800-del.sh +++ b/tests/t1800-del.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='basic del functionality ' diff --git a/tests/t1850-move.sh b/tests/t1850-move.sh index 2a9e6ea3..66f95d8e 100755 --- a/tests/t1850-move.sh +++ b/tests/t1850-move.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='basic move functionality ' diff --git a/tests/t1900-archive.sh b/tests/t1900-archive.sh index f8baca5e..af95ba0c 100755 --- a/tests/t1900-archive.sh +++ b/tests/t1900-archive.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='archive functionality diff --git a/tests/t1910-deduplicate.sh b/tests/t1910-deduplicate.sh index 67217864..186c6ec2 100755 --- a/tests/t1910-deduplicate.sh +++ b/tests/t1910-deduplicate.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='deduplicate functionality diff --git a/tests/t1950-report.sh b/tests/t1950-report.sh index 5e762e78..6b88d658 100755 --- a/tests/t1950-report.sh +++ b/tests/t1950-report.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='report functionality diff --git a/tests/t2000-multiline.sh b/tests/t2000-multiline.sh index fe35100d..06776804 100755 --- a/tests/t2000-multiline.sh +++ b/tests/t2000-multiline.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='Multi-line functionality' diff --git a/tests/t2100-help.sh b/tests/t2100-help.sh index 705ca1e7..ee8f57a6 100755 --- a/tests/t2100-help.sh +++ b/tests/t2100-help.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='help functionality diff --git a/tests/t2110-help-action.sh b/tests/t2110-help-action.sh index 06d910c8..ada2047b 100755 --- a/tests/t2110-help-action.sh +++ b/tests/t2110-help-action.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='built-in actions help functionality diff --git a/tests/t2120-shorthelp.sh b/tests/t2120-shorthelp.sh index 82275db5..fe50fb05 100755 --- a/tests/t2120-shorthelp.sh +++ b/tests/t2120-shorthelp.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='shorthelp functionality diff --git a/tests/t2200-no-done-report-files.sh b/tests/t2200-no-done-report-files.sh index a0a471fb..306fc4d2 100755 --- a/tests/t2200-no-done-report-files.sh +++ b/tests/t2200-no-done-report-files.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='todo.sh configuration with a sole todo.txt data file. diff --git a/tests/t6000-completion.sh b/tests/t6000-completion.sh index 61cf5948..71036308 100755 --- a/tests/t6000-completion.sh +++ b/tests/t6000-completion.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='Bash completion functionality diff --git a/tests/t6010-completion-contexts.sh b/tests/t6010-completion-contexts.sh index 5cc7862d..fe0cac05 100755 --- a/tests/t6010-completion-contexts.sh +++ b/tests/t6010-completion-contexts.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='Bash context completion functionality diff --git a/tests/t6020-completion-projects.sh b/tests/t6020-completion-projects.sh index 11f554b5..73f7ef0a 100755 --- a/tests/t6020-completion-projects.sh +++ b/tests/t6020-completion-projects.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='Bash project completion functionality diff --git a/tests/t6030-completion-tasks.sh b/tests/t6030-completion-tasks.sh index 35fc055a..ff3b7a8a 100755 --- a/tests/t6030-completion-tasks.sh +++ b/tests/t6030-completion-tasks.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='Bash task number completion functionality diff --git a/tests/t6040-completion-files.sh b/tests/t6040-completion-files.sh index 94ff2ba7..959abf60 100755 --- a/tests/t6040-completion-files.sh +++ b/tests/t6040-completion-files.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='Bash todo file completion functionality diff --git a/tests/t6050-completion-addons.sh b/tests/t6050-completion-addons.sh index 79ed0f19..20664590 100755 --- a/tests/t6050-completion-addons.sh +++ b/tests/t6050-completion-addons.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='Bash add-on action completion functionality diff --git a/tests/t6060-completion-addon-files.sh b/tests/t6060-completion-addon-files.sh index eb65662f..eb14e0d4 100755 --- a/tests/t6060-completion-addon-files.sh +++ b/tests/t6060-completion-addon-files.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='Bash add-on action file completion functionality diff --git a/tests/t6080-completion-path.sh b/tests/t6080-completion-path.sh index 7ec777c5..01459e57 100755 --- a/tests/t6080-completion-path.sh +++ b/tests/t6080-completion-path.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='Bash completion with different path functionality diff --git a/tests/t6090-completion-aliases.sh b/tests/t6090-completion-aliases.sh index f136ee74..2cf33632 100755 --- a/tests/t6090-completion-aliases.sh +++ b/tests/t6090-completion-aliases.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='Bash completion with different aliases functionality diff --git a/tests/t6100-completion-help.sh b/tests/t6100-completion-help.sh index a0440c44..c6db96fd 100755 --- a/tests/t6100-completion-help.sh +++ b/tests/t6100-completion-help.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='Bash help completion functionality diff --git a/tests/t8000-actions.sh b/tests/t8000-actions.sh index 1c480c67..3f9c607d 100755 --- a/tests/t8000-actions.sh +++ b/tests/t8000-actions.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='custom actions functionality diff --git a/tests/t8010-listaddons.sh b/tests/t8010-listaddons.sh index ee0495a9..a0426c5a 100755 --- a/tests/t8010-listaddons.sh +++ b/tests/t8010-listaddons.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='listaddons functionality diff --git a/tests/t8020-actions-help.sh b/tests/t8020-actions-help.sh index cc79bc14..449f46e8 100755 --- a/tests/t8020-actions-help.sh +++ b/tests/t8020-actions-help.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='custom actions help functionality diff --git a/tests/t9999-testsuite_example.sh b/tests/t9999-testsuite_example.sh index ef25884e..0228fc99 100755 --- a/tests/t9999-testsuite_example.sh +++ b/tests/t9999-testsuite_example.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='basic tests imported from previous framework ' diff --git a/tests/test-lib.sh b/tests/test-lib.sh index 121fa9a5..18d00564 100644 --- a/tests/test-lib.sh +++ b/tests/test-lib.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # # Copyright (c) 2005 Junio C Hamano # diff --git a/tests/testshell.sh b/tests/testshell.sh index 83abeaae..6008771f 100755 --- a/tests/testshell.sh +++ b/tests/testshell.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash test_description='Providing an interactive shell in the proper environment' . ./test-lib.sh From 465949b73c098698ff7a0a2b0686ece53c712d25 Mon Sep 17 00:00:00 2001 From: Alissa Huskey Date: Sun, 2 Jun 2024 18:40:31 -0600 Subject: [PATCH 43/55] Improved Makefile. --- Makefile | 73 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 55 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index d498004c..820415e5 100644 --- a/Makefile +++ b/Makefile @@ -34,41 +34,61 @@ else endif # Dynamically detect/generate version file as necessary -# This file will define a variable called VERSION. -.PHONY: .FORCE-VERSION-FILE -VERSION-FILE: .FORCE-VERSION-FILE +# This file will define a variable called VERSION used in +# both todo.sh and this Makefile. +VERSION-FILE: @./GEN-VERSION-FILE -include VERSION-FILE -# Maybe this will include the version in it. -todo.sh: VERSION-FILE +# dist/build directory name +DISTNAME=todo.txt_cli-$(VERSION) -# For packaging -DISTFILES := todo.cfg todo_completion +# files to copy unmodified into the dist directory +SRC_FILES := todo.cfg todo_completion -DISTNAME=todo.txt_cli-$(VERSION) -dist: $(DISTFILES) todo.sh +# path of SRC_FILES in the dist directory +OUTPUT_FILES := $(patsubst %, $(DISTNAME)/%, $(SRC_FILES)) + +# all dist files +DISTFILES := $(OUTPUT_FILES) $(DISTNAME)/todo.sh + +# create the dist directory +$(DISTNAME): VERSION-FILE mkdir -p $(DISTNAME) - cp -f $(DISTFILES) $(DISTNAME)/ + +# copy SRC_FILES to the dist directory +$(OUTPUT_FILES): $(DISTNAME)/%: % + cp -f $(*) $(DISTNAME)/ + +# generate todo.sh +$(DISTNAME)/todo.sh: VERSION-FILE sed -e 's/@DEV_VERSION@/'$(VERSION)'/' todo.sh > $(DISTNAME)/todo.sh chmod +x $(DISTNAME)/todo.sh + +.PHONY: build +build: $(DISTNAME) $(DISTFILES) ## create the dist directory and files + +.PHONY: dist +dist: build ## create the compressed release files tar cf $(DISTNAME).tar $(DISTNAME) gzip -f -9 $(DISTNAME).tar zip -r -9 $(DISTNAME).zip $(DISTNAME) rm -r $(DISTNAME) .PHONY: clean -clean: test-pre-clean +clean: test-pre-clean VERSION-FILE ## remove dist directory and all release files + rm -rf $(DISTNAME) rm -f $(DISTNAME).tar.gz $(DISTNAME).zip - rm VERSION-FILE -install: installdirs - $(INSTALL_PROGRAM) todo.sh $(DESTDIR)$(bindir)/todo.sh - $(INSTALL_DATA) todo_completion $(DESTDIR)$(datarootdir)/todo.sh +.PHONY: install +install: build installdirs ## local package install + $(INSTALL_PROGRAM) $(DISTNAME)/todo.sh $(DESTDIR)$(bindir)/todo.sh + $(INSTALL_DATA) $(DISTNAME)/todo_completion $(DESTDIR)$(datarootdir)/todo.sh [ -e $(DESTDIR)$(sysconfdir)/todo/config ] || \ - sed "s/^\(export[ \t]*TODO_DIR=\).*/\1~\/.todo/" todo.cfg > $(DESTDIR)$(sysconfdir)/todo/config + sed "s/^\(export[ \t]*TODO_DIR=\).*/\1~\/.todo/" $(DISTNAME)/todo.cfg > $(DESTDIR)$(sysconfdir)/todo/config -uninstall: +.PHONY: uninstall +uninstall: ## uninstall package rm -f $(DESTDIR)$(bindir)/todo.sh rm -f $(DESTDIR)$(datarootdir)/todo rm -f $(DESTDIR)$(sysconfdir)/todo/config @@ -76,6 +96,8 @@ uninstall: rmdir $(DESTDIR)$(datarootdir) rmdir $(DESTDIR)$(sysconfdir)/todo +# create local installation directories +.PHONY: installdirs installdirs: mkdir -p $(DESTDIR)$(bindir) \ $(DESTDIR)$(sysconfdir)/todo \ @@ -87,18 +109,33 @@ installdirs: TESTS = $(wildcard tests/t[0-9][0-9][0-9][0-9]-*.sh) #TEST_OPTIONS=--verbose +# remove test detritus test-pre-clean: rm -rf tests/test-results "tests/trash directory"* +# run tests and generate test result files aggregate-results: $(TESTS) $(TESTS): test-pre-clean cd tests && ./$(notdir $@) $(TEST_OPTIONS) -test: aggregate-results +# run tests, print a test result summary, and remove generated test results +test: aggregate-results ## run tests tests/aggregate-results.sh tests/test-results/t*-* rm -rf tests/test-results # Force tests to get run every time .PHONY: test test-pre-clean aggregate-results $(TESTS) +# generate list of targets from this Makefile +# looks for any lowercase target with a double hash mark (##) on the same line +# and uses the inline comment as the target description +.PHONY: help +.DEFAULT: help +help: ## list public targets + @echo + @echo todo.txt Makefile + @echo + @sed -ne '/^[a-z%-]\+:.*##/ s/:.*##/\t/p' $(word 1, $(MAKEFILE_LIST)) \ + | column -t -s $$'\t' + @echo From 98841b79e42c1f6bc390e7b6c2d99e837fcd590d Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Thu, 26 Dec 2024 11:12:25 +0100 Subject: [PATCH 44/55] FIX: Minor: Replace $'\t' with literal tab The default shell (/bin/sh) might not understand the Bash syntax. This happens on Ubuntu 20.04; column produces garbled output then. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 820415e5..69ea7af6 100644 --- a/Makefile +++ b/Makefile @@ -137,5 +137,5 @@ help: ## list public targets @echo todo.txt Makefile @echo @sed -ne '/^[a-z%-]\+:.*##/ s/:.*##/\t/p' $(word 1, $(MAKEFILE_LIST)) \ - | column -t -s $$'\t' + | column -t -s ' ' @echo From b4ab778e28edebc9924a375f8275f9b291619e28 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Thu, 26 Dec 2024 11:14:15 +0100 Subject: [PATCH 45/55] Make "help" the default target So far, the version file gets updated, which isn't a meaningful default action and rather incidental. Defaulting to help output that lists all available targets is a much better default. --- Makefile | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 69ea7af6..e17e7735 100644 --- a/Makefile +++ b/Makefile @@ -33,6 +33,19 @@ else datarootdir = $(prefix)/share/bash_completion.d endif +# generate list of targets from this Makefile +# looks for any lowercase target with a double hash mark (##) on the same line +# and uses the inline comment as the target description +.PHONY: help +.DEFAULT: help +help: ## list public targets + @echo + @echo todo.txt Makefile + @echo + @sed -ne '/^[a-z%-]\+:.*##/ s/:.*##/\t/p' $(word 1, $(MAKEFILE_LIST)) \ + | column -t -s ' ' + @echo + # Dynamically detect/generate version file as necessary # This file will define a variable called VERSION used in # both todo.sh and this Makefile. @@ -126,16 +139,3 @@ test: aggregate-results ## run tests # Force tests to get run every time .PHONY: test test-pre-clean aggregate-results $(TESTS) - -# generate list of targets from this Makefile -# looks for any lowercase target with a double hash mark (##) on the same line -# and uses the inline comment as the target description -.PHONY: help -.DEFAULT: help -help: ## list public targets - @echo - @echo todo.txt Makefile - @echo - @sed -ne '/^[a-z%-]\+:.*##/ s/:.*##/\t/p' $(word 1, $(MAKEFILE_LIST)) \ - | column -t -s ' ' - @echo From e9eaacb530ee9ebd977668fee9898f9e95eed5bb Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Thu, 26 Dec 2024 11:30:24 +0100 Subject: [PATCH 46/55] GEN-VERSION-FILE: Refactoring: Use "git describe --dirty", don't show closest tag only No need to emulate the dirty addition any longer; Git has this built-in. Use the full long version to avoid accidentally building packages that look like the released version, but contain further commits. The official build should be done after tagging, on the tagged version commit. --- GEN-VERSION-FILE | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/GEN-VERSION-FILE b/GEN-VERSION-FILE index 6308d3ef..9576b76d 100755 --- a/GEN-VERSION-FILE +++ b/GEN-VERSION-FILE @@ -4,18 +4,8 @@ VF=VERSION-FILE DEF_VER=v2.2 -LF=' -' - if test -d .git -o -f .git && - VN=$(git describe --abbrev=0 --tags 2>/dev/null) && - case "$VN" in - *$LF*) (exit 1) ;; - v[0-9]*) - git update-index -q --refresh - test -z "$(git diff-index --name-only HEAD --)" || - VN="$VN-dirty" ;; - esac + VN=$(git describe --dirty --tags 2>/dev/null) then VN=$(echo "$VN" | sed -e 's/-/./g'); else From fd6bab4b6d397d8e84e94ed568c66c239cfd6587 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Thu, 26 Dec 2024 11:32:54 +0100 Subject: [PATCH 47/55] GEN-VERSION-FILE: Minor: Default to 0.0 version, not 2.2 This could be confusing, as there have been 2.1.0 and 2.3.0 releases. --- GEN-VERSION-FILE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GEN-VERSION-FILE b/GEN-VERSION-FILE index 9576b76d..9162b235 100755 --- a/GEN-VERSION-FILE +++ b/GEN-VERSION-FILE @@ -2,7 +2,7 @@ # Based on git's GIT-VERSION-GEN. VF=VERSION-FILE -DEF_VER=v2.2 +DEF_VER=v0.0 if test -d .git -o -f .git && VN=$(git describe --dirty --tags 2>/dev/null) From 1a938c7a0814574da72461a02693d02df94ea96c Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Thu, 26 Dec 2024 11:34:50 +0100 Subject: [PATCH 48/55] GEN-VERSION-FILE: Refactoring: Switch to Bash to use ${parameter//pattern/string} instead of sed --- GEN-VERSION-FILE | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GEN-VERSION-FILE b/GEN-VERSION-FILE index 9162b235..aec88dfa 100755 --- a/GEN-VERSION-FILE +++ b/GEN-VERSION-FILE @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env bash # Based on git's GIT-VERSION-GEN. VF=VERSION-FILE @@ -7,7 +7,7 @@ DEF_VER=v0.0 if test -d .git -o -f .git && VN=$(git describe --dirty --tags 2>/dev/null) then - VN=$(echo "$VN" | sed -e 's/-/./g'); + VN=${VN//-/.} else VN="$DEF_VER" fi From 31d87721506fcbc38347fe5b46391fec06df1e16 Mon Sep 17 00:00:00 2001 From: chrysle <96722107+chrysle@users.noreply.github.com> Date: Thu, 26 Dec 2024 12:08:41 +0100 Subject: [PATCH 49/55] Improved usage messages for actions (#402) Co-authored-by: Ingo Karkat --- README.md | 4 +- USAGE.md | 44 +++++++------- tests/actions-test-lib.sh | 2 +- tests/t1100-replace.sh | 2 +- tests/t1200-pri.sh | 2 +- tests/t1400-prepend.sh | 2 +- tests/t1500-do.sh | 6 +- tests/t1600-append.sh | 2 +- tests/t1700-depri.sh | 2 +- tests/t1800-del.sh | 2 +- tests/t2110-help-action.sh | 16 ++--- tests/t6040-completion-files.sh | 6 +- tests/t6060-completion-addon-files.sh | 12 ++-- tests/t8020-actions-help.sh | 16 ++--- tests/t9999-testsuite_example.sh | 2 +- todo.sh | 86 ++++++++++++++------------- todo_completion | 2 +- 17 files changed, 105 insertions(+), 103 deletions(-) diff --git a/README.md b/README.md index 2601c7d9..67e15542 100644 --- a/README.md +++ b/README.md @@ -74,10 +74,10 @@ For example, to add a todo item, you can do: todo.sh add "THING I NEED TO DO +project @context" ``` ### `replace` -Replaces task on line ITEM# with UPDATED TODO. +Replaces task on line NR with UPDATED TODO. ```shell -todo.sh replace ITEM# "UPDATED TODO" +todo.sh replace NR "UPDATED TODO" ``` ### `report` Adds the number of open tasks and done tasks to report.txt. diff --git a/USAGE.md b/USAGE.md index 4500377b..b6b4f0f7 100644 --- a/USAGE.md +++ b/USAGE.md @@ -38,13 +38,13 @@ todo.sh addto DEST "TEXT TO ADD" ``` ### `append` -Adds TEXT TO APPEND to the end of the task on line ITEM#. +Adds TEXT TO APPEND to the end of the task on line NR. Quotes optional. ```shell -todo.sh append ITEM# "TEXT TO APPEND" -todo.sh app ITEM# "TEXT TO APPEND" +todo.sh append NR "TEXT TO APPEND" +todo.sh app NR "TEXT TO APPEND" ``` ### `archive` @@ -71,26 +71,26 @@ todo.sh deduplicate ``` ### `del` -Deletes the task on line ITEM# in todo.txt. If TERM specified, deletes only TERM from the task. +Deletes the task on line NR in todo.txt. If TERM specified, deletes only TERM from the task. ```shell -todo.sh del ITEM# [TERM] -todo.sh rm ITEM# [TERM] +todo.sh del NR [TERM] +todo.sh rm NR [TERM] ``` ### `depri` -Deprioritizes (removes the priority) from the task(s) on line ITEM# in todo.txt. +Deprioritizes (removes the priority) from the task(s) on line NR in todo.txt. ```shell -todo.sh depri ITEM#[, ITEM#, ITEM#, ...] -todo.sh dp ITEM#[, ITEM#, ITEM#, ...] +todo.sh depri NR [NR ...] +todo.sh dp NR [NR ...] ``` ### `do` -Marks task(s) on line ITEM# as done in todo.txt. +Marks task(s) on line NR as done in todo.txt. ```shell -todo.sh do ITEM#[, ITEM#, ITEM#, ...] +todo.sh do NR [NR ...] ``` ### `help` @@ -164,34 +164,34 @@ todo.sh lsprj [TERM...] ``` ### `move` -Moves a line from source text file (SRC) to destination text file (DEST). Both source and destination file must be located in the directory defined in the configuration directory. When SRC is not defined it's by default todo.txt. +Moves line NR from source text file (SRC) to destination text file (DEST). Both source and destination file must be located in the directory defined in the configuration directory. When SRC is not defined it's by default todo.txt. ```shell -todo.sh move ITEM# DEST [SRC] -todo.sh mv ITEM# DEST [SRC] +todo.sh move NR DEST [SRC] +todo.sh mv NR DEST [SRC] ``` ### `prepend` -Adds TEXT TO PREPEND to the beginning of the task on line ITEM#. Quotes optional. +Adds TEXT TO PREPEND to the beginning of the task on line NR. Quotes optional. ```shell -todo.sh prepend ITEM# "TEXT TO PREPEND" -todo.sh prep ITEM# "TEXT TO PREPEND" +todo.sh prepend NR "TEXT TO PREPEND" +todo.sh prep NR"TEXT TO PREPEND" ``` ### `pri` -Adds PRIORITY to task on line ITEM#. If the task is already prioritized, replaces current priority with new PRIORITY. PRIORITY must be a letter between A and Z. +Adds PRIORITY to task on line NR. If the task is already prioritized, replaces current priority with new PRIORITY. PRIORITY must be a letter between A and Z. ```shell -todo.sh pri ITEM# PRIORITY -todo.sh p ITEM# PRIORITY +todo.sh pri NR PRIORITY +todo.sh p NR PRIORITY ``` ### `replace` -Replaces task on line ITEM# with UPDATED TODO. +Replaces task on line NR with UPDATED TODO. ```shell -todo.sh replace ITEM# "UPDATED TODO" +todo.sh replace NR "UPDATED TODO" ``` ### `report` diff --git a/tests/actions-test-lib.sh b/tests/actions-test-lib.sh index 541babb3..e3cfe232 100644 --- a/tests/actions-test-lib.sh +++ b/tests/actions-test-lib.sh @@ -6,7 +6,7 @@ make_dummy_action() cat > "$1" < /dev/null test_todo_session 'replace usage' <>> todo.sh replace adf asdfa === 1 -usage: todo.sh replace ITEM# "UPDATED ITEM" +usage: todo.sh replace NR "UPDATED ITEM" EOF test_todo_session 'basic replace' <>> todo.sh pri B B -usage: todo.sh pri ITEM# PRIORITY[, ITEM# PRIORITY, ...] +usage: todo.sh pri NR PRIORITY [NR PRIORITY ...] note: PRIORITY must be anywhere from A to Z. === 1 EOF diff --git a/tests/t1400-prepend.sh b/tests/t1400-prepend.sh index c45a04ae..4d6adc0e 100755 --- a/tests/t1400-prepend.sh +++ b/tests/t1400-prepend.sh @@ -6,7 +6,7 @@ test_description='basic prepend functionality test_todo_session 'prepend usage' <>> todo.sh prepend B B -usage: todo.sh prepend ITEM# "TEXT TO PREPEND" +usage: todo.sh prepend NR "TEXT TO PREPEND" === 1 EOF diff --git a/tests/t1500-do.sh b/tests/t1500-do.sh index 20b2bccf..6ee2c48a 100755 --- a/tests/t1500-do.sh +++ b/tests/t1500-do.sh @@ -8,13 +8,13 @@ test_description='do functionality test_todo_session 'do usage' <>> todo.sh do B B -usage: todo.sh do ITEM#[, ITEM#, ITEM#, ...] +usage: todo.sh do NR [NR ...] === 1 EOF -test_todo_session 'do missing ITEM#' <>> todo.sh do -usage: todo.sh do ITEM#[, ITEM#, ITEM#, ...] +usage: todo.sh do NR [NR ...] === 1 EOF diff --git a/tests/t1600-append.sh b/tests/t1600-append.sh index 0d350882..626d1f4c 100755 --- a/tests/t1600-append.sh +++ b/tests/t1600-append.sh @@ -14,7 +14,7 @@ todo.sh add notice the daisies > /dev/null test_todo_session 'append usage' <>> todo.sh append adf asdfa === 1 -usage: todo.sh append ITEM# "TEXT TO APPEND" +usage: todo.sh append NR "TEXT TO APPEND" EOF test_todo_session 'append error' <>> todo.sh depri B B -usage: todo.sh depri ITEM#[, ITEM#, ITEM#, ...] +usage: todo.sh depri NR [NR ...] === 1 EOF diff --git a/tests/t1800-del.sh b/tests/t1800-del.sh index b9058ce5..970afe08 100755 --- a/tests/t1800-del.sh +++ b/tests/t1800-del.sh @@ -8,7 +8,7 @@ SPACE=' ' test_todo_session 'del usage' <>> todo.sh del B -usage: todo.sh del ITEM# [TERM] +usage: todo.sh del NR [TERM] === 1 EOF diff --git a/tests/t2110-help-action.sh b/tests/t2110-help-action.sh index ada2047b..f31de714 100755 --- a/tests/t2110-help-action.sh +++ b/tests/t2110-help-action.sh @@ -32,24 +32,24 @@ test_todo_session 'multiple actions help' <<'EOF' shorthelp List the one-line usage of all built-in and add-on actions. \ - append ITEM# "TEXT TO APPEND" - app ITEM# "TEXT TO APPEND" - Adds TEXT TO APPEND to the end of the task on line ITEM#. + append NR "TEXT TO APPEND" + app NR "TEXT TO APPEND" + Adds TEXT TO APPEND to the end of the task on line NR. Quotes optional. \ EOF test_todo_session 'short and long form of action help' <<'EOF' >>> todo.sh help append - append ITEM# "TEXT TO APPEND" - app ITEM# "TEXT TO APPEND" - Adds TEXT TO APPEND to the end of the task on line ITEM#. + append NR "TEXT TO APPEND" + app NR "TEXT TO APPEND" + Adds TEXT TO APPEND to the end of the task on line NR. Quotes optional. \ >>> todo.sh help app - app ITEM# "TEXT TO APPEND" - Adds TEXT TO APPEND to the end of the task on line ITEM#. + app NR "TEXT TO APPEND" + Adds TEXT TO APPEND to the end of the task on line NR. Quotes optional. \ EOF diff --git a/tests/t6040-completion-files.sh b/tests/t6040-completion-files.sh index 959abf60..aae89958 100755 --- a/tests/t6040-completion-files.sh +++ b/tests/t6040-completion-files.sh @@ -13,8 +13,8 @@ test_todo_completion 'files beginning with d after addto' 'todo.sh addto d' 'don test_todo_completion 'all files after listfile' 'todo.sh listfile ' "$FILES" test_todo_completion 'all files after lf' 'todo.sh -v lf ' "$FILES" test_todo_completion 'nothing after move' 'todo.sh move ' '' -test_todo_completion 'all files after move ITEM#' 'todo.sh move 1 ' "$FILES" -test_todo_completion 'all files after mv ITEM#' 'todo.sh mv 1 ' "$FILES" -test_todo_completion 'all files after move ITEM# DEST' 'todo.sh move 1 todo.sh ' "$FILES" +test_todo_completion 'all files after move NR' 'todo.sh move 1 ' "$FILES" +test_todo_completion 'all files after mv NR' 'todo.sh mv 1 ' "$FILES" +test_todo_completion 'all files after move NR DEST' 'todo.sh move 1 todo.sh ' "$FILES" test_done diff --git a/tests/t6060-completion-addon-files.sh b/tests/t6060-completion-addon-files.sh index eb14e0d4..07f19713 100755 --- a/tests/t6060-completion-addon-files.sh +++ b/tests/t6060-completion-addon-files.sh @@ -11,17 +11,17 @@ test_todo_completion 'nothing after unconfigured bar' 'todo.sh bar ' '' _todo_file1_actions='foo|bar' test_todo_completion 'all files after configured bar' 'todo.sh bar ' "$FILES" -test_todo_completion 'nothing after configured bar ITEM#' 'todo.sh bar 1 ' '' +test_todo_completion 'nothing after configured bar NR' 'todo.sh bar 1 ' '' _todo_file2_actions='baz' test_todo_completion 'nothing after configured baz' 'todo.sh baz ' '' -test_todo_completion 'all files after configured baz ITEM#' 'todo.sh baz 1 ' "$FILES" -test_todo_completion 'nothing after configured baz ITEM# MORE' 'todo.sh baz 1 more ' '' +test_todo_completion 'all files after configured baz NR' 'todo.sh baz 1 ' "$FILES" +test_todo_completion 'nothing after configured baz NR MORE' 'todo.sh baz 1 more ' '' _todo_file3_actions='biz' test_todo_completion 'nothing after configured biz' 'todo.sh biz ' '' -test_todo_completion 'nothing after configured biz ITEM#' 'todo.sh biz 1 ' '' -test_todo_completion 'all files after configured biz ITEM# MORE' 'todo.sh biz 1 more ' "$FILES" -test_todo_completion 'nothing after configured biz ITEM# EVEN MORE' 'todo.sh biz 1 even more ' '' +test_todo_completion 'nothing after configured biz NR' 'todo.sh biz 1 ' '' +test_todo_completion 'all files after configured biz NR MORE' 'todo.sh biz 1 more ' "$FILES" +test_todo_completion 'nothing after configured biz NR EVEN MORE' 'todo.sh biz 1 even more ' '' test_done diff --git a/tests/t8020-actions-help.sh b/tests/t8020-actions-help.sh index 449f46e8..09151169 100755 --- a/tests/t8020-actions-help.sh +++ b/tests/t8020-actions-help.sh @@ -20,22 +20,22 @@ make_action "quux" test_todo_session 'custom action help' <<'EOF' >>> todo.sh help foo - foo ITEM#[, ITEM#, ...] [TERM...] + foo NR [NR ...] [TERM...] This custom action does foo. \ >>> todo.sh help bar - bar ITEM#[, ITEM#, ...] [TERM...] + bar NR [NR ...] [TERM...] This custom action does bar. \ EOF test_todo_session 'multiple custom actions help' <<'EOF' >>> todo.sh help foo bar - foo ITEM#[, ITEM#, ...] [TERM...] + foo NR [NR ...] [TERM...] This custom action does foo. \ - bar ITEM#[, ITEM#, ...] [TERM...] + bar NR [NR ...] [TERM...] This custom action does bar. \ EOF @@ -46,7 +46,7 @@ TODO: No action "doesnotexist" exists. === 1 >>> todo.sh help foo doesnotexist bar - foo ITEM#[, ITEM#, ...] [TERM...] + foo NR [NR ...] [TERM...] This custom action does foo. \ TODO: No action "doesnotexist" exists. @@ -55,20 +55,20 @@ EOF test_todo_session 'mixed built-in and custom actions help' <<'EOF' >>> todo.sh help foo shorthelp bar - foo ITEM#[, ITEM#, ...] [TERM...] + foo NR [NR ...] [TERM...] This custom action does foo. \ shorthelp List the one-line usage of all built-in and add-on actions. \ - bar ITEM#[, ITEM#, ...] [TERM...] + bar NR [NR ...] [TERM...] This custom action does bar. \ EOF test_todo_session 'custom override of built-in action help' <<'EOF' >>> todo.sh help ls - ls ITEM#[, ITEM#, ...] [TERM...] + ls NR [NR ...] [TERM...] This custom action does ls. \ EOF diff --git a/tests/t9999-testsuite_example.sh b/tests/t9999-testsuite_example.sh index 0228fc99..cdc7a901 100755 --- a/tests/t9999-testsuite_example.sh +++ b/tests/t9999-testsuite_example.sh @@ -90,7 +90,7 @@ TODO: $HOME/todo.txt archived. TODO: Report file updated. >>> todo.sh append g a -usage: todo.sh append ITEM# "TEXT TO APPEND" +usage: todo.sh append NR "TEXT TO APPEND" === 1 >>> todo.sh append 2 and think diff --git a/todo.sh b/todo.sh index 34b9c60f..fa4601a6 100755 --- a/todo.sh +++ b/todo.sh @@ -45,13 +45,13 @@ shorthelp() addm "THINGS I NEED TO DO MORE THINGS I NEED TO DO" addto DEST "TEXT TO ADD" - append|app ITEM# "TEXT TO APPEND" + append|app NR "TEXT TO APPEND" archive command [ACTIONS] deduplicate - del|rm ITEM# [TERM] - depri|dp ITEM#[, ITEM#, ITEM#, ...] - done|do ITEM#[, ITEM#, ITEM#, ...] + del|rm NR [TERM] + depri|dp NR [NR ...] + done|do NR [NR ...] help [ACTION...] list|ls [TERM...] listall|lsa [TERM...] @@ -60,10 +60,10 @@ shorthelp() listfile|lf [SRC [TERM...]] listpri|lsp [PRIORITIES] [TERM...] listproj|lsprj [TERM...] - move|mv ITEM# DEST [SRC] - prepend|prep ITEM# "TEXT TO PREPEND" - pri|p ITEM# PRIORITY[, ITEM# PRIORITY, ...] - replace ITEM# "UPDATED TODO" + move|mv NR DEST [SRC] + prepend|prep NR "TEXT TO PREPEND" + pri|p NR PRIORITY [NR PRIORITY ...] + replace NR "UPDATED TODO" report shorthelp @@ -180,9 +180,9 @@ actionsHelp() Adds a line of text to any file located in the todo.txt directory. For example, addto inbox.txt "decide about vacation" - append ITEM# "TEXT TO APPEND" - app ITEM# "TEXT TO APPEND" - Adds TEXT TO APPEND to the end of the task on line ITEM#. + append NR "TEXT TO APPEND" + app NR "TEXT TO APPEND" + Adds TEXT TO APPEND to the end of the task on line NR. Quotes optional. archive @@ -195,19 +195,19 @@ actionsHelp() deduplicate Removes duplicate lines from todo.txt. - del ITEM# [TERM] - rm ITEM# [TERM] - Deletes the task on line ITEM# in todo.txt. + del NR [TERM] + rm NR [TERM] + Deletes the task on line NR in todo.txt. If TERM specified, deletes only TERM from the task. - depri ITEM#[, ITEM#, ITEM#, ...] - dp ITEM#[, ITEM#, ITEM#, ...] + depri NR [NR ...] + dp NR [NR ...] Deprioritizes (removes the priority) from the task(s) - on line ITEM# in todo.txt. + on line NR in todo.txt. - done ITEM#[, ITEM#, ITEM#, ...] - do ITEM#[, ITEM#, ITEM#, ...] - Marks task(s) on line ITEM# as done in todo.txt. + done NR [NR ...] + do NR [NR ...] + Marks task(s) on line NR as done in todo.txt. help [ACTION...] Display help about usage, options, built-in and add-on actions, @@ -266,26 +266,26 @@ actionsHelp() todo.txt. If TERM specified, considers only tasks that contain TERM(s). - move ITEM# DEST [SRC] - mv ITEM# DEST [SRC] - Moves a line from source text file (SRC) to destination text file (DEST). + move NR DEST [SRC] + mv NR DEST [SRC] + Moves the line NR from source text file (SRC) to destination text file (DEST). Both source and destination file must be located in the directory defined in the configuration directory. When SRC is not defined it's by default todo.txt. - prepend ITEM# "TEXT TO PREPEND" - prep ITEM# "TEXT TO PREPEND" - Adds TEXT TO PREPEND to the beginning of the task on line ITEM#. + prepend NR "TEXT TO PREPEND" + prep NR "TEXT TO PREPEND" + Adds TEXT TO PREPEND to the beginning of the task on line NR. Quotes optional. - pri ITEM# PRIORITY - p ITEM# PRIORITY - Adds PRIORITY to task on line ITEM#. If the task is already + pri NR PRIORITY + p NR PRIORITY + Adds PRIORITY to task on line NR. If the task is already prioritized, replaces current priority with new PRIORITY. PRIORITY must be a letter between A and Z. - replace ITEM# "UPDATED TODO" - Replaces task on line ITEM# with UPDATED TODO. + replace NR "UPDATED TODO" + Replaces task on line NR with UPDATED TODO. report Adds the number of open tasks and done tasks to report.txt. @@ -495,6 +495,7 @@ replaceOrPrepend() echo "$item $newtodo" ;; esac + fi } @@ -906,7 +907,7 @@ getPadding() _format() { # Parameters: $1: todo input file; when empty formats stdin - # $2: ITEM# number width; if empty auto-detects from $1 / $TODO_FILE. + # $2: NR number width; if empty auto-detects from $1 / $TODO_FILE. # Precondition: None # Postcondition: $NUMTASKS and $TOTALTASKS contain statistics (unless $TODOTXT_VERBOSE=0). @@ -1116,9 +1117,10 @@ case $action in ;; "addto" ) - [ -z "$2" ] && die "usage: $TODO_SH addto DEST \"TODO ITEM\"" + errmsg="usage: $TODO_SH addto DEST \"TODO ITEM\"" + [ -z "$2" ] && die "$errmsg" dest="$TODO_DIR/$2" - [ -z "$3" ] && die "usage: $TODO_SH addto DEST \"TODO ITEM\"" + [ -z "$3" ] && die "$errmsg" shift shift input=$* @@ -1131,7 +1133,7 @@ case $action in ;; "append" | "app" ) - errmsg="usage: $TODO_SH append ITEM# \"TEXT TO APPEND\"" + errmsg="usage: $TODO_SH append NR \"TEXT TO APPEND\"" shift; item=$1; shift getTodo "$item" @@ -1169,7 +1171,7 @@ case $action in "del" | "rm" ) # replace deleted line with a blank line when TODOTXT_PRESERVE_LINE_NUMBERS is 1 - errmsg="usage: $TODO_SH del ITEM# [TERM]" + errmsg="usage: $TODO_SH del NR [TERM]" item=$2 getTodo "$item" @@ -1211,7 +1213,7 @@ case $action in ;; "depri" | "dp" ) - errmsg="usage: $TODO_SH depri ITEM#[, ITEM#, ITEM#, ...]" + errmsg="usage: $TODO_SH depri NR [NR ...]" shift; [ $# -eq 0 ] && die "$errmsg" @@ -1237,7 +1239,7 @@ case $action in ;; "do" | "done" ) - errmsg="usage: $TODO_SH do ITEM#[, ITEM#, ITEM#, ...]" + errmsg="usage: $TODO_SH do NR [NR ...]" # shift so we get arguments to the do request shift; [ "$#" -eq 0 ] && die "$errmsg" @@ -1357,7 +1359,7 @@ case $action in "move" | "mv" ) # replace moved line with a blank line when TODOTXT_PRESERVE_LINE_NUMBERS is 1 - errmsg="usage: $TODO_SH mv ITEM# DEST [SRC]" + errmsg="usage: $TODO_SH mv NR DEST [SRC]" item=$2 dest="$TODO_DIR/$3" src="$TODO_DIR/$4" @@ -1391,7 +1393,7 @@ case $action in ;; "prepend" | "prep" ) - errmsg="usage: $TODO_SH prepend ITEM# \"TEXT TO PREPEND\"" + errmsg="usage: $TODO_SH prepend NR \"TEXT TO PREPEND\"" replaceOrPrepend 'prepend' "$@" ;; @@ -1402,7 +1404,7 @@ case $action in item=$1 newpri=$( printf "%s\n" "$2" | tr '[:lower:]' '[:upper:]' ) - errmsg="usage: $TODO_SH pri ITEM# PRIORITY[, ITEM# PRIORITY, ...] + errmsg="usage: $TODO_SH pri NR PRIORITY [NR PRIORITY ...] note: PRIORITY must be anywhere from A to Z." [ "$#" -lt 2 ] && die "$errmsg" @@ -1438,7 +1440,7 @@ note: PRIORITY must be anywhere from A to Z." ;; "replace" ) - errmsg="usage: $TODO_SH replace ITEM# \"UPDATED ITEM\"" + errmsg="usage: $TODO_SH replace NR \"UPDATED ITEM\"" replaceOrPrepend 'replace' "$@" ;; diff --git a/todo_completion b/todo_completion index 6f67c2fa..3287efea 100755 --- a/todo_completion +++ b/todo_completion @@ -25,7 +25,7 @@ _todo() elif [[ $COMP_CWORD -gt 2 && ( \ "${COMP_WORDS[COMP_CWORD-2]}" =~ ^($MOVE_COMMAND_PATTERN${_todo_file2_actions:+|${_todo_file2_actions}})$ || \ "${COMP_WORDS[COMP_CWORD-3]}" =~ ^($MOVE_COMMAND_PATTERN${_todo_file3_actions:+|${_todo_file3_actions}})$ ) ]]; then - # "move ITEM# DEST [SRC]" has file arguments on positions 2 and 3. + # "move NR DEST [SRC]" has file arguments on positions 2 and 3. completions=$(eval TODOTXT_VERBOSE=0 $_todo_sh command listfile 2>/dev/null) else case "$prev" in From 635bc2fa0a271237f4d610e88c71fedc48e10b0d Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Thu, 26 Dec 2024 12:21:10 +0100 Subject: [PATCH 50/55] Documentation: Update changelog Closes #159 --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73cf4d45..ed4ed586 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +### Added +- `TODOTXT_DEFAULT_ACTION` now also allows action parameters ([#159], [#407]) + ## [2.13.0] - 2024-12-25 ### Added @@ -513,6 +516,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. [#8]: https://github.com/todotxt/todo.txt-cli/pull/8 [#148]: https://github.com/todotxt/todo.txt-cli/pull/148 [#156]: https://github.com/todotxt/todo.txt-cli/pull/156 +[#159]: https://github.com/todotxt/todo.txt-cli/pull/159 [#160]: https://github.com/todotxt/todo.txt-cli/pull/160 [#169]: https://github.com/todotxt/todo.txt-cli/pull/169 [#217]: https://github.com/todotxt/todo.txt-cli/pull/217 @@ -536,3 +540,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. [#354]: https://github.com/todotxt/todo.txt-cli/pull/354 [#359]: https://github.com/todotxt/todo.txt-cli/pull/359 [#386]: https://github.com/todotxt/todo.txt-cli/pull/386 +[#407]: https://github.com/todotxt/todo.txt-cli/pull/407 From 84d18c12ff4d7c9cc77c029386b65df7fd1dbc4c Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Thu, 26 Dec 2024 12:21:57 +0100 Subject: [PATCH 51/55] todo.cfg: Cosmetics: Don't overload "parameters" (use "arguments"), drop trailing spaces --- todo.cfg | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/todo.cfg b/todo.cfg index 4341d904..8f50e4b8 100644 --- a/todo.cfg +++ b/todo.cfg @@ -97,7 +97,7 @@ export REPORT_FILE="$TODO_DIR/report.txt" # # export TODOTXT_FINAL_FILTER='cat' -## default actions -# Set a default action for calling todo.sh without parameters. -# Also allows for parameters for the action. +## default actions +# Set a default action for calling todo.sh without arguments. +# Also allows for parameters for the action. # export TODOTXT_DEFAULT_ACTION='' From 0e7c0915227713685ecd5b5cb95e14f7b12ec614 Mon Sep 17 00:00:00 2001 From: chrysle <96722107+chrysle@users.noreply.github.com> Date: Thu, 26 Dec 2024 12:36:12 +0100 Subject: [PATCH 52/55] Added status messages for listaddons and file test (#403) --- tests/t8010-listaddons.sh | 12 ++++++++++++ todo.sh | 16 +++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/tests/t8010-listaddons.sh b/tests/t8010-listaddons.sh index a0426c5a..66e992fa 100755 --- a/tests/t8010-listaddons.sh +++ b/tests/t8010-listaddons.sh @@ -9,12 +9,16 @@ This test checks listing of custom actions. test_todo_session 'no custom actions' <>> todo.sh listaddons +TODO: '$TODO_ACTIONS_DIR' does not exist. +=== 1 EOF make_action "foo" test_todo_session 'one custom action' <>> todo.sh listaddons foo +-- +TODO: 1 valid addon actions found. EOF make_action "bar" @@ -26,6 +30,8 @@ bar foo ls quux +-- +TODO: 4 valid addon actions found. EOF invalidate_action .todo.actions.d/foo t8010.4 @@ -34,6 +40,8 @@ test_todo_session 'nonexecutable action' <&2 "$*" @@ -878,7 +879,7 @@ _list() { local FILE="$1" ## If the file starts with a "/" use absolute path. Otherwise, ## try to find it in either $TODO_DIR or using a relative path - if [ "${1:0:1}" == / ]; then + if [ "${1:0:1}" == / ] && [ -f "$FILE" ]; then ## Absolute path src="$FILE" elif [ -f "$TODO_DIR/$FILE" ]; then @@ -1523,14 +1524,27 @@ note: PRIORITY must be anywhere from A to Z." "listaddons" ) if [ -d "$TODO_ACTIONS_DIR" ]; then cd "$TODO_ACTIONS_DIR" || exit $? + actionsCnt=0 for action in * do if [ -f "$action" ] && [ -x "$action" ]; then echo "$action" + ((actionsCnt+=1)) elif [ -d "$action" ] && [ -x "$action/$action" ]; then echo "$action" + ((actionsCnt+=1)) fi done + if ! [ "$actionsCnt" -gt 0 ]; then + die "TODO: '$TODO_ACTIONS_DIR' does not contain valid actions." + else + if [ "$TODOTXT_VERBOSE" -gt 0 ]; then + echo "--" + echo "TODO: $actionsCnt valid addon actions found." + fi + fi + else + die "TODO: '$TODO_ACTIONS_DIR' does not exist." fi ;; From 616e7a16bee5304b32237b0dc872215e67b0a2f9 Mon Sep 17 00:00:00 2001 From: chrysle <96722107+chrysle@users.noreply.github.com> Date: Thu, 26 Dec 2024 12:37:20 +0100 Subject: [PATCH 53/55] Added warning message for todo.sh archive (#399) --- tests/t1900-archive.sh | 5 +++++ tests/t1950-report.sh | 6 +++--- tests/t2200-no-done-report-files.sh | 2 +- tests/t9999-testsuite_example.sh | 2 +- todo.sh | 15 ++++++++++----- 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/tests/t1900-archive.sh b/tests/t1900-archive.sh index af95ba0c..9b5f00fb 100755 --- a/tests/t1900-archive.sh +++ b/tests/t1900-archive.sh @@ -32,4 +32,9 @@ test_todo_session 'list after archive' <>> todo.sh archive +TODO: $HOME/todo.txt does not contain any done tasks. +EOF + test_done diff --git a/tests/t1950-report.sh b/tests/t1950-report.sh index 6b88d658..9546e043 100755 --- a/tests/t1950-report.sh +++ b/tests/t1950-report.sh @@ -16,7 +16,7 @@ EOF test_todo_session 'create new report' <>> todo.sh report -TODO: $HOME/todo.txt archived. +TODO: $HOME/todo.txt does not contain any done tasks. 2009-02-13T04:40:00 5 0 TODO: Report file updated. @@ -38,7 +38,7 @@ x 2009-02-13 smell the coffee +wakeup TODO: $HOME/todo.txt archived. >>> todo.sh report -TODO: $HOME/todo.txt archived. +TODO: $HOME/todo.txt does not contain any done tasks. 2009-02-13T04:40:00 4 1 TODO: Report file updated. @@ -83,7 +83,7 @@ test_todo_session 'report is unchanged when no changes' <>> todo.sh report -TODO: $HOME/todo.txt archived. +TODO: $HOME/todo.txt does not contain any done tasks. 2009-02-13T04:40:00 3 2 TODO: Report file is up-to-date. diff --git a/tests/t2200-no-done-report-files.sh b/tests/t2200-no-done-report-files.sh index 306fc4d2..feb74304 100755 --- a/tests/t2200-no-done-report-files.sh +++ b/tests/t2200-no-done-report-files.sh @@ -38,7 +38,7 @@ test_expect_success 'no done file has been created by the archiving' '[ ! -e don test_todo_session 'perform report' <>> todo.sh -d test.cfg report -TODO: ./todo.txt archived. +TODO: ./todo.txt does not contain any done tasks. 2009-02-13T04:40:00 0 0 TODO: Report file updated. EOF diff --git a/tests/t9999-testsuite_example.sh b/tests/t9999-testsuite_example.sh index cdc7a901..c0aa6b09 100755 --- a/tests/t9999-testsuite_example.sh +++ b/tests/t9999-testsuite_example.sh @@ -85,7 +85,7 @@ TODO: $HOME/todo.txt archived. TODO: 5 of 5 tasks shown >>> todo.sh report -TODO: $HOME/todo.txt archived. +TODO: $HOME/todo.txt does not contain any done tasks. 2009-02-13T04:40:00 5 1 TODO: Report file updated. diff --git a/todo.sh b/todo.sh index a55310d0..130ed3f2 100755 --- a/todo.sh +++ b/todo.sh @@ -1172,11 +1172,16 @@ case $action in "archive" ) # defragment blank lines sed -i.bak -e '/./!d' "$TODO_FILE" - [ "$TODOTXT_VERBOSE" -gt 0 ] && grep "^x " "$TODO_FILE" - grep "^x " "$TODO_FILE" >> "$DONE_FILE" - sed -i.bak '/^x /d' "$TODO_FILE" - if [ "$TODOTXT_VERBOSE" -gt 0 ]; then - echo "TODO: $TODO_FILE archived." + if grep "^x " "$TODO_FILE" >> "$DONE_FILE"; then + [ "$TODOTXT_VERBOSE" -gt 0 ] && grep "^x " "$TODO_FILE" + sed -i.bak '/^x /d' "$TODO_FILE" + if [ "$TODOTXT_VERBOSE" -gt 0 ]; then + echo "TODO: $TODO_FILE archived." + fi + else + if [ "$TODOTXT_VERBOSE" -gt 0 ]; then + echo "TODO: $TODO_FILE does not contain any done tasks." + fi fi ;; From 85f14a4704a33eed83ed34473c8d6fefdf6d9c76 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Wed, 21 Feb 2024 15:23:43 +0100 Subject: [PATCH 54/55] Tests: Add coverage for listing projects at various positions To investigate whether todotxt/todo.txt-cli#430 can be reproduced. --- tests/t1320-listproj.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/t1320-listproj.sh b/tests/t1320-listproj.sh index 13d28b15..430193f5 100755 --- a/tests/t1320-listproj.sh +++ b/tests/t1320-listproj.sh @@ -74,6 +74,24 @@ test_todo_session 'listproj with context' < todo.txt <>> todo.sh listproj ++flowers ++roses +EOF + cat > todo.txt < Date: Thu, 13 Jan 2022 00:05:38 +0900 Subject: [PATCH 55/55] README.md: replace hardcoded path to command substitution Signed-off-by: KOSHIKAWA Kenichi --- README.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/README.md b/README.md index 67e15542..877981ea 100644 --- a/README.md +++ b/README.md @@ -24,11 +24,7 @@ Download the latest stable [release][release] for use on your desktop or server. ```shell brew install todo-txt -# For macOS on x86 CPU -cp -n /usr/local/opt/todo-txt/todo.cfg ~/.todo.cfg - -# For macOS on arm CPU -cp -n /opt/homebrew/opt/todo-txt/todo.cfg ~/.todo.cfg +cp -n $(brew --prefix)/opt/todo-txt/todo.cfg ~/.todo.cfg ``` **Note**: The `-n` flag for `cp` makes sure you do not overwrite an existing file.