Skip to content

refactor: extract paths/jsonio/argutils from cli.py - #91

Merged
DLANSAMA merged 3 commits into
mainfrom
refactor/extract-cli-helpers
Jul 30, 2026
Merged

refactor: extract paths/jsonio/argutils from cli.py#91
DLANSAMA merged 3 commits into
mainfrom
refactor/extract-cli-helpers

Conversation

@DLANSAMA

Copy link
Copy Markdown
Owner

What

Roadmap B.4: extract the shared helpers out of bambu_cli/cli.py into three focused modules, so domain code no longer reaches back into the CLI entrypoint for private _underscore helpers.

  • bambu_cli/paths.py — filesystem/path helpers: expand_path, display_path, path_for_message, exception_for_message (+ internal home-dir cache).
  • bambu_cli/jsonio.py — JSON-mode detection + URL-credential redaction for logs/JSON output: json_mode_requested, redact_url_credentials, looks_like_schemeless_credential_url.
  • bambu_cli/argutils.py — argparse/Namespace coercion: namespace_get, exit_code_from_system_exit, setup_args_provided.

cli.py re-imports these under their historical underscore aliases for internal use. Symbols keep their names minus the leading underscore in their new public homes; nothing else renamed.

Why

The domain→cli private-helper imports were the last thing pinning the Architecture grade at A− (the other item, B.5 single pin helper, landed in #89). This is a pure move-and-rewire refactor — no behaviour change, no user-visible change. Output, JSON envelopes, and exit codes are identical.

Proof the domain→cli private imports are gone

git grep for from bambu_cli.cli import (excluding cli.py itself):

Import statements Private-symbol imports
Before (origin/main) 44 (32 private-helper) 93
After 3 0

The 3 remaining are the public CLI API only — bambu_cli/bambu.py imports main, and interactive/{presets,session}.py import build_parser (function-local). No private helper is imported from cli anywhere.

Gates (all green locally)

  • pytest -m "not live" under -W error::ResourceWarning, --cov-fail-under=83: 1051 passed, coverage 84.76%
  • ruff check / ruff format --check / mypy -p bambu_cli (60 files) / bandit -ll (no issues): pass
  • syntax_smoke (79 files) / cli_help_smoke (20 subcommands) / ci_workflow_smoke (20 cmds, 60 modules) / privacy_smoke / python_compat_smoke: pass
  • sys.exit( grep outside cli.py/errors.py: clean (moved helpers carry none, incl. prose)

Test/patch-target changes

  • tests/test_job.py: _display_path now imported from bambu_cli.paths.
  • tests/test_access_code_deprecation.py: patch seam moved from bambu_cli.cli._expand_path to bambu_cli.paths.expand_path (where config.load_access_code looks it up). No assertions weakened.

Docs

  • AGENTS.md: module table now lists paths/jsonio/argutils; removed the B.4 debt bullet.
  • docs/quality-roadmap.md: Architecture grade A− → A; B.4/B.5 rows marked done.
  • CHANGELOG.md: one ### Changed entry under [Unreleased] (internal refactor, no user-visible change).

DLANSAMA added 3 commits July 29, 2026 14:44
`plate job/send <url> --dry-run` predicted `would_slice` from the raw URL-path
extension, which is absent for Printables model pages and extension-less direct
links. In those cases the predictor returned `would_slice: false`, but the real
run downloads a model file (the downloader falls back to `.stl` when it cannot
infer an extension) and slices it — so the dry-run pre-check disagreed with what
actually happened.

Fix: share one slicing predicate between the predictor and the doer.

- `_ext_would_slice(ext)` in bambu_cli/job/predict.py is now the single rule
  (`ext in SLICEABLE_EXTENSIONS`, applied to the single-suffix `_file_extension`
  so `foo.gcode.3mf` stays print-ready). The real-run local, ZIP-member, and
  post-download branches in orchestrate.py all route through it.
- `_predicted_download_slice_extension(url, args)` resolves the URL's predicted
  extension by reusing the downloader's own `_download_source_extension`, which
  falls back to `.stl` for sources whose extension is unknowable offline. `--name`
  is intentionally ignored because the real download overrides the `--name`
  extension with the URL/resolved-name extension.

`would_slice` remains a boolean; no JSON shape or schema change.

Tests: extended the direct-URL dry-run matrix (.stl/.step/.obj/.zip/.3mf and
.gcode.3mf), added Printables-model-URL and extension-less-URL predictions, a
predictor/doer shared-predicate equivalence test, local .gcode.3mf print-ready,
and a ZIP-member matrix (.stl slices, .3mf/.gcode.3mf do not). Strengthened the
Printables dry-run agent smoke to assert would_slice=True.
Extract the filesystem-path, JSON-mode/URL-redaction, and argparse-coercion
helpers out of bambu_cli/cli.py into three focused modules (paths.py,
jsonio.py, argutils.py) so domain modules no longer import private _underscore
helpers from the CLI entrypoint (roadmap B.4).

Pure move-and-rewire: symbols keep their names minus the leading underscore in
their new public homes; cli.py re-imports them under the old aliases for
internal use. Behaviour, JSON envelopes, output, and exit codes are unchanged.

Domain -> cli private-helper imports: 93 symbol imports across 32 statements
before, 0 after; only the public build_parser/main imports remain.

Docs updated: AGENTS.md module table + debt list, quality-roadmap Architecture
grade and B.4 row, CHANGELOG [Unreleased] Changed.
@DLANSAMA
DLANSAMA merged commit 3df1495 into main Jul 30, 2026
6 checks passed
@DLANSAMA
DLANSAMA deleted the refactor/extract-cli-helpers branch July 30, 2026 00:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant