freeagent-cli 0.2.0__tar.gz → 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: freeagent-cli
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: CLI for submitting FreeAgent timeslips
5
5
  Project-URL: Homepage, https://github.com/tomdyson/freeagent-cli
6
6
  Project-URL: Repository, https://github.com/tomdyson/freeagent-cli
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "freeagent-cli"
3
- version = "0.2.0"
3
+ version = "0.2.1"
4
4
  description = "CLI for submitting FreeAgent timeslips"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -0,0 +1 @@
1
+ __version__ = "0.2.1"
@@ -37,6 +37,22 @@ def parse_hours(s: str) -> float:
37
37
  raise ValueError(f"Cannot parse duration {s!r}; try 1.5, 90m, 1h30m, or 1:30")
38
38
 
39
39
 
40
+ def format_hours(value) -> str:
41
+ """Format a decimal-hours value as 40m / 1h / 1h30m, rounding to the nearest minute."""
42
+ try:
43
+ total_min = round(float(value) * 60)
44
+ except (TypeError, ValueError):
45
+ return str(value)
46
+ if total_min == 0:
47
+ return "0m"
48
+ h, m = divmod(total_min, 60)
49
+ if h == 0:
50
+ return f"{m}m"
51
+ if m == 0:
52
+ return f"{h}h"
53
+ return f"{h}h{m}m"
54
+
55
+
40
56
  def _resolve(items: list[dict], query: str, label: str) -> dict:
41
57
  if query.startswith("http"):
42
58
  match = [i for i in items if i["url"] == query]
@@ -73,9 +89,9 @@ def _pick_task(tasks: list[dict], task_q: str | None, project_name: str) -> dict
73
89
  @click.group(epilog="""
74
90
  \b
75
91
  Typical flow:
76
- freeagent-cli projects # projects + tasks in one call
92
+ freeagent-cli recent # check what you've already logged (avoids duplicates)
77
93
  freeagent-cli log <project> <duration> [comment] [--task <name>] [--dry-run]
78
- freeagent-cli recent # last few timeslips
94
+ freeagent-cli projects # first-time / discovery: projects + tasks
79
95
 
80
96
  \b
81
97
  Examples:
@@ -209,6 +225,8 @@ def log(project_q, duration, comment_parts, task_q, date_, dry_run):
209
225
  freeagent-cli log Acme 1h30m "fixed the thing"
210
226
  freeagent-cli log Acme 90m fixed the thing # comment without quotes
211
227
  freeagent-cli log "Big Co" 1.5 --task Coding --date 2026-05-01
228
+
229
+ Tip: run `freeagent-cli recent` first to avoid duplicate entries.
212
230
  """
213
231
  try:
214
232
  hours = parse_hours(duration)
@@ -222,7 +240,7 @@ def log(project_q, duration, comment_parts, task_q, date_, dry_run):
222
240
  dated_on = date_ or _dt.date.today().isoformat()
223
241
 
224
242
  if dry_run:
225
- click.echo(f"DRY RUN — would submit {hours}h on {dated_on} → {project['name']} / {task['name']}")
243
+ click.echo(f"DRY RUN — would submit {format_hours(hours)} on {dated_on} → {project['name']} / {task['name']}")
226
244
  click.echo(f" project: {project['url']}")
227
245
  click.echo(f" task: {task['url']}")
228
246
  if comment:
@@ -235,7 +253,7 @@ def log(project_q, duration, comment_parts, task_q, date_, dry_run):
235
253
  dated_on=dated_on, hours=hours, comment=comment,
236
254
  )
237
255
  ts = result["timeslips"][0] if "timeslips" in result else result.get("timeslip", result)
238
- click.echo(f"Submitted {hours}h on {dated_on} → {project['name']} / {task['name']}")
256
+ click.echo(f"Submitted {format_hours(hours)} on {dated_on} → {project['name']} / {task['name']}")
239
257
  if isinstance(ts, dict) and "url" in ts:
240
258
  click.echo(ts["url"])
241
259
 
@@ -265,7 +283,7 @@ def recent(limit, days, all_users):
265
283
  pname = proj["name"] if isinstance(proj, dict) else "?"
266
284
  tname = task_["name"] if isinstance(task_, dict) else "?"
267
285
  comment = (s.get("comment") or "").replace("\n", " ")
268
- click.echo(f"{s.get('dated_on','?')}\t{s.get('hours','?')}h\t{pname}\t{tname}\t{comment}")
286
+ click.echo(f"{s.get('dated_on','?')}\t{format_hours(s.get('hours'))}\t{pname}\t{tname}\t{comment}")
269
287
 
270
288
 
271
289
  if __name__ == "__main__":
@@ -47,7 +47,7 @@ wheels = [
47
47
 
48
48
  [[package]]
49
49
  name = "freeagent-cli"
50
- version = "0.2.0"
50
+ version = "0.2.1"
51
51
  source = { editable = "." }
52
52
  dependencies = [
53
53
  { name = "click" },
@@ -1 +0,0 @@
1
- __version__ = "0.2.0"
File without changes
File without changes
File without changes