fix: move the CLI into the hcl2 namespace (cli → hcl2.cli) - #359
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
7 tasks
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>
mluhovyi
approved these changes
Sep 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Since 8.0 the distribution has installed a top-level
clipackage intosite-packages. Thatsquats a very generic name: a downstream project with its own top-level
clipackage finds itscli.*imports resolving to whichever copy wins onsys.path. At least one consumer has pinnedpython-hcl2>=3.0.5,<8to work around it. Moving the modules underhcl2.climeans thedistribution 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
cli/tohcl2/cli/and repointed thehcl2tojson,jsontohcl2, andhqconsolescripts plus the
packageslist inpyproject.toml. The command names and their behaviour areunchanged, as is
python -m hcl2.hcl_to_json.pyandjson_to_hcl.pyto relativefrom .helpers import ..., matchingwhat
hq.pyalready did.cli/py.typed;hcl2/py.typedalready marks the whole package tree,hcl2.cliincluded.patch("hcl2.cli.json_to_hcl.dump")target, and thepython -ccommand strings intest_cli_subprocess.py.hcl2/cli/*from coverage, replacing the now-deadcli/__init__.pyomit entry(see below).
docs/06_migrating_to_v8.md, and corrected the modulemap 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
FAILEDfrom nose2's coverage plugin, not a test failure.tox.iniscopes measurement with[coverage] coverage=hcl2. The CLI has therefore never beenmeasured: it lived outside
hcl2/. Moving it inside pulled ~906 previously unmeasured statementsinto the gate at their existing coverage level (
hq.py79%,helpers.py89%, the two converters92%), dropping the total below
fail_under = 95:mainhcl2/cli/*omittedA 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 underthe gate is a separate decision with its own work (lifting
hq.pyoff 79%), not something tosmuggle into a packaging fix.
Test plan
nose2 --config tox.ini) on 3.13:Ran 1534 tests ... OK, exit 0, coverage 95.519% — identical tomainpip install .into a fresh venv:site-packagesholdshcl2,lark,regexand notop-level
cli;python -c "import cli"raisesModuleNotFoundErrorpython -c "import hcl2.cli.hq"succeeds from that venvecho 'x = 1' | hcl2tojson,echo 'x = 1' | hq .x,echo '{"x": 1}' | jsontohcl2echo 'x = 1' | python -m hcl2still prints{"x": 1}(the__main__shim)hcl2/py.typedstill present in the installed package, sohcl2.clistays typedruff check,ruff format,mypyclean🤖 Co-Authored-By: Claude Opus 5 (1M context) Claude Code