python-hcl2 5.0.0__tar.gz → 5.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/.github/workflows/pr_check.yml +1 -1
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/PKG-INFO +10 -1
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/README.md +8 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/hcl2/version.py +2 -2
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/pyproject.toml +1 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/python_hcl2.egg-info/PKG-INFO +10 -1
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/python_hcl2.egg-info/SOURCES.txt +1 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/tox.ini +2 -1
- python-hcl2-5.1.0/tree-to-hcl2-reconstruction.md +130 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/.codacy.yml +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/.coveragerc +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/.github/CODEOWNERS +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/.github/workflows/codeql-analysis.yml +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/.github/workflows/publish.yml +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/.gitignore +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/.pre-commit-config.yaml +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/.yamllint.yml +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/CHANGELOG.md +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/LICENSE +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/MANIFEST.in +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/bin/terraform_test +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/hcl2/__init__.py +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/hcl2/__main__.py +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/hcl2/api.py +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/hcl2/hcl2.lark +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/hcl2/parser.py +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/hcl2/py.typed +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/hcl2/reconstructor.py +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/hcl2/transformer.py +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/mypy.ini +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/pylintrc +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/python_hcl2.egg-info/dependency_links.txt +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/python_hcl2.egg-info/entry_points.txt +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/python_hcl2.egg-info/not-zip-safe +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/python_hcl2.egg-info/requires.txt +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/python_hcl2.egg-info/top_level.txt +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/reports/.gitignore +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/requirements.txt +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/setup.cfg +0 -0
- {python-hcl2-5.0.0 → python-hcl2-5.1.0}/test-requirements.txt +0 -0
|
@@ -13,7 +13,7 @@ jobs:
|
|
|
13
13
|
runs-on: ubuntu-22.04
|
|
14
14
|
strategy:
|
|
15
15
|
matrix:
|
|
16
|
-
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12']
|
|
16
|
+
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
|
|
17
17
|
steps:
|
|
18
18
|
- uses: actions/checkout@master
|
|
19
19
|
- name: Set up Python ${{ matrix.python-version }}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: python-hcl2
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.1.0
|
|
4
4
|
Summary: A parser for HCL2
|
|
5
5
|
Author-email: Amplify Education <github@amplify.com>
|
|
6
6
|
License: MIT
|
|
@@ -18,6 +18,7 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.10
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
22
|
Requires-Python: >=3.7.0
|
|
22
23
|
Description-Content-Type: text/markdown
|
|
23
24
|
License-File: LICENSE
|
|
@@ -66,6 +67,14 @@ with open('foo.tf', 'r') as file:
|
|
|
66
67
|
dict = hcl2.load(file)
|
|
67
68
|
```
|
|
68
69
|
|
|
70
|
+
### Parse Tree to HCL2 reconstruction
|
|
71
|
+
|
|
72
|
+
With version 5.0.0 the possibility of HCL2 reconstruction from Lark Parse Tree was introduced.
|
|
73
|
+
|
|
74
|
+
Example of manipulating Lark Parse Tree and reconstructing it back into valid HCL2 can be found in [tree-to-hcl2-reconstruction.md](tree-to-hcl2-reconstruction.md) file.
|
|
75
|
+
|
|
76
|
+
More details about reconstruction implementation can be found in this [PR](https://github.com/amplify-education/python-hcl2/pull/169).
|
|
77
|
+
|
|
69
78
|
## Building From Source
|
|
70
79
|
|
|
71
80
|
For development, `tox>=4.0.9` is recommended.
|
|
@@ -42,6 +42,14 @@ with open('foo.tf', 'r') as file:
|
|
|
42
42
|
dict = hcl2.load(file)
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
+
### Parse Tree to HCL2 reconstruction
|
|
46
|
+
|
|
47
|
+
With version 5.0.0 the possibility of HCL2 reconstruction from Lark Parse Tree was introduced.
|
|
48
|
+
|
|
49
|
+
Example of manipulating Lark Parse Tree and reconstructing it back into valid HCL2 can be found in [tree-to-hcl2-reconstruction.md](tree-to-hcl2-reconstruction.md) file.
|
|
50
|
+
|
|
51
|
+
More details about reconstruction implementation can be found in this [PR](https://github.com/amplify-education/python-hcl2/pull/169).
|
|
52
|
+
|
|
45
53
|
## Building From Source
|
|
46
54
|
|
|
47
55
|
For development, `tox>=4.0.9` is recommended.
|
|
@@ -22,6 +22,7 @@ classifiers = [
|
|
|
22
22
|
"Programming Language :: Python :: 3.10",
|
|
23
23
|
"Programming Language :: Python :: 3.11",
|
|
24
24
|
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Programming Language :: Python :: 3.13",
|
|
25
26
|
]
|
|
26
27
|
requires-python = ">=3.7.0"
|
|
27
28
|
dependencies = ["lark>=1,<2"]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: python-hcl2
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.1.0
|
|
4
4
|
Summary: A parser for HCL2
|
|
5
5
|
Author-email: Amplify Education <github@amplify.com>
|
|
6
6
|
License: MIT
|
|
@@ -18,6 +18,7 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.10
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
22
|
Requires-Python: >=3.7.0
|
|
22
23
|
Description-Content-Type: text/markdown
|
|
23
24
|
License-File: LICENSE
|
|
@@ -66,6 +67,14 @@ with open('foo.tf', 'r') as file:
|
|
|
66
67
|
dict = hcl2.load(file)
|
|
67
68
|
```
|
|
68
69
|
|
|
70
|
+
### Parse Tree to HCL2 reconstruction
|
|
71
|
+
|
|
72
|
+
With version 5.0.0 the possibility of HCL2 reconstruction from Lark Parse Tree was introduced.
|
|
73
|
+
|
|
74
|
+
Example of manipulating Lark Parse Tree and reconstructing it back into valid HCL2 can be found in [tree-to-hcl2-reconstruction.md](tree-to-hcl2-reconstruction.md) file.
|
|
75
|
+
|
|
76
|
+
More details about reconstruction implementation can be found in this [PR](https://github.com/amplify-education/python-hcl2/pull/169).
|
|
77
|
+
|
|
69
78
|
## Building From Source
|
|
70
79
|
|
|
71
80
|
For development, `tox>=4.0.9` is recommended.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
[tox]
|
|
2
|
-
envlist={py37}-unit,{py38}-unit,{py39}-unit,{py310}-unit,{py311}-unit,{py312}-unit
|
|
2
|
+
envlist={py37}-unit,{py38}-unit,{py39}-unit,{py310}-unit,{py311}-unit,{py312}-unit,{py313}-unit
|
|
3
3
|
skipsdist=true
|
|
4
4
|
|
|
5
5
|
[gh-actions]
|
|
@@ -10,6 +10,7 @@ python =
|
|
|
10
10
|
3.10: py310-unit
|
|
11
11
|
3.11: py311-unit
|
|
12
12
|
3.12: py312-unit
|
|
13
|
+
3.13: py313-unit
|
|
13
14
|
|
|
14
15
|
[testenv]
|
|
15
16
|
commands =
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
Given `example.tf` file with following content
|
|
2
|
+
|
|
3
|
+
```terraform
|
|
4
|
+
resource "aws_s3_bucket" "bucket" {
|
|
5
|
+
bucket = "bucket_id"
|
|
6
|
+
force_destroy = true
|
|
7
|
+
}
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
below code will add a `tags` object to the S3 bucket definition. The code can also be used to print out readable representation of **any** Parse Tree (any valid HCL2 file), which can be useful when working on your own logic for arbitrary Parse Tree manipulation.
|
|
11
|
+
|
|
12
|
+
```python
|
|
13
|
+
from copy import deepcopy
|
|
14
|
+
from lark import Token, Tree
|
|
15
|
+
import hcl2
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def build_tags_tree(base_indent: int = 0) -> Tree:
|
|
19
|
+
# build Tree representing following HCL2 structure
|
|
20
|
+
# tags = {
|
|
21
|
+
# Name = "My bucket"
|
|
22
|
+
# Environment = "Dev"
|
|
23
|
+
# }
|
|
24
|
+
return Tree('attribute', [
|
|
25
|
+
Tree('identifier', [
|
|
26
|
+
Token('NAME', 'tags')
|
|
27
|
+
]),
|
|
28
|
+
Token('EQ', '='),
|
|
29
|
+
Tree('expr_term', [
|
|
30
|
+
Tree('object', [
|
|
31
|
+
Tree('new_line_or_comment', [
|
|
32
|
+
Token('NL_OR_COMMENT', '\n' + ' ' * (base_indent + 1)),
|
|
33
|
+
]),
|
|
34
|
+
Tree('object_elem', [
|
|
35
|
+
Tree('identifier', [
|
|
36
|
+
Token('NAME', 'Name')
|
|
37
|
+
]),
|
|
38
|
+
Token('EQ', '='),
|
|
39
|
+
Tree('expr_term', [
|
|
40
|
+
Token('STRING_LIT', '"My bucket"')
|
|
41
|
+
])
|
|
42
|
+
]),
|
|
43
|
+
Tree('new_line_and_or_comma', [
|
|
44
|
+
Tree('new_line_or_comment', [
|
|
45
|
+
Token('NL_OR_COMMENT', '\n' + ' ' * (base_indent + 1)),
|
|
46
|
+
]),
|
|
47
|
+
]),
|
|
48
|
+
Tree('object_elem', [
|
|
49
|
+
Tree('identifier', [
|
|
50
|
+
Token('NAME', 'Environment')
|
|
51
|
+
]),
|
|
52
|
+
Token('EQ', '='),
|
|
53
|
+
Tree('expr_term', [
|
|
54
|
+
Token('STRING_LIT', '"Dev"')
|
|
55
|
+
])
|
|
56
|
+
]),
|
|
57
|
+
Tree('new_line_and_or_comma', [
|
|
58
|
+
Tree('new_line_or_comment', [
|
|
59
|
+
Token('NL_OR_COMMENT', '\n' + ' ' * base_indent),
|
|
60
|
+
]),
|
|
61
|
+
]),
|
|
62
|
+
]),
|
|
63
|
+
])
|
|
64
|
+
])
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def is_bucket_block(tree: Tree) -> bool:
|
|
68
|
+
# check whether given Tree represents `resource "aws_s3_bucket" "bucket"`
|
|
69
|
+
try:
|
|
70
|
+
return tree.data == 'block' and tree.children[2].value == '"bucket"'
|
|
71
|
+
except IndexError:
|
|
72
|
+
return False
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def insert_tags(tree: Tree, indent: int = 0) -> Tree:
|
|
76
|
+
# Insert tags tree and adjust surrounding whitespaces to match indentation
|
|
77
|
+
new_children = [*tree.children.copy(), build_tags_tree(indent)]
|
|
78
|
+
# add indentation before tags tree
|
|
79
|
+
new_children[len(tree.children) - 1] = Tree('new_line_or_comment', [
|
|
80
|
+
Token('NL_OR_COMMENT', '\n ')
|
|
81
|
+
])
|
|
82
|
+
# move closing bracket to the new line
|
|
83
|
+
new_children.append(
|
|
84
|
+
Tree('new_line_or_comment', [
|
|
85
|
+
Token('NL_OR_COMMENT', '\n')
|
|
86
|
+
])
|
|
87
|
+
)
|
|
88
|
+
return Tree(tree.data, new_children)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def process_token(node: Token, indent=0):
|
|
92
|
+
# Print details of this token and return its copy
|
|
93
|
+
print(f'[{indent}] (token)\t|', ' ' * indent, node.type, node.value)
|
|
94
|
+
return deepcopy(node)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def process_tree(node: Tree, depth=0) -> Tree:
|
|
98
|
+
# Recursively iterate over tree's children
|
|
99
|
+
# the depth parameter represents recursion depth,
|
|
100
|
+
# it's used to deduce indentation for printing tree and for adjusting whitespace after adding tags
|
|
101
|
+
new_children = []
|
|
102
|
+
print(f'[{depth}] (tree)\t|', ' ' * depth, node.data)
|
|
103
|
+
for child in node.children:
|
|
104
|
+
if isinstance(child, Tree):
|
|
105
|
+
if is_bucket_block(child):
|
|
106
|
+
block_children = child.children.copy()
|
|
107
|
+
# this child is the Tree representing block's actual body
|
|
108
|
+
block_children[3] = insert_tags(block_children[3], depth)
|
|
109
|
+
# replace original Tree with new one including the modified body
|
|
110
|
+
child = Tree(child.data, block_children)
|
|
111
|
+
|
|
112
|
+
new_children.append(process_tree(child, depth + 1))
|
|
113
|
+
|
|
114
|
+
else:
|
|
115
|
+
new_children.append(process_token(child, depth + 1))
|
|
116
|
+
|
|
117
|
+
return Tree(node.data, new_children)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def main():
|
|
121
|
+
tree = hcl2.parse(open('example.tf'))
|
|
122
|
+
new_tree = process_tree(tree)
|
|
123
|
+
reconstructed = hcl2.writes(new_tree)
|
|
124
|
+
open('example_reconstructed.tf', 'w').write(reconstructed)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
if __name__ == "__main__":
|
|
128
|
+
main()
|
|
129
|
+
|
|
130
|
+
```
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|