Skip to content

Commit 33590fc

Browse files
Consolidate v8 RC changelog into v8.1.0 release (2026-04-07) (#285)
Collapse 8.0.0-rc2 section and add entries for hq CLI, agent-friendly conversion CLIs, template directives, comment loading, and bug fixes shipped since rc2. Update README and getting-started docs with CLI mentions, pipx install, hq examples link, and revised roadmap. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 5da4887 commit 33590fc

4 files changed

Lines changed: 36 additions & 15 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
99

1010
- Nothing yet.
1111

12-
## \[8.0.0\] - rc2
12+
## \[8.1.0\] - 2026-04-07
1313

1414
### Added
1515

1616
- Full architecture overhaul: bidirectional HCL2 ↔ JSON pipeline with typed rule classes. ([#203](https://github.com/amplify-education/python-hcl2/pull/203))
17-
- add function tuples round-trip test suite ([#268](https://github.com/amplify-education/python-hcl2/pull/268))
18-
- Add postlexer to support multiline binary operators and ternary expressions ([#270](https://github.com/amplify-education/python-hcl2/pull/270))
19-
- more robust whitespace handling in reconstruction ([#271](https://github.com/amplify-education/python-hcl2/pull/271))
20-
- SerializationOptions - add an option to strip string quotes in dict/JSON output ([#272](https://github.com/amplify-education/python-hcl2/pull/272))
17+
- `hq` read-only query CLI for HCL2 files ([#277](https://github.com/amplify-education/python-hcl2/pull/277))
18+
- Agent-friendly conversion CLIs: `hcl2tojson` and `jsontohcl2` ([#274](https://github.com/amplify-education/python-hcl2/pull/274))
19+
- Add template directives support (`%{if}`, `%{for}`) in quoted strings ([#276](https://github.com/amplify-education/python-hcl2/pull/276))
20+
- Support loading comments ([#134](https://github.com/amplify-education/python-hcl2/issues/134))
2121
- CLAUDE.md ([#260](https://github.com/amplify-education/python-hcl2/pull/260))
2222

2323
### Fixed
@@ -34,7 +34,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
3434
- Interpolation literals added to locals/variables in maps ([#252](https://github.com/amplify-education/python-hcl2/issues/252))
3535
- Object literal expression can't be serialized ([#253](https://github.com/amplify-education/python-hcl2/issues/253))
3636
- Heredocs should interpret backslash literally ([#262](https://github.com/amplify-education/python-hcl2/issues/262))
37-
- Parsing a multi-line multi-conditional expression causes exception - Unexpected token Token('QMARK', '?') ([#269](https://github.com/amplify-education/python-hcl2/issues/269))
37+
- Parsing a multi-line multi-conditional expression causes exception — Unexpected token Token('QMARK', '?') ([#269](https://github.com/amplify-education/python-hcl2/issues/269))
38+
- Parsing error for multiline binary operators ([#246](https://github.com/amplify-education/python-hcl2/pull/246))
3839

3940
### Changed
4041

CLAUDE.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ The **Direct** pipeline (`parse_to_tree` → `transform` → `to_lark` → `reco
2323
| `hcl2/formatter.py` | Whitespace alignment and spacing on LarkElement trees |
2424
| `hcl2/reconstructor.py` | LarkElement tree → HCL2 text via Lark |
2525
| `hcl2/builder.py` | Programmatic HCL document construction |
26+
| `hcl2/walk.py` | Generic tree-walking primitives for the LarkElement IR tree |
2627
| `hcl2/utils.py` | `SerializationOptions`, `SerializationContext`, string helpers |
2728
| `hcl2/const.py` | Constants: `IS_BLOCK`, `COMMENTS_KEY`, `INLINE_COMMENTS_KEY` |
2829
| `cli/helpers.py` | File/directory/stdin conversion helpers |
@@ -31,8 +32,15 @@ The **Direct** pipeline (`parse_to_tree` → `transform` → `to_lark` → `reco
3132
| `cli/hq.py` | `hq` CLI entry point — query dispatch, formatting, optional operator |
3233
| `hcl2/query/__init__.py` | Public query API exports |
3334
| `hcl2/query/_base.py` | `NodeView` base class, view registry, `view_for()` factory |
35+
| `hcl2/query/body.py` | `DocumentView`, `BodyView` facades for top-level and body queries |
36+
| `hcl2/query/blocks.py` | `BlockView` facade for block queries |
37+
| `hcl2/query/attributes.py` | `AttributeView` facade for attribute queries |
38+
| `hcl2/query/containers.py` | `TupleView`, `ObjectView` facades for container queries |
39+
| `hcl2/query/expressions.py` | `ConditionalView` facade for conditional expressions |
40+
| `hcl2/query/functions.py` | `FunctionCallView` facade for function call queries |
41+
| `hcl2/query/for_exprs.py` | `ForTupleView`, `ForObjectView` facades for for-expressions |
3442
| `hcl2/query/path.py` | Structural path parser (`PathSegment`, `parse_path`, `[select()]`, `type:name`) |
35-
| `hcl2/query/resolver.py` | Path resolver — segment-by-segment with label depth, type filter, FunctionCallView |
43+
| `hcl2/query/resolver.py` | Path resolver — segment-by-segment with label depth, type filter |
3644
| `hcl2/query/pipeline.py` | Pipe operator — `split_pipeline`, `classify_stage`, `execute_pipeline` |
3745
| `hcl2/query/builtins.py` | Built-in transforms: `keys`, `values`, `length` |
3846
| `hcl2/query/diff.py` | Structural diff between two HCL documents |
@@ -65,12 +73,13 @@ Follows the `json` module convention. All option parameters are keyword-only.
6573

6674
- `load/loads` — HCL2 text → Python dict
6775
- `dump/dumps` — Python dict → HCL2 text
76+
- `query` — HCL2 text/file → `DocumentView` for structured queries
6877
- Intermediate stages: `parse/parses`, `parse_to_tree/parses_to_tree`, `transform`, `serialize`, `from_dict`, `from_json`, `reconstruct`
6978

7079
### Option Dataclasses
7180

7281
**`SerializationOptions`** (LarkElement → dict):
73-
`with_comments`, `with_meta`, `wrap_objects`, `wrap_tuples`, `explicit_blocks`, `preserve_heredocs`, `force_operation_parentheses`, `preserve_scientific_notation`
82+
`with_comments`, `with_meta`, `wrap_objects`, `wrap_tuples`, `explicit_blocks`, `preserve_heredocs`, `force_operation_parentheses`, `preserve_scientific_notation`, `strip_string_quotes`
7483

7584
**`DeserializerOptions`** (dict → LarkElement):
7685
`heredocs_to_strings`, `strings_to_heredocs`, `object_elements_colon`, `object_elements_trailing_comma`

README.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77
# Python HCL2
88

99
A parser for [HCL2](https://github.com/hashicorp/hcl/blob/hcl2/hclsyntax/spec.md) written in Python using
10-
[Lark](https://github.com/lark-parser/lark). This parser only supports HCL2 and isn't backwards compatible
11-
with HCL v1. It can be used to parse any HCL2 config file such as Terraform.
10+
[Lark](https://github.com/lark-parser/lark). It can be used as a Python library or through its CLI tools:
11+
`hcl2tojson`, `jsontohcl2`, and `hq` — a jq-like query tool for HCL files.
12+
Supports HCL2 only (not backwards compatible with HCL v1) and works with any HCL2 config file such as Terraform.
1213

1314
## About Amplify
1415

@@ -33,6 +34,12 @@ This package can be installed using `pip`
3334
pip3 install python-hcl2
3435
```
3536

37+
To install the CLI tools (`hcl2tojson`, `jsontohcl2`, `hq`) globally without affecting your project environments, use [pipx](https://pipx.pypa.io/):
38+
39+
```sh
40+
pipx install python-hcl2
41+
```
42+
3643
### Usage
3744

3845
**HCL2 to Python dict:**
@@ -75,6 +82,7 @@ hcl_string = hcl2.dumps(doc.build())
7582
| [Querying HCL (Python)](docs/02_querying.md) | DocumentView, BlockView, tree walking, view hierarchy |
7683
| [Advanced API](docs/03_advanced_api.md) | Pipeline stages, Builder |
7784
| [hq Reference](docs/04_hq.md) | `hq` CLI — structural queries, hybrid/eval, introspection |
85+
| [hq Examples](docs/05_hq_examples.md) | Real-world queries for discovery, compliance, extraction |
7886

7987
### CLI Tools
8088

@@ -123,13 +131,10 @@ Github actions will take care of publishing it to PyPi.
123131

124132
Planned features, roughly in priority order:
125133

126-
- **Agent-friendly CLIs** — structured errors, NDJSON streaming, and filtering for `hcl2tojson`/`jsontohcl2`
127-
- **Comment deserialization** — preserve comments through JSON round-trip (issue #134)
128-
- **jq syntax compatibility**`.[]` as alias for `[*]`; canonical `hq --json | jq` patterns for data transforms
129134
- **MCP server** — expose parsing, querying, and formatting as MCP tools for AI agents
130-
- **Canonical formatting**predictable whitespace output, closer to `terraform fmt`
135+
- **Predictable formatting**source-derived formatting heuristics and stable whitespace defaults
131136
- **In-place tree edits**`hq set`, `hq delete` for programmatic HCL modification
132-
- **Comment reserialization** — comments survive tree edits, not just JSON round-trips
137+
- **Comment deserialization** — comments survive JSON round-trips and tree edits
133138
- **Expression intelligence** — variable reference tracking, unused variable detection, cross-file analysis
134139
- **Refactoring operations**`hq rename`, `hq extract-module`, `hq sort` for high-level code transforms
135140

docs/01_getting_started.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ python-hcl2 requires Python 3.8 or higher.
1010
pip install python-hcl2
1111
```
1212

13+
For the CLI tools only (`hcl2tojson`, `jsontohcl2`, `hq`), [pipx](https://pipx.pypa.io/) installs them globally in an isolated environment:
14+
15+
```sh
16+
pipx install python-hcl2
17+
```
18+
1319
## Quick Reference
1420

1521
| Function | Description |

0 commit comments

Comments
 (0)