Skip to content

Commit 7e1dd4f

Browse files
committed
chore(linters): Introduce ruff and fix issues
1 parent c949dd2 commit 7e1dd4f

File tree

11 files changed

+196
-131
lines changed

11 files changed

+196
-131
lines changed

.pre-commit-config.yaml

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,21 @@ repos:
4747
hooks:
4848
- id: gitleaks
4949

50+
# Dockerfile linter
51+
- repo: https://github.com/hadolint/hadolint
52+
rev: v2.12.1-beta
53+
hooks:
54+
- id: hadolint
55+
args:
56+
- --ignore=DL3007 # Using latest
57+
- --ignore=DL3013 # Pin versions in pip
58+
- --ignore=DL3027 # Do not use apt
59+
- --ignore=DL3059 # Docker `RUN`s shouldn't be consolidated here
60+
- --ignore=DL4006 # Not related to alpine
61+
- --ignore=SC1091 # Useless check
62+
- --ignore=SC2015 # Useless check
63+
- --ignore=SC3037 # Not related to alpine
64+
5065
#
5166
# YAML Linters
5267
#
@@ -79,6 +94,32 @@ repos:
7994
# https://prettier.io/docs/en/options.html#parser
8095
files: .json5$
8196

97+
98+
# Bash Linter
99+
- repo: https://github.com/jumanjihouse/pre-commit-hooks
100+
rev: 3.0.0
101+
hooks:
102+
- id: shfmt
103+
args:
104+
- -l
105+
- -i
106+
- '2'
107+
- -ci
108+
- -sr
109+
- -w
110+
- id: shellcheck
111+
112+
#
113+
# Python Linters
114+
#
115+
- repo: https://github.com/astral-sh/ruff-pre-commit
116+
rev: v0.8.4
117+
hooks:
118+
- id: ruff
119+
args:
120+
- --fix
121+
- id: ruff-format
122+
82123
- repo: https://github.com/pre-commit/mirrors-mypy.git
83124
rev: v1.15.0
84125
hooks:
@@ -133,31 +174,3 @@ repos:
133174
- --lineprecision-report=.tox/.tmp/.test-results/mypy--py-3.9
134175
- --txt-report=.tox/.tmp/.test-results/mypy--py-3.9
135176
pass_filenames: false
136-
137-
- repo: https://github.com/jumanjihouse/pre-commit-hooks
138-
rev: 3.0.0
139-
hooks:
140-
- id: shfmt
141-
args:
142-
- -l
143-
- -i
144-
- '2'
145-
- -ci
146-
- -sr
147-
- -w
148-
- id: shellcheck
149-
150-
# Dockerfile linter
151-
- repo: https://github.com/hadolint/hadolint
152-
rev: v2.12.1-beta
153-
hooks:
154-
- id: hadolint
155-
args:
156-
- --ignore=DL3007 # Using latest
157-
- --ignore=DL3013 # Pin versions in pip
158-
- --ignore=DL3027 # Do not use apt
159-
- --ignore=DL3059 # Docker `RUN`s shouldn't be consolidated here
160-
- --ignore=DL4006 # Not related to alpine
161-
- --ignore=SC1091 # Useless check
162-
- --ignore=SC2015 # Useless check
163-
- --ignore=SC3037 # Not related to alpine

ruff.toml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Assume Python 3.9
2+
target-version = "py39"
3+
4+
[format]
5+
quote-style = "single"
6+
7+
[lint.flake8-quotes]
8+
inline-quotes = "single"
9+
10+
[lint]
11+
select = ["ALL"]
12+
preview = true
13+
ignore = [
14+
"CPY001", # Missing copyright notice at top of file
15+
"D213", # multi-line-summary-second-line. Incompatible with multi-line-summary-first-line (D212)
16+
"D203", # one-blank-line-before-class. Incompatible with no-blank-line-before-class (D211)
17+
"INP001", # We use namespace packages in this project
18+
]
19+
20+
[lint.isort]
21+
force-single-line = true
22+
23+
[lint.per-file-ignores]
24+
# Ignore in the `tests/` directory.
25+
"tests/**.py" = [
26+
"S101", # Use of `assert` detected
27+
"PLC2701", # We need import marked as internal files for testing
28+
]
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
"""A runpy-style CLI entry-point module."""
22

