audit: deprecate certain globals (#44895)
This commit is contained in:
parent
ef35811f39
commit
7573ea2ae5
@ -46,12 +46,14 @@ def _search_duplicate_compilers(error_cls):
|
|||||||
import pickle
|
import pickle
|
||||||
import re
|
import re
|
||||||
import warnings
|
import warnings
|
||||||
|
from typing import Iterable, List, Set, Tuple
|
||||||
from urllib.request import urlopen
|
from urllib.request import urlopen
|
||||||
|
|
||||||
import llnl.util.lang
|
import llnl.util.lang
|
||||||
|
|
||||||
import spack.config
|
import spack.config
|
||||||
import spack.patch
|
import spack.patch
|
||||||
|
import spack.paths
|
||||||
import spack.repo
|
import spack.repo
|
||||||
import spack.spec
|
import spack.spec
|
||||||
import spack.util.crypto
|
import spack.util.crypto
|
||||||
@ -73,7 +75,9 @@ def __init__(self, summary, details):
|
|||||||
self.details = tuple(details)
|
self.details = tuple(details)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.summary + "\n" + "\n".join([" " + detail for detail in self.details])
|
if self.details:
|
||||||
|
return f"{self.summary}\n" + "\n".join(f" {detail}" for detail in self.details)
|
||||||
|
return self.summary
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if self.summary != other.summary or self.details != other.details:
|
if self.summary != other.summary or self.details != other.details:
|
||||||
@ -679,6 +683,88 @@ def _ensure_env_methods_are_ported_to_builders(pkgs, error_cls):
|
|||||||
return errors
|
return errors
|
||||||
|
|
||||||
|
|
||||||
|
class DeprecatedMagicGlobals(ast.NodeVisitor):
|
||||||
|
def __init__(self, magic_globals: Iterable[str]):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
self.magic_globals: Set[str] = set(magic_globals)
|
||||||
|
|
||||||
|
# State to track whether we're in a class function
|
||||||
|
self.depth: int = 0
|
||||||
|
self.in_function: bool = False
|
||||||
|
self.path = (ast.Module, ast.ClassDef, ast.FunctionDef)
|
||||||
|
|
||||||
|
# Defined locals in the current function (heuristically at least)
|
||||||
|
self.locals: Set[str] = set()
|
||||||
|
|
||||||
|
# List of (name, lineno) tuples for references to magic globals
|
||||||
|
self.references_to_globals: List[Tuple[str, int]] = []
|
||||||
|
|
||||||
|
def descend_in_function_def(self, node: ast.AST) -> None:
|
||||||
|
if not isinstance(node, self.path[self.depth]):
|
||||||
|
return
|
||||||
|
self.depth += 1
|
||||||
|
if self.depth == len(self.path):
|
||||||
|
self.in_function = True
|
||||||
|
super().generic_visit(node)
|
||||||
|
if self.depth == len(self.path):
|
||||||
|
self.in_function = False
|
||||||
|
self.locals.clear()
|
||||||
|
self.depth -= 1
|
||||||
|
|
||||||
|
def generic_visit(self, node: ast.AST) -> None:
|
||||||
|
# Recurse into function definitions
|
||||||
|
if self.depth < len(self.path):
|
||||||
|
return self.descend_in_function_def(node)
|
||||||
|
elif not self.in_function:
|
||||||
|
return
|
||||||
|
elif isinstance(node, ast.Global):
|
||||||
|
for name in node.names:
|
||||||
|
if name in self.magic_globals:
|
||||||
|
self.references_to_globals.append((name, node.lineno))
|
||||||
|
elif isinstance(node, ast.Assign):
|
||||||
|
# visit the rhs before lhs
|
||||||
|
super().visit(node.value)
|
||||||
|
for target in node.targets:
|
||||||
|
super().visit(target)
|
||||||
|
elif isinstance(node, ast.Name) and node.id in self.magic_globals:
|
||||||
|
if isinstance(node.ctx, ast.Load) and node.id not in self.locals:
|
||||||
|
self.references_to_globals.append((node.id, node.lineno))
|
||||||
|
elif isinstance(node.ctx, ast.Store):
|
||||||
|
self.locals.add(node.id)
|
||||||
|
else:
|
||||||
|
super().generic_visit(node)
|
||||||
|
|
||||||
|
|
||||||
|
@package_properties
|
||||||
|
def _uses_deprecated_globals(pkgs, error_cls):
|
||||||
|
"""Ensure that packages do not use deprecated globals"""
|
||||||
|
errors = []
|
||||||
|
|
||||||
|
for pkg_name in pkgs:
|
||||||
|
# some packages scheduled to be removed in v0.23 are not worth fixing.
|
||||||
|
pkg_cls = spack.repo.PATH.get_pkg_class(pkg_name)
|
||||||
|
if all(v.get("deprecated", False) for v in pkg_cls.versions.values()):
|
||||||
|
continue
|
||||||
|
|
||||||
|
file = spack.repo.PATH.filename_for_package_name(pkg_name)
|
||||||
|
tree = ast.parse(open(file).read())
|
||||||
|
visitor = DeprecatedMagicGlobals(("std_cmake_args",))
|
||||||
|
visitor.visit(tree)
|
||||||
|
if visitor.references_to_globals:
|
||||||
|
errors.append(
|
||||||
|
error_cls(
|
||||||
|
f"Package '{pkg_name}' uses deprecated globals",
|
||||||
|
[
|
||||||
|
f"{file}:{line} references '{name}'"
|
||||||
|
for name, line in visitor.references_to_globals
|
||||||
|
],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return errors
|
||||||
|
|
||||||
|
|
||||||
@package_https_directives
|
@package_https_directives
|
||||||
def _linting_package_file(pkgs, error_cls):
|
def _linting_package_file(pkgs, error_cls):
|
||||||
"""Check for correctness of links"""
|
"""Check for correctness of links"""
|
||||||
|
@ -115,15 +115,11 @@ def audit(parser, args):
|
|||||||
def _process_reports(reports):
|
def _process_reports(reports):
|
||||||
for check, errors in reports:
|
for check, errors in reports:
|
||||||
if errors:
|
if errors:
|
||||||
msg = "{0}: {1} issue{2} found".format(
|
status = f"{len(errors)} issue{'' if len(errors) == 1 else 's'} found"
|
||||||
check, len(errors), "" if len(errors) == 1 else "s"
|
print(cl.colorize(f"{check}: @*r{{{status}}}"))
|
||||||
)
|
numdigits = len(str(len(errors)))
|
||||||
header = "@*b{" + msg + "}"
|
|
||||||
print(cl.colorize(header))
|
|
||||||
for idx, error in enumerate(errors):
|
for idx, error in enumerate(errors):
|
||||||
print(str(idx + 1) + ". " + str(error))
|
print(f"{idx + 1:>{numdigits}}. {error}")
|
||||||
raise SystemExit(1)
|
raise SystemExit(1)
|
||||||
else:
|
else:
|
||||||
msg = "{0}: 0 issues found.".format(check)
|
print(cl.colorize(f"{check}: @*g{{passed}}"))
|
||||||
header = "@*b{" + msg + "}"
|
|
||||||
print(cl.colorize(header))
|
|
||||||
|
Loading…
Reference in New Issue
Block a user