Enhancement - #326

- Added feature #326, allowing tasks to be added in the completed state,
  by using the 'log' command in place of 'add' (thanks to Cory Donnelly).
- Added log command to task.1 man page.
- Added log command to task-tutorial.5 man page.
- Added log command to help text.
- Added log command unit tests.
This commit is contained in:
Paul Beckingham
2010-05-30 15:20:12 -04:00
parent 336a4dea01
commit fcbc8a2ee2
12 changed files with 143 additions and 2 deletions

View File

@@ -4,6 +4,8 @@
1.9.2 () 1.9.2 ()
+ Added feature #320, so the command "task 123" is interpreted as an + Added feature #320, so the command "task 123" is interpreted as an
implicit "task info 123" command (thanks to John Florian). implicit "task info 123" command (thanks to John Florian).
+ Added feature #326, allowing tasks to be added in the completed state,
by using the 'log' command in place of 'add' (thanks to Cory Donnelly).
------ old releases ------------------------------ ------ old releases ------------------------------

1
NEWS
View File

@@ -15,6 +15,7 @@ New Features in task 1.9
task list project.not:foo project.not:bar task list project.not:foo project.not:bar
- Ability to do case-sensitive or case-insensitive search for keywords, and - Ability to do case-sensitive or case-insensitive search for keywords, and
substitutions in the description and annotations. substitutions in the description and annotations.
- New 'log' command to add tasks that are already completed.
- Task is now part of Debian - Task is now part of Debian
Please refer to the ChangeLog file for full details. There are too many to Please refer to the ChangeLog file for full details. There are too many to

View File

@@ -358,6 +358,15 @@ To remove a tag from a task, use the minus sign:
$ task 3 \-john $ task 3 \-john
.RE .RE
To add a task that you have already completed, use the log command:
.br
.RS
$ task log Notify postal service
.RE
This is equivalent to first adding a new task, then marking that new task
as done. It is simple a shortcut.
.SH Advanced usage of task .SH Advanced usage of task
Advanced examples of the usage of task can be found at the official site at Advanced examples of the usage of task can be found at the official site at
<http://taskwarrior.org> <http://taskwarrior.org>

View File

@@ -17,6 +17,10 @@ has a rich list of subcommands that allow you to do various things with it.
.B add [tags] [attrs] description .B add [tags] [attrs] description
Adds a new task to the task list. Adds a new task to the task list.
.TP
.B log [tags] [attrs] description
Adds a new task that is already completed, to the task list.
.TP .TP
.B append [tags] [attrs] description .B append [tags] [attrs] description
Appends information to an existing task. Appends information to an existing task.

View File

@@ -55,7 +55,7 @@
223 summary 223 summary
224 tags 224 tags
225 timesheet 225 timesheet
226 log
227 undo 227 undo
228 version 228 version
229 shell 229 shell

View File

@@ -127,6 +127,7 @@ void Cmd::load ()
commands.push_back (context.stringtable.get (CMD_GHISTORY, "ghistory")); commands.push_back (context.stringtable.get (CMD_GHISTORY, "ghistory"));
commands.push_back (context.stringtable.get (CMD_IMPORT, "import")); commands.push_back (context.stringtable.get (CMD_IMPORT, "import"));
commands.push_back (context.stringtable.get (CMD_INFO, "info")); commands.push_back (context.stringtable.get (CMD_INFO, "info"));
commands.push_back (context.stringtable.get (CMD_LOG, "log"));
commands.push_back (context.stringtable.get (CMD_PREPEND, "prepend")); commands.push_back (context.stringtable.get (CMD_PREPEND, "prepend"));
commands.push_back (context.stringtable.get (CMD_PROJECTS, "projects")); commands.push_back (context.stringtable.get (CMD_PROJECTS, "projects"));
#ifdef FEATURE_SHELL #ifdef FEATURE_SHELL
@@ -228,6 +229,7 @@ bool Cmd::isWriteCommand ()
command == context.stringtable.get (CMD_DUPLICATE, "duplicate") || command == context.stringtable.get (CMD_DUPLICATE, "duplicate") ||
command == context.stringtable.get (CMD_EDIT, "edit") || command == context.stringtable.get (CMD_EDIT, "edit") ||
command == context.stringtable.get (CMD_IMPORT, "import") || command == context.stringtable.get (CMD_IMPORT, "import") ||
command == context.stringtable.get (CMD_LOG, "log") ||
command == context.stringtable.get (CMD_PREPEND, "prepend") || command == context.stringtable.get (CMD_PREPEND, "prepend") ||
command == context.stringtable.get (CMD_START, "start") || command == context.stringtable.get (CMD_START, "start") ||
command == context.stringtable.get (CMD_STOP, "stop") || command == context.stringtable.get (CMD_STOP, "stop") ||

View File

@@ -219,6 +219,7 @@ int Context::dispatch (std::string &out)
else if (cmd.command == "calendar") { rc = handleReportCalendar (out); } else if (cmd.command == "calendar") { rc = handleReportCalendar (out); }
else if (cmd.command == "timesheet") { rc = handleReportTimesheet (out); } else if (cmd.command == "timesheet") { rc = handleReportTimesheet (out); }
else if (cmd.command == "add") { rc = handleAdd (out); } else if (cmd.command == "add") { rc = handleAdd (out); }
else if (cmd.command == "log") { rc = handleLog (out); }
else if (cmd.command == "append") { rc = handleAppend (out); } else if (cmd.command == "append") { rc = handleAppend (out); }
else if (cmd.command == "prepend") { rc = handlePrepend (out); } else if (cmd.command == "prepend") { rc = handlePrepend (out); }
else if (cmd.command == "annotate") { rc = handleAnnotate (out); } else if (cmd.command == "annotate") { rc = handleAnnotate (out); }

