mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-08-19 19:03:07 +02:00
Feature #457
- Tasks may now be given an 'until' date, after which they expire and are deleted.
This commit is contained in:
parent
d122173103
commit
665bc197dc
11 changed files with 40 additions and 18 deletions
|
@ -4,6 +4,8 @@
|
|||
2.0.1 ()
|
||||
|
||||
Features
|
||||
+ Feature #457, tasks may now be given an 'until' date, after which they expire
|
||||
and are deleted.
|
||||
+ Feature #516, which allows the duplication of completed tasks (thanks to
|
||||
Peter De Poorter, Ethan Schoonover).
|
||||
+ Applied patch for feature #1005, which prevents the update-holidays.pl script
|
||||
|
|
4
NEWS
4
NEWS
|
@ -5,13 +5,15 @@ New Features in taskwarrior 2.0.1
|
|||
and 'summary' commands.
|
||||
- Support for the 'scheduled' date for a task, which represent the earliest
|
||||
opportunity to work on a task.
|
||||
- All tasks may now be given an 'until' date, after which they will expire
|
||||
and are deleted.
|
||||
|
||||
Please refer to the ChangeLog file for full details. There are too many to
|
||||
list here.
|
||||
|
||||
New commands in taskwarrior 2.0.1
|
||||
|
||||
- None
|
||||
- New 'ready' report that lists tasks ready for work, sorted by urgency.
|
||||
|
||||
New configuration options in taskwarrior 2.0.1
|
||||
|
||||
|
|
|
@ -546,8 +546,8 @@ Specifies the due-date of a task.
|
|||
Specifies the frequency of a recurrence of a task.
|
||||
|
||||
.TP
|
||||
.B until:<end-date-of-recurrence>
|
||||
Specifies the Recurrence end-date of a task.
|
||||
.B until:<expiration date of task>
|
||||
Specifies the expiration date of a task, after which it will be deleted.
|
||||
|
||||
.TP
|
||||
.B fg:<color-spec>
|
||||
|
|
|
@ -1154,10 +1154,6 @@ void Task::validate ()
|
|||
if (! has ("due") && has ("recur"))
|
||||
throw std::string (STRING_TASK_VALID_REC_DUE);
|
||||
|
||||
// Cannot have an until date no recurrence frequency.
|
||||
if (has ("until") && !has ("recur"))
|
||||
throw std::string (STRING_TASK_VALID_UNTIL);
|
||||
|
||||
// Recur durations must be valid.
|
||||
if (has ("recur"))
|
||||
{
|
||||
|
|
|
@ -203,7 +203,7 @@ int CmdInfo::execute (std::string& output)
|
|||
if (task->has ("until"))
|
||||
{
|
||||
row = view.addRow ();
|
||||
view.set (row, 0, STRING_CMD_INFO_RECUR_UNTIL);
|
||||
view.set (row, 0, STRING_CMD_INFO_UNTIL);
|
||||
view.set (row, 1, Date (task->get_date ("until")).toString (dateformat));
|
||||
}
|
||||
|
||||
|
|
|
@ -225,7 +225,7 @@
|
|||
#define STRING_CMD_INFO_USAGE "Shows all data and metadata"
|
||||
#define STRING_CMD_INFO_BLOCKED "This task blocked by"
|
||||
#define STRING_CMD_INFO_BLOCKING "This task is blocking"
|
||||
#define STRING_CMD_INFO_RECUR_UNTIL "Recur until"
|
||||
#define STRING_CMD_INFO_UNTIL "Until"
|
||||
#define STRING_CMD_INFO_MODIFICATION "Modification"
|
||||
#define STRING_CMD_INFO_TOTAL_ACTIVE "Total active time"
|
||||
#define STRING_CMD_UNDO_USAGE "Reverts the most recent change to a task"
|
||||
|
@ -698,6 +698,7 @@
|
|||
#define STRING_FEEDBACK_TAG_NOCAL "The 'nocal' special tag will keep this task off the calendar report."
|
||||
#define STRING_FEEDBACK_TAG_NEXT "The 'next' special tag will boost the urgency of this task so it appears on the 'next' report."
|
||||
#define STRING_FEEDBACK_UNBLOCKED "Unblocked {1} '{2}'."
|
||||
#define STRING_FEEDBACK_EXPIRED "Task {1} '{2}' expired and was deleted."
|
||||
|
||||
// File
|
||||
#define STRING_FILE_PERMS "Task does not have the correct permissions for '{1}'."
|
||||
|
@ -732,9 +733,6 @@
|
|||
#define STRING_RECORD_JUNK_AT_EOL "Unrecognized characters at end of line."
|
||||
#define STRING_RECORD_NOT_FF4 "Record not recognized as format 4."
|
||||
|
||||
// recur
|
||||
#define STRING_RECUR_PAST_UNTIL "Task ({1}) has past its 'until' date, and has been deleted."
|
||||
|
||||
// 'show' command
|
||||
#define STRING_CMD_SHOW "Shows all configuration variables or subset"
|
||||
#define STRING_CMD_SHOW_ARGS "You can only specify 'all' or a search string."
|
||||
|
|
|
@ -468,6 +468,18 @@ std::string onProjectChange (Task& task1, Task& task2)
|
|||
return messages;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
std::string onExpiration (Task& task)
|
||||
{
|
||||
std::stringstream msg;
|
||||
|
||||
if (context.verbose ("affected"))
|
||||
msg << format (STRING_FEEDBACK_EXPIRED, task.id, task.get ("description"))
|
||||
<< "\n";
|
||||
|
||||
return msg.str ();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static void countTasks (
|
||||
const std::vector <Task>& all,
|
||||
|
|
|
@ -79,6 +79,7 @@ void feedback_special_tags (const Task&, const std::string&);
|
|||
void feedback_unblocked (const Task&);
|
||||
std::string onProjectChange (Task&, bool scope = true);
|
||||
std::string onProjectChange (Task&, Task&);
|
||||
std::string onExpiration (Task&);
|
||||
|
||||
// sort.cpp
|
||||
void sort_tasks (std::vector <Task>&, std::vector <int>&, const std::string&);
|
||||
|
|
|
@ -56,6 +56,7 @@ extern Context context;
|
|||
void handleRecurrence ()
|
||||
{
|
||||
std::vector <Task> tasks = context.tdb2.pending.get_tasks ();
|
||||
Date now;
|
||||
|
||||
// Look at all tasks and find any recurring ones.
|
||||
std::vector <Task>::iterator t;
|
||||
|
@ -68,12 +69,10 @@ void handleRecurrence ()
|
|||
std::vector <Date> due;
|
||||
if (!generateDueDates (*t, due))
|
||||
{
|
||||
std::cout << format (STRING_RECUR_PAST_UNTIL, trim (t->get ("description")))
|
||||
<< "\n";
|
||||
|
||||
// Determine the end date.
|
||||
t->setStatus (Task::deleted);
|
||||
context.tdb2.modify (*t);
|
||||
context.footnote (onExpiration (*t));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -137,6 +136,18 @@ void handleRecurrence ()
|
|||
context.tdb2.modify (*t);
|
||||
}
|
||||
}
|
||||
|
||||
// Non-recurring tasks expire too.
|
||||
else
|
||||
{
|
||||
if (t->has ("until") &&
|
||||
Date (t->get_date ("until")) < now)
|
||||
{
|
||||
t->setStatus (Task::deleted);
|
||||
context.tdb2.modify(*t);
|
||||
context.footnote (onExpiration (*t));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,8 +45,8 @@ qx{../src/task rc:bug.rc add foo due:today recur:daily until:eom};
|
|||
my $output = qx{../src/task rc:bug.rc info 1};
|
||||
|
||||
# Result: Make sure the 'until' date is rendered as a date, not an epoch.
|
||||
unlike ($output, qr/Recur until\s+\d{10}/, 'until is not shown as an epoch');
|
||||
like ($output, qr/Recur until\s+\d+\/\d+\/\d{4}/, 'until is shown as a date');
|
||||
unlike ($output, qr/Until\s+\d{10}/, 'until is not shown as an epoch');
|
||||
like ($output, qr/Until\s+\d+\/\d+\/\d{4}/, 'until is shown as a date');
|
||||
|
||||
# Cleanup.
|
||||
unlink qw(pending.data completed.data undo.data backlog.data synch.key bug.rc);
|
||||
|
|
|
@ -53,7 +53,7 @@ qx{../src/task rc:recur.rc 3 do};
|
|||
qx{../src/task rc:recur.rc 4 do};
|
||||
qx{../src/task rc:recur.rc 5 do};
|
||||
$output = qx{../src/task rc:recur.rc list};
|
||||
like ($output, qr/and has been deleted/, 'Parent task deleted');
|
||||
like ($output, qr/and was deleted/, 'Parent task deleted');
|
||||
|
||||
$output = qx{../src/task rc:recur.rc diag};
|
||||
like ($output, qr/No duplicates found/, 'No duplicate UUIDs detected');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue