mirror of
https://github.com/pytorch/pytorch.git
synced 2025-10-20 21:14:14 +08:00
Pull Request resolved: https://github.com/pytorch/pytorch/pull/129375 Approved by: https://github.com/malfet
141 lines
3.3 KiB
Python
141 lines
3.3 KiB
Python
from __future__ import annotations
|
|
|
|
import argparse
|
|
import concurrent.futures
|
|
import json
|
|
import logging
|
|
import os
|
|
import re
|
|
import subprocess
|
|
import time
|
|
from enum import Enum
|
|
from typing import NamedTuple
|
|
|
|
|
|
LINTER_CODE = "CMAKE"
|
|
|
|
|
|
class LintSeverity(str, Enum):
|
|
ERROR = "error"
|
|
WARNING = "warning"
|
|
ADVICE = "advice"
|
|
DISABLED = "disabled"
|
|
|
|
|
|
class LintMessage(NamedTuple):
|
|
path: str | None
|
|
line: int | None
|
|
char: int | None
|
|
code: str
|
|
severity: LintSeverity
|
|
name: str
|
|
original: str | None
|
|
replacement: str | None
|
|
description: str | None
|
|
|
|
|
|
# CMakeLists.txt:901: Lines should be <= 80 characters long [linelength]
|
|
RESULTS_RE: re.Pattern[str] = re.compile(
|
|
r"""(?mx)
|
|
^
|
|
(?P<file>.*?):
|
|
(?P<line>\d+):
|
|
\s(?P<message>.*)
|
|
\s(?P<code>\[.*\])
|
|
$
|
|
"""
|
|
)
|
|
|
|
|
|
def run_command(
|
|
args: list[str],
|
|
) -> subprocess.CompletedProcess[bytes]:
|
|
logging.debug("$ %s", " ".join(args))
|
|
start_time = time.monotonic()
|
|
try:
|
|
return subprocess.run(
|
|
args,
|
|
capture_output=True,
|
|
)
|
|
finally:
|
|
end_time = time.monotonic()
|
|
logging.debug("took %dms", (end_time - start_time) * 1000)
|
|
|
|
|
|
def check_file(
|
|
filename: str,
|
|
config: str,
|
|
) -> list[LintMessage]:
|
|
try:
|
|
proc = run_command(
|
|
["cmakelint", f"--config={config}", filename],
|
|
)
|
|
except OSError as err:
|
|
return [
|
|
LintMessage(
|
|
path=None,
|
|
line=None,
|
|
char=None,
|
|
code=LINTER_CODE,
|
|
severity=LintSeverity.ERROR,
|
|
name="command-failed",
|
|
original=None,
|
|
replacement=None,
|
|
description=(f"Failed due to {err.__class__.__name__}:\n{err}"),
|
|
)
|
|
]
|
|
stdout = str(proc.stdout, "utf-8").strip()
|
|
return [
|
|
LintMessage(
|
|
path=match["file"],
|
|
name=match["code"],
|
|
description=match["message"],
|
|
line=int(match["line"]),
|
|
char=None,
|
|
code=LINTER_CODE,
|
|
severity=LintSeverity.ERROR,
|
|
original=None,
|
|
replacement=None,
|
|
)
|
|
for match in RESULTS_RE.finditer(stdout)
|
|
]
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser(
|
|
description="cmakelint runner",
|
|
fromfile_prefix_chars="@",
|
|
)
|
|
parser.add_argument(
|
|
"--config",
|
|
required=True,
|
|
help="location of cmakelint config",
|
|
)
|
|
parser.add_argument(
|
|
"filenames",
|
|
nargs="+",
|
|
help="paths to lint",
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
|
|
with concurrent.futures.ThreadPoolExecutor(
|
|
max_workers=os.cpu_count(),
|
|
thread_name_prefix="Thread",
|
|
) as executor:
|
|
futures = {
|
|
executor.submit(
|
|
check_file,
|
|
filename,
|
|
args.config,
|
|
): filename
|
|
for filename in args.filenames
|
|
}
|
|
for future in concurrent.futures.as_completed(futures):
|
|
try:
|
|
for lint_message in future.result():
|
|
print(json.dumps(lint_message._asdict()), flush=True)
|
|
except Exception:
|
|
logging.critical('Failed at "%s".', futures[future])
|
|
raise
|