From 780c1142e0d91e5cfbc29e2036ae18392d34d934 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Mon, 3 Apr 2023 20:56:18 +0200 Subject: [PATCH] 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 42698db5..5968b9e7 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