Skip to content

fix: move the CLI into the hcl2 namespace (cli → hcl2.cli) - #359

Merged
kkozik-amplify merged 3 commits into
mainfrom
fix-move_cli_under_hcl2_namespace
Sep 21, 2026
Merged

kkozik-amplify merged 3 commits into
mainfrom
fix-move_cli_under_hcl2_namespace

Conversation

@kkozik-amplify

@kkozik-amplify kkozik-amplify commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

Since 8.0 the distribution has installed a top-level cli package into site-packages. That
squats a very generic name: a downstream project with its own top-level cli package finds its
cli.* imports resolving to whichever copy wins on sys.path. At least one consumer has pinned
python-hcl2>=3.0.5,<8 to work around it. Moving the modules under hcl2.cli means the
distribution installs nothing outside hcl2/, and that pin can be lifted.

Breaking only for code that imports cli.* directly, which was never documented as public API —
the docs reference it solely as an entry-point target. Intended for 8.2.0.

Changes

  • Moved cli/ to hcl2/cli/ and repointed the hcl2tojson, jsontohcl2, and hq console
    scripts plus the packages list in pyproject.toml. The command names and their behaviour are
    unchanged, as is python -m hcl2.
  • Switched hcl_to_json.py and json_to_hcl.py to relative from .helpers import ..., matching
    what hq.py already did.
  • Dropped the redundant cli/py.typed; hcl2/py.typed already marks the whole package tree,
    hcl2.cli included.
  • Updated the CLI test imports, the patch("hcl2.cli.json_to_hcl.dump") target, and the
    python -c command strings in test_cli_subprocess.py.
  • Omitted hcl2/cli/* from coverage, replacing the now-dead cli/__init__.py omit entry
    (see below).
  • Documented the move in the changelog and docs/06_migrating_to_v8.md, and corrected the module
    map in CLAUDE.md.

No compatibility shim ships: a shim would still occupy the colliding top-level name and so would
not fix the reported problem.

Why the coverage config had to change

The first CI run failed on every Python version with all 1534 tests passing — a bare
FAILED from nose2's coverage plugin, not a test failure.

tox.ini scopes measurement with [coverage] coverage=hcl2. The CLI has therefore never been
measured: it lived outside hcl2/. Moving it inside pulled ~906 previously unmeasured statements
into the gate at their existing coverage level (hq.py 79%, helpers.py 89%, the two converters
92%), dropping the total below fail_under = 95:

statements missed total
main 3956 112 95.519%
this branch, CLI measured 4862 219 93.483%
this branch, hcl2/cli/* omitted 3956 112 95.519%

A namespace move should not silently change what the quality gate covers, so the omit restores
the pre-move scope exactly — the third row is byte-identical to main. Bringing the CLI under
the gate is a separate decision with its own work (lifting hq.py off 79%), not something to
smuggle into a packaging fix.

Test plan

  • Full suite via the exact CI command (nose2 --config tox.ini) on 3.13: Ran 1534 tests ... OK, exit 0, coverage 95.519% — identical to main
  • pip install . into a fresh venv: site-packages holds hcl2, lark, regex and no
    top-level cli; python -c "import cli" raises ModuleNotFoundError
  • python -c "import hcl2.cli.hq" succeeds from that venv
  • All three console scripts work: echo 'x = 1' | hcl2tojson, echo 'x = 1' | hq .x,
    echo '{"x": 1}' | jsontohcl2
  • echo 'x = 1' | python -m hcl2 still prints {"x": 1} (the __main__ shim)
  • hcl2/py.typed still present in the installed package, so hcl2.cli stays typed
  • ruff check, ruff format, mypy clean

🤖 Co-Authored-By: Claude Opus 5 (1M context) Claude Code

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
tox measures `coverage=hcl2`, so moving the CLI under the package pulled
~906 previously unmeasured statements into scope and dropped the total
from 95.5% to 93.5%, tripping fail_under=95 with every test passing.
Omitting hcl2/cli/* restores the exact pre-move measurement (3956
statements, 95.519%) so the namespace move stays scope-neutral. The stale
cli/__init__.py omit entry, dead since the move, goes with it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@kkozik-amplify
kkozik-amplify merged commit 2f6d718 into main Sep 21, 2026
10 checks passed
@kkozik-amplify
kkozik-amplify deleted the fix-move_cli_under_hcl2_namespace branch September 21, 2026 12:33
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.

2 participants