Skip to content

Commit 53e3fb0

Browse files
committed
new terraform_fmt_v2 with better Windows support
1 parent 1bdc82b commit 53e3fb0

File tree

7 files changed

+281
-4
lines changed

7 files changed

+281
-4
lines changed

.gitignore

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,177 @@
11
tests/results/*
2+
# Created by https://www.toptal.com/developers/gitignore/api/python
3+
# Edit at https://www.toptal.com/developers/gitignore?templates=python
4+
5+
### Python ###
6+
# Byte-compiled / optimized / DLL files
7+
__pycache__/
8+
*.py[cod]
9+
*$py.class
10+
11+
# C extensions
12+
*.so
13+
14+
# Distribution / packaging
15+
.Python
16+
build/
17+
develop-eggs/
18+
dist/
19+
downloads/
20+
eggs/
21+
.eggs/
22+
lib/
23+
lib64/
24+
parts/
25+
sdist/
26+
var/
27+
wheels/
28+
share/python-wheels/
29+
*.egg-info/
30+
.installed.cfg
31+
*.egg
32+
MANIFEST
33+
34+
# PyInstaller
35+
# Usually these files are written by a python script from a template
36+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
37+
*.manifest
38+
*.spec
39+
40+
# Installer logs
41+
pip-log.txt
42+
pip-delete-this-directory.txt
43+
44+
# Unit test / coverage reports
45+
htmlcov/
46+
.tox/
47+
.nox/
48+
.coverage
49+
.coverage.*
50+
.cache
51+
nosetests.xml
52+
coverage.xml
53+
*.cover
54+
*.py,cover
55+
.hypothesis/
56+
.pytest_cache/
57+
cover/
58+
59+
# Translations
60+
*.mo
61+
*.pot
62+
63+
# Django stuff:
64+
*.log
65+
local_settings.py
66+
db.sqlite3
67+
db.sqlite3-journal
68+
69+
# Flask stuff:
70+
instance/
71+
.webassets-cache
72+
73+
# Scrapy stuff:
74+
.scrapy
75+
76+
# Sphinx documentation
77+
docs/_build/
78+
79+
# PyBuilder
80+
.pybuilder/
81+
target/
82+
83+
# Jupyter Notebook
84+
.ipynb_checkpoints
85+
86+
# IPython
87+
profile_default/
88+
ipython_config.py
89+
90+
# pyenv
91+
# For a library or package, you might want to ignore these files since the code is
92+
# intended to run in multiple environments; otherwise, check them in:
93+
# .python-version
94+
95+
# pipenv
96+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
97+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
98+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
99+
# install all needed dependencies.
100+
#Pipfile.lock
101+
102+
# poetry
103+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
104+
# This is especially recommended for binary packages to ensure reproducibility, and is more
105+
# commonly ignored for libraries.
106+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
107+
#poetry.lock
108+
109+
# pdm
110+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
111+
#pdm.lock
112+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
113+
# in version control.
114+
# https://pdm.fming.dev/#use-with-ide
115+
.pdm.toml
116+
117+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
118+
__pypackages__/
119+
120+
# Celery stuff
121+
celerybeat-schedule
122+
celerybeat.pid
123+
124+
# SageMath parsed files
125+
*.sage.py
126+
127+
# Environments
128+
.env
129+
.venv
130+
env/
131+
venv/
132+
ENV/
133+
env.bak/
134+
venv.bak/
135+
136+
# Spyder project settings
137+
.spyderproject
138+
.spyproject
139+
140+
# Rope project settings
141+
.ropeproject
142+
143+
# mkdocs documentation
144+
/site
145+
146+
# mypy
147+
.mypy_cache/
148+
.dmypy.json
149+
dmypy.json
150+
151+
# Pyre type checker
152+
.pyre/
153+
154+
# pytype static type analyzer
155+
.pytype/
156+
157+
# Cython debug symbols
158+
cython_debug/
159+
160+
# PyCharm
161+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
162+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
163+
# and can be added to the global gitignore or merged into this file. For a more nuclear
164+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
165+
#.idea/
166+
167+
### Python Patch ###
168+
# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
169+
poetry.toml
170+
171+
# ruff
172+
.ruff_cache/
173+
174+
# LSP config files
175+
pyrightconfig.json
176+
177+
# End of https://www.toptal.com/developers/gitignore/api/python

.pre-commit-hooks.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@
1515
files: (\.tf|\.tfvars)$
1616
exclude: \.terraform/.*$
1717

18+
- id: terraform_fmt_v2
19+
name: Terraform fmt
20+
description: Rewrites all Terraform configuration files to a canonical format.
21+
entry: terraform_fmt
22+
language: python
23+
files: (\.tf|\.tfvars)$
24+
exclude: \.terraform/.*$
25+
1826
- id: terraform_docs
1927
name: Terraform docs
2028
description: Inserts input and output documentation into README.md (using terraform-docs).

hooks/__init__.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +0,0 @@
1-
print(
2-
'`terraform_docs_replace` hook is DEPRECATED.'
3-
'For migration instructions see https://github.com/antonbabenko/pre-commit-terraform/issues/248#issuecomment-1290829226'
4-
)

hooks/common.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
from __future__ import annotations
2+
3+
import argparse
4+
import logging
5+
import os
6+
from collections.abc import Sequence
7+
8+
logger = logging.getLogger(__name__)
9+
10+
11+
def setup_logging():
12+
logging.basicConfig(
13+
level={
14+
"error": logging.ERROR,
15+
"warn": logging.WARNING,
16+
"warning": logging.WARNING,
17+
"info": logging.INFO,
18+
"debug": logging.DEBUG,
19+
}[os.environ.get("PRE_COMMIT_TERRAFORM_LOG_LEVEL", "warning").lower()]
20+
)
21+
22+
23+
def parse_env_vars(ev_strs: list[str]) -> dict[str, str]:
24+
ret = {}
25+
for ev_str in ev_strs:
26+
name, val = ev_str.split("=", 1)
27+
if val.startswith('"') and val.endswith('"'):
28+
val = val[1:-1]
29+
ret[name] = val
30+
return ret
31+
32+
33+
def parse_cmdline(
34+
argv: Sequence[str] | None = None,
35+
) -> tuple[list[str], list[str], list[str], list[str], dict[str, str]]:
36+
parser = argparse.ArgumentParser(
37+
add_help=False, # to allow us to use -h to be compatible with previous bash version
38+
)
39+
parser.add_argument("-a", "--args", action="append", help="Arguments")
40+
parser.add_argument("-h", "--hook-config", action="append", help="Hook Config")
41+
parser.add_argument("-i", "--init-args", "--tf-init-args", action="append", help="Init Args")
42+
parser.add_argument("-e", "--envs", "--env-vars", action="append", help="Environment Variables")
43+
parser.add_argument("FILES", nargs="*", help="Files")
44+
45+
parsed_args = parser.parse_args(argv)
46+
47+
args = parsed_args.args or []
48+
hook_config = parsed_args.hook_config or []
49+
files = parsed_args.FILES or []
50+
tc_init_args = parsed_args.init_args or []
51+
env_vars = parsed_args.envs or []
52+
53+
env_var_dict = parse_env_vars(env_vars)
54+
55+
if hook_config:
56+
raise NotImplementedError("TODO: implement: hook_config")
57+
58+
if tc_init_args:
59+
raise NotImplementedError("TODO: implement: tc_init_args")
60+
61+
return args, hook_config, files, tc_init_args, env_var_dict

hooks/terraform_docs_replace.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
import subprocess
44
import sys
55

6+
print(
7+
'`terraform_docs_replace` hook is DEPRECATED.'
8+
'For migration instructions see https://github.com/antonbabenko/pre-commit-terraform/issues/248#issuecomment-1290829226'
9+
)
10+
611

712
def main(argv=None):
813
parser = argparse.ArgumentParser(

hooks/terraform_fmt.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from __future__ import annotations
2+
3+
import logging
4+
import os
5+
import shlex
6+
import sys
7+
from subprocess import PIPE, run
8+
from typing import Sequence
9+
10+
from .common import parse_cmdline, setup_logging
11+
12+
logger = logging.getLogger(__name__)
13+
14+
15+
def main(argv: Sequence[str] | None = None) -> int:
16+
setup_logging()
17+
logger.debug(sys.version_info)
18+
args, hook_config, files, tf_init_args, env_vars = parse_cmdline(argv)
19+
cmd = ["terraform", "fmt", *args, *files]
20+
logger.info("calling %s", shlex.join(cmd))
21+
logger.debug("env_vars: %r", env_vars)
22+
logger.debug("args: %r", args)
23+
completed_process = run(cmd, env={**os.environ, **env_vars}, text=True, stdout=PIPE)
24+
if completed_process.stdout:
25+
print(completed_process.stdout)
26+
return completed_process.returncode
27+
28+
29+
if __name__ == "__main__":
30+
raise SystemExit(main())

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
entry_points={
2929
'console_scripts': [
3030
'terraform_docs_replace = hooks.terraform_docs_replace:main',
31+
'terraform_fmt = hooks.terraform_fmt:main',
3132
],
3233
},
3334
)

0 commit comments

Comments
 (0)