aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-07-03 17:56:03 +0200
committerDanilo M. <danix@danix.xyz>2026-07-03 17:56:03 +0200
commit203363fe96aabe2366985a769a7e10dabac69d04 (patch)
treed744d58c377d7d28b0d4f94d060079bd188e0228
parente30b3f203059d8d116f77185f0764c391cae07dc (diff)
downloadfirefly-cli-203363fe96aabe2366985a769a7e10dabac69d04.tar.gz
firefly-cli-203363fe96aabe2366985a769a7e10dabac69d04.zip
fix(budget): flatten limit commands to 2-token leaves (limit-list/limit-set)
The CLI dispatcher (cli.py _build_parser) and completion generator both partition the command name on the first space, nesting only two levels (group + leaf). A three-token 'budget limit set' registers but is unreachable via the CLI (invalid choice: 'limit'); the mocked unit suite missed this because it calls handlers directly, bypassing dispatch. Flatten to 'budget limit-list' / 'budget limit-set' (hyphenated 2-token leaf), matching every other command. Logged the n-level dispatcher refactor in TODO.md for when a future group needs real sub-subcommands. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
-rw-r--r--TODO.md10
-rw-r--r--firefly_cli/commands/budget.py4
2 files changed, 12 insertions, 2 deletions
diff --git a/TODO.md b/TODO.md
index fdbb4bc..43f4d6a 100644
--- a/TODO.md
+++ b/TODO.md
@@ -24,6 +24,16 @@ bash completion).
- [ ] Consider a `--no-color` flag (color is currently TTY-auto only).
## Infrastructure
+- [ ] n-level command nesting. `cli.py` `_build_parser` and
+ `scripts/gen_completion.py` both `partition(" ")` on the command name, so
+ they only nest two levels (group + leaf). `budget limit-set` /
+ `budget limit-list` are flattened to a hyphenated 2-token leaf as a
+ workaround (v0.4.0). Refactor both to split the full name into tokens and
+ build/scan nested subparsers per token, then a genuine `budget limit set`
+ (three tokens) works and future groups needing sub-subcommands are a
+ non-issue. Add a CLI-dispatch test (parse_args on the real parser), since
+ the mocked unit suite calls handlers directly and cannot catch a
+ dispatch/nesting break.
- [ ] `--raw` escape hatch for arbitrary API calls.
- [ ] OAuth as an alternative to personal access tokens.
- [ ] zsh / fish completion (bash done).
diff --git a/firefly_cli/commands/budget.py b/firefly_cli/commands/budget.py
index 733d092..f9999a5 100644
--- a/firefly_cli/commands/budget.py
+++ b/firefly_cli/commands/budget.py
@@ -107,7 +107,7 @@ def cmd_disable(args, ctx):
return _set_active(ctx, args.ref, False)
-@registry.command("budget limit list", help="list a budget's limits (name or id)", args=_ref_arg)
+@registry.command("budget limit-list", help="list a budget's limits (name or id)", args=_ref_arg)
def cmd_limit_list(args, ctx):
b = ctx.resolver.budget(args.ref)
resp = ctx.client.request("GET", f"/api/v1/budgets/{b['id']}/limits")
@@ -121,7 +121,7 @@ def _limit_set_args(p):
p.add_argument("--end", default=None, help="YYYY-MM-DD (default: last of this month)")
p.add_argument("--currency", default=None, help="currency code, e.g. EUR")
-@registry.command("budget limit set", help="set (create) a spending limit for a budget over a period", args=_limit_set_args)
+@registry.command("budget limit-set", help="set (create) a spending limit for a budget over a period", args=_limit_set_args)
def cmd_limit_set(args, ctx):
b = ctx.resolver.budget(args.ref)
first, last = _current_month()