diff --git a/ChangeLog b/ChangeLog index b01837b96..009c569ed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2.4.2 () - +- TW-41 Tasks in subprojects are not counted in project completion (thanks + to Renato Alves). +- TW-1450 Projects command should trigger running garbage collector (thanks to + Tomas Babej). - TW-1535 move default listing-break from list to ls (thanks to David Patrick). - TW-1545 cc1plus: error: unrecognized command line option '-std=c++11' (thanks to Petteri). @@ -17,6 +21,7 @@ - Closed dangling pipes in execute (), resolving problems when a hook script forks (thanks to Jens Erat). - Re-enabled hook script feedback when exiting with 0 exit status. +- The 'info' command now shows virtual tags. ------ current release --------------------------- diff --git a/NEWS b/NEWS index bebc9560c..16224a133 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,7 @@ New Features in taskwarrior 2.4.2 - Ability to set context, which serves as a permanent user-defined filter. + - The 'info' command now shows virtual tags. New commands in taskwarrior 2.4.2 diff --git a/scripts/bash/task.sh b/scripts/bash/task.sh index 58881ab06..7c37944cc 100644 --- a/scripts/bash/task.sh +++ b/scripts/bash/task.sh @@ -68,7 +68,13 @@ _task_offer_projects() { COMPREPLY=( $(compgen -W "$($taskcommand _projects)" -- ${cur/*:/}) ) } -_task() +_task_offer_contexts() { + COMPREPLY=( $(compgen -W "$($taskcommand _context) define delete list none show" -- $cur) ) +} + +_task_context_alias=$($taskcommand show | grep alias.*context | cut -d' ' -f1 | cut -d. -f2) + +_task() { local cur prev opts base @@ -91,6 +97,10 @@ _task() opts="$commands_aliases $($taskcommand _columns)" case "${prev}" in + $_task_context_alias|cont|conte|contex|context) + _task_offer_contexts + return 0 + ;; :) case "${prev2}" in pri|prior|priori|priorit|priority) diff --git a/src/Context.cpp b/src/Context.cpp index 4d0e6bc0b..e7adc9b89 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -275,7 +275,7 @@ int Context::initialize (int argc, const char** argv) //////////////////////////////////////////////////////////////////////////// // - // [8] Run on.launch hooks. + // [8] Initialize hooks. // //////////////////////////////////////////////////////////////////////////// diff --git a/src/Duration.cpp b/src/Duration.cpp index 36b4a8bfd..c0b24501b 100644 --- a/src/Duration.cpp +++ b/src/Duration.cpp @@ -61,31 +61,48 @@ static struct {"fortnight", 14 * DAY, true}, {"hours", 1 * HOUR, false}, {"hour", 1 * HOUR, true}, + {"hrs", 1 * HOUR, true}, + {"hr", 1 * HOUR, true}, {"h", 1 * HOUR, false}, {"minutes", 1 * MINUTE, false}, {"minute", 1 * MINUTE, false}, + {"mins", 1 * MINUTE, false}, {"min", 1 * MINUTE, false}, {"monthly", 30 * DAY, true}, {"months", 30 * DAY, false}, {"month", 30 * DAY, true}, + {"mnths", 30 * DAY, false}, + {"mths", 30 * DAY, false}, + {"mth", 30 * DAY, false}, + {"mos", 30 * DAY, false}, {"mo", 30 * DAY, false}, + {"m", 30 * DAY, false}, {"quarterly", 91 * DAY, true}, {"quarters", 91 * DAY, false}, {"quarter", 91 * DAY, true}, + {"qrtrs", 91 * DAY, false}, + {"qtrs", 91 * DAY, false}, + {"qtr", 91 * DAY, false}, {"q", 91 * DAY, false}, {"semiannual", 183 * DAY, true}, {"sennight", 14 * DAY, false}, {"seconds", 1 * SECOND, false}, {"second", 1 * SECOND, true}, + {"secs", 1 * SECOND, true}, + {"sec", 1 * SECOND, true}, {"s", 1 * SECOND, false}, {"weekdays", 1 * DAY, true}, {"weekly", 7 * DAY, true}, {"weeks", 7 * DAY, false}, {"week", 7 * DAY, true}, + {"wks", 7 * DAY, true}, + {"wk", 7 * DAY, true}, {"w", 7 * DAY, false}, {"yearly", 365 * DAY, true}, {"years", 365 * DAY, false}, {"year", 365 * DAY, true}, + {"yrs", 365 * DAY, true}, + {"yr", 365 * DAY, true}, {"y", 365 * DAY, false}, }; diff --git a/src/TDB2.cpp b/src/TDB2.cpp index d7d17d589..579090b77 100644 --- a/src/TDB2.cpp +++ b/src/TDB2.cpp @@ -572,7 +572,7 @@ void TDB2::add (Task& task, bool add_to_backlog /* = true */) if (add_to_backlog) context.hooks.onAdd (task); - update (uuid, task, add_to_backlog); + update (uuid, task, add_to_backlog, true); } //////////////////////////////////////////////////////////////////////////////// @@ -580,7 +580,6 @@ void TDB2::modify (Task& task, bool add_to_backlog /* = true */) { // Ensure the task is consistent, and provide defaults if necessary. task.validate (false); - task.upgradeLegacyValues (); std::string uuid = task.get ("uuid"); // Get the unmodified task as reference, so the hook can compare. @@ -598,14 +597,15 @@ void TDB2::modify (Task& task, bool add_to_backlog /* = true */) void TDB2::update ( const std::string& uuid, Task& task, - const bool add_to_backlog) + const bool add_to_backlog, + const bool addition) { // Validate to add metadata. task.validate (false); // If the task already exists, it is a modification, else addition. Task original; - if (get (task.get ("uuid"), original)) + if (not addition && get (task.get ("uuid"), original)) { // Update the task, wherever it is. if (!pending.modify_task (task)) @@ -1179,18 +1179,21 @@ int TDB2::gc () // Allowed as an override, but not recommended. if (context.config.getBoolean ("gc")) { - std::vector pending_tasks = pending.get_tasks (); + std::vector pending_tasks = pending.get_tasks (); + + // TODO Thread. std::vector completed_tasks = completed.get_tasks (); + // TODO Assume pending < completed, therefore there is room here to process + // data before joining with the completed.data thread. + bool pending_changes = false; bool completed_changes = false; - std::vector pending_tasks_after; std::vector completed_tasks_after; // Reduce unnecessary allocation/copies. pending_tasks_after.reserve (pending_tasks.size ()); - completed_tasks_after.reserve (completed_tasks.size ()); // Scan all pending tasks, looking for any that need to be relocated to // completed, or need to be 'woken'. @@ -1227,6 +1230,11 @@ int TDB2::gc () } } + // TODO Join completed.data thread. + + // Reduce unnecessary allocation/copies. + completed_tasks_after.reserve (completed_tasks.size ()); + // Scan all completed tasks, looking for any that need to be relocated to // pending. for (task = completed_tasks.begin (); diff --git a/src/TDB2.h b/src/TDB2.h index bb3f2cd32..d019fc487 100644 --- a/src/TDB2.h +++ b/src/TDB2.h @@ -128,7 +128,7 @@ public: private: void gather_changes (); - void update (const std::string&, Task&, const bool); + void update (const std::string&, Task&, const bool, const bool addition = false); bool verifyUniqueUUID (const std::string&); void show_diff (const std::string&, const std::string&, const std::string&); void revert_undo (std::vector &, std::string&, std::string&, std::string&, std::string&); diff --git a/src/Task.cpp b/src/Task.cpp index 0deb5b652..d60f26c11 100644 --- a/src/Task.cpp +++ b/src/Task.cpp @@ -565,7 +565,6 @@ void Task::parse (const std::string& input) nl.getQuoted ('"', value)) { legacyAttributeMap (name); - legacyValueMap (name, value); if (name.substr (0, 11) == "annotation_") ++annotation_count; @@ -586,8 +585,6 @@ void Task::parse (const std::string& input) parseJSON (copy); else throw std::string (STRING_RECORD_NOT_FF4); - - upgradeLegacyValues (); } catch (const std::string&) @@ -719,8 +716,6 @@ void Task::parseJSON (const std::string& line) } } } - - upgradeLegacyValues (); } } @@ -1105,6 +1100,7 @@ int Task::getTagCount () const bool Task::hasTag (const std::string& tag) const { // Synthetic tags - dynamically generated, but do not occupy storage space. + // Note: This list must match that in CmdInfo::execute. if (tag == "BLOCKED") return is_blocked; if (tag == "UNBLOCKED") return !is_blocked; if (tag == "BLOCKING") return is_blocking; @@ -2214,78 +2210,3 @@ void Task::modify (modType type, bool text_required /* = false */) } //////////////////////////////////////////////////////////////////////////////// -void Task::upgradeLegacyValues () -{ - // 2.4.0 Update recurrence values. - if (has ("recur")) - { - std::string value = get ("recur"); - if (value != "") - { - std::string new_value = value; - upgradeLegacyValue (new_value); - - if (new_value != value) - { - set ("recur", new_value); - context.debug (format ("Legacy upgrade: recur {1} --> {2}", value, new_value)); - } - } - } - - // 2.4.0 Update UDA duration values. - Config::const_iterator name; - for (name = context.config.begin (); name != context.config.end (); ++name) - { - if (name->first.substr (0, 4) == "uda." && - name->first.find (".type") != std::string::npos) - { - if (name->second == "duration") - { - std::string::size_type period = name->first.find ('.', 4); - if (period != std::string::npos) - { - std::string uda = name->first.substr (4, period - 4); - std::string value = get (uda); - std::string new_value = value; - upgradeLegacyValue (new_value); - - if (new_value != value) - { - set ("recur", new_value); - context.debug (format ("Legacy upgrade: UDA {1}, {2} --> {3}", uda, value, new_value)); - } - } - } - } - } -} - -//////////////////////////////////////////////////////////////////////////////// -void Task::upgradeLegacyValue (std::string& value) -{ - std::string::size_type len = value.length (); - std::string::size_type p; - - if (value == "-") value = "0s"; - else if ((p = value.find ("hr")) != std::string::npos && p == len - 2) value = value.substr (0, p) + "h"; - else if ((p = value.find ("hrs")) != std::string::npos && p == len - 3) value = value.substr (0, p) + "h"; - else if ((p = value.find ("mins")) != std::string::npos && p == len - 4) value = value.substr (0, p) + "min"; - else if ((p = value.find ("mnths")) != std::string::npos && p == len - 5) value = value.substr (0, p) + "mo"; - else if ((p = value.find ("mos")) != std::string::npos && p == len - 3) value = value.substr (0, p) + "mo"; - else if ((p = value.find ("mth")) != std::string::npos && p == len - 3) value = value.substr (0, p) + "mo"; - else if ((p = value.find ("mths")) != std::string::npos && p == len - 4) value = value.substr (0, p) + "mo"; - else if ((p = value.find ("qrtrs")) != std::string::npos && p == len - 5) value = value.substr (0, p) + "q"; - else if ((p = value.find ("qtr")) != std::string::npos && p == len - 3) value = value.substr (0, p) + "q"; - else if ((p = value.find ("qtrs")) != std::string::npos && p == len - 4) value = value.substr (0, p) + "q"; - else if ((p = value.find ("sec")) != std::string::npos && p == len - 3) value = value.substr (0, p) + "s"; - else if ((p = value.find ("secs")) != std::string::npos && p == len - 4) value = value.substr (0, p) + "s"; - else if ((p = value.find ("wk")) != std::string::npos && p == len - 2) value = value.substr (0, p) + "w"; - else if ((p = value.find ("wks")) != std::string::npos && p == len - 3) value = value.substr (0, p) + "w"; - else if ((p = value.find ("yr")) != std::string::npos && p == len - 2) value = value.substr (0, p) + "y"; - else if ((p = value.find ("yrs")) != std::string::npos && p == len - 3) value = value.substr (0, p) + "y"; - - // It is not an error to have a non-legacy value. -} - -//////////////////////////////////////////////////////////////////////////////// diff --git a/src/Task.h b/src/Task.h index 0c13cce33..4eeca3854 100644 --- a/src/Task.h +++ b/src/Task.h @@ -154,7 +154,6 @@ public: enum modType {modReplace, modPrepend, modAppend, modAnnotate}; void modify (modType, bool text_required = false); - void upgradeLegacyValues (); private: int determineVersion (const std::string&); @@ -163,7 +162,6 @@ private: void validate_before (const std::string&, const std::string&); const std::string encode (const std::string&) const; const std::string decode (const std::string&) const; - void upgradeLegacyValue (std::string&); public: float urgency_priority () const; diff --git a/src/commands/CmdInfo.cpp b/src/commands/CmdInfo.cpp index 9097472df..8121dd168 100644 --- a/src/commands/CmdInfo.cpp +++ b/src/commands/CmdInfo.cpp @@ -314,6 +314,40 @@ int CmdInfo::execute (std::string& output) view.set (row, 1, allTags); } + // Virtual tags. + { + // Note: This list must match that in Task::hasTag. + std::string virtualTags = ""; + if (task->hasTag ("ACTIVE")) virtualTags += "ACTIVE "; + if (task->hasTag ("ANNOTATED")) virtualTags += "ANNOTATED "; + if (task->hasTag ("BLOCKED")) virtualTags += "BLOCKED "; + if (task->hasTag ("BLOCKING")) virtualTags += "BLOCKING "; + if (task->hasTag ("CHILD")) virtualTags += "CHILD "; + if (task->hasTag ("COMPLETED")) virtualTags += "COMPLETED "; + if (task->hasTag ("DELETED")) virtualTags += "DELETED "; + if (task->hasTag ("DUE")) virtualTags += "DUE "; + if (task->hasTag ("DUETODAY")) virtualTags += "DUETODAY "; + if (task->hasTag ("MONTH")) virtualTags += "MONTH "; + if (task->hasTag ("OVERDUE")) virtualTags += "OVERDUE "; + if (task->hasTag ("PARENT")) virtualTags += "PARENT "; + if (task->hasTag ("PENDING")) virtualTags += "PENDING "; + if (task->hasTag ("READY")) virtualTags += "READY "; + if (task->hasTag ("SCHEDULED")) virtualTags += "SCHEDULED "; + if (task->hasTag ("TAGGED")) virtualTags += "TAGGED "; + if (task->hasTag ("TODAY")) virtualTags += "TODAY "; + if (task->hasTag ("TOMORROW")) virtualTags += "TOMORROW "; + if (task->hasTag ("UNBLOCKED")) virtualTags += "UNBLOCKED "; + if (task->hasTag ("UNTIL")) virtualTags += "UNTIL "; + if (task->hasTag ("WAITING")) virtualTags += "WAITING "; + if (task->hasTag ("WEEK")) virtualTags += "WEEK "; + if (task->hasTag ("YEAR")) virtualTags += "YEAR "; + if (task->hasTag ("YESTERDAY")) virtualTags += "YESTERDAY "; + + row = view.addRow (); + view.set (row, 0, STRING_CMD_INFO_VIRTUAL_TAGS); + view.set (row, 1, virtualTags); + } + // uuid row = view.addRow (); view.set (row, 0, STRING_COLUMN_LABEL_UUID); diff --git a/src/commands/CmdProjects.cpp b/src/commands/CmdProjects.cpp index 048ca701b..1c69929cb 100644 --- a/src/commands/CmdProjects.cpp +++ b/src/commands/CmdProjects.cpp @@ -53,6 +53,9 @@ int CmdProjects::execute (std::string& output) { int rc = 0; + // Enforce the garbage collector to show correct task counts + context.tdb2.gc (); + // Get all the tasks. handleRecurrence (); std::vector tasks = context.tdb2.pending.get_tasks (); @@ -89,8 +92,16 @@ int CmdProjects::execute (std::string& output) continue; } + // Increase the count for the project the task belongs to and all + // its super-projects project = task->get ("project"); - unique[project] += 1; + + std::vector projects = extractParents (project); + projects.push_back (project); + + std::vector ::const_iterator parent; + for (parent = projects.begin (); parent != projects.end (); ++parent) + unique[*parent] += 1; if (project == "") no_project = true; diff --git a/src/commands/CmdSummary.cpp b/src/commands/CmdSummary.cpp index d012fb0dd..842948e33 100644 --- a/src/commands/CmdSummary.cpp +++ b/src/commands/CmdSummary.cpp @@ -92,27 +92,34 @@ int CmdSummary::execute (std::string& output) for (task = filtered.begin (); task != filtered.end (); ++task) { std::string project = task->get ("project"); - ++counter[project]; + std::vector projects = extractParents (project); + projects.push_back (project); + + std::vector ::const_iterator parent; + for (parent = projects.begin (); parent != projects.end (); ++parent) + ++counter[*parent]; if (task->getStatus () == Task::pending || task->getStatus () == Task::waiting) - { - ++countPending[project]; + for (parent = projects.begin (); parent != projects.end (); ++parent) + { + ++countPending[*parent]; - time_t entry = strtol (task->get ("entry").c_str (), NULL, 10); - if (entry) - sumEntry[project] = sumEntry[project] + (double) (now - entry); - } + time_t entry = strtol (task->get ("entry").c_str (), NULL, 10); + if (entry) + sumEntry[*parent] = sumEntry[*parent] + (double) (now - entry); + } else if (task->getStatus () == Task::completed) - { - ++countCompleted[project]; + for (parent = projects.begin (); parent != projects.end (); ++parent) + { + ++countCompleted[*parent]; - time_t entry = strtol (task->get ("entry").c_str (), NULL, 10); - time_t end = strtol (task->get ("end").c_str (), NULL, 10); - if (entry && end) - sumEntry[project] = sumEntry[project] + (double) (end - entry); - } + time_t entry = strtol (task->get ("entry").c_str (), NULL, 10); + time_t end = strtol (task->get ("end").c_str (), NULL, 10); + if (entry && end) + sumEntry[*parent] = sumEntry[*parent] + (double) (end - entry); + } } diff --git a/src/l10n/deu-DEU.h b/src/l10n/deu-DEU.h index a374165d1..7d4491b8f 100644 --- a/src/l10n/deu-DEU.h +++ b/src/l10n/deu-DEU.h @@ -296,6 +296,7 @@ #define STRING_CMD_INFO_UNTIL "Bis" #define STRING_CMD_INFO_MODIFICATION "Änderung" #define STRING_CMD_INFO_MODIFIED "Letzte Änderung" +#define STRING_CMD_INFO_VIRTUAL_TAGS "Virtual tags" #define STRING_CMD_UNDO_USAGE "Macht die letzte Änderung an einer Aufgabe Rückgängig" #define STRING_CMD_UNDO_MODS "Der undo-Befehl erlaubt keine weitere Aufgaben-Änderung." #define STRING_CMD_STATS_USAGE "Zeigt Statistiken zur Aufgaben-Datenbank" diff --git a/src/l10n/eng-USA.h b/src/l10n/eng-USA.h index 112db87ae..bbc9393d7 100644 --- a/src/l10n/eng-USA.h +++ b/src/l10n/eng-USA.h @@ -296,6 +296,7 @@ #define STRING_CMD_INFO_UNTIL "Until" #define STRING_CMD_INFO_MODIFICATION "Modification" #define STRING_CMD_INFO_MODIFIED "Last modified" +#define STRING_CMD_INFO_VIRTUAL_TAGS "Virtual tags" #define STRING_CMD_UNDO_USAGE "Reverts the most recent change to a task" #define STRING_CMD_UNDO_MODS "The undo command does not allow further task modification." #define STRING_CMD_STATS_USAGE "Shows task database statistics" diff --git a/src/l10n/epo-RUS.h b/src/l10n/epo-RUS.h index 057946ca3..8b231086e 100644 --- a/src/l10n/epo-RUS.h +++ b/src/l10n/epo-RUS.h @@ -296,6 +296,7 @@ #define STRING_CMD_INFO_UNTIL "Ĝis" #define STRING_CMD_INFO_MODIFICATION "Modifado" #define STRING_CMD_INFO_MODIFIED "Modifado lasta" +#define STRING_CMD_INFO_VIRTUAL_TAGS "Virtual tags" #define STRING_CMD_UNDO_USAGE "Malfaras la plej malfrua modifado al tasko" #define STRING_CMD_UNDO_MODS "La komando 'undo' ne permesos, ke oni pli modifus la taskojn." #define STRING_CMD_STATS_USAGE "Montras statistikon de la taska datumbazo" diff --git a/src/l10n/esp-ESP.h b/src/l10n/esp-ESP.h index d99053429..cba68f585 100644 --- a/src/l10n/esp-ESP.h +++ b/src/l10n/esp-ESP.h @@ -298,6 +298,7 @@ #define STRING_CMD_INFO_UNTIL "Hasta" #define STRING_CMD_INFO_MODIFICATION "Modificación" #define STRING_CMD_INFO_MODIFIED "Modificada por última vez" +#define STRING_CMD_INFO_VIRTUAL_TAGS "Virtual tags" #define STRING_CMD_UNDO_USAGE "Revierte el cambio más reciente a una tarea" #define STRING_CMD_UNDO_MODS "El comando undo no permite más modificación a la tarea." #define STRING_CMD_STATS_USAGE "Muestra estadísticas de la base de datos de tareas" diff --git a/src/l10n/fra-FRA.h b/src/l10n/fra-FRA.h index 11d3b2cb6..f2f1ebe50 100644 --- a/src/l10n/fra-FRA.h +++ b/src/l10n/fra-FRA.h @@ -296,6 +296,7 @@ #define STRING_CMD_INFO_UNTIL "Jusqu'au" #define STRING_CMD_INFO_MODIFICATION "Modification" #define STRING_CMD_INFO_MODIFIED "Dernier modifié" +#define STRING_CMD_INFO_VIRTUAL_TAGS "Virtual tags" #define STRING_CMD_UNDO_USAGE "Annule les changements les plus récents sur une tâche" #define STRING_CMD_UNDO_MODS "The undo command does not allow further task modification." #define STRING_CMD_STATS_USAGE "Affiche les statistiques de la base de donnée" diff --git a/src/l10n/ita-ITA.h b/src/l10n/ita-ITA.h index 5e5255572..358da09a0 100644 --- a/src/l10n/ita-ITA.h +++ b/src/l10n/ita-ITA.h @@ -295,6 +295,7 @@ #define STRING_CMD_INFO_UNTIL "Fino a" #define STRING_CMD_INFO_MODIFICATION "Modifica" #define STRING_CMD_INFO_MODIFIED "Ultima modifica" +#define STRING_CMD_INFO_VIRTUAL_TAGS "Virtual tags" #define STRING_CMD_UNDO_USAGE "Ritorna alla più recente modifica di un task" #define STRING_CMD_UNDO_MODS "Il comando undo non ammette ulteriori modifiche al task." #define STRING_CMD_STATS_USAGE "Mostra le statistiche sul task" diff --git a/src/l10n/pol-POL.h b/src/l10n/pol-POL.h index f3e2a0fcd..e313f2fad 100644 --- a/src/l10n/pol-POL.h +++ b/src/l10n/pol-POL.h @@ -296,6 +296,7 @@ #define STRING_CMD_INFO_UNTIL "Do" #define STRING_CMD_INFO_MODIFICATION "Modyfikacja" #define STRING_CMD_INFO_MODIFIED "Ostatnio zmodyfikowane" +#define STRING_CMD_INFO_VIRTUAL_TAGS "Virtual tags" #define STRING_CMD_UNDO_USAGE "Odwraca ostatnią zmianę w zadaniu" #define STRING_CMD_UNDO_MODS "Polecenie cofnij nie pozwala na późniejsze modyfikacje zadania." #define STRING_CMD_STATS_USAGE "Pokazuje statystyki bazy danych zadań" diff --git a/src/l10n/por-PRT.h b/src/l10n/por-PRT.h index 97d9de571..64c9ca459 100644 --- a/src/l10n/por-PRT.h +++ b/src/l10n/por-PRT.h @@ -296,6 +296,7 @@ #define STRING_CMD_INFO_UNTIL "Até" #define STRING_CMD_INFO_MODIFICATION "Modificação" #define STRING_CMD_INFO_MODIFIED "Última modificação" +#define STRING_CMD_INFO_VIRTUAL_TAGS "Virtual tags" #define STRING_CMD_UNDO_USAGE "Reverte a mais recente modificação a uma tarefa" #define STRING_CMD_UNDO_MODS "O comando undo não permite outras modificações simultâneas." #define STRING_CMD_STATS_USAGE "Exibe estatísticas da base de dados de tarefas" diff --git a/src/legacy.cpp b/src/legacy.cpp index 6d697281a..dc124558c 100644 --- a/src/legacy.cpp +++ b/src/legacy.cpp @@ -166,48 +166,3 @@ void legacyAttributeMap (std::string& name) } //////////////////////////////////////////////////////////////////////////////// -// TODO Is this needed, given Task::upgradeLegacyValues? -void legacyValueMap (const std::string& name, std::string& value) -{ - // 2014-07-03: One-time initialization value mapping. - static std::map mapping; - if (mapping.size () == 0) - { - mapping["hrs"] = "hours"; - mapping["hr"] = "hours"; - mapping["mins"] = "minutes"; - mapping["mnths"] = "months"; - mapping["mths"] = "months"; - mapping["mth"] = "months"; - mapping["mos"] = "months"; - mapping["m"] = "months"; // ? - mapping["qrtrs"] = "quarters"; - mapping["qtrs"] = "quarters"; - mapping["qtr"] = "quarters"; - mapping["secs"] = "seconds"; - mapping["sec"] = "seconds"; - mapping["s"] = "seconds"; // ? - mapping["wks"] = "weeks"; - mapping["wk"] = "weeks"; - mapping["yrs"] = "years"; - mapping["yr"] = "years"; - } - - if (name == "recur") - { - std::size_t letter = value.find_first_not_of ("0123456789."); - if (letter == std::string::npos) - letter = 0; - - std::map ::iterator i = mapping.find (value.substr (letter)); - if (i != mapping.end ()) - { - if (letter) - value = value.substr (0, letter) + i->second; - else - value = i->second; - } - } -} - -//////////////////////////////////////////////////////////////////////////////// diff --git a/src/main.h b/src/main.h index a4f6acf0b..3c2b0be86 100644 --- a/src/main.h +++ b/src/main.h @@ -86,7 +86,6 @@ std::string legacyCheckForDeprecatedColor (); std::string legacyCheckForDeprecatedVariables (); std::string legacyCheckForDeprecatedColumns (); void legacyAttributeMap (std::string&); -void legacyValueMap (const std::string&, std::string&); // list template /////////////////////////////////////////////////////////////////////////////// diff --git a/test/project.t b/test/project.t index 6d1093ac8..c84e43c5c 100755 --- a/test/project.t +++ b/test/project.t @@ -84,78 +84,26 @@ qx{../src/task rc:$rc add testing project:.myProject. 2>&1 >/dev/null}; $output = qx{../src/task rc:$rc projects 2>&1}; my @lines = split ('\n',$output); -# It's easier to make a pattern for the end than the beginning because priority -# counts are more predictable than project names. -my $project_name_column; -if ($lines[4] =~ s/\d+$//) -{ - $project_name_column = $lines[4]; -} -else -{ - $project_name_column = "error"; -} -like ($project_name_column, qr/^\.myProject\s*$/, "$ut: '.myProject' not indented"); +my ($project_name_column) = $lines[4] =~ /^(\s*\S+)/; +like ($project_name_column, qr/^\.myProject$/, "$ut: '.myProject' not indented"); -if ($lines[5] =~ s/\d+$//) -{ - $project_name_column = $lines[5]; -} -else -{ - $project_name_column = "error"; -} -like ($project_name_column, qr/^\.myProject\.\s*$/, "$ut: '.myProject.' not indented"); +($project_name_column) = $lines[5] =~ /^(\s*\S+)/; +like ($project_name_column, qr/^\.myProject\.$/, "$ut: '.myProject.' not indented"); -if ($lines[6] =~ s/\d+$//) -{ - $project_name_column = "error"; -} -else -{ - $project_name_column = $lines[6]; -} -like ($project_name_column, qr/^abstractParent\s*$/, "$ut: abstract parent not indented and no priority columns"); +($project_name_column) = $lines[6] =~ /^(\s*\S+)/; +like ($project_name_column, qr/^abstractParent$/, "$ut: abstract parent not indented"); -if ($lines[7] =~ s/\d+$//) -{ - $project_name_column = $lines[7]; -} -else -{ - $project_name_column = "error"; -} -like ($project_name_column, qr/^ kid\s*$/, "$ut: child indented and without parent name"); +($project_name_column) = $lines[7] =~ /^(\s*\S+)/; +like ($project_name_column, qr/^ kid$/, "$ut: child indented and without parent name"); -if ($lines[8] =~ s/\d+$//) -{ - $project_name_column = $lines[8]; -} -else -{ - $project_name_column = "error"; -} -like ($project_name_column, qr/^existingParent\s*$/, "$ut: existing parent not indented and has priority columns"); +($project_name_column) = $lines[8] =~ /^(\s*\S+)/; +like ($project_name_column, qr/^existingParent$/, "$ut: existing parent not indented"); -if ($lines[9] =~ s/\d+$//) -{ - $project_name_column = $lines[9]; -} -else -{ - $project_name_column = "error"; -} -like ($project_name_column, qr/^ child\s*$/, "$ut: child of existing parent indented and without parent name"); +($project_name_column) = $lines[9] =~ /^(\s*\S+)/; +like ($project_name_column, qr/^ child$/, "$ut: child of existing parent indented and without parent name"); -if ($lines[12] =~ s/\d+$//) -{ - $project_name_column = $lines[12]; -} -else -{ - $project_name_column = "error"; -} -like ($project_name_column, qr/^myProject\.\s*$/, "$ut: 'myProject.' not indented"); +($project_name_column) = $lines[12] =~ /^(\s*\S+)/; +like ($project_name_column, qr/^myProject\.$/, "$ut: 'myProject.' not indented"); # Cleanup. unlink qw(pending.data completed.data undo.data backlog.data), $rc;