Skip to content

Commit 256593d

Browse files
committed
BadCommandsCheck: more regex checking simplifications
1 parent 87a76b1 commit 256593d

1 file changed

Lines changed: 36 additions & 35 deletions

File tree

src/pkgcheck/checks/codingstyle.py

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
from pkgcore.ebuild.eapi import EAPI
77
from snakeoil.demandload import demand_compile_regexp
8+
from snakeoil.klass import jit_attr
9+
from snakeoil.mappings import ImmutableDict
810
from snakeoil.strings import pluralism as _pl
911

1012
from .. import base
@@ -85,15 +87,19 @@ def feed(self, entry):
8587
yield HttpsAvailable(link, lines, pkg=pkg)
8688

8789

88-
class PortageInternals(base.VersionedResult, base.Warning):
89-
"""Ebuild uses a function or variable internal to portage."""
90+
class _CommandResult(base.VersionedResult):
91+
"""Generic command result."""
9092

9193
def __init__(self, command, line, lineno, **kwargs):
9294
super().__init__(**kwargs)
9395
self.command = command
9496
self.line = line
9597
self.lineno = lineno
9698

99+
100+
class PortageInternals(_CommandResult, base.Warning):
101+
"""Ebuild uses a function or variable internal to portage."""
102+
97103
@property
98104
def desc(self):
99105
s = f'{self.command!r}, used on line {self.lineno}'
@@ -102,15 +108,12 @@ def desc(self):
102108
return s
103109

104110

105-
class _EapiCommandResult(base.VersionedResult):
111+
class _EapiCommandResult(_CommandResult):
106112
"""Generic EAPI command result."""
107113

108-
def __init__(self, command, eapi, line, lineno, **kwargs):
109-
super().__init__(**kwargs)
110-
self.command = command
114+
def __init__(self, *args, eapi, **kwargs):
115+
super().__init__(*args, **kwargs)
111116
self.eapi = eapi
112-
self.line = line
113-
self.lineno = lineno
114117

115118
@property
116119
def desc(self):
@@ -151,21 +154,29 @@ class BadCommandsCheck(base.Check):
151154

152155
CMD_USAGE_REGEX = r'^(\s*|.*[|&{{(]+\s*)\b(?P<cmd>{})(?!\.)\b'
153156

154-
def __init__(self, options):
155-
super().__init__(options)
156-
self.internals_re = self._cmds_regex(self.INTERNALS)
157-
self.banned_eapi_cmds = {}
158-
self.deprecated_eapi_cmds = {}
157+
def _cmds_regex(self, cmds):
158+
return re.compile(self.CMD_USAGE_REGEX.format(r'|'.join(cmds)))
159+
160+
@jit_attr
161+
def regexes(self):
162+
d = {}
163+
internals_re = self._cmds_regex(self.INTERNALS)
159164
for eapi_str, eapi in EAPI.known_eapis.items():
165+
regexes = [(internals_re, PortageInternals, {})]
160166
if eapi.bash_cmds_banned:
161-
self.banned_eapi_cmds[eapi_str] = self._cmds_regex(
162-
eapi.bash_cmds_banned)
167+
regexes.append((
168+
self._cmds_regex(eapi.bash_cmds_banned),
169+
BannedEapiCommand,
170+
{'eapi': eapi_str},
171+
))
163172
if eapi.bash_cmds_deprecated:
164-
self.deprecated_eapi_cmds[eapi_str] = self._cmds_regex(
165-
eapi.bash_cmds_deprecated)
166-
167-
def _cmds_regex(self, cmds):
168-
return re.compile(self.CMD_USAGE_REGEX.format(r'|'.join(cmds)))
173+
regexes.append((
174+
self._cmds_regex(eapi.bash_cmds_deprecated),
175+
DeprecatedEapiCommand,
176+
{'eapi': eapi_str},
177+
))
178+
d[eapi_str] = tuple(regexes)
179+
return ImmutableDict(d)
169180

170181
def feed(self, entry):
171182
pkg, lines = entry
@@ -174,21 +185,11 @@ def feed(self, entry):
174185
if not line:
175186
continue
176187
if line[0] != '#':
177-
# searching for multiple matches on a single line is too slow
178-
matches = self.internals_re.match(line)
179-
if matches is not None:
180-
yield PortageInternals(matches.group('cmd'), line, lineno, pkg=pkg)
181-
eapi = str(pkg.eapi)
182-
banned_eapi_cmds_re = self.banned_eapi_cmds.get(eapi)
183-
if banned_eapi_cmds_re is not None:
184-
matches = banned_eapi_cmds_re.match(line)
185-
if matches is not None:
186-
yield BannedEapiCommand(matches.group('cmd'), eapi, line, lineno, pkg=pkg)
187-
deprecated_eapi_cmds_re = self.deprecated_eapi_cmds.get(eapi)
188-
if deprecated_eapi_cmds_re is not None:
189-
matches = deprecated_eapi_cmds_re.match(line)
190-
if matches is not None:
191-
yield DeprecatedEapiCommand(matches.group('cmd'), eapi, line, lineno, pkg=pkg)
188+
eapi_str = str(pkg.eapi)
189+
for regex, result_cls, kwargs in self.regexes[eapi_str]:
190+
match = regex.match(line)
191+
if match is not None:
192+
yield result_cls(match.group('cmd'), line, lineno, pkg=pkg, **kwargs)
192193

193194

194195
class MissingSlash(base.VersionedResult, base.Error):

0 commit comments

Comments
 (0)