mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-07-07 20:06:36 +02:00
Dependencies
- Supports new "depends" attribute. - Supports "task <id> depends:1,2". - Supports "task <id> depends:-1,-2". - Supports id <--> uuid mapping in TDB.
This commit is contained in:
parent
c6f6d405e3
commit
7e5c0eb9a5
6 changed files with 127 additions and 1 deletions
|
@ -63,6 +63,7 @@ static const char* modifiableNames[] =
|
|||
"recur",
|
||||
"until",
|
||||
"wait",
|
||||
"depends",
|
||||
};
|
||||
|
||||
// Synonyms on the same line.
|
||||
|
|
26
src/TDB.cpp
26
src/TDB.cpp
|
@ -304,6 +304,10 @@ int TDB::loadPending (std::vector <Task>& tasks, Filter& filter)
|
|||
task.id = mId++;
|
||||
|
||||
mPending.push_back (task);
|
||||
|
||||
// Maintain mapping for ease of link/dependency resolution.
|
||||
mI2U[task.id] = task.get ("uuid");
|
||||
mU2I[task.get ("uuid")] = task.id;
|
||||
}
|
||||
|
||||
++line_number;
|
||||
|
@ -425,6 +429,8 @@ int TDB::loadCompleted (std::vector <Task>& tasks, Filter& filter)
|
|||
void TDB::add (const Task& task)
|
||||
{
|
||||
mNew.push_back (task);
|
||||
mI2U[task.id] = task.get ("uuid");
|
||||
mU2I[task.get ("uuid")] = task.id;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1425,6 +1431,26 @@ void TDB::merge (const std::string& mergeFile)
|
|||
mods.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string TDB::uuid (int id) const
|
||||
{
|
||||
std::map <int, std::string>::const_iterator i;
|
||||
if ((i = mI2U.find (id)) != mI2U.end ())
|
||||
return i->second;
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int TDB::id (const std::string& uuid) const
|
||||
{
|
||||
std::map <std::string, int>::const_iterator i;
|
||||
if ((i = mU2I.find (uuid)) != mU2I.end ())
|
||||
return i->second;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
FILE* TDB::openAndLock (const std::string& file)
|
||||
{
|
||||
|
|
|
@ -64,6 +64,9 @@ public:
|
|||
void undo ();
|
||||
void merge (const std::string&);
|
||||
|
||||
std::string uuid (int) const;
|
||||
int id (const std::string&) const;
|
||||
|
||||
private:
|
||||
FILE* openAndLock (const std::string&);
|
||||
void writeUndo (const Task&, FILE*);
|
||||
|
@ -79,6 +82,9 @@ private:
|
|||
std::vector <Task> mCompleted; // Contents of pending.data
|
||||
std::vector <Task> mNew; // Uncommitted new tasks
|
||||
std::vector <Task> mModified; // Uncommitted modified tasks
|
||||
|
||||
std::map <int, std::string> mI2U; // ID -> UUID map
|
||||
std::map <std::string, int> mU2I; // UUID -> ID map
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
66
src/Task.cpp
66
src/Task.cpp
|
@ -467,6 +467,72 @@ void Task::removeAnnotations ()
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Task::addDependency (int id)
|
||||
{
|
||||
std::string uuid = context.tdb.uuid (id);
|
||||
if (uuid == "")
|
||||
{
|
||||
std::stringstream s;
|
||||
s << "Could not create a dependency on task " << id << " - not found.";
|
||||
throw s.str ();
|
||||
}
|
||||
|
||||
std::string depends = get ("depends");
|
||||
if (depends.length ())
|
||||
{
|
||||
if (depends.find (uuid) == std::string::npos)
|
||||
set ("depends", depends + "," + uuid);
|
||||
}
|
||||
else
|
||||
set ("depends", uuid);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Task::removeDependency (int id)
|
||||
{
|
||||
std::string uuid = context.tdb.uuid (id);
|
||||
if (uuid == "")
|
||||
{
|
||||
std::stringstream s;
|
||||
s << "Could not find a UUID for id " << id << ".";
|
||||
throw s.str ();
|
||||
}
|
||||
|
||||
std::vector <std::string> deps;
|
||||
split (deps, get ("depends"), ',');
|
||||
|
||||
std::vector <std::string>::iterator i;
|
||||
i = std::find (deps.begin (), deps.end (), uuid);
|
||||
if (i != deps.end ())
|
||||
{
|
||||
deps.erase (i);
|
||||
std::string combined;
|
||||
join (combined, ",", deps);
|
||||
set ("depends", combined);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Task::getDependencies (std::vector <int>& all) const
|
||||
{
|
||||
std::vector <std::string> deps;
|
||||
split (deps, get ("depends"), ',');
|
||||
|
||||
all.clear ();
|
||||
|
||||
std::vector <std::string>::iterator i;
|
||||
for (i = deps.begin (); i != deps.end (); ++i)
|
||||
all.push_back (context.tdb.id (*i));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Task::getDependencies (std::vector <std::string>& all) const
|
||||
{
|
||||
all.clear ();
|
||||
split (all, get ("depends"), ',');
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int Task::getTagCount ()
|
||||
{
|
||||
|
|
|
@ -73,6 +73,11 @@ public:
|
|||
void addAnnotation (const std::string&);
|
||||
void removeAnnotations ();
|
||||
|
||||
void addDependency (int);
|
||||
void removeDependency (int);
|
||||
void getDependencies (std::vector <int>&) const;
|
||||
void getDependencies (std::vector <std::string>&) const;
|
||||
|
||||
void validate () const;
|
||||
|
||||
private:
|
||||
|
|
|
@ -99,6 +99,8 @@ int handleAdd (std::string &outs)
|
|||
!context.task.has ("recur"))
|
||||
throw std::string ("You cannot specify an until date for a non-recurring task.");
|
||||
|
||||
// TODO Resolve dependencies.
|
||||
|
||||
// Only valid tasks can be added.
|
||||
context.task.validate ();
|
||||
|
||||
|
@ -164,6 +166,8 @@ int handleLog (std::string &outs)
|
|||
foreach (tag, context.tagAdditions)
|
||||
context.task.addTag (*tag);
|
||||
|
||||
// TODO Resolve dependencies.
|
||||
|
||||
// Only valid tasks can be added.
|
||||
context.task.validate ();
|
||||
|
||||
|
@ -2231,7 +2235,25 @@ int deltaAttributes (Task& task)
|
|||
task.setStatus (Task::waiting);
|
||||
}
|
||||
|
||||
if (att->second.value () == "")
|
||||
// Modifying dependencies requires adding/removing uuids.
|
||||
else if (att->second.name () == "depends")
|
||||
{
|
||||
std::vector <std::string> deps;
|
||||
split (deps, att->second.value (), ',');
|
||||
|
||||
std::vector <std::string>::iterator i;
|
||||
for (i = deps.begin (); i != deps.end (); i++)
|
||||
{
|
||||
int id = atoi (i->c_str ());
|
||||
if (id < 0)
|
||||
task.removeDependency (-id);
|
||||
else
|
||||
task.addDependency (id);
|
||||
}
|
||||
}
|
||||
|
||||
// Now the generalized handling.
|
||||
else if (att->second.value () == "")
|
||||
task.remove (att->second.name ());
|
||||
else
|
||||
// One of the few places where the compound attribute name is used.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue