Compare commits

..

6 Commits

Author SHA1 Message Date
Ingo Karkat
b7ffb96695 Pull archive() in-line and delegate via recursive call, also for report.
The report action should delegate to archive; it previously (half) did this via duplicated code (and forgot to defragment empty lines, so the tally could be off, and kept silent about the archiving).

The do action directly invoked archive(); if the user had extended / modified the archive action via an eponymous custom action, it would not run. Therefore, always invoke archive through another call of todo.sh, so that a possible custom action is considered.
2012-01-13 23:46:08 +01:00
Ingo Karkat
67e0d9dd98 Support "preserve line numbers" in deduplicate. 2012-01-13 23:27:58 +01:00
Ingo Karkat
1160ae1276 Fix deduplicate for non-printable (and non-ASCII) characters. 2012-01-13 22:44:35 +01:00
Ingo Karkat
534184e4dd Rework fixed archive deduplication into new deduplicate action.
As per discussion on the mailing list (http://tech.groups.yahoo.com/group/todotxt/message/3775), the automatic deduplication during archiving is unexpected and difficult to enforce in other implementations. Rather, make this a separate (optional) action.
2012-01-13 22:41:33 +01:00
Paul Roub
cd2f585fb6 explained the sed duplicate-removal pattern 2012-01-09 10:34:05 -05:00
Paul Roub
492d98e50a Fix typo in duplicate removal on archive, per discussion at http://tech.groups.yahoo.com/group/todotxt/message/3775 2012-01-08 12:14:08 -05:00
5 changed files with 210 additions and 121 deletions

35
tests/t1900-archive.sh Executable file
View File

@@ -0,0 +1,35 @@
#!/bin/sh
test_description='archive functionality
Ensure we can archive items successfully.
'
. ./test-lib.sh
cat > todo.txt <<EOF
one
two
three
one
x done
four
EOF
test_todo_session 'archive with duplicates' <<EOF
>>> todo.sh archive
x done
TODO: $HOME/todo.txt archived.
EOF
test_todo_session 'list after archive' <<EOF
>>> todo.sh ls
5 four
1 one
4 one
3 three
2 two
--
TODO: 5 of 5 tasks shown
EOF
test_done

103
tests/t1910-deduplicate.sh Executable file
View File

@@ -0,0 +1,103 @@
#!/bin/sh
test_description='deduplicate functionality
Ensure we can deduplicate items successfully.
'
. ./test-lib.sh
cat > todo.txt <<EOF
duplicated
two
x done
duplicated
double task
double task
three
EOF
test_todo_session 'deduplicate and preserve line numbers' <<EOF
>>> todo.sh deduplicate
TODO: 2 duplicate task(s) removed
>>> todo.sh -p ls
5 double task
1 duplicated
7 three
2 two
3 x done
--
TODO: 5 of 5 tasks shown
EOF
test_todo_session 'deduplicate without duplicates' <<EOF
>>> todo.sh deduplicate
TODO: No duplicate tasks found
EOF
cat > todo.txt <<EOF
duplicated
two
x done
duplicated
double task
double task
three
EOF
test_todo_session 'deduplicate and delete lines' <<EOF
>>> todo.sh -n deduplicate
TODO: 2 duplicate task(s) removed
>>> todo.sh -p ls
4 double task
1 duplicated
5 three
2 two
3 x done
--
TODO: 5 of 5 tasks shown
EOF
cat > todo.txt <<EOF
one
duplicated
three
duplicated
duplicated
six
duplicated
EOF
test_todo_session 'deduplicate more than two occurrences' <<EOF
>>> todo.sh deduplicate
TODO: 3 duplicate task(s) removed
>>> todo.sh -p ls
2 duplicated
1 one
6 six
3 three
--
TODO: 4 of 4 tasks shown
EOF
cat > todo.txt <<EOF
normal task
a bold action
something else
a bold action
something more
EOF
test_todo_session 'deduplicate with non-printable duplicates' <<EOF
>>> todo.sh deduplicate
TODO: 1 duplicate task(s) removed
>>> todo.sh -p ls
2 a bold action
1 normal task
3 something else
5 something more
--
TODO: 4 of 4 tasks shown
EOF
test_done

View File

@@ -1,91 +0,0 @@
#!/bin/sh
test_description='report functionality
This test checks the reporting and the format of the report file.
'
. ./test-lib.sh
cat > todo.txt <<EOF
(B) smell the uppercase Roses +flowers @outside
stop and think
smell the coffee +wakeup
make the coffee +wakeup
visit http://example.com
EOF
test_todo_session 'create new report' <<EOF
>>> todo.sh report
2009-02-13T04:40:00 5 0
TODO: Report file updated.
>>> todo.sh -p list
1 (B) smell the uppercase Roses +flowers @outside
4 make the coffee +wakeup
3 smell the coffee +wakeup
2 stop and think
5 visit http://example.com
--
TODO: 5 of 5 tasks shown
EOF
test_todo_session 'report of done tasks' <<EOF
>>> todo.sh -A do 3
3 x 2009-02-13 smell the coffee +wakeup
TODO: 3 marked as done.
x 2009-02-13 smell the coffee +wakeup
TODO: $HOME/todo.txt archived.
>>> todo.sh report
2009-02-13T04:40:00 4 1
TODO: Report file updated.
>>> todo.sh -p list
1 (B) smell the uppercase Roses +flowers @outside
3 make the coffee +wakeup
2 stop and think
4 visit http://example.com
--
TODO: 4 of 4 tasks shown
EOF
test_todo_session 'report performs archiving' <<EOF
>>> todo.sh -a do 3
3 x 2009-02-13 make the coffee +wakeup
TODO: 3 marked as done.
>>> todo.sh report
2009-02-13T04:40:00 3 2
TODO: Report file updated.
>>> todo.sh -p list
1 (B) smell the uppercase Roses +flowers @outside
2 stop and think
3 visit http://example.com
--
TODO: 3 of 3 tasks shown
>>> todo.sh -p listfile done.txt
2 x 2009-02-13 make the coffee +wakeup
1 x 2009-02-13 smell the coffee +wakeup
--
DONE: 2 of 2 tasks shown
EOF
test_todo_session 'report is unchanged when no changes' <<EOF
>>> cat report.txt
2009-02-13T04:40:00 5 0
2009-02-13T04:40:00 4 1
2009-02-13T04:40:00 3 2
>>> todo.sh report
2009-02-13T04:40:00 3 2
TODO: Report file is up-to-date.
>>> cat report.txt
2009-02-13T04:40:00 5 0
2009-02-13T04:40:00 4 1
2009-02-13T04:40:00 3 2
EOF
test_done

View File

@@ -85,8 +85,15 @@ TODO: $HOME/todo.txt archived.
TODO: 5 of 5 tasks shown TODO: 5 of 5 tasks shown
>>> todo.sh report >>> todo.sh report
2009-02-13T04:40:00 5 1 TODO: $HOME/todo.txt archived.
TODO: Report file updated. TODO: Report file updated.
2009-02-13-04:40:00 5 1
>>> todo.sh report
TODO: $HOME/todo.txt archived.
TODO: Report file updated.
2009-02-13-04:40:00 5 1
2009-02-13-04:40:00 5 1
>>> todo.sh append g a >>> todo.sh append g a
usage: todo.sh append ITEM# "TEXT TO APPEND" usage: todo.sh append ITEM# "TEXT TO APPEND"

93
todo.sh
View File

@@ -50,6 +50,7 @@ shorthelp()
append|app ITEM# "TEXT TO APPEND" append|app ITEM# "TEXT TO APPEND"
archive archive
command [ACTIONS] command [ACTIONS]
deduplicate
del|rm ITEM# [TERM] del|rm ITEM# [TERM]
depri|dp ITEM#[, ITEM#, ITEM#, ...] depri|dp ITEM#[, ITEM#, ITEM#, ...]
do ITEM#[, ITEM#, ITEM#, ...] do ITEM#[, ITEM#, ITEM#, ...]
@@ -180,6 +181,9 @@ help()
Runs the remaining arguments using only todo.sh builtins. Runs the remaining arguments using only todo.sh builtins.
Will not call any .todo.actions.d scripts. Will not call any .todo.actions.d scripts.
deduplicate
Removes duplicate lines from todo.txt.
del ITEM# [TERM] del ITEM# [TERM]
rm ITEM# [TERM] rm ITEM# [TERM]
Deletes the task on line ITEM# in todo.txt. Deletes the task on line ITEM# in todo.txt.
@@ -353,20 +357,6 @@ getNewtodo()
[ -z "$newtodo" ] && die "$(getPrefix "$2"): No updated task $item." [ -z "$newtodo" ] && die "$(getPrefix "$2"): No updated task $item."
} }
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"
cp "$TODO_FILE" "$TMP_FILE"
sed -n 'G; s/\n/&&/; /^\([ ~-]*\n\).*\n\1/d; s/\n//; h; P' "$TMP_FILE" > "$TODO_FILE"
if [ $TODOTXT_VERBOSE -gt 0 ]; then
echo "TODO: $TODO_FILE archived."
fi
}
replaceOrPrepend() replaceOrPrepend()
{ {
action=$1; shift action=$1; shift
@@ -933,7 +923,15 @@ case $action in
;; ;;
"archive" ) "archive" )
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."
fi
;;
"del" | "rm" ) "del" | "rm" )
# replace deleted line with a blank line when TODOTXT_PRESERVE_LINE_NUMBERS is 1 # replace deleted line with a blank line when TODOTXT_PRESERVE_LINE_NUMBERS is 1
@@ -1035,7 +1033,9 @@ case $action in
done done
if [ $TODOTXT_AUTO_ARCHIVE = 1 ]; then if [ $TODOTXT_AUTO_ARCHIVE = 1 ]; then
archive # Recursively invoke the script to allow overriding of the archive
# action.
"$TODO_FULL_SH" archive
fi fi
;; ;;
@@ -1187,23 +1187,58 @@ note: PRIORITY must be anywhere from A to Z."
;; ;;
"report" ) "report" )
#archive first # archive first
sed '/^x /!d' "$TODO_FILE" >> "$DONE_FILE" # Recursively invoke the script to allow overriding of the archive
sed -i.bak '/^x /d' "$TODO_FILE" # action.
"$TODO_FULL_SH" archive
NUMLINES=$( sed -n '$ =' "$TODO_FILE" )
if [ ${NUMLINES:-0} = "0" ]; then
echo "datetime todos dones" >> "$REPORT_FILE"
fi
#now report
TOTAL=$( sed -n '$ =' "$TODO_FILE" ) TOTAL=$( sed -n '$ =' "$TODO_FILE" )
TDONE=$( sed -n '$ =' "$DONE_FILE" ) TDONE=$( sed -n '$ =' "$DONE_FILE" )
NEWDATA="${TOTAL:-0} ${TDONE:-0}" TECHO=$(echo $(date +%Y-%m-%d-%T); echo ' '; echo ${TOTAL:-0}; echo ' ';
LASTREPORT=$(sed -ne '$p' "$REPORT_FILE") echo ${TDONE:-0})
LASTDATA=${LASTREPORT#* } # Strip timestamp. echo $TECHO >> "$REPORT_FILE"
if [ "$LASTDATA" = "$NEWDATA" ]; then
echo "$LASTREPORT"
[ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: Report file is up-to-date."
else
NEWREPORT="$(date +%Y-%m-%dT%T) ${NEWDATA}"
echo "${NEWREPORT}" >> "$REPORT_FILE"
echo "${NEWREPORT}"
[ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: Report file updated." [ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: Report file updated."
cat "$REPORT_FILE"
;;
"deduplicate" )
if [ $TODOTXT_PRESERVE_LINE_NUMBERS = 0 ]; then
deduplicateSedCommand='d'
else
deduplicateSedCommand='{ s/^.*//; p; b }'
fi
# To determine the difference when deduplicated lines are preserved, only
# non-empty lines must be counted.
originalTaskNum=$( sed -e '/./!d' "$TODO_FILE" | sed -n '$ =' )
# Look for duplicate lines and discard the second occurrence.
# We start with an empty hold space on the first line. For each line:
# G - appends newline + hold space to the pattern space
# s/\n/&&/; - double up the first new line so we catch adjacent dups
# /^\([^\n]*\n\).*\n\1/
# If the first line of the hold space shows up again later as an
# entire line, it's a duplicate.
# d; - Delete the current pattern space, quit this line
# and move on to the next, or:
# { s/^.*//; p; b }; - Clear the task text, print this line and move on
# to the next.
# s/\n//; - else, drop the doubled newline
# h; - replace the hold space with the expanded pattern space
# P; - print up to the first newline (that is, the input line)
sed -i.bak -n 'G; s/\n/&&/; /^\([^\n]*\n\).*\n\1/'"$deduplicateSedCommand"'; s/\n//; h; P' "$TODO_FILE"
newTaskNum=$( sed -e '/./!d' "$TODO_FILE" | sed -n '$ =' )
deduplicateNum=$(( originalTaskNum - newTaskNum ))
if [ $deduplicateNum -eq 0 ]; then
echo "TODO: No duplicate tasks found"
else
echo "TODO: $deduplicateNum duplicate task(s) removed"
fi fi
;; ;;