Skip to content

Commit ed1b56b

Browse files
committed
Update
[ghstack-poisoned]
1 parent 8d57c95 commit ed1b56b

File tree

3 files changed

+188
-1
lines changed

3 files changed

+188
-1
lines changed

.lintrunner.toml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,37 @@ init_command = [
136136
'--requirement=requirements-lintrunner.txt',
137137
]
138138

139+
[[linter]]
140+
code = 'CMAKEFORMAT'
141+
include_patterns = [
142+
"**/*.cmake",
143+
"**/*.cmake.in",
144+
"**/CMakeLists.txt",
145+
]
146+
exclude_patterns = [
147+
'third-party/**',
148+
'**/third-party/**',
149+
]
150+
# NOTE: We can remove our copy of this linter once lintrunner-adapters
151+
# has a release including
152+
# https://github.com/justinchuby/lintrunner-adapters/pull/117 and we
153+
# update to it.
154+
command = [
155+
'python',
156+
'tools/linter/adapters/cmake_format_linter.py',
157+
'--',
158+
'@{{PATHSFILE}}',
159+
]
160+
init_command = [
161+
'python',
162+
'-m',
163+
'lintrunner_adapters',
164+
'run',
165+
'pip_init',
166+
'--dry-run={{DRYRUN}}',
167+
'--requirement=requirements-lintrunner.txt',
168+
]
169+
139170
[[linter]]
140171
code = 'ETCAPITAL'
141172
include_patterns = [

requirements-lintrunner.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ usort==1.0.8.post1
1515

1616
# Other linters
1717
clang-format==18.1.3
18+
cmakelang==0.6.13
1819
cmakelint==1.4.1
1920

2021
# MyPy
21-
mypy==1.14.1
22+
mypy==1.14.1
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
"""Adapter for https://github.com/cheshirekow/cmake_format."""
2+
3+
from __future__ import annotations
4+
5+
import argparse
6+
import concurrent.futures
7+
import logging
8+
import os
9+
import subprocess
10+
import sys
11+
12+
from lintrunner_adapters import (
13+
LintMessage,
14+
LintSeverity,
15+
add_default_options,
16+
as_posix,
17+
run_command,
18+
)
19+
20+
LINTER_CODE = "CMAKEFORMAT"
21+
22+
23+
def check_file(
24+
filename: str,
25+
retries: int,
26+
timeout: int,
27+
config_file: str | None = None,
28+
) -> list[LintMessage]:
29+
try:
30+
with open(filename, "rb") as f:
31+
original = f.read()
32+
with open(filename, "rb") as f:
33+
command = ["cmake-format", "-"]
34+
if config_file:
35+
command.extend(["-c", config_file])
36+
37+
proc = run_command(
38+
command,
39+
stdin=f,
40+
retries=retries,
41+
timeout=timeout,
42+
check=True,
43+
)
44+
except subprocess.TimeoutExpired:
45+
return [
46+
LintMessage(
47+
path=filename,
48+
line=None,
49+
char=None,
50+
code=LINTER_CODE,
51+
severity=LintSeverity.ERROR,
52+
name="timeout",
53+
original=None,
54+
replacement=None,
55+
description=f"cmake-format timed out while trying to process {filename}.",
56+
)
57+
]
58+
except (OSError, subprocess.CalledProcessError) as err:
59+
return [
60+
LintMessage(
61+
path=filename,
62+
line=None,
63+
char=None,
64+
code=LINTER_CODE,
65+
severity=LintSeverity.ADVICE,
66+
name="command-failed",
67+
original=None,
68+
replacement=None,
69+
description=(
70+
f"Failed due to {err.__class__.__name__}:\n{err}"
71+
if not isinstance(err, subprocess.CalledProcessError)
72+
else (
73+
f"COMMAND (exit code {err.returncode})\n"
74+
f"{' '.join(as_posix(x) for x in err.cmd)}\n\n"
75+
f"STDERR\n{err.stderr.decode('utf-8').strip() or '(empty)'}\n\n"
76+
f"STDOUT\n{err.stdout.decode('utf-8').strip() or '(empty)'}"
77+
)
78+
),
79+
)
80+
]
81+
82+
replacement = proc.stdout
83+
if original == replacement:
84+
return []
85+
86+
return [
87+
LintMessage(
88+
path=filename,
89+
line=None,
90+
char=None,
91+
code=LINTER_CODE,
92+
severity=LintSeverity.WARNING,
93+
name="format",
94+
original=original.decode("utf-8"),
95+
replacement=replacement.decode("utf-8"),
96+
description="Run `lintrunner -a` to apply this patch.",
97+
)
98+
]
99+
100+
101+
def main() -> None:
102+
parser = argparse.ArgumentParser(
103+
description=f"Format files with cmake-format. Linter code: {LINTER_CODE}",
104+
fromfile_prefix_chars="@",
105+
)
106+
parser.add_argument(
107+
"--config-file",
108+
help="Path to cmake-format configuration file",
109+
)
110+
parser.add_argument(
111+
"--timeout",
112+
default=90,
113+
type=int,
114+
help="seconds to wait for cmake-format",
115+
)
116+
add_default_options(parser)
117+
args = parser.parse_args()
118+
119+
logging.basicConfig(
120+
format="<%(threadName)s:%(levelname)s> %(message)s",
121+
level=(
122+
logging.NOTSET
123+
if args.verbose
124+
else logging.DEBUG
125+
if len(args.filenames) < 1000
126+
else logging.INFO
127+
),
128+
stream=sys.stderr,
129+
)
130+
131+
with concurrent.futures.ThreadPoolExecutor(
132+
max_workers=os.cpu_count(),
133+
thread_name_prefix="Thread",
134+
) as executor:
135+
futures = {
136+
executor.submit(
137+
check_file,
138+
x,
139+
args.retries,
140+
args.timeout,
141+
args.config_file,
142+
): x
143+
for x in args.filenames
144+
}
145+
for future in concurrent.futures.as_completed(futures):
146+
try:
147+
for lint_message in future.result():
148+
lint_message.display()
149+
except Exception:
150+
logging.critical('Failed at "%s".', futures[future])
151+
raise
152+
153+
154+
if __name__ == "__main__":
155+
main()

0 commit comments

Comments
 (0)