TW-303: Make "task import" update existing tasks

This commit is contained in:
Wilhelm Schuermann
2015-05-29 19:49:54 +02:00
parent 45088dc9ce
commit 9d6067e2fe
7 changed files with 50 additions and 19 deletions

View File

@@ -213,7 +213,7 @@ suggestions:
Dmitriy Matrosov
Michele Santullo
Scott Kroll
Kosta H
Kosta Harlan
Hector Arciga
Jan Kunder
jck

View File

@@ -1,8 +1,11 @@
2.4.5 () -
- TW-303 Ability for "import" to update existing tasks (thanks to Kosta
Harlan).
- TW-1440 "task import" from STDIN (thanks to Renato Alves).
- TW-1432 start/stop can be issued on completed tasks (thanks to Renato Alves).
- TW-1572 Better urgency inheritance (thanks to Jens Erat).
- Prevent potential task duplication during import for non-pending tasks.
------ current release ---------------------------

View File

@@ -346,14 +346,17 @@ provided for exceptional circumstances. Use carefully.
.TP
.B task import [<file> ...]
Imports tasks in the JSON format. The standard task release comes with a few
example scripts, such as:
Imports tasks in the JSON format. Can be used to add new tasks, or update
existing ones. Tasks are identified by their UUID.
If no file or "-" is specified, import tasks from STDIN.
For importing other file formats, the standard task release comes with a
few example scripts, such as:
import-todo.sh.pl
import-yaml.pl
If no file or "-" is specified, import tasks from STDIN.
.TP
.B task log <mods>
Adds a new task that is already completed, to the task list.

View File

@@ -110,11 +110,22 @@ int CmdImport::import (std::vector <std::string>& lines)
// Parse the whole thing.
Task task (object);
context.tdb2.add (task);
// Check whether the imported task is new or a modified existing task.
Task dummy;
if (context.tdb2.get (task.get ("uuid"), dummy))
{
context.tdb2.modify (task);
std::cout << " mod ";
}
else
{
context.tdb2.add (task);
std::cout << " add ";
}
++count;
std::cout << " "
<< task.get ("uuid")
std::cout << task.get ("uuid")
<< " "
<< task.get ("description")
<< "\n";

View File

@@ -27,7 +27,7 @@
use strict;
use warnings;
use Test::More tests => 9;
use Test::More tests => 8;
# Ensure environment has no influence.
delete $ENV{'TASKDATA'};
@@ -79,10 +79,6 @@ unlike ($output, qr/1.+A.+zero/, 't1 missing');
unlike ($output, qr/2.+B.+one/, 't2 missing');
like ($output, qr/2\/13\/2009.+two/, 't3 present');
# Make sure that a duplicate task cannot be imported.
$output = qx{../src/task rc:import.rc import import.txt 2>&1 >/dev/null};
like ($output, qr/Cannot add task because the uuid .+ is not unique\./, 'error on duplicate uuid');
# Create import file.
if (open my $fh, '>', 'import2.txt')
{

View File

@@ -27,7 +27,7 @@
use strict;
use warnings;
use Test::More tests => 16;
use Test::More tests => 15;
# Ensure environment has no influence.
delete $ENV{'TASKDATA'};
@@ -136,10 +136,6 @@ like ($output, qr/1.+A.+zero.*\n.+ONE/, "$ut: t1 selected by tag, has
like ($output, qr/2.+B.+one.*\n.+TWO.*\n.+THREE/, "$ut: t2 selected by tag, has two annotations");
like ($output, qr/\n2 tasks\n/, "$ut: tag selected two tasks");
# Make sure that a duplicate task cannot be imported.
$output = qx{../src/task rc:$rc import import.json 2>&1 >/dev/null};
like ($output, qr/Cannot add task because the uuid '.{36}' is not unique\./, "$ut: error on duplicate uuid");
# Create import file.
if (open my $fh, '>', 'import.txt')
{

View File

@@ -35,7 +35,7 @@ sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from basetest import Task, TestCase
class TestImportSTDIN(TestCase):
class TestImport(TestCase):
def setUp(self):
self.t = Task()
self.t.config("report.foo.description", "foo")
@@ -55,6 +55,28 @@ class TestImportSTDIN(TestCase):
self.assertRegexpMatches(out, "2\s+one", "second task present")
self.assertRegexpMatches(out, "-\s+two", "third task present")
def test_import_update(self):
"""Update existing tasks"""
json_data = """
{"uuid":"00000000-0000-0000-0000-000000000000","description":"zero","project":"A","status":"pending","entry":"1234567889"}
{"uuid":"11111111-1111-1111-1111-111111111111","description":"one","project":"B","status":"deleted","entry":"1234567889"}
{"uuid":"22222222-2222-2222-2222-222222222222","description":"two","status":"completed","entry":"1234524689","end":"1234524690"}"""
self.t("import", input=json_data)
self.t("next") # Run GC
json_data = """
{"uuid":"00000000-0000-0000-0000-000000000000","description":"zero","project":"C","status":"pending","entry":"1234567889"}
{"uuid":"11111111-1111-1111-1111-111111111111","description":"one","project":"B","status":"pending","entry":"1234567889"}
{"uuid":"22222222-2222-2222-2222-222222222222","description":"two","status":"pending","entry":"1234524689","end":"1234524690"}"""
self.t("import", input=json_data)
zero, one, two = sorted(self.t.export(), key=lambda t: t["uuid"])
self.assertEqual(zero["status"], "pending", "status for 'zero' unchanged")
self.assertEqual(zero["project"], "C", "project for 'zero' changed to 'C'")
self.assertEqual(one["status"], "pending", "status for 'one' changed to pending")
self.assertEqual(two["status"], "pending", "status for 'two' changed to pending")
if __name__ == "__main__":
from simpletap import TAPTestRunner