mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
Improved GC and Shadow File Handling
- Every command now returns an output string, or at least has an opportunity to do so. - TDB::gc is only performed a) when allowed, and b) when the command will display line numbers. - updateShadowFile is only performed when a) shadow updates are allowed, and either b) when a command is guaranteed to have modified a task or c) when TDB:gc has already made changes.
This commit is contained in:
parent
64cfc26ff3
commit
c9a6d2a750
3 changed files with 107 additions and 74 deletions
|
@ -48,8 +48,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void handleAdd (TDB& tdb, T& task, Config& conf)
|
std::string handleAdd (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
char entryTime[16];
|
char entryTime[16];
|
||||||
sprintf (entryTime, "%u", (unsigned int) time (NULL));
|
sprintf (entryTime, "%u", (unsigned int) time (NULL));
|
||||||
task.setAttribute ("entry", entryTime);
|
task.setAttribute ("entry", entryTime);
|
||||||
|
@ -86,6 +88,8 @@ void handleAdd (TDB& tdb, T& task, Config& conf)
|
||||||
|
|
||||||
if (!tdb.addT (task))
|
if (!tdb.addT (task))
|
||||||
throw std::string ("Could not create new task.");
|
throw std::string ("Could not create new task.");
|
||||||
|
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -547,8 +551,10 @@ std::string handleStop (TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void handleDone (TDB& tdb, T& task, Config& conf)
|
std::string handleDone (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
if (!tdb.completeT (task))
|
if (!tdb.completeT (task))
|
||||||
throw std::string ("Could not mark task as completed.");
|
throw std::string ("Could not mark task as completed.");
|
||||||
|
|
||||||
|
@ -566,11 +572,14 @@ void handleDone (TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
nag (tdb, task, conf);
|
nag (tdb, task, conf);
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void handleExport (TDB& tdb, T& task, Config& conf)
|
std::string handleExport (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
// Use the description as a file name, then clobber the description so the
|
// Use the description as a file name, then clobber the description so the
|
||||||
// file name isn't used for filtering.
|
// file name isn't used for filtering.
|
||||||
std::string file = trim (task.getDescription ());
|
std::string file = trim (task.getDescription ());
|
||||||
|
@ -610,11 +619,14 @@ void handleExport (TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw std::string ("You must specify a file to write to.");
|
throw std::string ("You must specify a file to write to.");
|
||||||
|
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void handleModify (TDB& tdb, T& task, Config& conf)
|
std::string handleModify (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
std::vector <T> all;
|
std::vector <T> all;
|
||||||
tdb.pendingT (all);
|
tdb.pendingT (all);
|
||||||
|
|
||||||
|
@ -695,11 +707,12 @@ void handleModify (TDB& tdb, T& task, Config& conf)
|
||||||
tdb.modifyT (original);
|
tdb.modifyT (original);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return out.str ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw std::string ("Task not found.");
|
throw std::string ("Task not found.");
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
74
src/task.cpp
74
src/task.cpp
|
@ -27,6 +27,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -47,8 +48,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
static void shortUsage (Config& conf)
|
static std::string shortUsage (Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
Table table;
|
Table table;
|
||||||
int width = conf.get ("defaultwidth", 80);
|
int width = conf.get ("defaultwidth", 80);
|
||||||
#ifdef HAVE_LIBNCURSES
|
#ifdef HAVE_LIBNCURSES
|
||||||
|
@ -192,21 +194,22 @@ static void shortUsage (Config& conf)
|
||||||
table.addCell (row, 2, description);
|
table.addCell (row, 2, description);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << table.render ()
|
out << table.render ()
|
||||||
<< std::endl
|
<< std::endl
|
||||||
<< "See http://www.beckingham.net/task.html for the latest releases and a "
|
<< "See http://www.beckingham.net/task.html for the latest releases and a "
|
||||||
<< "full tutorial. New releases containing fixes and enhancements are "
|
<< "full tutorial. New releases containing fixes and enhancements are "
|
||||||
<< "made frequently."
|
<< "made frequently."
|
||||||
<< std::endl
|
<< std::endl
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
static void longUsage (Config& conf)
|
static std::string longUsage (Config& conf)
|
||||||
{
|
{
|
||||||
shortUsage (conf);
|
std::stringstream out;
|
||||||
|
out << shortUsage (conf)
|
||||||
std::cout
|
|
||||||
<< "ID is the numeric identifier displayed by the 'task list' command." << "\n"
|
<< "ID is the numeric identifier displayed by the 'task list' command." << "\n"
|
||||||
<< "\n"
|
<< "\n"
|
||||||
<< "Tags are arbitrary words, any quantity:" << "\n"
|
<< "Tags are arbitrary words, any quantity:" << "\n"
|
||||||
|
@ -234,6 +237,8 @@ static void longUsage (Config& conf)
|
||||||
<< "Many characters have special meaning to the shell, including:" << "\n"
|
<< "Many characters have special meaning to the shell, including:" << "\n"
|
||||||
<< " $ ! ' \" ( ) ; \\ ` * ? { } [ ] < > | & % # ~" << "\n"
|
<< " $ ! ' \" ( ) ; \\ ` * ? { } [ ] < > | & % # ~" << "\n"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -790,34 +795,49 @@ std::string runTaskCommand (
|
||||||
T task;
|
T task;
|
||||||
parse (args, command, task, conf);
|
parse (args, command, task, conf);
|
||||||
|
|
||||||
std::string out = "";
|
bool gcMod = false; // Change occurred by way of gc.
|
||||||
|
bool cmdMod = false; // Change occurred by way of command type.
|
||||||
|
std::string out;
|
||||||
|
|
||||||
if (command == "" && task.getId ()) { handleModify (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); }
|
// Read-only commands with no side effects.
|
||||||
else if (command == "add") { handleAdd (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); }
|
if (command == "export") { out = handleExport (tdb, task, conf); }
|
||||||
else if (command == "done") { handleDone (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); }
|
|
||||||
else if (command == "export") { handleExport (tdb, task, conf ); }
|
|
||||||
else if (command == "projects") { out = handleProjects (tdb, task, conf); }
|
else if (command == "projects") { out = handleProjects (tdb, task, conf); }
|
||||||
else if (command == "tags") { out = handleTags (tdb, task, conf); }
|
else if (command == "tags") { out = handleTags (tdb, task, conf); }
|
||||||
else if (command == "info") { out = handleInfo (tdb, task, conf); }
|
else if (command == "info") { out = handleInfo (tdb, task, conf); }
|
||||||
else if (command == "undelete") { out = handleUndelete (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); }
|
|
||||||
else if (command == "delete") { out = handleDelete (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); }
|
|
||||||
else if (command == "start") { out = handleStart (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); }
|
|
||||||
else if (command == "stop") { out = handleStop (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); }
|
|
||||||
else if (command == "undo") { out = handleUndo (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); }
|
|
||||||
else if (command == "stats") { out = handleReportStats (tdb, task, conf); }
|
else if (command == "stats") { out = handleReportStats (tdb, task, conf); }
|
||||||
else if (command == "completed") { if (gc) tdb.gc (); out = handleCompleted (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); } // TODO replace with Custom
|
else if (command == "history") { out = handleReportHistory (tdb, task, conf); }
|
||||||
else if (command == "summary") { if (gc) tdb.gc (); out = handleReportSummary (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); }
|
else if (command == "ghistory") { out = handleReportGHistory (tdb, task, conf); }
|
||||||
else if (command == "next") { if (gc) tdb.gc (); out = handleReportNext (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); } // TODO replace with Custom
|
else if (command == "calendar") { out = handleReportCalendar (tdb, task, conf); }
|
||||||
else if (command == "history") { if (gc) tdb.gc (); out = handleReportHistory (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); }
|
else if (command == "summary") { out = handleReportSummary (tdb, task, conf); }
|
||||||
else if (command == "ghistory") { if (gc) tdb.gc (); out = handleReportGHistory (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); }
|
|
||||||
else if (command == "calendar") { if (gc) tdb.gc (); out = handleReportCalendar (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); }
|
|
||||||
else if (command == "active") { if (gc) tdb.gc (); out = handleReportActive (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); } // TODO replace with Custom
|
|
||||||
else if (command == "overdue") { if (gc) tdb.gc (); out = handleReportOverdue (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); } // TODO replace with Custom
|
|
||||||
else if (command == "colors") { out = handleColor ( conf); }
|
else if (command == "colors") { out = handleColor ( conf); }
|
||||||
else if (command == "version") { out = handleVersion ( conf); }
|
else if (command == "version") { out = handleVersion ( conf); }
|
||||||
else if (command == "help") { longUsage ( conf ); }
|
else if (command == "help") { out = longUsage ( conf); }
|
||||||
else if (isCustomReport (command)) { if (gc) tdb.gc (); out = handleCustomReport (tdb, task, conf, command); if (shadow) updateShadowFile (tdb, conf); } // New Custom reports
|
|
||||||
else { shortUsage ( conf ); }
|
// Commands that cause updates.
|
||||||
|
else if (command == "" && task.getId ()) { cmdMod = true; out = handleModify (tdb, task, conf); }
|
||||||
|
else if (command == "add") { cmdMod = true; out = handleAdd (tdb, task, conf); }
|
||||||
|
else if (command == "done") { cmdMod = true; out = handleDone (tdb, task, conf); }
|
||||||
|
else if (command == "undelete") { cmdMod = true; out = handleUndelete (tdb, task, conf); }
|
||||||
|
else if (command == "delete") { cmdMod = true; out = handleDelete (tdb, task, conf); }
|
||||||
|
else if (command == "start") { cmdMod = true; out = handleStart (tdb, task, conf); }
|
||||||
|
else if (command == "stop") { cmdMod = true; out = handleStop (tdb, task, conf); }
|
||||||
|
else if (command == "undo") { cmdMod = true; out = handleUndo (tdb, task, conf); }
|
||||||
|
|
||||||
|
// Command that display IDs and therefore need TDB::gc first.
|
||||||
|
|
||||||
|
else if (command == "completed") { if (gc) gcMod = tdb.gc (); out = handleCompleted (tdb, task, conf); }
|
||||||
|
else if (command == "next") { if (gc) gcMod = tdb.gc (); out = handleReportNext (tdb, task, conf); }
|
||||||
|
else if (command == "active") { if (gc) gcMod = tdb.gc (); out = handleReportActive (tdb, task, conf); }
|
||||||
|
else if (command == "overdue") { if (gc) gcMod = tdb.gc (); out = handleReportOverdue (tdb, task, conf); }
|
||||||
|
else if (isCustomReport (command)) { if (gc) gcMod = tdb.gc (); out = handleCustomReport (tdb, task, conf, command); }
|
||||||
|
|
||||||
|
// If the command is not recognized, display usage.
|
||||||
|
else { out = shortUsage (conf); }
|
||||||
|
|
||||||
|
// Only update the shadow file if such an update was not suppressed (shadow),
|
||||||
|
// and if an actual change occurred (gcMod || cmdMod).
|
||||||
|
if (shadow && (gcMod || cmdMod))
|
||||||
|
updateShadowFile (tdb, conf);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,10 +74,10 @@ std::string runTaskCommand (int, char**, TDB&, Config&, bool gc = true, bool sha
|
||||||
std::string runTaskCommand (std::vector <std::string>&, TDB&, Config&, bool gc = false, bool shadow = false);
|
std::string runTaskCommand (std::vector <std::string>&, TDB&, Config&, bool gc = false, bool shadow = false);
|
||||||
|
|
||||||
// command.cpp
|
// command.cpp
|
||||||
void handleAdd (TDB&, T&, Config&);
|
std::string handleAdd (TDB&, T&, Config&);
|
||||||
void handleExport (TDB&, T&, Config&);
|
std::string handleExport (TDB&, T&, Config&);
|
||||||
void handleDone (TDB&, T&, Config&);
|
std::string handleDone (TDB&, T&, Config&);
|
||||||
void handleModify (TDB&, T&, Config&);
|
std::string handleModify (TDB&, T&, Config&);
|
||||||
std::string handleProjects (TDB&, T&, Config&);
|
std::string handleProjects (TDB&, T&, Config&);
|
||||||
std::string handleTags (TDB&, T&, Config&);
|
std::string handleTags (TDB&, T&, Config&);
|
||||||
std::string handleUndelete (TDB&, T&, Config&);
|
std::string handleUndelete (TDB&, T&, Config&);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue