Add ~ marker to exclude entries from CSV export

Prefix the project name or note column with ~ to mark an entry as
count-but-don't-export. Marked entries are included in summary and
status totals but omitted from all csv output (both --raw and
aggregated, single-day and weekly).

  | 09:00 | 17:00 | 8:00 | ~Leave |  | Day off  |
  | 09:00 | 17:00 | 8:00 |  Leave |  | ~Day off |

The ~ is stripped from whichever field carries it before any
downstream processing, so project map resolution is unaffected.

Implementation:
- parse_table sets skip_csv=True on marked rows and strips the ~
- new filter_skip_csv() helper in parser.py
- to_csv_entries() skips skip_csv rows
- _cmd_csv calls filter_skip_csv() before aggregate_rows()
This commit is contained in:
Jef Roosens 2026-05-28 13:37:44 +02:00
parent 8b6f0b24e2
commit de46399010
Signed by: Jef Roosens
GPG key ID: 119385BCAA005C21
6 changed files with 209 additions and 25 deletions

View file

@ -72,6 +72,19 @@ class TestToCsvEntries:
rows = [_raw_row(" bugs ", "", "dsu", 0.25)]
assert to_csv_entries(rows)[0]["project"] == "bugs"
def test_skips_skip_csv_rows(self):
row = {**_raw_row("Leave", "", "Day off", 8.0), "skip_csv": True}
assert to_csv_entries([row]) == []
def test_skip_csv_row_mixed_with_normal(self):
rows = [
{**_raw_row("Leave", "", "Day off", 8.0), "skip_csv": True},
_raw_row("bugs", "ticket 1", "", 1.0),
]
entries = to_csv_entries(rows)
assert len(entries) == 1
assert entries[0]["project"] == "bugs"
def test_mixed_open_and_closed(self):
rows = [
_raw_row("bugs", "ticket 1", "", 1.0),