View File

@@ -123,6 +123,62 @@ int handleAdd (std::string &outs)
return rc; return rc;
} }
////////////////////////////////////////////////////////////////////////////////
int handleLog (std::string &outs)
{
int rc = 0;
if (context.hooks.trigger ("pre-log-command"))
{
std::stringstream out;
context.task.setStatus (Task::completed);
context.task.set ("uuid", uuid ());
context.task.setEntry ();
// Add an end date.
char entryTime[16];
sprintf (entryTime, "%u", (unsigned int) time (NULL));
context.task.set ("end", entryTime);
// Recurring tasks get a special status.
if (context.task.has ("recur"))
throw std::string ("You cannot log recurring tasks.");
if (context.task.has ("wait"))
throw std::string ("You cannot log waiting tasks.");
// Override with default.project, if not specified.
if (context.task.get ("project") == "")
context.task.set ("project", context.config.get ("default.project"));
// Override with default.priority, if not specified.
if (context.task.get ("priority") == "")
{
std::string defaultPriority = context.config.get ("default.priority");
if (Att::validNameValue ("priority", "", defaultPriority))
context.task.set ("priority", defaultPriority);
}
// Include tags.
foreach (tag, context.tagAdditions)
context.task.addTag (*tag);
// Only valid tasks can be added.
context.task.validate ();
context.tdb.lock (context.config.getBoolean ("locking"));
context.tdb.add (context.task);
context.tdb.commit ();
context.tdb.unlock ();
outs = out.str ();
context.hooks.trigger ("post-log-command");
}
return rc;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int handleProjects (std::string &outs) int handleProjects (std::string &outs)
{ {

View File

@@ -92,7 +92,7 @@
#define CMD_SUMMARY 223 #define CMD_SUMMARY 223
#define CMD_TAGS 224 #define CMD_TAGS 224
#define CMD_TIMESHEET 225 #define CMD_TIMESHEET 225
#define CMD_LOG 226
#define CMD_UNDO 227 #define CMD_UNDO 227
#define CMD_VERSION 228 #define CMD_VERSION 228
#define CMD_SHELL 229 #define CMD_SHELL 229

View File

@@ -56,6 +56,7 @@ bool nag (Task&);
// command.cpp // command.cpp
int handleAdd (std::string &); int handleAdd (std::string &);
int handleLog (std::string &);
int handleAppend (std::string &); int handleAppend (std::string &);
int handlePrepend (std::string &); int handlePrepend (std::string &);
int handleExport (std::string &); int handleExport (std::string &);

View File

@@ -77,6 +77,10 @@ int shortUsage (std::string &outs)
table.addCell (row, 1, "task add [tags] [attrs] desc..."); table.addCell (row, 1, "task add [tags] [attrs] desc...");
table.addCell (row, 2, "Adds a new task."); table.addCell (row, 2, "Adds a new task.");
row = table.addRow ();
table.addCell (row, 1, "task log [tags] [attrs] desc...");
table.addCell (row, 2, "Adds a new task that is already completed.");
row = table.addRow (); row = table.addRow ();
table.addCell (row, 1, "task append [tags] [attrs] desc..."); table.addCell (row, 1, "task append [tags] [attrs] desc...");
table.addCell (row, 2, "Appends more description to an existing task."); table.addCell (row, 2, "Appends more description to an existing task.");

61
src/tests/log.t Executable file
View File

@@ -0,0 +1,61 @@
#! /usr/bin/perl
################################################################################
## task - a command line task list manager.
##
## Copyright 2006 - 2010, Paul Beckingham.
## All rights reserved.
##
## This program is free software; you can redistribute it and/or modify it under
## the terms of the GNU General Public License as published by the Free Software
## Foundation; either version 2 of the License, or (at your option) any later
## version.
##
## This program is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
## FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
## details.
##
## You should have received a copy of the GNU General Public License along with
## this program; if not, write to the
##
## Free Software Foundation, Inc.,
## 51 Franklin Street, Fifth Floor,
## Boston, MA
## 02110-1301
## USA
##
################################################################################
use strict;
use warnings;
use Test::More tests => 8;
# Create the rc file.
if (open my $fh, '>', 'log.rc')
{
print $fh "data.location=.\n",
"confirmation=off\n";
close $fh;
ok (-r 'log.rc', 'Created log.rc');
}
# Test the log command.
qx{../task rc:log.rc log This is a test};
my $output = qx{../task rc:log.rc info 1};
like ($output, qr/ID\s+1\n/, 'log ID');
like ($output, qr/Description\s+This is a test\n/, 'log ID');
like ($output, qr/Status\s+Completed\n/, 'log Completed');
like ($output, qr/UUID\s+[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}\n/, 'log UUID');
# Cleanup.
unlink 'pending.data';
ok (!-r 'pending.data', 'Removed pending.data');
unlink 'undo.data';
ok (!-r 'undo.data', 'Removed undo.data');
unlink 'log.rc';
ok (!-r 'log.rc', 'Removed log.rc');
exit 0;