summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Cristian Sarbu <paul.cristian.sarbu@huawei.com>2025-06-16 15:13:22 +0200
committerPaul Cristian Sarbu <paul.cristian.sarbu@huawei.com>2025-06-17 13:51:48 +0200
commit1fa9984b7f65638515c0be743abe15bb0b8170e8 (patch)
treede548e2622c4c4fb3759e6aa1c0290cf38210f1b
parent9b8989da51d55ac3b4664ffcfd07abbb305ee8a9 (diff)
downloadjustbuild-1fa9984b7f65638515c0be743abe15bb0b8170e8.tar.gz
lint scripts: Add typing and basic documentation
-rwxr-xr-xlint/run_clang_format.py30
-rwxr-xr-xlint/run_clang_tidy.py37
-rwxr-xr-xlint/run_iwyu.py35
-rwxr-xr-xlint/run_strict_deps.py32
-rwxr-xr-xlint/summary.py11
5 files changed, 97 insertions, 48 deletions
diff --git a/lint/run_clang_format.py b/lint/run_clang_format.py
index b33f0c1f..7bb20ba5 100755
--- a/lint/run_clang_format.py
+++ b/lint/run_clang_format.py
@@ -19,19 +19,28 @@ import shutil
import subprocess
import sys
+from typing import List
-def dump_meta(src, cmd):
+
+def dump_meta(src: str, cmd: List[str]) -> None:
+ """Dump linter action metadata for further analysis."""
OUT = os.environ.get("OUT")
if OUT:
with open(os.path.join(OUT, "config.json"), "w") as f:
json.dump({"src": src, "cmd": cmd}, f)
-def run_lint(src, cmd):
+def run_lint(src: str, cmd: List[str]) -> int:
+ """Run the lint command for the specified source file."""
dump_meta(src, cmd)
- config = os.environ.get("CONFIG")
- out = os.environ.get("OUT")
- shutil.copyfile(os.path.join(config, ".clang-format"), ".clang-format")
+
+ CONFIG = os.environ.get("CONFIG")
+ if CONFIG is None:
+ print("Failed to get CONFIG", file=sys.stderr)
+ return 1
+
+ shutil.copyfile(os.path.join(CONFIG, ".clang-format"), ".clang-format")
+
extra = []
if src.endswith(".tpp"):
extra = ["-x", "c++"]
@@ -42,13 +51,20 @@ def run_lint(src, cmd):
}]
with open("compile_commands.json", "w") as f:
json.dump(db, f)
+
new_cmd = [
- os.path.join(config, "toolchain", "bin", "clang-format"),
+ os.path.join(CONFIG, "toolchain", "bin", "clang-format"),
"-style=file",
src,
]
- formatted = os.path.join(out, "formatted")
+
+ OUT = os.environ.get("OUT")
+ if OUT is None:
+ print("Failed to get OUT", file=sys.stderr)
+ sys.exit(1)
+ formatted = os.path.join(OUT, "formatted")
with open(formatted, "w") as f:
+ print("Running cmd %r with db %r" % (new_cmd, db), file=sys.stderr)
res = subprocess.run(new_cmd, stdout=f).returncode
if res != 0:
return res
diff --git a/lint/run_clang_tidy.py b/lint/run_clang_tidy.py
index 7f48e007..b8df6fef 100755
--- a/lint/run_clang_tidy.py
+++ b/lint/run_clang_tidy.py
@@ -19,39 +19,47 @@ import shutil
import subprocess
import sys
+from typing import List
+
CXX_LIB_VERSION = "13.3.0"
-def dump_meta(src, cmd):
+
+def dump_meta(src: str, cmd: List[str]) -> None:
+ """Dump linter action metadata for further analysis."""
OUT = os.environ.get("OUT")
- if OUT:
+ if OUT is not None:
with open(os.path.join(OUT, "config.json"), "w") as f:
json.dump({"src": src, "cmd": cmd}, f)
-def run_lint(src, cmd):
+def run_lint(src: str, cmd: List[str]) -> int:
+ """Run the lint command for the specified source file."""
dump_meta(src, cmd)
- config = os.environ.get("CONFIG")
- shutil.copyfile(os.path.join(config, ".clang-tidy"), ".clang-tidy")
- extra = [ "-Wno-unused-command-line-argument"]
+ CONFIG = os.environ.get("CONFIG")
+ if CONFIG is None:
+ print("Failed to get CONFIG", file=sys.stderr)
+ return 1
+ shutil.copyfile(os.path.join(CONFIG, ".clang-tidy"), ".clang-tidy")
+
+ extra = ["-Wno-unused-command-line-argument"]
# add include paths from the bundled toolchain
- baseincludepath = os.path.join(
- config, "toolchain", "include", "c++", CXX_LIB_VERSION
- )
+ baseincludepath = os.path.join(CONFIG, "toolchain", "include", "c++",
+ CXX_LIB_VERSION)
# We're using the native toolchain, so arch-specific headers are
# only available for one arch. Hence we can try all supported candidates
# and add the ones found
for arch in ["x86_64", "arm"]:
- idir = os.path.join(baseincludepath,
- "%s-pc-linux-gnu" % (arch,))
+ idir = os.path.join(baseincludepath, "%s-pc-linux-gnu" % (arch, ))
if os.path.exists(idir):
extra += ["-isystem", idir]
extra += [
- "-isystem", baseincludepath,
+ "-isystem",
+ baseincludepath,
]
-
if src.endswith(".tpp"):
extra += ["-x", "c++"]
+
db = [{
"directory": os.getcwd(),
"arguments": cmd[:1] + extra + cmd[1:],
@@ -59,8 +67,9 @@ def run_lint(src, cmd):
}]
with open("compile_commands.json", "w") as f:
json.dump(db, f)
+
new_cmd = [
- os.path.join(config, "toolchain", "bin", "clang-tidy"),
+ os.path.join(CONFIG, "toolchain", "bin", "clang-tidy"),
src,
]
print("Running cmd %r with db %r" % (new_cmd, db), file=sys.stderr)
diff --git a/lint/run_iwyu.py b/lint/run_iwyu.py
index f4be3604..ef8413b5 100755
--- a/lint/run_iwyu.py
+++ b/lint/run_iwyu.py
@@ -19,19 +19,29 @@ import shutil
import subprocess
import sys
+from typing import List
+
CXX_LIB_VERSION = "13.3.0"
-def dump_meta(src, cmd):
+
+def dump_meta(src: str, cmd: List[str]) -> None:
+ """Dump linter action metadata for further analysis."""
OUT = os.environ.get("OUT")
if OUT:
with open(os.path.join(OUT, "config.json"), "w") as f:
json.dump({"src": src, "cmd": cmd}, f)
-def run_lint(src, cmd):
+def run_lint(src: str, cmd: List[str]) -> int:
+ """Run the lint command for the specified source file."""
dump_meta(src, cmd)
- config = os.environ.get("CONFIG")
- shutil.copyfile(os.path.join(config, "iwyu-mapping"), "iwyu-mapping.imp")
+
+ CONFIG = os.environ.get("CONFIG")
+ if CONFIG is None:
+ print("Failed to get CONFIG", file=sys.stderr)
+ return 1
+
+ shutil.copyfile(os.path.join(CONFIG, "iwyu-mapping"), "iwyu-mapping.imp")
# Currently, .tpp files cannot be processed to produce meaningful suggestions
# Their corresponding .hpp files are analyzed separately, so just skip
@@ -67,7 +77,7 @@ def run_lint(src, cmd):
os.path.realpath(fake_stem) + ".o"
] + cmd[e_index + 2:]
- iwyu_flags = [
+ iwyu_flags: List[str] = [
"--cxx17ns", # suggest the more concise syntax introduced in C++17
"--no_fwd_decls", # do not use forward declarations
"--no_default_mappings", # do not add iwyu's default mappings
@@ -77,25 +87,24 @@ def run_lint(src, cmd):
"--max_line_length=1000" # don't limit explanation messages
]
- iwyu_options = []
+ iwyu_options: List[str] = []
for option in iwyu_flags:
iwyu_options.append("-Xiwyu")
iwyu_options.append(option)
# add include paths from the bundled toolchain
- baseincludepath = os.path.join(
- config, "toolchain", "include", "c++", CXX_LIB_VERSION
- )
+ baseincludepath = os.path.join(CONFIG, "toolchain", "include", "c++",
+ CXX_LIB_VERSION)
# We're using the native toolchain, so arch-specific headers are
# only available for one arch. Hence we can try all supported candidates
# and add the ones found
for arch in ["x86_64", "arm"]:
- idir = os.path.join(baseincludepath,
- "%s-pc-linux-gnu" % (arch,))
+ idir = os.path.join(baseincludepath, "%s-pc-linux-gnu" % (arch, ))
if os.path.exists(idir):
iwyu_options += ["-isystem", idir]
iwyu_options += [
- "-isystem", baseincludepath,
+ "-isystem",
+ baseincludepath,
]
iwyu_options.extend(cmd[1:])
@@ -105,7 +114,7 @@ def run_lint(src, cmd):
# So we "ask" IWYU here to include all non-system dependencies with quotes
iwyu_options = ["-I" if x == "-isystem" else x for x in iwyu_options]
- new_cmd = [os.path.join(config, "toolchain", "bin", "include-what-you-use")]
+ new_cmd = [os.path.join(CONFIG, "toolchain", "bin", "include-what-you-use")]
new_cmd.extend(iwyu_options)
new_cmd.append(src)
diff --git a/lint/run_strict_deps.py b/lint/run_strict_deps.py
index c963f3cd..7f2ddcf4 100755
--- a/lint/run_strict_deps.py
+++ b/lint/run_strict_deps.py
@@ -16,25 +16,33 @@
import json
import os
-import json
-import os
import sys
+from typing import List
-def dump_meta(src, cmd):
+
+def dump_meta(src: str, cmd: List[str]) -> None:
+ """Dump linter action metadata for further analysis."""
OUT = os.environ.get("OUT")
if OUT:
with open(os.path.join(OUT, "config.json"), "w") as f:
json.dump({"src": src, "cmd": cmd}, f)
-def run_lint(src, cmd):
+def run_lint(src: str, cmd: List[str]) -> int:
+ """Run the lint command for the specified source file."""
dump_meta(src, cmd)
- with open(os.environ.get("META")) as f:
+ META = os.environ.get("META")
+ if META is None:
+ print("Failed to get META", file=sys.stderr)
+ return 1
+
+ direct: List[str] = []
+ with open(META) as f:
direct = json.load(f)["direct deps artifact names"]
- include_dirs = []
+ include_dirs: List[str] = []
for i in range(len(cmd)):
if cmd[i] in ["-I", "-isystem"]:
include_dirs += [cmd[i + 1]]
@@ -42,16 +50,16 @@ def run_lint(src, cmd):
with open(src) as f:
lines = f.read().splitlines()
- failed = False
+ failed: bool = False
- def include_covered(include_path):
+ def include_covered(include_path: str) -> bool:
for d in direct:
rel_path = os.path.relpath(include_path, d)
if not rel_path.startswith('../'):
return True
return False
- def handle_resolved_include(i, to_include, resolved):
+ def handle_resolved_include(i: int, resolved: str) -> None:
nonlocal failed
if not include_covered(resolved):
failed = True
@@ -60,11 +68,11 @@ def run_lint(src, cmd):
" ---> including %r which is only provided by an indirect dependency"
% (resolved, ))
- def handle_include(i, to_include):
+ def handle_include(i: int, to_include: str) -> None:
for d in include_dirs:
candidate = os.path.join(d, to_include)
if os.path.exists(candidate):
- handle_resolved_include(i, to_include, candidate)
+ handle_resolved_include(i, candidate)
for i in range(len(lines)):
to_include = None
@@ -72,7 +80,7 @@ def run_lint(src, cmd):
to_include = lines[i].split('"')[1]
if lines[i].startswith('#include <'):
to_include = lines[i].split('<', 1)[1].split('>')[0]
- if to_include:
+ if to_include: # if non-empty string
handle_include(i, to_include)
return 1 if failed else 0
diff --git a/lint/summary.py b/lint/summary.py
index ca7445db..49126c61 100755
--- a/lint/summary.py
+++ b/lint/summary.py
@@ -17,7 +17,9 @@ import json
import os
import sys
-FAILED = {}
+from typing import Any, Dict
+
+FAILED: Dict[str, Any] = {}
for lint in sorted(os.listdir()):
if os.path.isdir(lint):
@@ -34,7 +36,12 @@ for lint in sorted(os.listdir()):
record["log"] = log
FAILED[lint] = record
-with open(os.path.join(os.environ.get("OUT"), "failures.json"), "w") as f:
+OUT = os.environ.get("OUT")
+if OUT is None:
+ print("Failed to get OUT")
+ sys.exit(1)
+
+with open(os.path.join(OUT, "failures.json"), "w") as f:
json.dump(FAILED, f)
failures = list(FAILED.keys())