3-
from sys import argv, exit as exit_with_return_code
3+
from sys import argv
4+
from sys import exit as exit_with_return_code
45

56
from ._cli import invoke_cli_app
67

7-
88
return_code = invoke_cli_app(argv[1:])
99
exit_with_return_code(return_code)

src/pre_commit_terraform/_cli.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,49 +4,51 @@
44
from typing import cast as cast_to
55

66
from ._cli_parsing import initialize_argument_parser
7-
from ._errors import (
8-
PreCommitTerraformBaseError,
9-
PreCommitTerraformExit,
10-
PreCommitTerraformRuntimeError,
11-
)
7+
from ._errors import PreCommitTerraformBaseError
8+
from ._errors import PreCommitTerraformExit
9+
from ._errors import PreCommitTerraformRuntimeError
1210
from ._structs import ReturnCode
13-
from ._types import CLIAppEntryPointCallableType, ReturnCodeType
11+
from ._types import CLIAppEntryPointCallableType
12+
from ._types import ReturnCodeType
1413

1514

1615
def invoke_cli_app(cli_args: list[str]) -> ReturnCodeType:
1716
"""Run the entry-point of the CLI app.
1817
1918
Includes initializing parsers of all the sub-apps and
2019
choosing what to execute.
20+
21+
Returns:
22+
ReturnCodeType: The return code of the app.
23+
2124
"""
2225
root_cli_parser = initialize_argument_parser()
2326
parsed_cli_args = root_cli_parser.parse_args(cli_args)
2427
invoke_cli_app = cast_to(
25-
# FIXME: attempt typing per https://stackoverflow.com/a/75666611/595220
26-
CLIAppEntryPointCallableType,
28+
# FIXME: attempt typing per https://stackoverflow.com/a/75666611/595220 # noqa: TD001, TD002, TD003, FIX001, E501
29+
'CLIAppEntryPointCallableType',
2730
parsed_cli_args.invoke_cli_app,
2831
)
2932

