From 4a18500191e51535f4f73fdaba5bd8052e2308a5 Mon Sep 17 00:00:00 2001 From: Federico Hernandez Date: Thu, 18 Jan 2018 15:53:08 +0100 Subject: [PATCH 01/10] Bumped version number to 1.1.1 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 95ad7d02..6bded2eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ set (HAVE_CMAKE true) project (timew) include (CXXSniffer) -set (PROJECT_VERSION "1.1.0") +set (PROJECT_VERSION "1.1.1") message ("-- Looking for SHA1 references") if (EXISTS ${CMAKE_SOURCE_DIR}/.git/index) From 47466cdcab9443a3310b3eb8358c19d28939277d Mon Sep 17 00:00:00 2001 From: Thomas Lauf Date: Fri, 19 Jan 2018 16:24:39 +0100 Subject: [PATCH 02/10] TI-102: Add tests --- test/export.t | 125 +++++++++++++++++++++++++++++++++++++++++++++++- test/start.t | 129 +++++++++++++++++++++++++++++++++++++++++++++++++- test/stop.t | 122 ++++++++++++++++++++++++++++++++++++++++++++++- test/track.t | 6 ++- 4 files changed, 374 insertions(+), 8 deletions(-) diff --git a/test/export.t b/test/export.t index 938ad0d2..5db70137 100755 --- a/test/export.t +++ b/test/export.t @@ -26,10 +26,12 @@ # ############################################################################### -import sys import os +import sys import unittest -from datetime import datetime + +import datetime + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -51,6 +53,7 @@ from basetest import Timew, TestCase # self.assertNotRegexpMatches(text, pattern) # self.tap("") + class TestExport(TestCase): def setUp(self): """Executed before each test in the class""" @@ -72,6 +75,124 @@ class TestExport(TestCase): self.assertTrue('tags' in j[0]) self.assertEqual(j[0]['tags'][0], 'foo') + def test_changing_exclusion_does_not_change_flattened_intervals(self): + """Changing exclusions does not change flattened intervals""" + self.t.config("exclusions.monday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.tuesday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.wednesday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.thursday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.friday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.saturday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.sunday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + + self.t("track 20160101T102255 - 20160101T154422 foo") + + self.t.config("exclusions.monday", "<9:11:50 12:44:22-13:23:32 >18:05:11") + self.t.config("exclusions.tuesday", "<9:11:50 12:44:22-13:23:32 >18:05:11") + self.t.config("exclusions.wednesday", "<9:11:50 12:44:22-13:23:32 >18:05:11") + self.t.config("exclusions.thursday", "<9:11:50 12:44:22-13:23:32 >18:05:11") + self.t.config("exclusions.friday", "<9:11:50 12:44:22-13:23:32 >18:05:11") + self.t.config("exclusions.saturday", "<9:11:50 12:44:22-13:23:32 >18:05:11") + self.t.config("exclusions.sunday", "<9:11:50 12:44:22-13:23:32 >18:05:11") + + self.t("track 20160102T102255 - 20160102T154422 bar") + + j = self.t.export() + self.assertEqual(len(j), 4) + + self.assertTrue('start' in j[0]) + self.assertIn('2255Z', j[0]['start']) + self.assertTrue('end' in j[0]) + self.assertIn('2244Z', j[0]['end']) + self.assertTrue('tags' in j[0]) + self.assertEqual(j[0]['tags'][0], 'foo') + + self.assertTrue('start' in j[1]) + self.assertIn('3223Z', j[1]['start']) + self.assertTrue('end' in j[1]) + self.assertIn('4422Z', j[1]['end']) + self.assertTrue('tags' in j[1]) + self.assertEqual(j[1]['tags'][0], 'foo') + + self.assertTrue('start' in j[2]) + self.assertIn('2255Z', j[2]['start']) + self.assertTrue('end' in j[2]) + self.assertIn('4422Z', j[2]['end']) + self.assertTrue('tags' in j[2]) + self.assertEqual(j[2]['tags'][0], 'bar') + + self.assertTrue('start' in j[3]) + self.assertIn('2332Z', j[3]['start']) + self.assertTrue('end' in j[3]) + self.assertIn('4422Z', j[3]['end']) + self.assertTrue('tags' in j[3]) + self.assertEqual(j[3]['tags'][0], 'bar') + + def test_changing_exclusion_does_change_open_interval(self): + """Changing exclusions does change open interval""" + now = datetime.datetime.now() + + if now.time() < datetime.time(5): + self.skipTest("Test cannot not be run before 05:00:00") + return + + three_hours_before = now - datetime.timedelta(hours=3) + four_hours_before = now - datetime.timedelta(hours=4) + five_hours_before = now - datetime.timedelta(hours=5) + + exclusion = "{:%H}:12:21-{:%H}:34:43".format(four_hours_before, three_hours_before) + + self.t.config("exclusions.friday", exclusion) + self.t.config("exclusions.thursday", exclusion) + self.t.config("exclusions.wednesday", exclusion) + self.t.config("exclusions.tuesday", exclusion) + self.t.config("exclusions.monday", exclusion) + self.t.config("exclusions.sunday", exclusion) + self.t.config("exclusions.saturday", exclusion) + + self.t("start {}T{:%H}:00:00 foo".format(now.date(), five_hours_before)) + + j = self.t.export() + + self.assertEqual(len(j), 2) + + self.assertTrue('start' in j[0]) + self.assertIn('0000Z', j[0]['start']) + self.assertTrue('end' in j[0]) + self.assertIn('1221Z', j[0]['end']) + self.assertTrue('tags' in j[0]) + self.assertEqual(j[0]['tags'][0], 'foo') + + self.assertTrue('start' in j[1]) + self.assertIn('3443Z', j[1]['start']) + self.assertFalse('end' in j[1]) + + exclusion = "{:%H}:34:43-{:%H}:12:21".format(four_hours_before, three_hours_before) + + self.t.config("exclusions.friday", exclusion) + self.t.config("exclusions.thursday", exclusion) + self.t.config("exclusions.wednesday", exclusion) + self.t.config("exclusions.tuesday", exclusion) + self.t.config("exclusions.monday", exclusion) + self.t.config("exclusions.sunday", exclusion) + self.t.config("exclusions.saturday", exclusion) + + j = self.t.export() + + self.assertEqual(len(j), 2) + + self.assertTrue('start' in j[0]) + self.assertIn('0000Z', j[0]['start']) + self.assertTrue('end' in j[0]) + self.assertIn('3443Z', j[0]['end']) + self.assertTrue('tags' in j[0]) + self.assertEqual(j[0]['tags'][0], 'foo') + + self.assertTrue('start' in j[1]) + self.assertIn('1221Z', j[1]['start']) + self.assertFalse('end' in j[1]) + + if __name__ == "__main__": from simpletap import TAPTestRunner unittest.main(testRunner=TAPTestRunner()) diff --git a/test/start.t b/test/start.t index 2be8426b..6d9df54b 100755 --- a/test/start.t +++ b/test/start.t @@ -26,10 +26,10 @@ # ############################################################################### -import sys import os +import sys import unittest -from datetime import datetime + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -114,6 +114,131 @@ class TestStart(TestCase): self.assertNotIn("Recorded bar foo", out) + def test_single_interval_enclosing_exclusion(self): + """Add one interval that encloseѕ an exclusion, and is therefore flattened""" + self.t.config("exclusions.monday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.tuesday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.wednesday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.thursday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.friday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.saturday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.sunday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + + self.t("start 20160101T102255 foo") + self.t("start 20160101T154422 bar") # start bar, so foo gets closed and flattened + self.t("cancel") # cancel tracking of bar + + j = self.t.export() + self.assertEqual(len(j), 2) + + self.assertTrue('start' in j[0]) + self.assertIn('2255Z', j[0]['start']) + self.assertTrue('end' in j[0]) + self.assertIn('2244Z', j[0]['end']) + self.assertTrue('tags' in j[0]) + self.assertEqual(j[0]['tags'][0], 'foo') + + self.assertTrue('start' in j[1]) + self.assertIn('3223Z', j[1]['start']) + self.assertTrue('end' in j[1]) + self.assertIn('4422Z', j[1]['end']) + self.assertTrue('tags' in j[1]) + self.assertEqual(j[1]['tags'][0], 'foo') + + def test_single_interval_starting_within_an_exclusion_and_enclosing_an_exclusion(self): + """Add one interval that starts within an exclusion and encloses an exclusion""" + self.t.config("exclusions.monday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.tuesday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.wednesday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.thursday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.friday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.saturday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.sunday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + + self.t("start 20160101T082255 foo") + self.t("start 20160101T144422 bar") # start bar, so foo gets closed and flattened + self.t("cancel") # cancel tracking of bar + + j = self.t.export() + self.assertEqual(len(j), 2) + + self.assertTrue('start' in j[0]) + self.assertIn('2255Z', j[0]['start']) + self.assertTrue('end' in j[0]) + self.assertIn('2244Z', j[0]['end']) + self.assertTrue('tags' in j[0]) + self.assertEqual(j[0]['tags'][0], 'foo') + + self.assertTrue('start' in j[1]) + self.assertIn('3223Z', j[1]['start']) + self.assertTrue('end' in j[1]) + self.assertIn('4422Z', j[1]['end']) + self.assertTrue('tags' in j[1]) + self.assertEqual(j[1]['tags'][0], 'foo') + + def test_single_interval_ending_within_an_exclusion_and_enclosing_an_exclusion(self): + """Add one interval that ends within an exclusion and encloses an exclusion""" + self.t.config("exclusions.monday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.tuesday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.wednesday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.thursday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.friday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.saturday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.sunday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + + self.t("start 20160101T102255 foo") + self.t("start 20160101T194422 bar") # start bar, so foo gets closed and flattened + self.t("cancel") # cancel tracking of bar + + j = self.t.export() + self.assertEqual(len(j), 2) + + self.assertTrue('start' in j[0]) + self.assertIn('2255Z', j[0]['start']) + self.assertTrue('end' in j[0]) + self.assertIn('2244Z', j[0]['end']) + self.assertTrue('tags' in j[0]) + self.assertEqual(j[0]['tags'][0], 'foo') + + self.assertTrue('start' in j[1]) + self.assertIn('3223Z', j[1]['start']) + self.assertTrue('end' in j[1]) + self.assertIn('4422Z', j[1]['end']) + self.assertTrue('tags' in j[1]) + self.assertEqual(j[1]['tags'][0], 'foo') + + def test_single_interval_and_enclosing_an_exclusion_with_day_change(self): + """Add one interval that encloses an exclusion with day change""" + self.t.config("exclusions.monday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.tuesday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.wednesday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.thursday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.friday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.saturday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.sunday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + + self.t("start 20160101T172255 foo") + self.t("start 20160102T104422 bar") # start bar, so foo gets closed and flattened + self.t("cancel") # cancel tracking of bar + + j = self.t.export() + self.assertEqual(len(j), 2) + + self.assertTrue('start' in j[0]) + self.assertIn('2255Z', j[0]['start']) + self.assertTrue('end' in j[0]) + self.assertIn('0511Z', j[0]['end']) + self.assertTrue('tags' in j[0]) + self.assertEqual(j[0]['tags'][0], 'foo') + + self.assertTrue('start' in j[1]) + self.assertIn('1150Z', j[1]['start']) + self.assertTrue('end' in j[1]) + self.assertIn('4422Z', j[1]['end']) + self.assertTrue('tags' in j[1]) + self.assertEqual(j[1]['tags'][0], 'foo') + + if __name__ == "__main__": from simpletap import TAPTestRunner unittest.main(testRunner=TAPTestRunner()) diff --git a/test/stop.t b/test/stop.t index 4be5cc9e..262c001d 100755 --- a/test/stop.t +++ b/test/stop.t @@ -26,10 +26,10 @@ # ############################################################################### -import sys import os +import sys import unittest -from datetime import datetime + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -51,6 +51,7 @@ from basetest import Timew, TestCase # self.assertNotRegexpMatches(text, pattern) # self.tap("") + class TestStop(TestCase): def setUp(self): """Executed before each test in the class""" @@ -108,6 +109,123 @@ class TestStop(TestCase): code, out, err = self.t.runError("stop four") self.assertIn("The current interval does not have the 'four' tag.", err) + def test_single_interval_enclosing_exclusion(self): + """Add one interval that encloseѕ an exclusion, and is therefore flattened""" + self.t.config("exclusions.monday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.tuesday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.wednesday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.thursday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.friday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.saturday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.sunday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + + self.t("start 20160101T100000 foo") + self.t("stop 20160101T150000") + + j = self.t.export() + self.assertEqual(len(j), 2) + + self.assertTrue('start' in j[0]) + self.assertTrue('end' in j[0]) + self.assertTrue('tags' in j[0]) + self.assertEqual(j[0]['tags'][0], 'foo') + + self.assertTrue('start' in j[1]) + self.assertTrue('end' in j[1]) + self.assertTrue('tags' in j[1]) + self.assertEqual(j[1]['tags'][0], 'foo') + + def test_single_interval_starting_within_an_exclusion_and_enclosing_an_exclusion(self): + """Add one interval that starts within an exclusion and encloses an exclusion""" + self.t.config("exclusions.monday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.tuesday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.wednesday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.thursday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.friday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.saturday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.sunday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + + self.t("start 20160101T082255 foo") + self.t("stop 20160101T144422") # stop, so foo gets closed and flattened + + j = self.t.export() + self.assertEqual(len(j), 2) + + self.assertTrue('start' in j[0]) + self.assertIn('2255Z', j[0]['start']) + self.assertTrue('end' in j[0]) + self.assertIn('2244Z', j[0]['end']) + self.assertTrue('tags' in j[0]) + self.assertEqual(j[0]['tags'][0], 'foo') + + self.assertTrue('start' in j[1]) + self.assertIn('3223Z', j[1]['start']) + self.assertTrue('end' in j[1]) + self.assertIn('4422Z', j[1]['end']) + self.assertTrue('tags' in j[1]) + self.assertEqual(j[1]['tags'][0], 'foo') + + def test_single_interval_ending_within_an_exclusion_and_enclosing_an_exclusion(self): + """Add one interval that ends within an exclusion and encloses an exclusion""" + self.t.config("exclusions.monday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.tuesday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.wednesday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.thursday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.friday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.saturday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.sunday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + + self.t("start 20160101T102255 foo") + self.t("stop 20160101T194422") # stop, so foo gets closed and flattened + + j = self.t.export() + self.assertEqual(len(j), 2) + + self.assertTrue('start' in j[0]) + self.assertIn('2255Z', j[0]['start']) + self.assertTrue('end' in j[0]) + self.assertIn('2244Z', j[0]['end']) + self.assertTrue('tags' in j[0]) + self.assertEqual(j[0]['tags'][0], 'foo') + + self.assertTrue('start' in j[1]) + self.assertIn('3223Z', j[1]['start']) + self.assertTrue('end' in j[1]) + self.assertIn('4422Z', j[1]['end']) + self.assertTrue('tags' in j[1]) + self.assertEqual(j[1]['tags'][0], 'foo') + + def test_single_interval_and_enclosing_an_exclusion_with_day_change(self): + """Add one interval that encloses an exclusion with day change""" + self.t.config("exclusions.monday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.tuesday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.wednesday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.thursday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.friday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.saturday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + self.t.config("exclusions.sunday", "<9:11:50 12:22:44-13:32:23 >18:05:11") + + self.t("start 20160101T172255 foo") + self.t("stop 20160102T104422") # stop, so foo gets closed and flattened + + j = self.t.export() + self.assertEqual(len(j), 2) + + self.assertTrue('start' in j[0]) + self.assertIn('2255Z', j[0]['start']) + self.assertTrue('end' in j[0]) + self.assertIn('0511Z', j[0]['end']) + self.assertTrue('tags' in j[0]) + self.assertEqual(j[0]['tags'][0], 'foo') + + self.assertTrue('start' in j[1]) + self.assertIn('1150Z', j[1]['start']) + self.assertTrue('end' in j[1]) + self.assertIn('4422Z', j[1]['end']) + self.assertTrue('tags' in j[1]) + self.assertEqual(j[1]['tags'][0], 'foo') + + if __name__ == "__main__": from simpletap import TAPTestRunner unittest.main(testRunner=TAPTestRunner()) diff --git a/test/track.t b/test/track.t index bbfebdc9..89d0b91a 100755 --- a/test/track.t +++ b/test/track.t @@ -26,10 +26,10 @@ # ############################################################################### -import sys import os +import sys import unittest -from datetime import datetime + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -51,6 +51,7 @@ from basetest import Timew, TestCase # self.assertNotRegexpMatches(text, pattern) # self.tap("") + class TestTrack(TestCase): def setUp(self): """Executed before each test in the class""" @@ -124,6 +125,7 @@ class TestTrack(TestCase): j = self.t.export() self.assertTrue(len(j) > 0) + if __name__ == "__main__": from simpletap import TAPTestRunner unittest.main(testRunner=TAPTestRunner()) From 1aee90199a83da0336b60cf14276a00fb3e3271f Mon Sep 17 00:00:00 2001 From: Thomas Lauf Date: Fri, 19 Jan 2018 15:25:33 +0100 Subject: [PATCH 03/10] TI-102: Improve interval flattening for CmdTrack - Report on added intervals, not on entered interval --- src/commands/CmdTrack.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/commands/CmdTrack.cpp b/src/commands/CmdTrack.cpp index 3c32e727..5cdfeabd 100644 --- a/src/commands/CmdTrack.cpp +++ b/src/commands/CmdTrack.cpp @@ -24,7 +24,6 @@ // //////////////////////////////////////////////////////////////////////////////// -#include #include #include #include @@ -35,9 +34,10 @@ int CmdTrack ( Rules& rules, Database& database) { + auto filter = getFilter (cli); + // If this is not a proper closed interval, then the user is trying to make // the 'track' command behave like 'start', so delegate to CmdStart. - auto filter = getFilter (cli); if (! filter.range.is_started () || ! filter.range.is_ended ()) return CmdStart (cli, rules, database); @@ -45,12 +45,13 @@ int CmdTrack ( // Validation must occur before flattening. validate (cli, rules, database, filter); - auto exclusions = getAllExclusions (rules, filter.range); - for (auto& interval : flatten (filter, exclusions)) + for (auto& interval : flatten (filter, getAllExclusions (rules, filter.range))) + { database.addInterval (interval); - if (rules.getBoolean ("verbose")) - std::cout << intervalSummarize (database, rules, filter); + if (rules.getBoolean ("verbose")) + std::cout << intervalSummarize (database, rules, interval); + } return 0; } From 238456aa0dd8bdf93a7544cbc77c675eec542927 Mon Sep 17 00:00:00 2001 From: Thomas Lauf Date: Fri, 19 Jan 2018 15:26:03 +0100 Subject: [PATCH 04/10] TI-102: Add interval flattening to CmdStop --- src/commands/CmdStop.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/commands/CmdStop.cpp b/src/commands/CmdStop.cpp index 799ac0e7..52e85c15 100644 --- a/src/commands/CmdStop.cpp +++ b/src/commands/CmdStop.cpp @@ -24,12 +24,9 @@ // //////////////////////////////////////////////////////////////////////////////// -#include #include #include #include -#include -#include #include template T setIntersect ( @@ -69,12 +66,21 @@ int CmdStop ( modified.range.end = filter.range.start; } else + { modified.range.end = Datetime (); + } // Close the interval. database.deleteInterval (latest); validate (cli, rules, database, modified); - database.addInterval (modified); + + for (auto& interval : flatten (modified, getAllExclusions (rules, modified.range))) + { + database.addInterval (interval); + + if (rules.getBoolean ("verbose")) + std::cout << intervalSummarize (database, rules, interval); + } // If tags are specified, but are not a full set of tags, remove them // before closing the interval. From 986041dcba72f8b13463bcb423ceaa82cca30acf Mon Sep 17 00:00:00 2001 From: Thomas Lauf Date: Fri, 19 Jan 2018 15:32:21 +0100 Subject: [PATCH 05/10] TI-102: Fix interval flattening in CmdStart - set correct range for exclusion retrieval - report on added intervals not on entered --- src/commands/CmdStart.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/commands/CmdStart.cpp b/src/commands/CmdStart.cpp index f08c100f..a2260cf1 100644 --- a/src/commands/CmdStart.cpp +++ b/src/commands/CmdStart.cpp @@ -24,10 +24,8 @@ // //////////////////////////////////////////////////////////////////////////////// -#include #include #include -#include #include //////////////////////////////////////////////////////////////////////////////// @@ -37,12 +35,10 @@ int CmdStart ( Database& database) { // Add a new open interval, which may have a defined start time. - auto filter = getFilter (cli); - auto holidays = subset (filter.range, getHolidays (rules)); - auto exclusions = getAllExclusions (rules, filter.range); + auto filter = getFilter (cli); + auto latest = getLatestInterval (database); // If the latest interval is open, close it. - auto latest = getLatestInterval (database); if (latest.range.is_open ()) { // If the new interval tags match those of the currently open interval, then @@ -64,13 +60,15 @@ int CmdStart ( // Update database. database.deleteInterval (latest); - for (auto& interval : flatten (modified, exclusions)) + validate (cli, rules, database, modified); + + for (auto& interval : flatten (modified, getAllExclusions (rules, modified.range))) { database.addInterval (interval); - } - if (rules.getBoolean ("verbose")) - std::cout << intervalSummarize (database, rules, modified); + if (rules.getBoolean ("verbose")) + std::cout << intervalSummarize (database, rules, interval); + } } // Now add the new open interval. From e2ebc7a9862e2082d0a2ec7aaf80f77ed877060b Mon Sep 17 00:00:00 2001 From: Thomas Lauf Date: Mon, 29 Jan 2018 22:48:11 +0100 Subject: [PATCH 06/10] TI-102: Update AUTHORS and ChangeLog --- AUTHORS | 1 + ChangeLog | 13 +++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/AUTHORS b/AUTHORS index a662a342..979b0132 100644 --- a/AUTHORS +++ b/AUTHORS @@ -58,3 +58,4 @@ suggestions: Bodo Graumann Lynoure Tim Ruffing + Christian Decker diff --git a/ChangeLog b/ChangeLog index 98f8321b..cc8cebb8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +1.1.1 () - + +- TI-102 Exclusions stopped working + (thanks to Christian Decker) + +------ current release --------------------------- + 1.1.0 (2018-01-13) 836bc41014018ab333e6ea73412ee09d015beb4e - TD-120 Missing cmakedefine for HAVE_GET_CURRENT_DIR_NAME @@ -66,7 +73,7 @@ (thanks to Tim Ruffing) - TI-90 Let 'continue' accept a date or a date range - TI-91 Timewarrior does not compile on DragonFly - (thanks to Michael Neumann). + (thanks to Michael Neumann) - Fixed Python 3 support of the holiday/refresh script (thanks to Jelle van der Waa). - Added missing man page link @@ -79,7 +86,7 @@ 'soq' and 'soy'. Similarly the 'eocw' etc are modified. The 'c' is now implicit. ------- current release --------------------------- +------ old release ------------------------------- 1.0.0 (2016-08-17) 6428ce89fcf2a5665d9351c50c2a84c98543206c @@ -90,8 +97,6 @@ - Added 'totals.py' sample extension. - Added extension list to the 'help' command. ------- old release --------------------------- - 1.0.0.beta1 (2016-07-26) - - TI-9 Task spanning over whole day should show up as taking 24:00 instead From ef26ebd6fec8472d4b91644806f48b546bb35747 Mon Sep 17 00:00:00 2001 From: Federico Hernandez Date: Sat, 3 Feb 2018 22:39:18 +0100 Subject: [PATCH 07/10] Version number and release date for 1.1.1 --- ChangeLog | 2 +- doc/man/timew.1.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index cc8cebb8..1953eaa1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -1.1.1 () - +1.1.1 (2018-02-03) - - TI-102 Exclusions stopped working (thanks to Christian Decker) diff --git a/doc/man/timew.1.in b/doc/man/timew.1.in index 300c5ff3..6c58fac7 100644 --- a/doc/man/timew.1.in +++ b/doc/man/timew.1.in @@ -1,4 +1,4 @@ -.TH timew 1 2018-01-13 "${PACKAGE_STRING}" "User Manuals" +.TH timew 1 2018-02-03 "${PACKAGE_STRING}" "User Manuals" .SH NAME timew \- A command line time tracker. From f5fbdc8d1604ff32237f2e1c7cf67876e319eade Mon Sep 17 00:00:00 2001 From: Federico Hernandez Date: Sat, 3 Feb 2018 23:10:05 +0100 Subject: [PATCH 08/10] Added SHA1 of tagged release commit --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1953eaa1..a40c6059 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -1.1.1 (2018-02-03) - +1.1.1 (2018-02-03) ef26ebd6fec8472d4b91644806f48b546bb35747 - TI-102 Exclusions stopped working (thanks to Christian Decker) From c23dd3eb5a6147a0d285d747a06809b428daf067 Mon Sep 17 00:00:00 2001 From: Thomas Lauf Date: Sun, 4 Feb 2018 23:49:23 +0100 Subject: [PATCH 09/10] Update Readme --- README.md | 62 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index be4f5dbe..4f2baa64 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,67 @@ +# Timewarrior + Thank you for taking a look at Timewarrior! -Timewarrior is a time tracking utility that offers simple stopwatch features as -well as sophisticated calendar-base backfill, along with flexible reporting. It -is a portable, well supported and very active Open Source project. +Timewarrior is a time tracking utility that offers simple stopwatch features as well as sophisticated calendar-base backfill, along with flexible reporting. +It is a portable, well supported and very active Open Source project. -Although Timewarrior is a new project there is extensive online documentation. +## Installing + +### From Package + +Thanks to the community, there are binary packages available [here](https://taskwarrior.org/docs/timewarrior/download.html#Distributions). + +### From Tarball + +Building Timewarrior yourself requires + +* git +* cmake +* make +* C++ compiler, currently gcc 4.7+ or clang 3.3+ for full C++11 support + +You can download the tarball with curl, as an example of just one of many ways to download the tarball. + + $ curl -O https://taskwarrior.org/download/timew-1.1.1.tar.gz + +Expand the tarball, build Timewarrior, optionally run the test suite, and install it. +This copies files into the right place, and installs man pages. + + $ tar xzf timew-1.1.1.tar.gz + $ cd timew-1.1.1 + $ cmake -DCMAKE_BUILD_TYPE=release . + ... + $ make + ... + [$ make test] + ... + $ sudo make install + +## Documentation + +There is extensive online documentation. You'll find all the details at: http://taskwarrior.org/docs/timewarrior At the site you'll find online documentation, downloads, news and more. -Your contributions are especially welcome. Whether it comes in the form of code -patches, ideas, discussion, bug reports, encouragement or criticism, your input -is needed. +## Contributing + +Your contributions are especially welcome. +Whether it comes in the form of code patches, ideas, discussion, bug reports, encouragement or criticism, your input is needed. For support options, take a look at: http://taskwarrior.org/support -Please send your code patches to: +Please use pull requests, or send your code patches to: - support@taskwarrior.org + support@gothenburgbitfactory.org -Consider joining bug.tasktools.org and participating in the future of Timewarrior. +Visit https://github.com/GothenburgBitFactory/timewarrior and participate in the future of Timewarrior. ---- +## License -Timewarrior is released under the MIT license. For details check the LICENSE -file. +Timewarrior is released under the MIT license. +For details check the [LICENSE](LICENSE) file. From ad18c842f99040ab0144915013d2a21bf78fb8c5 Mon Sep 17 00:00:00 2001 From: Thomas Lauf Date: Sun, 4 Feb 2018 23:58:39 +0100 Subject: [PATCH 10/10] Update AUTHORS --- AUTHORS | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/AUTHORS b/AUTHORS index f2f60c81..518e82c7 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,11 +1,11 @@ The development of Timewarrior was made possible by the significant contributions of the following people: - Paul Beckingham (Principal Author) - Federico Hernandez (Principal Author) + Thomas Lauf (Principal Author) + Paul Beckingham (Contributing Author) + Federico Hernandez (Contributing Author) Dirk Deimeke (Technical Advisor) Tomas Babej (Contributing Author) - Thomas Lauf (Contributing Author) The following submitted code, packages or analysis, and deserve special thanks: