diff --git a/.github/workflows/release-check.yaml b/.github/workflows/release-check.yaml index 57cfa0dc7..715e5857a 100644 --- a/.github/workflows/release-check.yaml +++ b/.github/workflows/release-check.yaml @@ -15,8 +15,11 @@ jobs: path: ~/.cargo/registry key: ${{ runner.os }}-cargo-registry-${{ steps.toolchain.outputs.cachekey }}-${{ hashFiles('**/Cargo.lock') }} + - name: Update apt repos + run: sudo apt-get update -y + - name: Install uuid-dev - run: sudo apt install uuid-dev + run: sudo apt-get install -y uuid-dev - name: make a release tarball and build from it run: | diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index bdc3347ee..513b46701 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -7,6 +7,9 @@ jobs: coverage: runs-on: ubuntu-latest steps: + - name: Update apt repos + run: sudo apt-get update -y + - name: Install apt packages run: sudo apt-get install -y build-essential cmake git uuid-dev faketime locales python3 curl gcovr ninja-build diff --git a/src/columns/ColTags.cpp b/src/columns/ColTags.cpp index 2d0f278c0..ceaf86187 100644 --- a/src/columns/ColTags.cpp +++ b/src/columns/ColTags.cpp @@ -66,28 +66,21 @@ void ColumnTags::setStyle(const std::string& value) { // Set the minimum and maximum widths for the value. void ColumnTags::measure(Task& task, unsigned int& minimum, unsigned int& maximum) { minimum = maximum = 0; - if (task.has(_name)) { + if (task.getTagCount() > 0) { if (_style == "indicator") { minimum = maximum = utf8_width(Context::getContext().config.get("tag.indicator")); } else if (_style == "count") { minimum = maximum = 3; } else if (_style == "default" || _style == "list") { - std::string tags = task.get(_name); + auto tags = task.getTags(); - // Find the widest tag. - if (tags.find(',') != std::string::npos) { - auto all = split(tags, ','); - for (const auto& tag : all) { - auto length = utf8_width(tag); - if (length > minimum) minimum = length; - } - - maximum = utf8_width(tags); + // Find the widest tag (minimum) and width of all tags together (maximum) + maximum = tags.size() - 1; + for (const auto& tag : tags) { + auto length = utf8_width(tag); + maximum += length; + if (length > minimum) minimum = length; } - - // No need to split a single tag. - else - minimum = maximum = utf8_width(tags); } } } diff --git a/test/custom.test.py b/test/custom.test.py index bf7a194ff..804b69833 100755 --- a/test/custom.test.py +++ b/test/custom.test.py @@ -74,6 +74,30 @@ class TestCustomReports(TestCase): self.assertIn("[44m", out) +class TestReportTags(TestCase): + def setUp(self): + """Executed before each test in the class""" + self.t = Task() + self.t.config("report.foo.description", "DESC") + self.t.config("report.foo.labels", "ID,TAGS") + self.t.config("report.foo.columns", "id,tags") + self.t.config("report.foo.sort", "id+") + + def test_report_with_tags(self): + """Verify custom report includes tags even when `tags` property is not included""" + # Create a task directly with TC, avoiding TaskWarrior's creation of the deprecated + # `tags` property. + uuid = self.t.make_tc_task( + status="pending", + description="task with tags", + tag_tag1="x", + tag_tag2="x", + ) + code, out, err = self.t("foo") + self.assertIn("tag1", out) + self.assertIn("tag2", out) + + class TestCustomErrorHandling(TestCase): def setUp(self): self.t = Task() diff --git a/test/info.test.py b/test/info.test.py index 79ffe80fa..a951daa89 100755 --- a/test/info.test.py +++ b/test/info.test.py @@ -26,6 +26,7 @@ ############################################################################### import sys +import time import os import unittest @@ -114,6 +115,21 @@ class TestInfoCommand(TestCase): self.assertRegex(out, r"U_ONE\s+\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}") self.assertRegex(out, r"U_TWO\s+P1D") + def test_tags_without_tags_attribute(self): + """Verify info command shows tags, even if the `tags` property is not present""" + # Create a task directly with TC, avoiding TaskWarrior's creation of the deprecated + # `tags` property. + uuid = self.t.make_tc_task( + status="pending", + description="task with tags", + due=str(int(time.time())), + tag_foo="x", + tag_bar="x", + ) + code, out, err = self.t("1 info") + # Tags can occur in any order + self.assertRegex(out, r"Tags\s+(bar|foo)\s(foo|bar)") + class TestBug425(TestCase): def setUp(self):