aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-07-03 18:07:47 +0200
committerDanilo M. <danix@danix.xyz>2026-07-03 18:07:47 +0200
commitd44d62f5944c2765ba009197cc3ac5bb50d073e2 (patch)
tree0d63be2ea8671ed50ffde99ad533a852444c47d8
parent73fffe2e6f359b302b72b1f3740a08e471a31acc (diff)
downloadfirefly-cli-d44d62f5944c2765ba009197cc3ac5bb50d073e2.tar.gz
firefly-cli-d44d62f5944c2765ba009197cc3ac5bb50d073e2.zip
fix(budget): group help blurb, exact Decimal spent, resolver comment (v0.4.1)v0.4.1
Follow-ups from the v0.4.0 review: - add the missing _GROUP_HELP blurb for the budget group (every other group shows one) + a regression test asserting all groups have one. - _spent_scalar sums with decimal.Decimal instead of float (exact money). - note the numeric-name sniffing tradeoff in resolver.budget(). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
-rw-r--r--firefly_cli/__init__.py2
-rw-r--r--firefly_cli/cli.py1
-rw-r--r--firefly_cli/commands/budget.py7
-rw-r--r--firefly_cli/resolver.py4
-rw-r--r--pyproject.toml2
-rw-r--r--tests/unit/test_cli.py9
6 files changed, 20 insertions, 5 deletions
diff --git a/firefly_cli/__init__.py b/firefly_cli/__init__.py
index f2c1864..1d2fe01 100644
--- a/firefly_cli/__init__.py
+++ b/firefly_cli/__init__.py
@@ -2,4 +2,4 @@
# Copyright (C) 2026 Danilo M. <danix@danix.xyz>
# Licensed under the GNU General Public License v2.0 only.
-__version__ = "0.4.0"
+__version__ = "0.4.1"
diff --git a/firefly_cli/cli.py b/firefly_cli/cli.py
index ad54504..712d52d 100644
--- a/firefly_cli/cli.py
+++ b/firefly_cli/cli.py
@@ -19,6 +19,7 @@ _GROUP_HELP = {
"category": "list categories (categories auto-create when used on a tx)",
"tag": "list tags (tags auto-create when attached to a tx)",
"tx": "record, list, and search transactions",
+ "budget": "manage budgets and per-period spending limits",
}
def _build_parser():
diff --git a/firefly_cli/commands/budget.py b/firefly_cli/commands/budget.py
index f9999a5..86317fa 100644
--- a/firefly_cli/commands/budget.py
+++ b/firefly_cli/commands/budget.py
@@ -1,6 +1,7 @@
# Copyright (C) 2026 Danilo M. <danix@danix.xyz> GPL-2.0-only
import calendar
from datetime import date
+from decimal import Decimal, InvalidOperation
from firefly_cli import registry, output
from firefly_cli.errors import FireflyError
@@ -18,11 +19,11 @@ def _spent_scalar(budget_obj):
"""Sum a budget's nested `spent` array into a single number (for --human).
Firefly sends spent as a per-currency list of {sum: "-12.34", ...}; we sum
the sums. JSON output is untouched; this only feeds the table view."""
- total = 0.0
+ total = Decimal(0)
for entry in budget_obj.get("spent") or []:
try:
- total += float(entry.get("sum", 0))
- except (TypeError, ValueError):
+ total += Decimal(str(entry.get("sum", 0)))
+ except (TypeError, InvalidOperation):
pass
return f"{total:.2f}"
diff --git a/firefly_cli/resolver.py b/firefly_cli/resolver.py
index 53144e1..cb7e9a8 100644
--- a/firefly_cli/resolver.py
+++ b/firefly_cli/resolver.py
@@ -48,6 +48,10 @@ class Resolver:
# transaction), so we resolve to an id. A numeric-looking ref goes
# straight to the show endpoint (lets same-name-safe callers pin an id);
# otherwise match by name against the list.
+ # ponytail: sniffing digits makes a budget literally named "7"
+ # unreachable by name (same lossy tradeoff ISSUES.md #2 hit for
+ # accounts). All-digit budget names are rare; add a --budget-id flag to
+ # tx add if this ever bites, mirroring --from-id/--to-id.
if str(name_or_id).isdigit():
return self.budget_by_id(name_or_id)
return self._match("budget", self._list("/api/v1/budgets"), name_or_id)
diff --git a/pyproject.toml b/pyproject.toml
index 0d1f7e6..27034f8 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "firefly-iii-agent"
-version = "0.4.0"
+version = "0.4.1"
description = "CLI tool for agent interaction with Firefly III"
readme = "README.md"
requires-python = ">=3.11"
diff --git a/tests/unit/test_cli.py b/tests/unit/test_cli.py
index 883f200..47e01cc 100644
--- a/tests/unit/test_cli.py
+++ b/tests/unit/test_cli.py
@@ -24,3 +24,12 @@ class TestCli(unittest.TestCase):
w.return_value = "/tmp/x"
rc = cli.main(["auth", "set", "--url", "https://f", "--token", "t"])
self.assertEqual(rc, 0)
+
+ def test_every_command_group_has_a_help_blurb(self):
+ # Every group shown in `firefly --help` should carry a _GROUP_HELP
+ # blurb; a new group added without one is easy to miss (budget did).
+ from firefly_cli import registry
+ import firefly_cli.commands # noqa: F401 ensure registration
+ groups = {c.name.split(" ", 1)[0] for c in registry.all_commands()}
+ missing = groups - set(cli._GROUP_HELP)
+ self.assertFalse(missing, f"groups without _GROUP_HELP: {missing}")