Skip to content

Commit 3283507

Browse files
authored
REL: dev into main for version 0.1.0 (#3)
1 parent 2ab2460 commit 3283507

7 files changed

Lines changed: 46 additions & 17 deletions

File tree

.bumpversion.cfg

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 0.1.0-rc.1
2+
current_version = 0.1.0
33
commit = True
44
tag_name = v{new_version}
55
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(-(?P<release>rc)\.(?P<build>\d+))?
@@ -21,6 +21,6 @@ first_value = 1
2121
search = version = "{current_version}"
2222
replace = version = "{new_version}"
2323

24-
[bumpversion:file:src/utt_balance/__init__.py]
24+
[bumpversion:file:src/utt_project_summary/__init__.py]
2525
search = __version__ = "{current_version}"
2626
replace = __version__ = "{new_version}"

.github/workflows/unit-tests.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ on:
44
push:
55
branches:
66
- dev
7+
- main
78
pull_request:
89

910
jobs:
@@ -34,5 +35,5 @@ jobs:
3435
- name: Run tests
3536
run: pytest
3637

37-
- name: Complete messsge
38+
- name: Complete message
3839
run: echo "unit tests completed"

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# utt-project-summary
22

3+
[![CI - Test](https://github.com/loganthomas/utt-project-summary/actions/workflows/unit-tests.yml/badge.svg?branch=main)](https://github.com/loganthomas/utt-project-summary/actions/workflows/unit-tests.yml)
4+
[![PyPI Latest Release](https://img.shields.io/pypi/v/utt-project-summary.svg)](https://pypi.org/project/utt-project-summary/)
5+
[![PyPI Downloads](https://img.shields.io/pypi/dm/utt-project-summary.svg?label=PyPI%20downloads)](https://pypi.org/project/utt-project-summary/)
6+
[![License - GPL-3.0](https://img.shields.io/pypi/l/utt-project-summary.svg)](https://github.com/loganthomas/utt-project-summary/blob/main/LICENSE)
7+
[![Python Versions](https://img.shields.io/pypi/pyversions/utt-project-summary.svg)](https://pypi.org/project/utt-project-summary/)
8+
39
A [`utt`](https://github.com/larose/utt) plugin that shows projects sorted by time spent.
410

511
## Why utt-project-summary?

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "utt-project-summary"
7-
version = "0.1.0-rc.1"
7+
version = "0.1.0"
88
description = "A utt plugin to show projects sorted by time spent"
99
readme = "README.md"
1010
license = "GPL-3.0-only"

src/utt/plugins/project_summary.py

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
from utt.api import _v1
1111

12+
DEFAULT_CURRENT_ACTIVITY_NAME = "-- Current Activity --"
13+
1214
if TYPE_CHECKING:
1315
from collections.abc import Sequence
1416

@@ -85,10 +87,10 @@ def _aggregate_projects(self, activities: Sequence[_v1.Activity]) -> list[Projec
8587

8688
def _extract_current(self, activities: Sequence[_v1.Activity]) -> CurrentActivity | None:
8789
"""Extract current activity if present."""
88-
for activity in activities:
89-
if activity.is_current_activity:
90-
return CurrentActivity(activity.name.name, activity.duration)
91-
return None
90+
return next(
91+
(CurrentActivity(a.name.name, a.duration) for a in activities if a.is_current_activity),
92+
None,
93+
)
9294

9395
def _compute_total(self) -> timedelta:
9496
"""Sum all project durations plus current activity."""
@@ -101,9 +103,17 @@ def _compute_total(self) -> timedelta:
101103
class ProjectSummaryView:
102104
"""Render project summary output."""
103105

104-
def __init__(self, model: ProjectSummaryModel, show_perc: bool = False) -> None:
106+
def __init__(
107+
self,
108+
model: ProjectSummaryModel,
109+
show_perc: bool = False,
110+
show_current: bool = True,
111+
current_activity_name: str = DEFAULT_CURRENT_ACTIVITY_NAME,
112+
) -> None:
105113
self._model = model
106114
self._show_perc = show_perc
115+
self._show_current = show_current
116+
self._current_activity_name = current_activity_name
107117

108118
def render(self, output: _v1.Output) -> None:
109119
"""Render the project summary to output stream."""
@@ -128,13 +138,13 @@ def render(self, output: _v1.Output) -> None:
128138
dur_str = f"{dur_str:<{max_dur_len}} ({perc:5.1f}%)"
129139
print(f"{project.name:<{max_name_len}}: {dur_str}", file=output)
130140

131-
if self._model.current_activity:
141+
if self._show_current and self._model.current_activity:
132142
ca = self._model.current_activity
133143
dur_str = ca.formatted
134144
if self._show_perc and total_secs > 0:
135145
perc = (ca.duration.total_seconds() / total_secs) * 100
136-
dur_str = f"{dur_str} ({perc:5.1f}%)"
137-
print(f"{ca.name:<{max_name_len}}: {dur_str}", file=output)
146+
dur_str = f"{dur_str:<{max_dur_len}} ({perc:5.1f}%)"
147+
print(f"{self._current_activity_name:<{max_name_len}}: {dur_str}", file=output)
138148

139149
print(file=output)
140150
total_str = format_duration(self._model.total_duration)
@@ -160,7 +170,13 @@ def __init__(
160170
def __call__(self) -> None:
161171
"""Execute command."""
162172
model = ProjectSummaryModel(self._activities)
163-
ProjectSummaryView(model, self._args.show_perc).render(self._output)
173+
view = ProjectSummaryView(
174+
model,
175+
show_perc=self._args.show_perc,
176+
show_current=not self._args.no_current_activity,
177+
current_activity_name=self._args.current_activity,
178+
)
179+
view.render(self._output)
164180

165181

166182
def add_args(parser: argparse.ArgumentParser) -> None:
@@ -176,9 +192,9 @@ def add_args(parser: argparse.ArgumentParser) -> None:
176192
)
177193
parser.add_argument(
178194
"--current-activity",
179-
default="-- Current Activity --",
195+
default=DEFAULT_CURRENT_ACTIVITY_NAME,
180196
type=str,
181-
help="Set the current activity",
197+
help="Set the current activity name",
182198
)
183199
parser.add_argument(
184200
"--no-current-activity",
@@ -224,6 +240,8 @@ def add_args(parser: argparse.ArgumentParser) -> None:
224240
)
225241

226242

243+
# Note: type: ignore needed because _v1.Command expects a specific handler protocol
244+
# that differs from our implementation's signature (uses filtered_activities vs activities)
227245
project_summary_command = _v1.Command(
228246
name="project-summary",
229247
description="Show projects sorted by time spent",
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""utt-project-summary: A utt plugin to show projects sorted by time spent."""
22

3-
__version__ = "0.1.0-rc.1"
3+
__version__ = "0.1.0"

tests/test_project_summary.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,11 @@ def test_handler_renders_output(self):
445445
create_activity("backend: task1", datetime(2024, 1, 1, 9, 0), 120),
446446
create_activity("frontend: task1", datetime(2024, 1, 1, 11, 0), 60),
447447
]
448-
args = argparse.Namespace(show_perc=False)
448+
args = argparse.Namespace(
449+
show_perc=False,
450+
no_current_activity=False,
451+
current_activity="-- Current Activity --",
452+
)
449453
output = io.StringIO()
450454

451455
handler = ProjectSummaryHandler(args, activities, output)

0 commit comments

Comments
 (0)