3033
try:
3134
return invoke_cli_app(parsed_cli_args)
3235
except PreCommitTerraformExit as exit_err:
33-
print(f'App exiting: {exit_err !s}', file=sys.stderr)
36+
print(f'App exiting: {exit_err !s}', file=sys.stderr) # noqa: T201 FIXME
3437
raise
3538
except PreCommitTerraformRuntimeError as unhandled_exc:
36-
print(
37-
f'App execution took an unexpected turn: {unhandled_exc !s}. '
38-
'Exiting...',
39+
print( # noqa: T201 FIXME
40+
f'App execution took an unexpected turn: {unhandled_exc !s}. Exiting...',
3941
file=sys.stderr,
4042
)
4143
return ReturnCode.ERROR
4244
except PreCommitTerraformBaseError as unhandled_exc:
43-
print(
45+
print( # noqa: T201 FIXME
4446
f'A surprising exception happened: {unhandled_exc !s}. Exiting...',
4547
file=sys.stderr,
4648
)
4749
return ReturnCode.ERROR
4850
except KeyboardInterrupt as ctrl_c_exc:
49-
print(
51+
print( # noqa: T201 FIXME
5052
f'User-initiated interrupt: {ctrl_c_exc !s}. Exiting...',
5153
file=sys.stderr,
5254
)

src/pre_commit_terraform/_cli_parsing.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,22 @@ def attach_subcommand_parsers_to(root_cli_parser: ArgumentParser, /) -> None:
2222
required=True,
2323
)
2424
for subcommand_module in SUBCOMMAND_MODULES:
25-
subcommand_parser = subcommand_parsers.add_parser(subcommand_module.CLI_SUBCOMMAND_NAME)
25+
subcommand_parser = subcommand_parsers.add_parser(
26+
subcommand_module.CLI_SUBCOMMAND_NAME,
27+
)
2628
subcommand_parser.set_defaults(
2729
invoke_cli_app=subcommand_module.invoke_cli_app,
2830
)
2931
subcommand_module.populate_argument_parser(subcommand_parser)
3032

3133

3234
def initialize_argument_parser() -> ArgumentParser:
33-
"""Return the root argument parser with sub-commands."""
35+
"""Return the root argument parser with sub-commands.
36+
37+
Returns:
38+
ArgumentParser: The root parser with sub-commands attached.
39+
40+
"""
3441
root_cli_parser = ArgumentParser(prog=f'python -m {__package__ !s}')
3542
attach_subcommand_parsers_to(root_cli_parser)
3643
return root_cli_parser

src/pre_commit_terraform/_cli_subcommands.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from . import terraform_docs_replace
44
from ._types import CLISubcommandModuleProtocol
55

6-
76
SUBCOMMAND_MODULES: list[CLISubcommandModuleProtocol] = [
87
terraform_docs_replace,
98
]

src/pre_commit_terraform/_errors.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ class PreCommitTerraformBaseError(Exception):
66

77

88
class PreCommitTerraformRuntimeError(
9-
PreCommitTerraformBaseError,
10-
RuntimeError,
9+
PreCommitTerraformBaseError,
10+
RuntimeError,
1111
):
1212
"""An exception representing a runtime error condition."""
1313

1414

15-
class PreCommitTerraformExit(PreCommitTerraformBaseError, SystemExit):
15+
class PreCommitTerraformExit(PreCommitTerraformBaseError, SystemExit): # noqa: N818 FIXME
1616
"""An exception for terminating execution from deep app layers."""

src/pre_commit_terraform/_types.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
"""Composite types for annotating in-project code."""
22

3-
from argparse import ArgumentParser, Namespace
3+
from argparse import ArgumentParser
4+
from argparse import Namespace
45
from collections.abc import Callable
5-
from typing import Protocol, Union
6+
from typing import Protocol
7+
from typing import Union
68

79
from ._structs import ReturnCode
810

9-
1011
ReturnCodeType = Union[ReturnCode, int] # Union instead of pipe for Python 3.9
1112
CLIAppEntryPointCallableType = Callable[[Namespace], ReturnCodeType]
1213

@@ -17,9 +18,7 @@ class CLISubcommandModuleProtocol(Protocol):
1718
CLI_SUBCOMMAND_NAME: str
1819
"""This constant contains a CLI."""
1920

20-
def populate_argument_parser(
21-
self, subcommand_parser: ArgumentParser,
22-
) -> None:
21+
def populate_argument_parser(self, subcommand_parser: ArgumentParser) -> None:
2322
"""Run a module hook for populating the subcommand parser."""
2423

2524
def invoke_cli_app(self, parsed_cli_args: Namespace) -> ReturnCodeType:
Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,40 @@
1+
"""`terraform_docs_replace` hook. Deprecated."""
2+
13
import os
2-
import subprocess
4+
import subprocess # noqa: S404. We invoke cli tools
35
import warnings
4-
from argparse import ArgumentParser, Namespace
6+
from argparse import ArgumentParser
7+
from argparse import Namespace
58
from typing import cast as cast_to
69

710
from ._structs import ReturnCode
811
from ._types import ReturnCodeType
912

10-
1113
CLI_SUBCOMMAND_NAME: str = 'replace-docs'
1214

1315

1416
def populate_argument_parser(subcommand_parser: ArgumentParser) -> None:
17+
"""Populate the parser for the subcommand."""
1518
subcommand_parser.description = (
1619
'Run terraform-docs on a set of files. Follows the standard '
1720
'convention of pulling the documentation from main.tf in order to '
1821
'replace the entire README.md file each time.'
1922
)
2023
subcommand_parser.add_argument(
21-
'--dest', dest='dest', default='README.md',
24+
'--dest',
25+
dest='dest',
26+
default='README.md',
2227
)
2328
subcommand_parser.add_argument(
24-
'--sort-inputs-by-required', dest='sort', action='store_true',
29+
'--sort-inputs-by-required',
30+
dest='sort',
31+
action='store_true',
2532
help='[deprecated] use --sort-by-required instead',
2633
)
2734
subcommand_parser.add_argument(
28-
'--sort-by-required', dest='sort', action='store_true',
35+
'--sort-by-required',
36+
dest='sort',
37+
action='store_true',
2938
)
3039
subcommand_parser.add_argument(
3140
'--with-aggregate-type-defaults',
@@ -41,7 +50,13 @@ def populate_argument_parser(subcommand_parser: ArgumentParser) -> None:
4150

4251

4352
def invoke_cli_app(parsed_cli_args: Namespace) -> ReturnCodeType:
44-
warnings.warn(
53+
"""Run the entry-point of the CLI app.
54+
55+
Returns:
56+
ReturnCodeType: The return code of the app.
57+
58+
"""
59+
warnings.warn( # noqa: B028. that's user warning, no need to show stacktrace etc.
4560
'`terraform_docs_replace` hook is DEPRECATED.'
4661
'For migration instructions see '
4762
'https://github.com/antonbabenko/pre-commit-terraform/issues/248'
@@ -50,28 +65,32 @@ def invoke_cli_app(parsed_cli_args: Namespace) -> ReturnCodeType:
5065
)
5166

5267
dirs: list[str] = []
53-
for filename in cast_to(list[str], parsed_cli_args.filenames):
54-
if (os.path.realpath(filename) not in dirs and
55-
(filename.endswith(".tf") or filename.endswith(".tfvars"))):
56-
dirs.append(os.path.dirname(filename))
68+
for filename in cast_to('list[str]', parsed_cli_args.filenames):
69+
if os.path.realpath(filename) not in dirs and (
70+
filename.endswith(('.tf', '.tfvars'))
71+
):
72+
dirs.append(os.path.dirname(filename)) # noqa: PTH120. Legacy hook, no need to refactor
5773

5874
retval = ReturnCode.OK
5975

60-
for dir in dirs:
76+
for directory in dirs:
6177
try:
62-
procArgs = []
63-
procArgs.append('terraform-docs')
64-
if cast_to(bool, parsed_cli_args.sort):
65-
procArgs.append('--sort-by-required')
66-
procArgs.append('md')
67-
procArgs.append("./{dir}".format(dir=dir))
68-
procArgs.append('>')
69-
procArgs.append(
70-
'./{dir}/{dest}'.
71-
format(dir=dir, dest=cast_to(bool, parsed_cli_args.dest)),
78+
proc_args = []
79+
proc_args.append('terraform-docs')
80+
if cast_to('bool', parsed_cli_args.sort):
81+
proc_args.append('--sort-by-required')
82+
proc_args.extend(
83+
(
84+
'md',
85+
f'./{directory}',
86+
'>',
87+
f"./{directory}/{cast_to('bool', parsed_cli_args.dest)}",
88+
),
7289
)
73-
subprocess.check_call(" ".join(procArgs), shell=True)
74-
except subprocess.CalledProcessError as e:
75-
print(e)
90+
# We call cli tools, of course we use shell=True
91+
subprocess.check_call(' '.join(proc_args), shell=True) # noqa: S602
92+
# Legacy hook, no need to refactor
93+
except subprocess.CalledProcessError as e: # noqa: PERF203
94+
print(e) # noqa: T201
7695
retval = ReturnCode.ERROR
7796
return retval

0 commit comments

Comments
 (0)