From 194a062c2d07eb43a14182d9fb2e4c20c7051f72 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Mon, 9 Aug 2010 08:06:09 +0200 Subject: [PATCH 1/9] BUG: tr: extra operand `d' error caused by missing quoting Reported by Bill Goffe on the todotxt mailing list. --- todo.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/todo.sh b/todo.sh index 315987a..eba4b47 100755 --- a/todo.sh +++ b/todo.sh @@ -550,7 +550,7 @@ _addto() { if [ $TODOTXT_VERBOSE -gt 0 ]; then TASKNUM=$(sed -n '$ =' "$file") BASE=$(basename "$file") - PREFIX=$(echo ${BASE%%.[^.]*} | tr [a-z] [A-Z]) + PREFIX=$(echo ${BASE%%.[^.]*} | tr 'a-z' 'A-Z') echo "$TASKNUM $input" echo "${PREFIX}: $TASKNUM added." fi @@ -658,7 +658,7 @@ _list() { if [ $TODOTXT_VERBOSE -gt 0 ]; then BASE=$(basename "$FILE") - PREFIX=$(echo ${BASE%%.[^.]*} | tr [a-z] [A-Z]) + PREFIX=$(echo ${BASE%%.[^.]*} | tr 'a-z' 'A-Z') NUMTASKS=$( echo -ne "$filtered_items" | sed -n '$ =' ) TOTALTASKS=$( echo -ne "$items" | sed -n '$ =' ) From 824101defdf5b4104e789aa17456badde35f1a0d Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Thu, 21 Oct 2010 10:11:40 +0200 Subject: [PATCH 2/9] BUG: task listing aborted on embedded \c escape sequence Fixed by removing the -e option that causes the echo command to interpret escape characters. Coloring of done tasks (the only step in the _list pipeline that required this interpretation) has been moved into the AWK pipeline step which is responsible for the priority coloring, and which does the escape character interpretation internally. As a nice side effect, this shortening of the _list pipeline should also speed up the listing a wee bit. --- tests/t1340-listescapes.sh | 33 +++++++++++++++++++++++++++++++++ todo.sh | 22 +++++++++++----------- 2 files changed, 44 insertions(+), 11 deletions(-) create mode 100755 tests/t1340-listescapes.sh diff --git a/tests/t1340-listescapes.sh b/tests/t1340-listescapes.sh new file mode 100755 index 0000000..b4be9db --- /dev/null +++ b/tests/t1340-listescapes.sh @@ -0,0 +1,33 @@ +#!/bin/sh +# + +test_description='list with escape sequences + +This test checks listing of tasks that have embedded escape sequences in them. +' +. ./test-lib.sh + +# +# check aborted list output on \c escape sequence +# +cat > todo.txt <<'EOF' +first todo +second todo run C:\WINDOWS\sysnative\cscript.exe +third todo +EOF + +test_todo_session 'aborted list output on backslash-c' <<'EOF' +>>> todo.sh ls +1 first todo +2 second todo run C:\\\\WINDOWS\\\\sysnative\\\\cscript.exe +3 third todo +-- +TODO: 3 of 3 tasks shown + +>>> todo.sh ls 2 +2 second todo run C:\\\\WINDOWS\\\\sysnative\\\\cscript.exe +-- +TODO: 1 of 3 tasks shown +EOF + +test_done diff --git a/todo.sh b/todo.sh index eba4b47..c47b9a1 100755 --- a/todo.sh +++ b/todo.sh @@ -622,12 +622,12 @@ _list() { | grep -v "^[ 0-9]\+ *$" ) if [ "${filter_command}" ]; then - filtered_items=$(echo -ne "$items" | eval ${filter_command}) + filtered_items=$(echo -n "$items" | eval ${filter_command}) else filtered_items=$items fi filtered_items=$( - echo -ne "$filtered_items" \ + echo -n "$filtered_items" \ | sed ''' s/^ /00000/; s/^ /0000/; @@ -636,15 +636,15 @@ _list() { s/^ /0/; ''' \ | eval ${TODOTXT_SORT_COMMAND} \ - | sed ''' - /^[0-9]\{'$PADDING'\} x /s|^.*|'$COLOR_DONE'&'$DEFAULT'| - ''' \ | awk '''{ pos = match($0, /\([A-Z]\)/) - if( pos > 0 && match($0, /^[0-9]+ x /) != 1 ) { - clr=ENVIRON["PRI_" substr($0, pos+1, 1)] + if (match($0, /^[0-9]+ x /)) { + str = ENVIRON["COLOR_DONE"] $0 ENVIRON["DEFAULT"] + gsub(/\\+033/, "\033", str); print str + } else if (pos > 0) { + clr = ENVIRON["PRI_" substr($0, pos+1, 1)] str = ( clr ? clr : ENVIRON["PRI_X"] ) $0 ENVIRON["DEFAULT"] - gsub( /\\+033/, "\033", str) ; print str + gsub(/\\+033/, "\033", str); print str } else { print } }''' \ | sed ''' @@ -654,13 +654,13 @@ _list() { ''' \ | eval ${TODOTXT_FINAL_FILTER} \ ) - echo -ne "$filtered_items${filtered_items:+\n}" + [ "$filtered_items" ] && echo "$filtered_items" if [ $TODOTXT_VERBOSE -gt 0 ]; then BASE=$(basename "$FILE") PREFIX=$(echo ${BASE%%.[^.]*} | tr 'a-z' 'A-Z') - NUMTASKS=$( echo -ne "$filtered_items" | sed -n '$ =' ) - TOTALTASKS=$( echo -ne "$items" | sed -n '$ =' ) + NUMTASKS=$( echo -n "$filtered_items" | sed -n '$ =' ) + TOTALTASKS=$( echo -n "$items" | sed -n '$ =' ) echo "--" echo "${PREFIX}: ${NUMTASKS:-0} of ${TOTALTASKS:-0} tasks shown" From ce501c5362963a98a8d26fa0d4309e9c166a2958 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Thu, 21 Oct 2010 11:30:31 +0200 Subject: [PATCH 3/9] BUG: interpretation of \033 escape sequences in task The global substitution in the AWK highlighting of prioritized and done tasks also affected the task text itself, not just the inserted color definitions. Factored out the evaluation of the color variables and interpretation of \033 into a highlight() AWK function. Added test cases which check that \a, \t, \n, \x.. and \0.. escape characters in the task text are listed as-is, without interpretation. --- tests/t1340-listescapes.sh | 36 ++++++++++++++++++++++++++++++++++++ todo.sh | 27 ++++++++++++++++----------- 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/tests/t1340-listescapes.sh b/tests/t1340-listescapes.sh index b4be9db..e0682c3 100755 --- a/tests/t1340-listescapes.sh +++ b/tests/t1340-listescapes.sh @@ -7,6 +7,10 @@ This test checks listing of tasks that have embedded escape sequences in them. ' . ./test-lib.sh +# Note: The quadrupled escaped backslashes (even 8-fold for the escape color +# code) in the expected output are necessary due to (superfluous?!) +# interpretation of the expected output in the test library itself. + # # check aborted list output on \c escape sequence # @@ -30,4 +34,36 @@ TODO: 3 of 3 tasks shown TODO: 1 of 3 tasks shown EOF +# +# check various escape sequences +# +cat > todo.txt <<'EOF' +first todo with \\, \a and \t +second todo with \r\n line break +third todo with \x42\x55\x47 and \033[0;31m color codes \033[0;30m +EOF + +test_todo_session 'various escape sequences' <<'EOF' +>>> todo.sh ls +1 first todo with \\\\\\\\, \\\\a and \\\\t +2 second todo with \\\\r\\\\n line break +3 third todo with \\\\x42\\\\x55\\\\x47 and \\\\\\\\033[0;31m color codes \\\\\\\\033[0;30m +-- +TODO: 3 of 3 tasks shown +EOF + +# +# check embedding of actual color sequence +# +cat > todo.txt <<'EOF' +A task with  actual color  +EOF + +test_todo_session 'embedding of actual color sequence' <<'EOF' +>>> todo.sh ls +1 A task with  actual color  +-- +TODO: 1 of 1 tasks shown +EOF + test_done diff --git a/todo.sh b/todo.sh index c47b9a1..99320c9 100755 --- a/todo.sh +++ b/todo.sh @@ -636,17 +636,22 @@ _list() { s/^ /0/; ''' \ | eval ${TODOTXT_SORT_COMMAND} \ - | awk '''{ - pos = match($0, /\([A-Z]\)/) - if (match($0, /^[0-9]+ x /)) { - str = ENVIRON["COLOR_DONE"] $0 ENVIRON["DEFAULT"] - gsub(/\\+033/, "\033", str); print str - } else if (pos > 0) { - clr = ENVIRON["PRI_" substr($0, pos+1, 1)] - str = ( clr ? clr : ENVIRON["PRI_X"] ) $0 ENVIRON["DEFAULT"] - gsub(/\\+033/, "\033", str); print str - } else { print } - }''' \ + | awk ''' + function highlight(colorVar, color) { + color = ENVIRON[colorVar] + gsub(/\\+033/, "\033", color) + return color + } + { + pos = match($0, /\([A-Z]\)/) + if (match($0, /^[0-9]+ x /)) { + print highlight("COLOR_DONE") $0 highlight("DEFAULT") + } else if (pos > 0) { + clr = highlight("PRI_" substr($0, pos+1, 1)) + print ( clr ? clr : highlight("PRI_X") ) $0 highlight("DEFAULT") + } else { print } + } + ''' \ | sed ''' s/'${HIDE_PRIORITY_SUBSTITUTION:-^}'//g s/'${HIDE_PROJECTS_SUBSTITUTION:-^}'//g From 9760ee23c79818e7d94c11b895e9f923335cc58f Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Thu, 21 Oct 2010 12:27:30 +0200 Subject: [PATCH 4/9] Avoiding todo.sh help error when .todo.actions.d contains subdirs. I have placed tests for my custom todo actions in ~/.todo.actions.d/tests/; this causes a ".../.todo.actions.d/tests: is a directory" error on todo.sh help. Added condition for regular files to the executable check in order to exclude subdirectories. --- todo.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/todo.sh b/todo.sh index 99320c9..4d0fb15 100755 --- a/todo.sh +++ b/todo.sh @@ -232,7 +232,7 @@ help() echo "" for action in "$TODO_ACTIONS_DIR"/* do - if [ -x "$action" ] + if [ -f "$action" -a -x "$action" ] then "$action" usage fi From a117b7cb3cc34792e4561273ee307a70bca506cf Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Thu, 30 Dec 2010 23:19:57 +0100 Subject: [PATCH 5/9] MINOR: Removed unnecessary empty & reference in sed substitution. --- todo.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/todo.sh b/todo.sh index 4d0fb15..e04ed37 100755 --- a/todo.sh +++ b/todo.sh @@ -882,7 +882,7 @@ case $action in now=`date '+%Y-%m-%d'` # remove priority once item is done sed -i.bak $item"s/^(.) //" "$TODO_FILE" - sed -i.bak $item"s|^|&x $now |" "$TODO_FILE" + sed -i.bak $item"s|^|x $now |" "$TODO_FILE" if [ $TODOTXT_VERBOSE -gt 0 ]; then newtodo=$(sed "$item!d" "$TODO_FILE") echo "$item $newtodo" From 2df5f9fee95800686223ee9f5078c132947637d2 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Thu, 20 Jan 2011 13:23:06 +0100 Subject: [PATCH 6/9] Fixed test environment for escaped test output. - test-lib uses 'read -r' to parse the test session input literally, without interpretation of backslashes. - FIX: Use quoting to maintain original whitespace (tabs and multiple spaces) from the test session input (instead of condensing into a single space). - Using Bash instead of POSIX shell for t1340-listescapes.sh, so that the interpretation of escape sequences is not dependent on the POSIX shell being used. - Changed Makefile so that the shell selected by the shebang line is actually used when invoking tests, not the POSIX shell. - Above changes obsolete the multiple escaping of the test session data; now, the test session can actually be pasted as-is into a test script, even when it contains backslashes. (I.e. works as expected now.) --- Makefile | 2 +- tests/t1340-listescapes.sh | 16 ++++++---------- tests/test-lib.sh | 4 ++-- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 5ef5431..3219f85 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,7 @@ test-pre-clean: aggregate-results: $(TESTS) $(TESTS): test-pre-clean - -cd tests && sh $(notdir $@) $(TEST_OPTIONS) + -cd tests && ./$(notdir $@) $(TEST_OPTIONS) test: aggregate-results tests/aggregate-results.sh tests/test-results/t*-* diff --git a/tests/t1340-listescapes.sh b/tests/t1340-listescapes.sh index e0682c3..075b9ec 100755 --- a/tests/t1340-listescapes.sh +++ b/tests/t1340-listescapes.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # test_description='list with escape sequences @@ -7,10 +7,6 @@ This test checks listing of tasks that have embedded escape sequences in them. ' . ./test-lib.sh -# Note: The quadrupled escaped backslashes (even 8-fold for the escape color -# code) in the expected output are necessary due to (superfluous?!) -# interpretation of the expected output in the test library itself. - # # check aborted list output on \c escape sequence # @@ -23,13 +19,13 @@ EOF test_todo_session 'aborted list output on backslash-c' <<'EOF' >>> todo.sh ls 1 first todo -2 second todo run C:\\\\WINDOWS\\\\sysnative\\\\cscript.exe +2 second todo run C:\WINDOWS\sysnative\cscript.exe 3 third todo -- TODO: 3 of 3 tasks shown >>> todo.sh ls 2 -2 second todo run C:\\\\WINDOWS\\\\sysnative\\\\cscript.exe +2 second todo run C:\WINDOWS\sysnative\cscript.exe -- TODO: 1 of 3 tasks shown EOF @@ -45,9 +41,9 @@ EOF test_todo_session 'various escape sequences' <<'EOF' >>> todo.sh ls -1 first todo with \\\\\\\\, \\\\a and \\\\t -2 second todo with \\\\r\\\\n line break -3 third todo with \\\\x42\\\\x55\\\\x47 and \\\\\\\\033[0;31m color codes \\\\\\\\033[0;30m +1 first todo with \\, \a and \t +2 second todo with \r\n line break +3 third todo with \x42\x55\x47 and \033[0;31m color codes \033[0;30m -- TODO: 3 of 3 tasks shown EOF diff --git a/tests/test-lib.sh b/tests/test-lib.sh index efe8960..c4f3ff5 100644 --- a/tests/test-lib.sh +++ b/tests/test-lib.sh @@ -527,7 +527,7 @@ test_todo_session () { cmd="" status=0 > expect - while read line + while read -r line do case $line in ">>> "*) @@ -552,7 +552,7 @@ test_todo_session () { fi ;; *) - echo $line >> expect + echo "$line" >> expect ;; esac done From 819a8285cc95dc4972a6e6b3c8c98a3a59f30a6b Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Thu, 20 Jan 2011 15:07:47 +0100 Subject: [PATCH 7/9] Factored out generation of custom action scripts. - Reduced duplication via common make_action() function. - ENH: Adding proper shebang line to the custom action scripts. - Changed output of custom action to better differentiate from todo.sh output. --- tests/t8000-actions.sh | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/tests/t8000-actions.sh b/tests/t8000-actions.sh index 3d92248..91e3f19 100755 --- a/tests/t8000-actions.sh +++ b/tests/t8000-actions.sh @@ -8,10 +8,22 @@ This test covers the contract between todo.sh and custom actions. unset TODO_ACTIONS_DIR mkdir .todo.actions.d -cat > .todo.actions.d/foo << EOF -echo "TODO: foo" +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 +custom action foo EOF +chmod -x .todo.actions.d/foo test_todo_session 'nonexecutable action' <>> todo.sh foo Usage: todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description] @@ -19,33 +31,21 @@ Try 'todo.sh -h' for more information. === 1 EOF -chmod +x .todo.actions.d/foo -test_todo_session 'executable action' <>> todo.sh foo -TODO: foo -EOF - -cat > .todo.actions.d/ls << EOF -echo "TODO: my ls" -EOF -chmod +x .todo.actions.d/ls +make_action "ls" test_todo_session 'overriding built-in action' <>> todo.sh ls -TODO: my ls +custom action ls >>> todo.sh command ls -- TODO: 0 of 0 tasks shown EOF -cat > .todo.actions.d/bad << EOF -echo "TODO: bad" -exit 42 -EOF -chmod +x .todo.actions.d/bad +make_action "bad" +echo "exit 42" >> .todo.actions.d/bad test_todo_session 'failing action' <>> todo.sh bad -TODO: bad +custom action bad === 42 EOF From a82fd583630fd578e8ba2e19b98a789553b3855c Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Thu, 20 Jan 2011 15:34:46 +0100 Subject: [PATCH 8/9] Skipping 'nonexecutable action' test on Cygwin. 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 instead of failing. --- tests/t8000-actions.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/t8000-actions.sh b/tests/t8000-actions.sh index 91e3f19..03a1fbe 100755 --- a/tests/t8000-actions.sh +++ b/tests/t8000-actions.sh @@ -24,6 +24,11 @@ custom action foo 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+ }t8000.2" +fi test_todo_session 'nonexecutable action' <>> todo.sh foo Usage: todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description] From 9a5668a51ce2e7f4a06fd1134267527322668443 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Thu, 20 Jan 2011 16:08:20 +0100 Subject: [PATCH 9/9] Cosmetics: Corrected inconsistent indentation. --- tests/test-lib.sh | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/test-lib.sh b/tests/test-lib.sh index c4f3ff5..29f3246 100644 --- a/tests/test-lib.sh +++ b/tests/test-lib.sh @@ -12,8 +12,10 @@ done,*) *' --tee '*|*' --va'*) mkdir -p test-results BASE=test-results/$(basename "$0" .sh) - (TEST_TEE_STARTED=done ${SHELL-sh} "$0" "$@" 2>&1; - echo $? > $BASE.exit) | tee $BASE.out + ( + TEST_TEE_STARTED=done ${SHELL-sh} "$0" "$@" 2>&1; + echo $? > $BASE.exit + ) | tee $BASE.out test "$(cat $BASE.exit)" = 0 exit ;; @@ -395,7 +397,7 @@ test_done () { 0) say_color pass "passed all $msg" - # Clean up this test. + # Clean up this test. test -d "$remove_trash" && cd "$(dirname "$remove_trash")" && rm -rf "$(basename "$remove_trash")" @@ -434,8 +436,8 @@ test_init_todo () { root="$1" mkdir -p "$root" cd "$root" || error "Cannot setup todo dir in $root" - # Initialize the configuration file. Carefully quoted. - sed -e 's|TODO_DIR=.*$|TODO_DIR="'"$TEST_DIRECTORY/$test"'"|' $TEST_DIRECTORY/../todo.cfg > todo.cfg + # Initialize the configuration file. Carefully quoted. + sed -e 's|TODO_DIR=.*$|TODO_DIR="'"$TEST_DIRECTORY/$test"'"|' $TEST_DIRECTORY/../todo.cfg > todo.cfg # Install latest todo.sh mkdir bin