From fac5533b9676495ee763f3565920871a8c45ae97 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Fri, 27 Apr 2012 09:25:00 +0200 Subject: [PATCH 1/9] Tests: Add test for listaddons. --- tests/t8010-listaddons.sh | 54 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100755 tests/t8010-listaddons.sh diff --git a/tests/t8010-listaddons.sh b/tests/t8010-listaddons.sh new file mode 100755 index 0000000..2c1dc17 --- /dev/null +++ b/tests/t8010-listaddons.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +test_description='listaddons functionality + +This test checks listing of custom actions. +' +. ./test-lib.sh + +unset TODO_ACTIONS_DIR +mkdir .todo.actions.d +make_action() +{ + cat > ".todo.actions.d/$1" <<- EOF + #!/bin/bash + echo "custom action $1" +EOF +chmod +x ".todo.actions.d/$1" +} + +test_todo_session 'no custom actions' <>> todo.sh listaddons +EOF + +make_action "foo" +test_todo_session 'one custom action' <>> todo.sh listaddons +foo +EOF + +make_action "bar" +make_action "ls" +make_action "quux" +test_todo_session 'multiple custom actions' <>> todo.sh listaddons +bar +foo +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. +if [ -x .todo.actions.d/foo ]; then + SKIP_TESTS="${SKIP_TESTS}${SKIP_TESTS+ }t8010.4" +fi +test_todo_session 'nonexecutable action' <>> todo.sh listaddons +bar +ls +quux +EOF + +test_done From 7ab90476f73d89dba2d0327006daf3f452edafbe Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Fri, 27 Apr 2012 11:34:46 +0200 Subject: [PATCH 2/9] Tests: Add test for ordinary help. --- tests/t2100-help.sh | 55 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100755 tests/t2100-help.sh diff --git a/tests/t2100-help.sh b/tests/t2100-help.sh new file mode 100755 index 0000000..16de5a0 --- /dev/null +++ b/tests/t2100-help.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# + +test_description='help functionality + +This test covers the help output. +' +. ./test-lib.sh + +unset TODO_ACTIONS_DIR + +# Note: To avoid having to adapt the test whenever the help documentation +# slightly changes, only check for the section headers. +test_todo_session 'help output' <>> todo.sh help | sed '/^ \w/!d' + Usage: todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description] + Options: + Built-in Actions: +EOF + +test_todo_session 'verbose help output' <>> todo.sh -v help | sed '/^ \w/!d' + Usage: todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description] + Options: + Built-in Actions: +EOF + +test_todo_session 'very verbose help output' <>> todo.sh -vv help | sed '/^ \w/!d' + Usage: todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description] + Options: + Environment variables: + Built-in Actions: +EOF + +mkdir .todo.actions.d +make_action() +{ + cat > ".todo.actions.d/$1" <<- EOF + #!/bin/bash + echo "custom action $1" +EOF +chmod +x ".todo.actions.d/$1" +} + +make_action "foo" +test_todo_session 'help output with custom action' <>> todo.sh -v help | sed '/^ \w/!d' + Usage: todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description] + Options: + Built-in Actions: + Add-on Actions: +EOF + +test_done From 42424d58817383d94fef85b6ba301dc3bb0cfd7d Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Fri, 27 Apr 2012 11:48:01 +0200 Subject: [PATCH 3/9] ENH: Print usage help for custom action. Currently, the only way to get usage help for a custom action is to use "todo.sh help" and scroll / search for the action name. (Or try to call the action without / with invalid parameters to hopefully get a one-line syntax summary.) This extends the help command to print the usage of optionally passed custom action names. --- tests/t8020-actions-help.sh | 71 +++++++++++++++++++++++++++++++++++++ todo.sh | 33 ++++++++++++++--- 2 files changed, 99 insertions(+), 5 deletions(-) create mode 100755 tests/t8020-actions-help.sh diff --git a/tests/t8020-actions-help.sh b/tests/t8020-actions-help.sh new file mode 100755 index 0000000..6f6746b --- /dev/null +++ b/tests/t8020-actions-help.sh @@ -0,0 +1,71 @@ +#!/bin/bash + +test_description='actions help functionality + +This test checks listing the usage help of a custom action. +' +. ./test-lib.sh + +unset TODO_ACTIONS_DIR +test_todo_session 'custom action help with no custom action directory' <<'EOF' +>>> todo.sh help foo +TODO: No actions directory exists. +=== 1 +EOF + +mkdir .todo.actions.d +make_action() +{ + cat > ".todo.actions.d/$1" <>> todo.sh help foo + foo ITEM#[, ITEM#, ...] [TERM...] + This custom action does foo. +\ + +>>> todo.sh help bar + bar ITEM#[, ITEM#, ...] [TERM...] + This custom action does bar. +\ +EOF + +test_todo_session 'multiple custom actions help' <<'EOF' +>>> todo.sh help foo bar + foo ITEM#[, ITEM#, ...] [TERM...] + This custom action does foo. +\ + bar ITEM#[, ITEM#, ...] [TERM...] + This custom action does bar. +\ +EOF + +test_todo_session 'nonexisting action help' <<'EOF' +>>> todo.sh help doesnotexist +TODO: No add-on action "doesnotexist" exists. +=== 1 + +>>> todo.sh help foo doesnotexist bar + foo ITEM#[, ITEM#, ...] [TERM...] + This custom action does foo. +\ +TODO: No add-on action "doesnotexist" exists. +=== 1 +EOF + +test_done diff --git a/todo.sh b/todo.sh index 4837120..8d1080e 100755 --- a/todo.sh +++ b/todo.sh @@ -302,6 +302,23 @@ addonHelp() fi } +addonUsage() +{ + if [ -d "$TODO_ACTIONS_DIR" ]; then + for actionName + do + action="${TODO_ACTIONS_DIR}/${actionName}" + if [ -f "$action" -a -x "$action" ]; then + "$action" usage + else + die "TODO: No add-on action \"${actionName}\" exists." + fi + done + else + die "TODO: No actions directory exists." + fi +} + die() { echo "$*" @@ -1075,13 +1092,19 @@ case $action in ;; "help" ) - if [ -t 1 ] ; then # STDOUT is a TTY - if which "${PAGER:-less}" >/dev/null 2>&1; then - # we have a working PAGER (or less as a default) - help | "${PAGER:-less}" && exit 0 + shift ## Was help; new $1 is first help topic / action name + if [ $# -gt 0 ]; then + # Don't use PAGER here; we don't expect much usage output from one / few actions. + addonUsage "$@" + else + if [ -t 1 ] ; then # STDOUT is a TTY + if which "${PAGER:-less}" >/dev/null 2>&1; then + # we have a working PAGER (or less as a default) + help | "${PAGER:-less}" && exit 0 + fi fi + help # just in case something failed above, we go ahead and just spew to STDOUT fi - help # just in case something failed above, we go ahead and just spew to STDOUT ;; "shorthelp" ) From 99e5e57a75e5a6f938882d231d0b53212f7c42d4 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Fri, 27 Apr 2012 12:42:10 +0200 Subject: [PATCH 4/9] Refactoring: Extract make_action into actions-test-lib.sh. This reduces the duplication in the individual test files. --- tests/actions-test-lib.sh | 18 ++++++++++++++++++ tests/t2100-help.sh | 13 +------------ tests/t8000-actions.sh | 12 +----------- tests/t8010-listaddons.sh | 12 +----------- tests/t8020-actions-help.sh | 18 +----------------- 5 files changed, 22 insertions(+), 51 deletions(-) create mode 100755 tests/actions-test-lib.sh diff --git a/tests/actions-test-lib.sh b/tests/actions-test-lib.sh new file mode 100755 index 0000000..2928261 --- /dev/null +++ b/tests/actions-test-lib.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +make_action() +{ + unset TODO_ACTIONS_DIR + [ -d .todo.actions.d ] || mkdir .todo.actions.d + cat > ".todo.actions.d/$1" < ".todo.actions.d/$1" <<- EOF - #!/bin/bash - echo "custom action $1" -EOF -chmod +x ".todo.actions.d/$1" -} - make_action "foo" test_todo_session 'help output with custom action' <>> todo.sh -v help | sed '/^ \w/!d' diff --git a/tests/t8000-actions.sh b/tests/t8000-actions.sh index 5c8b7d5..763c4e9 100755 --- a/tests/t8000-actions.sh +++ b/tests/t8000-actions.sh @@ -4,19 +4,9 @@ test_description='custom actions functionality This test covers the contract between todo.sh and custom actions. ' +. ./actions-test-lib.sh . ./test-lib.sh -unset TODO_ACTIONS_DIR -mkdir .todo.actions.d -make_action() -{ - cat > ".todo.actions.d/$1" <<- EOF - #!/bin/bash - echo "custom action $1" -EOF -chmod +x ".todo.actions.d/$1" -} - make_action "foo" test_todo_session 'executable action' <>> todo.sh foo diff --git a/tests/t8010-listaddons.sh b/tests/t8010-listaddons.sh index 2c1dc17..ed0cb05 100755 --- a/tests/t8010-listaddons.sh +++ b/tests/t8010-listaddons.sh @@ -4,19 +4,9 @@ test_description='listaddons functionality This test checks listing of custom actions. ' +. ./actions-test-lib.sh . ./test-lib.sh -unset TODO_ACTIONS_DIR -mkdir .todo.actions.d -make_action() -{ - cat > ".todo.actions.d/$1" <<- EOF - #!/bin/bash - echo "custom action $1" -EOF -chmod +x ".todo.actions.d/$1" -} - test_todo_session 'no custom actions' <>> todo.sh listaddons EOF diff --git a/tests/t8020-actions-help.sh b/tests/t8020-actions-help.sh index 6f6746b..3d6ee1f 100755 --- a/tests/t8020-actions-help.sh +++ b/tests/t8020-actions-help.sh @@ -4,31 +4,15 @@ test_description='actions help functionality This test checks listing the usage help of a custom action. ' +. ./actions-test-lib.sh . ./test-lib.sh -unset TODO_ACTIONS_DIR test_todo_session 'custom action help with no custom action directory' <<'EOF' >>> todo.sh help foo TODO: No actions directory exists. === 1 EOF -mkdir .todo.actions.d -make_action() -{ - cat > ".todo.actions.d/$1" < Date: Fri, 27 Apr 2012 13:37:14 +0200 Subject: [PATCH 5/9] ENH: Print usage help for all passed actions. Extend the support for specific usage help to built-in actions. --- tests/t2110-help-action.sh | 66 +++++++++++++++++++++++++++++++++++++ tests/t8020-actions-help.sh | 29 +++++++++++++--- todo.sh | 45 ++++++++++++++----------- 3 files changed, 117 insertions(+), 23 deletions(-) create mode 100755 tests/t2110-help-action.sh diff --git a/tests/t2110-help-action.sh b/tests/t2110-help-action.sh new file mode 100755 index 0000000..06d910c --- /dev/null +++ b/tests/t2110-help-action.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +test_description='built-in actions help functionality + +This test checks listing the usage help of a built-in action. +' +. ./test-lib.sh + +test_todo_session 'nonexisting action help' <<'EOF' +>>> todo.sh help doesnotexist +TODO: No action "doesnotexist" exists. +=== 1 + +>>> todo.sh help hel +TODO: No action "hel" exists. +=== 1 + +>>> todo.sh help h +TODO: No action "h" exists. +=== 1 +EOF + +test_todo_session 'single action help' <<'EOF' +>>> todo.sh help shorthelp + shorthelp + List the one-line usage of all built-in and add-on actions. +\ +EOF + +test_todo_session 'multiple actions help' <<'EOF' +>>> todo.sh help shorthelp append + 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#. + 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#. + Quotes optional. +\ + +>>> todo.sh help app + app ITEM# "TEXT TO APPEND" + Adds TEXT TO APPEND to the end of the task on line ITEM#. + Quotes optional. +\ +EOF + +test_todo_session 'mixed existing and nonexisting action help' <<'EOF' +>>> todo.sh help shorthelp doesnotexist list + shorthelp + List the one-line usage of all built-in and add-on actions. +\ +TODO: No action "doesnotexist" exists. +=== 1 +EOF + +test_done diff --git a/tests/t8020-actions-help.sh b/tests/t8020-actions-help.sh index 3d6ee1f..cc79bc1 100755 --- a/tests/t8020-actions-help.sh +++ b/tests/t8020-actions-help.sh @@ -1,6 +1,6 @@ #!/bin/bash -test_description='actions help functionality +test_description='custom actions help functionality This test checks listing the usage help of a custom action. ' @@ -9,12 +9,13 @@ This test checks listing the usage help of a custom action. test_todo_session 'custom action help with no custom action directory' <<'EOF' >>> todo.sh help foo -TODO: No actions directory exists. +TODO: No action "foo" exists. === 1 EOF make_action "foo" make_action "bar" +make_action "ls" make_action "quux" test_todo_session 'custom action help' <<'EOF' @@ -41,15 +42,35 @@ EOF test_todo_session 'nonexisting action help' <<'EOF' >>> todo.sh help doesnotexist -TODO: No add-on action "doesnotexist" exists. +TODO: No action "doesnotexist" exists. === 1 >>> todo.sh help foo doesnotexist bar foo ITEM#[, ITEM#, ...] [TERM...] This custom action does foo. \ -TODO: No add-on action "doesnotexist" exists. +TODO: No action "doesnotexist" exists. === 1 EOF +test_todo_session 'mixed built-in and custom actions help' <<'EOF' +>>> todo.sh help foo shorthelp bar + foo ITEM#[, ITEM#, ...] [TERM...] + This custom action does foo. +\ + shorthelp + List the one-line usage of all built-in and add-on actions. +\ + bar ITEM#[, ITEM#, ...] [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...] + This custom action does ls. +\ +EOF + test_done diff --git a/todo.sh b/todo.sh index 8d1080e..807ac2c 100755 --- a/todo.sh +++ b/todo.sh @@ -54,7 +54,7 @@ shorthelp() del|rm ITEM# [TERM] depri|dp ITEM#[, ITEM#, ITEM#, ...] do ITEM#[, ITEM#, ITEM#, ...] - help + help [ACTION...] list|ls [TERM...] listall|lsa [TERM...] listaddons @@ -154,6 +154,13 @@ help() EndVerboseHelp + actionsHelp + addonHelp + exit 1 +} + +actionsHelp() +{ cat <<-EndActionsHelp Built-in Actions: add "THING I NEED TO DO +project @context" @@ -200,8 +207,9 @@ help() do ITEM#[, ITEM#, ITEM#, ...] Marks task(s) on line ITEM# as done in todo.txt. - help - Display this help message. + help [ACTION...] + Display help about usage, options, built-in and add-on actions, + or just the usage help for the passed ACTION(s). list [TERM...] ls [TERM...] @@ -278,9 +286,6 @@ help() List the one-line usage of all built-in and add-on actions. EndActionsHelp - - addonHelp - exit 1 } addonHelp() @@ -302,21 +307,23 @@ addonHelp() fi } -addonUsage() +actionUsage() { - if [ -d "$TODO_ACTIONS_DIR" ]; then - for actionName - do - action="${TODO_ACTIONS_DIR}/${actionName}" - if [ -f "$action" -a -x "$action" ]; then - "$action" usage + for actionName + do + action="${TODO_ACTIONS_DIR}/${actionName}" + if [ -f "$action" -a -x "$action" ]; then + "$action" usage + else + builtinActionUsage=$(actionsHelp | sed -ne "/^ ${actionName//\//\\/}\\( \\|\$\\)/,/^\$/p") + if [ "$builtinActionUsage" ]; then + echo "$builtinActionUsage" + echo else - die "TODO: No add-on action \"${actionName}\" exists." + die "TODO: No action \"${actionName}\" exists." fi - done - else - die "TODO: No actions directory exists." - fi + fi + done } die() @@ -1095,7 +1102,7 @@ case $action in shift ## Was help; new $1 is first help topic / action name if [ $# -gt 0 ]; then # Don't use PAGER here; we don't expect much usage output from one / few actions. - addonUsage "$@" + actionUsage "$@" else if [ -t 1 ] ; then # STDOUT is a TTY if which "${PAGER:-less}" >/dev/null 2>&1; then From f2b97340474700f1eff53fae97f6b80bf32da2a7 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Fri, 27 Apr 2012 13:40:52 +0200 Subject: [PATCH 6/9] FIX: Always return success after help. Usually (i.e. when a pager is available), the help() output is piped through the pager, and then the return code will be the one of the pager. So the exit 1 at the end of help() doesn't make much sense, and should be abolished for consistency. --- todo.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/todo.sh b/todo.sh index 807ac2c..2a77dc5 100755 --- a/todo.sh +++ b/todo.sh @@ -156,7 +156,6 @@ help() EndVerboseHelp actionsHelp addonHelp - exit 1 } actionsHelp() From 7acb52119096c5e5a1615c477069561f9060da5c Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Fri, 27 Apr 2012 14:29:29 +0200 Subject: [PATCH 7/9] Add action argument for help to todo_completion. Note that this is not perfect, as it only handles completing a single action after "help", but that should over the most important use case. --- tests/actions-test-lib.sh | 0 tests/t6100-completion-help.sh | 20 ++++++++++++++++++++ todo_completion | 2 ++ 3 files changed, 22 insertions(+) mode change 100755 => 100644 tests/actions-test-lib.sh create mode 100755 tests/t6100-completion-help.sh diff --git a/tests/actions-test-lib.sh b/tests/actions-test-lib.sh old mode 100755 new mode 100644 diff --git a/tests/t6100-completion-help.sh b/tests/t6100-completion-help.sh new file mode 100755 index 0000000..079099f --- /dev/null +++ b/tests/t6100-completion-help.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# + +test_description='Bash help completion functionality + +This test checks todo_completion of actions for usage help. +' +. ./actions-test-lib.sh +. ./test-lib.sh +make_action "zany" +make_action "aardvark" + +readonly ACTIONS='add a addto addm append app archive command del rm depri dp do help list ls listaddons listall lsa listcon lsc listfile lf listpri lsp listproj lsprj move mv prepend prep pri p replace report shorthelp' +readonly ADDONS='aardvark zany' + +test_todo_completion 'all actions after help' 'todo.sh help ' "$ACTIONS $ADDONS" +test_todo_completion 'all actions after command help' 'todo.sh command help ' "$ACTIONS $ADDONS" +test_todo_completion 'actions beginning with a' 'todo.sh help a' 'add a addto addm append app archive aardvark' + +test_done diff --git a/todo_completion b/todo_completion index 3f9d308..80abc68 100644 --- a/todo_completion +++ b/todo_completion @@ -28,6 +28,8 @@ _todo() case "$prev" in command) completions=$COMMANDS;; + help) + completions="$COMMANDS $(eval TODOTXT_VERBOSE=0 $_todo_sh command listaddons)";; addto|listfile|lf) completions=$(eval TODOTXT_VERBOSE=0 $_todo_sh command listfile);; -*) completions="$COMMANDS $(eval TODOTXT_VERBOSE=0 $_todo_sh command listaddons) $OPTS";; From c0c93c8c0c1849ddb2492910cafb6dad4a3468ad Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Fri, 11 May 2012 09:05:44 +0200 Subject: [PATCH 8/9] FIX: Adapt test for OS X. POSIX sed doesn't understand the \w atom; use [A-Z] instead; it's also more precise. --- tests/t2100-help.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/t2100-help.sh b/tests/t2100-help.sh index 2ee8bed..38e7bb8 100755 --- a/tests/t2100-help.sh +++ b/tests/t2100-help.sh @@ -11,21 +11,21 @@ This test covers the help output. # Note: To avoid having to adapt the test whenever the help documentation # slightly changes, only check for the section headers. test_todo_session 'help output' <>> todo.sh help | sed '/^ \w/!d' +>>> todo.sh help | sed '/^ [A-Z]/!d' Usage: todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description] Options: Built-in Actions: EOF test_todo_session 'verbose help output' <>> todo.sh -v help | sed '/^ \w/!d' +>>> todo.sh -v help | sed '/^ [A-Z]/!d' Usage: todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description] Options: Built-in Actions: EOF test_todo_session 'very verbose help output' <>> todo.sh -vv help | sed '/^ \w/!d' +>>> todo.sh -vv help | sed '/^ [A-Z]/!d' Usage: todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description] Options: Environment variables: @@ -34,7 +34,7 @@ EOF make_action "foo" test_todo_session 'help output with custom action' <>> todo.sh -v help | sed '/^ \w/!d' +>>> todo.sh -v help | sed '/^ [A-Z]/!d' Usage: todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description] Options: Built-in Actions: From e48ad81ecc2af64a03b8bd427ffff8d065723a8c Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Fri, 11 May 2012 21:18:43 +0200 Subject: [PATCH 9/9] FIX: Built-in action help for OS X. POSIX sed doesn't support regex branches; I don't want to switch to modern regexp (via -E), since that makes more characters special. Rather, expand the alternatives into two sed commands. --- todo.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/todo.sh b/todo.sh index 2a77dc5..766672a 100755 --- a/todo.sh +++ b/todo.sh @@ -314,7 +314,7 @@ actionUsage() if [ -f "$action" -a -x "$action" ]; then "$action" usage else - builtinActionUsage=$(actionsHelp | sed -ne "/^ ${actionName//\//\\/}\\( \\|\$\\)/,/^\$/p") + builtinActionUsage=$(actionsHelp | sed -n -e "/^ ${actionName//\//\\/} /,/^\$/p" -e "/^ ${actionName//\//\\/}$/,/^\$/p") if [ "$builtinActionUsage" ]; then echo "$builtinActionUsage" echo