New 'ids' command, and stdin reading

- New 'ids' command that returns a filtered set of task ID numbers, instead
  of the actual tasks.  For advanced pipeline use.
- Now supplements the command line with data read from standard input, which
  allows commands like:  echo 'add Pay the bills' | task
This commit is contained in:
Paul Beckingham 2011-03-16 00:53:29 -04:00
parent dd8bceecf7
commit 9470e9af17
22 changed files with 173 additions and 50 deletions

View file

@ -3,9 +3,13 @@
2.0.0 () 2.0.0 ()
+ autoconf eliminated. + autoconf eliminated.
+ New 'ids' command that returns a filtered set of task ID numbers, instead
of the actual tasks. For advanced pipeline use.
+ Now supplements the command line with data read from standard input, which
allows commands like: echo 'add Pay the bills' | task
+ Added feature #700, which adds tab-completion of built-in tags.
+ Corrected sorting to use std::stable_sort instead of std::sort, which is not + Corrected sorting to use std::stable_sort instead of std::sort, which is not
guaranteed stable (thanks to Stefan Hacker). guaranteed stable (thanks to Stefan Hacker).
+ Added feature #700, which adds tab-completion of built-in tags.
------ old releases ------------------------------ ------ old releases ------------------------------

7
NEWS
View file

@ -1,14 +1,17 @@
New Features in taskwarrior 2.0.0 New Features in taskwarrior 2.0.0
- - New 'ids' command that returns a filtered set of task ID numbers, instead
of the actual tasks. For advanced pipeline use.
- Now supplements the command line with data read from standard input, which
allows commands like: echo 'add Pay the bills' | task
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
list here. list here.
New commands in taskwarrior 2.0.0 New commands in taskwarrior 2.0.0
- - "ids" command that accepts filters, and returns an ID sequence.
New configuration options in taskwarrior 2.0.0 New configuration options in taskwarrior 2.0.0

View file

@ -149,6 +149,7 @@ void Cmd::load ()
commands.push_back ("burndown.weekly"); commands.push_back ("burndown.weekly");
commands.push_back ("burndown.monthly"); commands.push_back ("burndown.monthly");
commands.push_back ("count"); commands.push_back ("count");
commands.push_back ("ids");
// Commands whose names are localized. // Commands whose names are localized.
commands.push_back (context.stringtable.get (CMD_ADD, "add")); commands.push_back (context.stringtable.get (CMD_ADD, "add"));
@ -258,6 +259,7 @@ bool Cmd::isReadOnlyCommand ()
command == "burndown.weekly" || command == "burndown.weekly" ||
command == "burndown.monthly" || command == "burndown.monthly" ||
command == "count" || command == "count" ||
command == "ids" ||
command == context.stringtable.get (CMD_CALENDAR, "calendar") || command == context.stringtable.get (CMD_CALENDAR, "calendar") ||
command == context.stringtable.get (CMD_COLORS, "colors") || command == context.stringtable.get (CMD_COLORS, "colors") ||
command == context.stringtable.get (CMD_DIAGNOSTICS, "diagnostics") || command == context.stringtable.get (CMD_DIAGNOSTICS, "diagnostics") ||

View file

@ -31,6 +31,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <sys/select.h>
#include "Context.h" #include "Context.h"
#include "Directory.h" #include "Directory.h"
#include "File.h" #include "File.h"
@ -84,6 +85,26 @@ void Context::initialize (int argc, char** argv)
args.push_back (argv[i]); args.push_back (argv[i]);
} }
// Capture any stdin args.
struct timeval tv;
fd_set fds;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO (&fds);
FD_SET (STDIN_FILENO, &fds);
select (STDIN_FILENO + 1, &fds, NULL, NULL, &tv);
if (FD_ISSET (0, &fds))
{
std::string arg;
while (std::cin >> arg)
{
if (arg == "--")
break;
args.push_back (arg);
}
}
initialize (); initialize ();
// Hook system init, plus post-start event occurring at the first possible // Hook system init, plus post-start event occurring at the first possible
@ -263,6 +284,7 @@ int Context::dispatch (std::string &out)
else if (cmd.command == "pull") { handlePull (out); } else if (cmd.command == "pull") { handlePull (out); }
else if (cmd.command == "diagnostics") { handleDiagnostics (out); } else if (cmd.command == "diagnostics") { handleDiagnostics (out); }
else if (cmd.command == "count") { rc = handleCount (out); } else if (cmd.command == "count") { rc = handleCount (out); }
else if (cmd.command == "ids") { rc = handleIds (out); }
else if (cmd.command == "_projects") { rc = handleCompletionProjects (out); } else if (cmd.command == "_projects") { rc = handleCompletionProjects (out); }
else if (cmd.command == "_tags") { rc = handleCompletionTags (out); } else if (cmd.command == "_tags") { rc = handleCompletionTags (out); }
else if (cmd.command == "_commands") { rc = handleCompletionCommands (out); } else if (cmd.command == "_commands") { rc = handleCompletionCommands (out); }

