hq: read-only query CLI for HCL2 files#277
Open
kkozik-amplify wants to merge 1 commit intorelease/8.xfrom
Open
hq: read-only query CLI for HCL2 files#277kkozik-amplify wants to merge 1 commit intorelease/8.xfrom
kkozik-amplify wants to merge 1 commit intorelease/8.xfrom
Conversation
6051210 to
6cff160
Compare
There was a problem hiding this comment.
Pull request overview
Adds an initial HCL2 “query” layer (typed view facades + structural path/pipeline/predicate system) and a new hq CLI for jq-like querying, introspection, and structural diffs.
Changes:
- Introduces
hcl2.querypackage (views, path parsing, resolver, pipeline, predicates, builtins, introspection, diff utilities). - Adds
hqCLI entrypoint and registers it inpyproject.toml, with docs updates and extensive unit tests. - Adds generic IR tree-walking helpers (
hcl2.walk) and improves HCL reconstruction for subtrees (reconstruct_fragment).
Reviewed changes
Copilot reviewed 52 out of 53 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| test/unit/test_walk.py | New tests for generic tree walking and find helpers. |
| test/unit/test_api.py | Adds coverage for new hcl2.api.query() convenience entrypoint. |
| test/unit/rules/test_whitespace.py | Updates comment serialization expectations and adds multiline block-comment test. |
| test/unit/query/init.py | Test package marker for query tests. |
| test/unit/query/test_safe_eval.py | Tests for AST validation and restricted eval behavior. |
| test/unit/query/test_resolver.py | Tests for structural resolver (wildcards, recursion, type filters, skip-labels). |
| test/unit/query/test_predicate.py | Tests for predicate tokenizer/parser/evaluator (select(), any/all/has, string funcs, postfix not). |
| test/unit/query/test_pipeline.py | Tests for pipeline splitting/classification/execution and construct stage. |
| test/unit/query/test_path.py | Tests for structural path parsing including recursion, type filters, skip-labels, optional suffix. |
| test/unit/query/test_introspect.py | Tests for --describe/--schema output structure. |
| test/unit/query/test_functions.py | Tests for FunctionCallView facade. |
| test/unit/query/test_for_exprs.py | Tests for for-expression view facades. |
| test/unit/query/test_expressions.py | Tests for ConditionalView and resolver/pipeline integration. |
| test/unit/query/test_diff.py | Tests for structural diff utilities. |
| test/unit/query/test_containers.py | Tests for TupleView/ObjectView behaviors. |
| test/unit/query/test_builtins.py | Tests for built-in pipeline transforms (keys/values/length). |
| test/unit/query/test_body.py | Tests for DocumentView/BodyView parsing and lookup helpers. |
| test/unit/query/test_blocks.py | Tests for BlockView label handling and body delegation. |
| test/unit/query/test_base.py | Tests for NodeView base behaviors and view registry dispatch. |
| test/unit/query/test_attributes.py | Tests for AttributeView name/value/value_node and serialization. |
| test/unit/cli/test_hq.py | CLI behavior tests (modes, output flags, optional, schema/describe, diff). |
| pyproject.toml | Registers hq console script and packages hcl2.query. |
| pylintrc | Disables/adjusts pylint rules to accommodate new query modules. |
| hcl2/walk.py | Adds generic walk/find/ancestors helpers over IR nodes. |
| hcl2/rules/whitespace.py | Changes comment extraction format to object list {value: ...} and adds block-comment handling. |
| hcl2/rules/base.py | Ensures BodyRule.serialize returns a plain dict (not defaultdict). |
| hcl2/reconstructor.py | Adds reconstruct_fragment() for subtree reconstruction without newline normalization. |
| hcl2/query/safe_eval.py | Adds AST-validated restricted eval for hq eval/hybrid modes. |
| hcl2/query/resolver.py | Implements structural path resolver with recursion/type filters/predicates. |
| hcl2/query/predicate.py | Implements predicate tokenizer/parser/evaluator (no Python eval). |
| hcl2/query/pipeline.py | Adds pipeline splitting/classification/execution, plus construct stage support. |
| hcl2/query/path.py | Parses structural paths including recursion, type qualifiers, select(), skip-labels. |
| hcl2/query/introspect.py | Adds schema/describe builders for CLI introspection. |
| hcl2/query/functions.py | Adds FunctionCallView facade. |
| hcl2/query/for_exprs.py | Adds ForTupleView/ForObjectView facades. |
| hcl2/query/expressions.py | Adds ConditionalView facade. |
| hcl2/query/diff.py | Adds structural diff + JSON/text formatting. |
| hcl2/query/containers.py | Adds TupleView/ObjectView facades. |
| hcl2/query/builtins.py | Adds built-in transforms used by pipeline stages. |
| hcl2/query/body.py | Adds DocumentView/BodyView facades and parsing helpers. |
| hcl2/query/blocks.py | Adds BlockView facade for labels/body delegation. |
| hcl2/query/attributes.py | Adds AttributeView facade for name/value access. |
| hcl2/query/_base.py | Adds NodeView base, registry, view factory, and common helpers. |
| hcl2/query/init.py | Public exports for query system. |
| hcl2/api.py | Adds query(source) convenience function returning DocumentView. |
| hcl2/init.py | Re-exports query from api module. |
| docs/04_hq.md | Adds full hq CLI reference and query language documentation. |
| docs/03_advanced_api.md | Updates advanced docs to match new doc structure and references. |
| docs/02_querying.md | Adds Python query API guide for view facades and walking. |
| docs/01_getting_started.md | Reworks getting started guide; documents new comment format and hcl2.query(). |
| README.md | Updates documentation links and mentions the hq CLI tool. |
| CLAUDE.md | Updates architecture map and docs guidance to include query/hq components. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 53 out of 54 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
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
Adds
hq, a read-only query CLI for HCL2 files, and thehcl2.queryPython API it's built on.Query API (
hcl2/query/)A typed view layer over the LarkElement IR tree, enabling structural navigation without serializing to dicts.
NodeViewhierarchy — typed wrappers for every IR node:DocumentView,BodyView,BlockView,AttributeView,TupleView,ObjectView,ForTupleView,ForObjectView,FunctionCallView,ConditionalView. Each exposes semantic accessors (.block_type,.name_labels,.value,.elements, etc.)resource.aws_instance.main), type filters (resource:aws_instance), wildcards ([*]), andselect()predicatesresource[*] | .tags | keys)and,or,not), comparisons (==,!=,>,<), and string functions (contains,test,has,startswith,endswith)keys,values,length,type,flatten,unique,sort,reverse,first,last,min,max,group_by,sort_by,to_entries,from_entries{key: .path}syntax for reshaping results--describeshows view type and available accessors;--schemadumps the full view hierarchystructural::evalfor mixing path queries with Python attribute access;-efor pure eval with AST-validated safe expressionshcl2.walk— generic tree walker for LarkElement treesCLI (
cli/hq.py)--json,--ndjson,--value,--raw--with-locationfor file + line metadata in JSON output--with-commentsfor comment extraction__file__provenance in multi-file JSON results?suffix) — exit 0 on empty results--difffor structural comparison between two filesDocs & tests
Test plan
python -m unittest discover -s test -p "test_*.py"— all tests passecho "" | hq 'x' -exits 1;hq 'x' nonexistent.tfexits 4hq --json 'resource[*]' dir/includes__file__in each resulthq --ndjson 'resource[*]' dir/produces one compact JSON per linehq --json --with-location 'resource[*]' file.tfincludes__line__and__end_line__hq 'query' file1.tf file2.tf dir/works with multiple paths🤖 Generated with Claude Code