View file

@ -2398,6 +2398,36 @@ int handleCount (std::string& outs)
return rc; return rc;
} }
////////////////////////////////////////////////////////////////////////////////
int handleIds (std::string& outs)
{
int rc = 0;
if (context.hooks.trigger ("pre-ids-command"))
{
// Scan the pending tasks, applying any filter.
std::vector <Task> tasks;
context.tdb.lock (context.config.getBoolean ("locking"));
handleRecurrence ();
context.tdb.load (tasks, context.filter);
context.tdb.commit ();
context.tdb.unlock ();
// Find number of matching tasks.
std::vector <int> ids;
foreach (task, tasks)
if (task->id)
ids.push_back (task->id);
std::sort (ids.begin (), ids.end ());
outs = compressIds (ids) + "\n";
context.hooks.trigger ("post-ids-command");
}
return rc;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#ifdef FEATURE_SHELL #ifdef FEATURE_SHELL
void handleShell () void handleShell ()

View file

@ -64,7 +64,7 @@ int main (int argc, char** argv)
{ {
context.initialize (argc, argv); context.initialize (argc, argv);
/* From 2.0.0 /* From old 2.0.0
std::string::size_type task = context.program.find ("/task"); std::string::size_type task = context.program.find ("/task");
std::string::size_type t = context.program.find ("/t"); std::string::size_type t = context.program.find ("/t");
std::string::size_type cal = context.program.find ("/cal"); std::string::size_type cal = context.program.find ("/cal");

View file

@ -84,6 +84,7 @@ int handleAnnotate (std::string&);
int handleDenotate (std::string&); int handleDenotate (std::string&);
int handleDuplicate (std::string&); int handleDuplicate (std::string&);
int handleCount (std::string&); int handleCount (std::string&);
int handleIds (std::string&);
void handleUndo (); void handleUndo ();
void handleMerge (std::string&); void handleMerge (std::string&);
void handlePush (std::string&); void handlePush (std::string&);

View file

@ -244,6 +244,10 @@ int shortUsage (std::string& outs)
table.addCell (row, 1, "task count [filter]"); table.addCell (row, 1, "task count [filter]");
table.addCell (row, 2, "Shows only the number of matching tasks."); table.addCell (row, 2, "Shows only the number of matching tasks.");
row = table.addRow ();
table.addCell (row, 1, "task ids [filter]");
table.addCell (row, 2, "Shows only the IDs of matching tasks, in the form of a range.");
row = table.addRow (); row = table.addRow ();
table.addCell (row, 1, "task version"); table.addCell (row, 1, "task version");
table.addCell (row, 2, "Shows the task version number."); table.addCell (row, 2, "Shows the task version number.");

View file

@ -577,3 +577,58 @@ std::string renderAttribute (const std::string& name, const std::string& value)
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// The vector must be sorted first. This is a modified version of the run-
// length encoding algorithm.
//
// This function converts the vector:
//
// [1, 3, 4, 6, 7, 8, 9, 11]
//
// to ths string:
//
// 1,3-4,6-9,11
//
std::string compressIds (const std::vector <int>& ids)
{
std::stringstream result;
int range_start = 0;
int range_end = 0;
for (int i = 0; i < ids.size (); ++i)
{
if (i + 1 == ids.size ())
{
if (result.str ().length ())
result << ",";
if (range_start < range_end)
result << ids[range_start] << "-" << ids[range_end];
else
result << ids[range_start];
}
else
{
if (ids[range_end] + 1 == ids[i + 1])
{
++range_end;
}
else
{
if (result.str ().length ())
result << ",";
if (range_start < range_end)
result << ids[range_start] << "-" << ids[range_end];
else
result << ids[range_start];
range_start = range_end = i + 1;
}
}
}
return result.str ();
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -72,6 +72,7 @@ bool taskDiff (const Task&, const Task&);
std::string taskDifferences (const Task&, const Task&); std::string taskDifferences (const Task&, const Task&);
std::string taskInfoDifferences (const Task&, const Task&); std::string taskInfoDifferences (const Task&, const Task&);
std::string renderAttribute (const std::string&, const std::string&); std::string renderAttribute (const std::string&, const std::string&);
std::string compressIds (const std::vector <int>&);
#endif #endif
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View file

@ -44,7 +44,7 @@ if (open my $fh, '>', 'bug.rc')
qx{../src/task rc:bug.rc add One project:p1}; qx{../src/task rc:bug.rc add One project:p1};
# Delete the task and note the completion status of the project # Delete the task and note the completion status of the project
my $output = qx{echo 'y' | ../src/task rc:bug.rc del 1}; my $output = qx{echo '-- y' | ../src/task rc:bug.rc del 1};
like ($output, qr/is 100\% complete/ms, 'Empty project correctly reported as being 100% completed.'); like ($output, qr/is 100\% complete/ms, 'Empty project correctly reported as being 100% completed.');
# Cleanup. # Cleanup.

View file

@ -45,7 +45,7 @@ if (open my $fh, '>', 'bug.rc')
qx{../src/task rc:bug.rc add Test}; qx{../src/task rc:bug.rc add Test};
# Result: Attempt to undo add with confirmation=off # Result: Attempt to undo add with confirmation=off
my $output = qx{echo 'n' |../src/task rc:bug.rc rc.confirmation=off undo}; my $output = qx{echo '-- n' |../src/task rc:bug.rc rc.confirmation=off undo};
unlike ($output, qr/Are you sure/ms, 'Undo honours confirmation=off.'); unlike ($output, qr/Are you sure/ms, 'Undo honours confirmation=off.');
# Cleanup. # Cleanup.

View file

@ -49,10 +49,10 @@ qx{../src/task rc:bulk.rc add t4 due:thursday};
qx{../src/task rc:bulk.rc add t5 due:friday}; qx{../src/task rc:bulk.rc add t5 due:friday};
qx{../src/task rc:bulk.rc add t6 due:saturday}; qx{../src/task rc:bulk.rc add t6 due:saturday};
my $output = qx{echo "quit"|../src/task rc:bulk.rc pro:p1 pri:M 4 5 6}; my $output = qx{echo "-- quit"|../src/task rc:bulk.rc pro:p1 pri:M 4 5 6};
like ($output, qr/Modified 0 tasks/, '"quit" prevents any further modifications'); like ($output, qr/Modified 0 tasks/, '"quit" prevents any further modifications');
$output = qx{echo "All"|../src/task rc:bulk.rc pro:p1 pri:M 4 5 6}; $output = qx{echo "-- All"|../src/task rc:bulk.rc pro:p1 pri:M 4 5 6};
unlike ($output, qr/Task 4 "t4"\n - No changes were made/, 'Task 4 modified'); unlike ($output, qr/Task 4 "t4"\n - No changes were made/, 'Task 4 modified');
unlike ($output, qr/Task 5 "t5"\n - No changes were made/, 'Task 5 modified'); unlike ($output, qr/Task 5 "t5"\n - No changes were made/, 'Task 5 modified');
unlike ($output, qr/Task 6 "t6"\n - No changes were made/, 'Task 6 modified'); unlike ($output, qr/Task 6 "t6"\n - No changes were made/, 'Task 6 modified');

View file

@ -42,7 +42,7 @@ if (open my $fh, '>', 'confirm.rc')
# Create the response file. # Create the response file.
if (open my $fh, '>', 'response.txt') if (open my $fh, '>', 'response.txt')
{ {
print $fh "\n\nn\n"; print $fh "-- \n\nn\n";
close $fh; close $fh;
ok (-r 'response.txt', 'Created response.txt'); ok (-r 'response.txt', 'Created response.txt');
} }
@ -50,49 +50,49 @@ if (open my $fh, '>', 'response.txt')
qx{../src/task rc:confirm.rc add foo} for 1..10; qx{../src/task rc:confirm.rc add foo} for 1..10;
# Test the various forms of "Yes". # Test the various forms of "Yes".
my $output = qx{echo "Yes" | ../src/task rc:confirm.rc del 1}; my $output = qx{echo "-- Yes" | ../src/task rc:confirm.rc del 1};
like ($output, qr/Permanently delete task 1 'foo'\? \(y\/n\)/, 'confirmation - Yes works'); like ($output, qr/Permanently delete task 1 'foo'\? \(y\/n\)/, 'confirmation - Yes works');
unlike ($output, qr/Task not deleted\./, 'confirmation - Yes works'); unlike ($output, qr/Task not deleted\./, 'confirmation - Yes works');
$output = qx{echo "ye" | ../src/task rc:confirm.rc del 2}; $output = qx{echo "-- ye" | ../src/task rc:confirm.rc del 2};
like ($output, qr/Permanently delete task 2 'foo'\? \(y\/n\)/, 'confirmation - ye works'); like ($output, qr/Permanently delete task 2 'foo'\? \(y\/n\)/, 'confirmation - ye works');
unlike ($output, qr/Task not deleted\./, 'confirmation - ye works'); unlike ($output, qr/Task not deleted\./, 'confirmation - ye works');
$output = qx{echo "y" | ../src/task rc:confirm.rc del 3}; $output = qx{echo "-- y" | ../src/task rc:confirm.rc del 3};
like ($output, qr/Permanently delete task 3 'foo'\? \(y\/n\)/, 'confirmation - y works'); like ($output, qr/Permanently delete task 3 'foo'\? \(y\/n\)/, 'confirmation - y works');
unlike ($output, qr/Task not deleted\./, 'confirmation - y works'); unlike ($output, qr/Task not deleted\./, 'confirmation - y works');
$output = qx{echo "YES" | ../src/task rc:confirm.rc del 4}; $output = qx{echo "-- YES" | ../src/task rc:confirm.rc del 4};
like ($output, qr/Permanently delete task 4 'foo'\? \(y\/n\)/, 'confirmation - YES works'); like ($output, qr/Permanently delete task 4 'foo'\? \(y\/n\)/, 'confirmation - YES works');
unlike ($output, qr/Task not deleted\./, 'confirmation - YES works'); unlike ($output, qr/Task not deleted\./, 'confirmation - YES works');
$output = qx{echo "YE" | ../src/task rc:confirm.rc del 5}; $output = qx{echo "-- YE" | ../src/task rc:confirm.rc del 5};
like ($output, qr/Permanently delete task 5 'foo'\? \(y\/n\)/, 'confirmation - YE works'); like ($output, qr/Permanently delete task 5 'foo'\? \(y\/n\)/, 'confirmation - YE works');
unlike ($output, qr/Task not deleted\./, 'confirmation - YE works'); unlike ($output, qr/Task not deleted\./, 'confirmation - YE works');
$output = qx{echo "Y" | ../src/task rc:confirm.rc del 6}; $output = qx{echo "-- Y" | ../src/task rc:confirm.rc del 6};
like ($output, qr/Permanently delete task 6 'foo'\? \(y\/n\)/, 'confirmation - Y works'); like ($output, qr/Permanently delete task 6 'foo'\? \(y\/n\)/, 'confirmation - Y works');
unlike ($output, qr/Task not deleted\./, 'confirmation - Y works'); unlike ($output, qr/Task not deleted\./, 'confirmation - Y works');
# Test the various forms of "no". # Test the various forms of "no".
$output = qx{echo "no" | ../src/task rc:confirm.rc del 7}; $output = qx{echo "-- no" | ../src/task rc:confirm.rc del 7};
like ($output, qr/Permanently delete task 7 'foo'\? \(y\/n\)/, 'confirmation - no works'); like ($output, qr/Permanently delete task 7 'foo'\? \(y\/n\)/, 'confirmation - no works');
like ($output, qr/Task not deleted\./, 'confirmation - no works'); like ($output, qr/Task not deleted\./, 'confirmation - no works');
$output = qx{echo "n" | ../src/task rc:confirm.rc del 7}; $output = qx{echo "-- n" | ../src/task rc:confirm.rc del 7};
like ($output, qr/Permanently delete task 7 'foo'\? \(y\/n\)/, 'confirmation - n works'); like ($output, qr/Permanently delete task 7 'foo'\? \(y\/n\)/, 'confirmation - n works');
like ($output, qr/Task not deleted\./, 'confirmation - n works'); like ($output, qr/Task not deleted\./, 'confirmation - n works');
$output = qx{echo "NO" | ../src/task rc:confirm.rc del 7}; $output = qx{echo "-- NO" | ../src/task rc:confirm.rc del 7};
like ($output, qr/Permanently delete task 7 'foo'\? \(y\/n\)/, 'confirmation - NO works'); like ($output, qr/Permanently delete task 7 'foo'\? \(y\/n\)/, 'confirmation - NO works');
like ($output, qr/Task not deleted\./, 'confirmation - NO works'); like ($output, qr/Task not deleted\./, 'confirmation - NO works');
$output = qx{echo "N" | ../src/task rc:confirm.rc del 7}; $output = qx{echo "-- N" | ../src/task rc:confirm.rc del 7};
like ($output, qr/Permanently delete task 7 'foo'\? \(y\/n\)/, 'confirmation - N works'); like ($output, qr/Permanently delete task 7 'foo'\? \(y\/n\)/, 'confirmation - N works');
like ($output, qr/Task not deleted\./, 'confirmation - N works'); like ($output, qr/Task not deleted\./, 'confirmation - N works');
# Test Yes for multiple changes # Test Yes for multiple changes
$output = qx{echo -e "y\nY\nY\nY\nY" | ../src/task rc:confirm.rc 7-10 +bar}; $output = qx{echo -e "-- y\nY\nY\nY\nY" | ../src/task rc:confirm.rc 7-10 +bar};
like ($output, qr/Proceed with change\? \(yes\/no\/all\/quit\)/, 'multiple confirmations - Y works'); like ($output, qr/Proceed with change\? \(yes\/no\/all\/quit\)/, 'multiple confirmations - Y works');
like ($output, qr/Task 7 "foo"/, 'multiple confirmations - Y works'); like ($output, qr/Task 7 "foo"/, 'multiple confirmations - Y works');
like ($output, qr/Task 8 "foo"/, 'multiple confirmations - Y works'); like ($output, qr/Task 8 "foo"/, 'multiple confirmations - Y works');
@ -101,7 +101,7 @@ like ($output, qr/Task 10 "foo"/, 'multiple confirmations - Y works');
like ($output, qr/Modified 4 tasks/, 'multiple confirmations - Y works'); like ($output, qr/Modified 4 tasks/, 'multiple confirmations - Y works');
# Test no for multiple changes # Test no for multiple changes
$output = qx{echo -e "N\nn\nn\nn\nn" | ../src/task rc:confirm.rc 7-10 -bar}; $output = qx{echo -e "-- N\nn\nn\nn\nn" | ../src/task rc:confirm.rc 7-10 -bar};
like ($output, qr/Proceed with change\? \(yes\/no\/all\/quit\)/, 'multiple confirmations - n works'); like ($output, qr/Proceed with change\? \(yes\/no\/all\/quit\)/, 'multiple confirmations - n works');
like ($output, qr/Task 7 "foo"/, 'multiple confirmations - n works'); like ($output, qr/Task 7 "foo"/, 'multiple confirmations - n works');
like ($output, qr/Task 8 "foo"/, 'multiple confirmations - n works'); like ($output, qr/Task 8 "foo"/, 'multiple confirmations - n works');
@ -110,14 +110,14 @@ like ($output, qr/Task 10 "foo"/, 'multiple confirmations - n works');
like ($output, qr/Modified 0 tasks/, 'multiple confirmations - n works'); like ($output, qr/Modified 0 tasks/, 'multiple confirmations - n works');
# Test All for multiple changes # Test All for multiple changes
$output = qx{echo -e "a\nA" | ../src/task rc:confirm.rc 7-10 -bar}; $output = qx{echo -e "-- a\nA" | ../src/task rc:confirm.rc 7-10 -bar};
like ($output, qr/Proceed with change\? \(yes\/no\/all\/quit\)/, 'multiple confirmations - A works'); like ($output, qr/Proceed with change\? \(yes\/no\/all\/quit\)/, 'multiple confirmations - A works');
like ($output, qr/Task 7 "foo"/, 'multiple confirmations - A works'); like ($output, qr/Task 7 "foo"/, 'multiple confirmations - A works');
unlike ($output, qr/Task 8 "foo"/, 'multiple confirmations - A works'); unlike ($output, qr/Task 8 "foo"/, 'multiple confirmations - A works');
like ($output, qr/Modified 4 tasks/, 'multiple confirmations - A works'); like ($output, qr/Modified 4 tasks/, 'multiple confirmations - A works');
# Test quit for multiple changes # Test quit for multiple changes
$output = qx{echo "q" | ../src/task rc:confirm.rc 7-10 +bar}; $output = qx{echo "-- q" | ../src/task rc:confirm.rc 7-10 +bar};
like ($output, qr/Proceed with change\? \(yes\/no\/all\/quit\)/, 'multiple confirmations - q works'); like ($output, qr/Proceed with change\? \(yes\/no\/all\/quit\)/, 'multiple confirmations - q works');
like ($output, qr/Task 7 "foo"/, 'multiple confirmations - q works'); like ($output, qr/Task 7 "foo"/, 'multiple confirmations - q works');
unlike ($output, qr/Task 8 "foo"/, 'multiple confirmations - q works'); unlike ($output, qr/Task 8 "foo"/, 'multiple confirmations - q works');

View file

@ -49,7 +49,7 @@ $output = qx{../src/task rc:delete.rc delete 1; ../src/task rc:delete.rc info 1}
like ($output, qr/Status\s+Deleted\n/, 'Deleted'); like ($output, qr/Status\s+Deleted\n/, 'Deleted');
ok (-r 'completed.data', 'completed.data created'); ok (-r 'completed.data', 'completed.data created');
$output = qx{echo 'y' | ../src/task rc:delete.rc undo; ../src/task rc:delete.rc info 1}; $output = qx{echo '-- y' | ../src/task rc:delete.rc undo; ../src/task rc:delete.rc info 1};
like ($output, qr/Status\s+Pending\n/, 'Pending'); like ($output, qr/Status\s+Pending\n/, 'Pending');
ok (-r 'completed.data', 'completed.data created'); ok (-r 'completed.data', 'completed.data created');

View file

@ -175,16 +175,16 @@ qx{../src/task rc:dep.rc add Four};
qx{../src/task rc:dep.rc 2 dep:1; ../src/task rc:dep.rc 3 dep:2; ../src/task rc:dep.rc 4 dep:3}; qx{../src/task rc:dep.rc 2 dep:1; ../src/task rc:dep.rc 3 dep:2; ../src/task rc:dep.rc 4 dep:3};
# [30,31] # [30,31]
$output = qx{echo y | ../src/task rc:dep.rc do 2}; $output = qx{echo '-- y' | ../src/task rc:dep.rc do 2};
like ($output, qr/fixed/, 'dependencies - user prompted to fix broken chain after completing a blocked task'); like ($output, qr/fixed/, 'dependencies - user prompted to fix broken chain after completing a blocked task');
like ($output, qr/is blocked by/, 'dependencies - user nagged for completing a blocked task'); like ($output, qr/is blocked by/, 'dependencies - user nagged for completing a blocked task');
# [32] # [32]
$output = qx{echo y | ../src/task rc:dep.rc do 1}; $output = qx{echo '-- y' | ../src/task rc:dep.rc do 1};
unlike ($output, qr/fixed/, 'dependencies - user not prompted to fix broken chain when the head of the chain is marked as complete'); unlike ($output, qr/fixed/, 'dependencies - user not prompted to fix broken chain when the head of the chain is marked as complete');
# [33] # [33]
$output = qx{echo y | ../src/task rc:dep.rc del 4}; $output = qx{echo '-- y' | ../src/task rc:dep.rc del 4};
unlike ($output, qr/fixed/, 'dependencies - user not prompted to fix broken chain when the tail of the chain is deleted'); unlike ($output, qr/fixed/, 'dependencies - user not prompted to fix broken chain when the tail of the chain is deleted');
# [34] # [34]
@ -203,17 +203,17 @@ qx{../src/task rc:dep.rc 4 dep:3};
qx{../src/task rc:dep.rc 5 dep:4}; qx{../src/task rc:dep.rc 5 dep:4};
# [35] # [35]
qx{echo y | ../src/task rc:dep.rc do 2}; qx{echo '-- y' | ../src/task rc:dep.rc do 2};
$output = qx{../src/task rc:dep.rc depreport}; $output = qx{../src/task rc:dep.rc depreport};
like ($output, qr/\s1\s+One\s*\n\s2\s+1\s+Three\s*\n\s3\s+2\s+Four\s*\n\s4\s+3\s+Five/, 'dependencies - fixed chain after completing a blocked task'); like ($output, qr/\s1\s+One\s*\n\s2\s+1\s+Three\s*\n\s3\s+2\s+Four\s*\n\s4\s+3\s+Five/, 'dependencies - fixed chain after completing a blocked task');
# [36] # [36]
qx{printf "Y\nY\n" | ../src/task rc:dep.rc del 2}; qx{echo "-- Y\nY\n" | ../src/task rc:dep.rc del 2};
$output = qx{../src/task rc:dep.rc depreport}; $output = qx{../src/task rc:dep.rc depreport};
like ($output, qr/\s1\s+One\s*\n\s2\s+1\s+Four\s*\n\s3\s+2\s+Five/, 'dependencies - fixed chain after deleting a blocked task'); like ($output, qr/\s1\s+One\s*\n\s2\s+1\s+Four\s*\n\s3\s+2\s+Five/, 'dependencies - fixed chain after deleting a blocked task');
# [37] # [37]
qx{../src/task rc:dep.rc 2 dep:-1}; qx{../src/task rc:dep.rc 2 dep:-1};
$output = qx{../src/task rc:dep.rc depreport}; $output = qx{../src/task rc:dep.rc depreport};
like ($output, qr/\s1\s+One\s*\n\s2\s+Four\s*\n\s3\s+2\s+Five/, 'dependencies - chain should not be automatically repaired after manually removing a dependency'); like ($output, qr/\s1\s+One\s*\n\s2\s+Four\s*\n\s3\s+2\s+Five/, 'dependencies - chain should not be automatically repaired after manually removing a dependency');

View file

@ -56,7 +56,7 @@ if (open my $fh, '>', 'hook')
my $output = qx{../src/task rc:hook.rc version}; my $output = qx{../src/task rc:hook.rc version};
if ($output =~ /PUC-Rio/) if ($output =~ /PUC-Rio/)
{ {
my $output = qx{echo "\\nquit\\n" | ../src/task rc:hook.rc shell}; my $output = qx{echo "-- \\nquit\\n" | ../src/task rc:hook.rc shell};
like ($output, qr/<foo>/, 'format-prompt hook prompt -> <prompt>'); like ($output, qr/<foo>/, 'format-prompt hook prompt -> <prompt>');
} }
else else

View file

@ -54,12 +54,12 @@ if ($output =~ /PUC-Rio/)
my $good = $ENV{'PWD'} . '/hook:good'; my $good = $ENV{'PWD'} . '/hook:good';
my $bad = $ENV{'PWD'} . '/hook:bad'; my $bad = $ENV{'PWD'} . '/hook:bad';
qx{echo 'y'|../src/task rc:hook.rc config -- hook.pre-completed "$bad"}; qx{echo '-- y'|../src/task rc:hook.rc config -- hook.pre-completed "$bad"};
qx{../src/task rc:hook.rc add foo}; qx{../src/task rc:hook.rc add foo};
$output = qx{../src/task rc:hook.rc done 1}; $output = qx{../src/task rc:hook.rc done 1};
like ($output, qr/disallowed/, 'pre-completed hook rejected completion'); like ($output, qr/disallowed/, 'pre-completed hook rejected completion');
qx{echo 'y'|../src/task rc:hook.rc config -- hook.pre-completed "$good"}; qx{echo '-- y'|../src/task rc:hook.rc config -- hook.pre-completed "$good"};
$output = qx{../src/task rc:hook.rc done 1}; $output = qx{../src/task rc:hook.rc done 1};
like ($output, qr/Marked 1 task as done/, 'pre-completed hook allowed completion'); like ($output, qr/Marked 1 task as done/, 'pre-completed hook allowed completion');
} }

View file

@ -34,7 +34,7 @@ use Test::More tests => 15;
# Create the rc file, using rc.name:value. # Create the rc file, using rc.name:value.
unlink 'foo.rc'; unlink 'foo.rc';
rmtree 'foo', 0, 0; rmtree 'foo', 0, 0;
qx{echo 'y'|../src/task rc:foo.rc rc.data.location:foo}; qx{echo '-- y'|../src/task rc:foo.rc rc.data.location:foo};
ok (-r 'foo.rc', 'Created default rc file'); ok (-r 'foo.rc', 'Created default rc file');
ok (-d 'foo', 'Created default data directory'); ok (-d 'foo', 'Created default data directory');
@ -46,40 +46,40 @@ unlink 'foo.rc';
ok (!-r 'foo.rc', 'Removed foo.rc'); ok (!-r 'foo.rc', 'Removed foo.rc');
# Do it all again, with rc.name=value. # Do it all again, with rc.name=value.
qx{echo 'y'|../src/task rc:foo.rc rc.data.location:foo}; qx{echo '-- y'|../src/task rc:foo.rc rc.data.location:foo};
ok (-r 'foo.rc', 'Created default rc file'); ok (-r 'foo.rc', 'Created default rc file');
ok (-d 'foo', 'Created default data directory'); ok (-d 'foo', 'Created default data directory');
# Add a setting. # Add a setting.
qx{echo 'y'|../src/task rc:foo.rc config must_be_unique old}; qx{echo '-- y'|../src/task rc:foo.rc config must_be_unique old};
my $output = qx{../src/task rc:foo.rc show}; my $output = qx{../src/task rc:foo.rc show};
like ($output, qr/^must_be_unique\s+old/ms, 'config setting a new value'); like ($output, qr/^must_be_unique\s+old/ms, 'config setting a new value');
qx{echo 'y'|../src/task rc:foo.rc config must_be_unique new}; qx{echo '-- y'|../src/task rc:foo.rc config must_be_unique new};
$output = qx{../src/task rc:foo.rc show}; $output = qx{../src/task rc:foo.rc show};
like ($output, qr/^must_be_unique\s+new/ms, 'config overwriting an existing value'); like ($output, qr/^must_be_unique\s+new/ms, 'config overwriting an existing value');
qx{echo 'y'|../src/task rc:foo.rc config must_be_unique ''}; qx{echo '-- y'|../src/task rc:foo.rc config must_be_unique ''};
$output = qx{../src/task rc:foo.rc show}; $output = qx{../src/task rc:foo.rc show};
like ($output, qr/^must_be_unique/ms, 'config setting a blank value'); like ($output, qr/^must_be_unique/ms, 'config setting a blank value');
qx{echo 'y'|../src/task rc:foo.rc config must_be_unique}; qx{echo '-- y'|../src/task rc:foo.rc config must_be_unique};
$output = qx{../src/task rc:foo.rc show}; $output = qx{../src/task rc:foo.rc show};
unlike ($output, qr/^must_be_unique/ms, 'config removing a value'); unlike ($output, qr/^must_be_unique/ms, 'config removing a value');
# 'report.:b' is designed to get past the config command checks for recognized # 'report.:b' is designed to get past the config command checks for recognized
# names. # names.
qx{echo 'y'|../src/task rc:foo.rc config -- report.:b +c}; qx{echo '-- y'|../src/task rc:foo.rc config -- report.:b +c};
$output = qx{../src/task rc:foo.rc show}; $output = qx{../src/task rc:foo.rc show};
like ($output, qr/^report\.:b\s+\+c/ms, 'the -- operator is working'); like ($output, qr/^report\.:b\s+\+c/ms, 'the -- operator is working');
# Make sure the value is accepted if it has multiple words. # Make sure the value is accepted if it has multiple words.
qx{echo 'y'|../src/task rc:foo.rc config must_be_unique 'one two three'}; qx{echo '-- y'|../src/task rc:foo.rc config must_be_unique 'one two three'};
$output = qx{../src/task rc:foo.rc show}; $output = qx{../src/task rc:foo.rc show};
like ($output, qr/^must_be_unique\s+one two three/ms, 'config allows multi-word quoted values'); like ($output, qr/^must_be_unique\s+one two three/ms, 'config allows multi-word quoted values');
qx{echo 'y'|../src/task rc:foo.rc config must_be_unique one two three}; qx{echo '-- y'|../src/task rc:foo.rc config must_be_unique one two three};
$output = qx{../src/task rc:foo.rc show}; $output = qx{../src/task rc:foo.rc show};
like ($output, qr/^must_be_unique\s+one two three/ms, 'config allows multi-word unquoted values'); like ($output, qr/^must_be_unique\s+one two three/ms, 'config allows multi-word unquoted values');

View file

@ -47,8 +47,8 @@ my $output = qx{../src/task rc:seq.rc info 1};
like ($output, qr/Status\s+Completed/, 'sequence do 1'); like ($output, qr/Status\s+Completed/, 'sequence do 1');
$output = qx{../src/task rc:seq.rc info 2}; $output = qx{../src/task rc:seq.rc info 2};
like ($output, qr/Status\s+Completed/, 'sequence do 2'); like ($output, qr/Status\s+Completed/, 'sequence do 2');
qx{echo 'y'|../src/task rc:seq.rc undo}; qx{../src/task rc:seq.rc undo};
qx{echo 'y'|../src/task rc:seq.rc undo}; qx{../src/task rc:seq.rc undo};
$output = qx{../src/task rc:seq.rc info 1}; $output = qx{../src/task rc:seq.rc info 1};
like ($output, qr/Status\s+Pending/, 'sequence undo 1'); like ($output, qr/Status\s+Pending/, 'sequence undo 1');
$output = qx{../src/task rc:seq.rc info 2}; $output = qx{../src/task rc:seq.rc info 2};
@ -60,8 +60,8 @@ $output = qx{../src/task rc:seq.rc info 1};
like ($output, qr/Status\s+Deleted/, 'sequence delete 1'); like ($output, qr/Status\s+Deleted/, 'sequence delete 1');
$output = qx{../src/task rc:seq.rc info 2}; $output = qx{../src/task rc:seq.rc info 2};
like ($output, qr/Status\s+Deleted/, 'sequence delete 2'); like ($output, qr/Status\s+Deleted/, 'sequence delete 2');
qx{echo 'y'|../src/task rc:seq.rc undo}; qx{../src/task rc:seq.rc undo};
qx{echo 'y'|../src/task rc:seq.rc undo}; qx{../src/task rc:seq.rc undo};
$output = qx{../src/task rc:seq.rc info 1}; $output = qx{../src/task rc:seq.rc info 1};
like ($output, qr/Status\s+Pending/, 'sequence undo 1'); like ($output, qr/Status\s+Pending/, 'sequence undo 1');
$output = qx{../src/task rc:seq.rc info 2}; $output = qx{../src/task rc:seq.rc info 2};

View file

@ -41,11 +41,11 @@ if (open my $fh, '>', 'shell.rc')
} }
# Test the prompt. # Test the prompt.
my $output = qx{echo "\\nquit\\n" | ../src/task rc:shell.rc shell}; my $output = qx{echo "-- \\nquit\\n" | ../src/task rc:shell.rc shell};
like ($output, qr/testprompt>/, 'custom prompt is being used'); like ($output, qr/testprompt>/, 'custom prompt is being used');
# Test a simple add, then info. # Test a simple add, then info.
$output = qx{echo "add foo\ninfo 1\n" | ../src/task rc:shell.rc shell}; $output = qx{echo "-- add foo\ninfo 1\n" | ../src/task rc:shell.rc shell};
like ($output, qr/Description\s+foo/, 'add/info working'); like ($output, qr/Description\s+foo/, 'add/info working');
# Cleanup. # Cleanup.

View file

@ -34,7 +34,8 @@ use Test::More tests => 15;
if (open my $fh, '>', 'undo.rc') if (open my $fh, '>', 'undo.rc')
{ {
print $fh "data.location=.\n", print $fh "data.location=.\n",
"echo.command=no\n"; "echo.command=no\n",
"confirmation=no\n";
close $fh; close $fh;
ok (-r 'undo.rc', 'Created undo.rc'); ok (-r 'undo.rc', 'Created undo.rc');
} }
@ -48,7 +49,7 @@ $output = qx{../src/task rc:undo.rc do 1; ../src/task rc:undo.rc info 1};
ok (-r 'completed.data', 'completed.data created'); ok (-r 'completed.data', 'completed.data created');
like ($output, qr/Status\s+Completed\n/, 'Completed'); like ($output, qr/Status\s+Completed\n/, 'Completed');
$output = qx{echo 'y'|../src/task rc:undo.rc undo; ../src/task rc:undo.rc info 1}; $output = qx{../src/task rc:undo.rc undo; ../src/task rc:undo.rc info 1};
ok (-r 'completed.data', 'completed.data created'); ok (-r 'completed.data', 'completed.data created');
like ($output, qr/Status\s+Pending\n/, 'Pending'); like ($output, qr/Status\s+Pending\n/, 'Pending');