1 |
Rather than copying & pasting the same behavior for the different eclass |
2 |
checks, add a common class for them to extend. This makes adding more |
3 |
eclass checks trivial, and keeps down bitrot. |
4 |
|
5 |
This does abuse the checking interface slightly -- the eclass will change |
6 |
its category between unused and missing based on the checks. |
7 |
|
8 |
URL: https://bugs.gentoo.org/417159 |
9 |
URL: https://bugs.gentoo.org/417231 |
10 |
Signed-off-by: Mike Frysinger <vapier@g.o> |
11 |
--- |
12 |
v2 |
13 |
- fix optimization aspects |
14 |
|
15 |
bin/repoman | 6 +- |
16 |
pym/repoman/checks.py | 161 ++++++++++++++++++++++++++++++++++--------------- |
17 |
pym/repoman/errors.py | 1 - |
18 |
3 files changed, 116 insertions(+), 52 deletions(-) |
19 |
|
20 |
diff --git a/bin/repoman b/bin/repoman |
21 |
index fd87847..779e651 100755 |
22 |
--- a/bin/repoman |
23 |
+++ b/bin/repoman |
24 |
@@ -315,8 +315,9 @@ qahelp={ |
25 |
"file.size.fatal":"Files in the files directory must be under 60 KiB", |
26 |
"file.name":"File/dir name must be composed of only the following chars: %s " % allowed_filename_chars, |
27 |
"file.UTF8":"File is not UTF8 compliant", |
28 |
- "inherit.autotools":"Ebuild inherits autotools but does not call eautomake, eautoconf or eautoreconf", |
29 |
"inherit.deprecated":"Ebuild inherits a deprecated eclass", |
30 |
+ "inherit.missing":"Ebuild uses functions from an eclass but does not inherit it", |
31 |
+ "inherit.unused":"Ebuild inherits an eclass but does not use it", |
32 |
"java.eclassesnotused":"With virtual/jdk in DEPEND you must inherit a java eclass", |
33 |
"wxwidgets.eclassnotused":"Ebuild DEPENDs on x11-libs/wxGTK without inheriting wxwidgets.eclass", |
34 |
"KEYWORDS.dropped":"Ebuilds that appear to have dropped KEYWORDS for some arch", |
35 |
@@ -382,7 +383,6 @@ qahelp={ |
36 |
"ebuild.majorsyn":"This ebuild has a major syntax error that may cause the ebuild to fail partially or fully", |
37 |
"ebuild.minorsyn":"This ebuild has a minor syntax error that contravenes gentoo coding style", |
38 |
"ebuild.badheader":"This ebuild has a malformed header", |
39 |
- "eprefixify.defined":"The ebuild uses eprefixify, but does not inherit the prefix eclass", |
40 |
"manifest.bad":"Manifest has missing or incorrect digests", |
41 |
"metadata.missing":"Missing metadata.xml files", |
42 |
"metadata.bad":"Bad metadata.xml files", |
43 |
@@ -425,7 +425,7 @@ qawarnings = set(( |
44 |
"ebuild.badheader", |
45 |
"ebuild.patches", |
46 |
"file.size", |
47 |
-"inherit.autotools", |
48 |
+"inherit.unused", |
49 |
"inherit.deprecated", |
50 |
"java.eclassesnotused", |
51 |
"wxwidgets.eclassnotused", |
52 |
diff --git a/pym/repoman/checks.py b/pym/repoman/checks.py |
53 |
index 77df603..c17a0bd 100644 |
54 |
--- a/pym/repoman/checks.py |
55 |
+++ b/pym/repoman/checks.py |
56 |
@@ -331,24 +331,6 @@ class EbuildQuotedA(LineCheck): |
57 |
if match: |
58 |
return "Quoted \"${A}\" on line: %d" |
59 |
|
60 |
-class EprefixifyDefined(LineCheck): |
61 |
- """ Check that prefix.eclass is inherited if needed""" |
62 |
- |
63 |
- repoman_check_name = 'eprefixify.defined' |
64 |
- |
65 |
- _eprefixify_re = re.compile(r'\beprefixify\b') |
66 |
- _inherit_prefix_re = re.compile(r'^\s*inherit\s(.*\s)?prefix\b') |
67 |
- |
68 |
- def new(self, pkg): |
69 |
- self._prefix_inherited = False |
70 |
- |
71 |
- def check(self, num, line): |
72 |
- if self._eprefixify_re.search(line) is not None: |
73 |
- if not self._prefix_inherited: |
74 |
- return errors.EPREFIXIFY_MISSING_INHERIT |
75 |
- elif self._inherit_prefix_re.search(line) is not None: |
76 |
- self._prefix_inherited = True |
77 |
- |
78 |
class NoOffsetWithHelpers(LineCheck): |
79 |
""" Check that the image location, the alternate root offset, and the |
80 |
offset prefix (D, ROOT, ED, EROOT and EPREFIX) are not used with |
81 |
@@ -464,43 +446,124 @@ class InheritDeprecated(LineCheck): |
82 |
(eclass, replacement) |
83 |
del self._indirect_deprecated |
84 |
|
85 |
-class InheritAutotools(LineCheck): |
86 |
+class InheritEclass(LineCheck): |
87 |
""" |
88 |
- Make sure appropriate functions are called in |
89 |
- ebuilds that inherit autotools.eclass. |
90 |
+ Base class for checking for missing inherits, as well as excess inherits. |
91 |
+ |
92 |
+ Args: |
93 |
+ _eclass: Set to the name of your eclass. |
94 |
+ _funcs: A tuple of functions that this eclass provides. |
95 |
+ _comprehensive: Is the list of functions complete? |
96 |
+ _exempt_eclasses: If these eclasses are inherited, disable the missing |
97 |
+ inherit check. |
98 |
""" |
99 |
|
100 |
- repoman_check_name = 'inherit.autotools' |
101 |
- _inherit_autotools_re = re.compile(r'^\s*inherit\s(.*\s)?autotools(\s|$)') |
102 |
- _autotools_funcs = ( |
103 |
- "eaclocal", "eautoconf", "eautoheader", |
104 |
- "eautomake", "eautoreconf", "_elibtoolize") |
105 |
- _autotools_func_re = re.compile(r'\b(' + \ |
106 |
- "|".join(_autotools_funcs) + r')\b') |
107 |
- # Exempt eclasses: |
108 |
- # git - An EGIT_BOOTSTRAP variable may be used to call one of |
109 |
- # the autotools functions. |
110 |
- # subversion - An ESVN_BOOTSTRAP variable may be used to call one of |
111 |
- # the autotools functions. |
112 |
- _exempt_eclasses = frozenset(["git", "subversion"]) |
113 |
+ def __init__(self): |
114 |
+ self._inherit_re = re.compile(r'^\s*inherit\s(.*\s)?%s(\s|$)' % self._eclass) |
115 |
+ self._func_re = re.compile(r'\b(' + '|'.join(self._funcs) + r')\b') |
116 |
|
117 |
def new(self, pkg): |
118 |
- self._inherit_autotools = None |
119 |
- self._autotools_func_call = None |
120 |
- self._disabled = self._exempt_eclasses.intersection(pkg.inherited) |
121 |
+ self.repoman_check_name = 'inherit.missing' |
122 |
+ # We can't use pkg.inherited because that tells us all the eclass that |
123 |
+ # have been inherited and not just the ones we inherit directly. |
124 |
+ self._inherit = False |
125 |
+ self._func_call = False |
126 |
+ if hasattr(self, '_exempt_eclasses'): |
127 |
+ self._disabled = self._exempt_eclasses.intersection(pkg.inherited) |
128 |
+ else: |
129 |
+ self._disabled = False |
130 |
|
131 |
def check(self, num, line): |
132 |
- if self._disabled: |
133 |
- return |
134 |
- if self._inherit_autotools is None: |
135 |
- self._inherit_autotools = self._inherit_autotools_re.match(line) |
136 |
- if self._inherit_autotools is not None and \ |
137 |
- self._autotools_func_call is None: |
138 |
- self._autotools_func_call = self._autotools_func_re.search(line) |
139 |
+ if not self._inherit: |
140 |
+ self._inherit = self._inherit_re.match(line) |
141 |
+ if not self._inherit: |
142 |
+ if self._disabled: |
143 |
+ return |
144 |
+ s = self._func_re.search(line) |
145 |
+ if s: |
146 |
+ self._func_call = True |
147 |
+ return '%s.eclass is not inherited, but "%s" found at line: %s' % \ |
148 |
+ (self._eclass, s.group(0), '%d') |
149 |
+ elif not self._func_call: |
150 |
+ self._func_call = self._func_re.search(line) |
151 |
|
152 |
def end(self): |
153 |
- if self._inherit_autotools and self._autotools_func_call is None: |
154 |
- yield 'no eauto* function called' |
155 |
+ if self._comprehensive and self._inherit and not self._func_call: |
156 |
+ self.repoman_check_name = 'inherit.unused' |
157 |
+ yield 'no function called from %s.eclass; please drop' % self._eclass |
158 |
+ |
159 |
+class InheritAutotools(InheritEclass): |
160 |
+ _eclass = 'autotools' |
161 |
+ _funcs = ( |
162 |
+ 'eaclocal', 'eautoconf', 'eautoheader', |
163 |
+ 'eautomake', 'eautoreconf', '_elibtoolize', |
164 |
+ 'eautopoint' |
165 |
+ ) |
166 |
+ _comprehensive = True |
167 |
+ |
168 |
+ # Exempt eclasses: |
169 |
+ # git - An EGIT_BOOTSTRAP variable may be used to call one of |
170 |
+ # the autotools functions. |
171 |
+ # subversion - An ESVN_BOOTSTRAP variable may be used to call one of |
172 |
+ # the autotools functions. |
173 |
+ _exempt_eclasses = frozenset(['git', 'subversion', 'autotools-utils']) |
174 |
+ |
175 |
+class InheritEutils(InheritEclass): |
176 |
+ _eclass = 'eutils' |
177 |
+ _funcs = ( |
178 |
+ 'estack_push', 'estack_pop', 'eshopts_push', 'eshopts_pop', |
179 |
+ 'eumask_push', 'eumask_pop', 'epatch', 'epatch_user', |
180 |
+ 'emktemp', 'edos2unix', 'in_iuse', 'use_if_iuse', 'usex', |
181 |
+ 'makeopts_jobs' |
182 |
+ ) |
183 |
+ _comprehensive = False |
184 |
+ |
185 |
+ # These are "eclasses are the whole ebuild" type thing. |
186 |
+ _exempt_eclasses = frozenset(['toolchain', 'toolchain-binutils']) |
187 |
+ |
188 |
+class InheritFlagOMatic(InheritEclass): |
189 |
+ _eclass = 'flag-o-matic' |
190 |
+ _funcs = ( |
191 |
+ 'filter-(ld)?flags', 'strip-flags', 'strip-unsupported-flags', |
192 |
+ 'append-((ld|c(pp|xx)?))?flags', 'append-libs', |
193 |
+ ) |
194 |
+ _comprehensive = False |
195 |
+ |
196 |
+class InheritLibtool(InheritEclass): |
197 |
+ _eclass = 'libtool' |
198 |
+ _funcs = ( |
199 |
+ 'elibtoolize', |
200 |
+ ) |
201 |
+ _comprehensive = True |
202 |
+ |
203 |
+class InheritMultilib(InheritEclass): |
204 |
+ _eclass = 'multilib' |
205 |
+ _funcs = ( |
206 |
+ 'get_libdir', |
207 |
+ ) |
208 |
+ _comprehensive = False |
209 |
+ |
210 |
+class InheritPrefix(InheritEclass): |
211 |
+ _eclass = 'prefix' |
212 |
+ _funcs = ( |
213 |
+ 'eprefixify', |
214 |
+ ) |
215 |
+ _comprehensive = True |
216 |
+ |
217 |
+class InheritToolchainFuncs(InheritEclass): |
218 |
+ _eclass = 'toolchain-funcs' |
219 |
+ _funcs = ( |
220 |
+ 'gen_usr_ldscript', |
221 |
+ ) |
222 |
+ _comprehensive = False |
223 |
+ |
224 |
+class InheritUser(InheritEclass): |
225 |
+ _eclass = 'user' |
226 |
+ _funcs = ( |
227 |
+ 'enewuser', 'enewgroup', |
228 |
+ 'egetent', 'egethome', 'egetshell' |
229 |
+ ) |
230 |
+ _comprehensive = True |
231 |
|
232 |
class IUseUndefined(LineCheck): |
233 |
""" |
234 |
@@ -679,8 +742,10 @@ _constant_checks = tuple((c() for c in ( |
235 |
EbuildHeader, EbuildWhitespace, EbuildBlankLine, EbuildQuote, |
236 |
EbuildAssignment, Eapi3EbuildAssignment, EbuildUselessDodoc, |
237 |
EbuildUselessCdS, EbuildNestedDie, |
238 |
- EbuildPatches, EbuildQuotedA, EapiDefinition, EprefixifyDefined, |
239 |
- ImplicitRuntimeDeps, InheritAutotools, InheritDeprecated, IUseUndefined, |
240 |
+ EbuildPatches, EbuildQuotedA, EapiDefinition, |
241 |
+ ImplicitRuntimeDeps, InheritAutotools, InheritDeprecated, InheritEutils, |
242 |
+ InheritFlagOMatic, InheritMultilib, InheritLibtool, InheritPrefix, |
243 |
+ InheritToolchainFuncs, InheritUser, IUseUndefined, |
244 |
EMakeParallelDisabled, EMakeParallelDisabledViaMAKEOPTS, NoAsNeeded, |
245 |
DeprecatedBindnowFlags, SrcUnpackPatches, WantAutoDefaultValue, |
246 |
SrcCompileEconf, Eapi3DeprecatedFuncs, NoOffsetWithHelpers, |
247 |
diff --git a/pym/repoman/errors.py b/pym/repoman/errors.py |
248 |
index 3209243..c515502 100644 |
249 |
--- a/pym/repoman/errors.py |
250 |
+++ b/pym/repoman/errors.py |
251 |
@@ -19,7 +19,6 @@ EAPI_DEFINED_AFTER_INHERIT = 'EAPI defined after inherit on line: %d' |
252 |
NO_AS_NEEDED = 'Upstream asneeded linking bug (no-as-needed on line: %d)' |
253 |
PRESERVE_OLD_LIB = 'Upstream ABI change workaround on line: %d' |
254 |
BUILT_WITH_USE = 'built_with_use on line: %d' |
255 |
-EPREFIXIFY_MISSING_INHERIT = "prefix.eclass is not inherited, but eprefixify is used on line: %d" |
256 |
NO_OFFSET_WITH_HELPERS = "Helper function is used with D, ROOT, ED, EROOT or EPREFIX on line :%d" |
257 |
SANDBOX_ADDPREDICT = 'Ebuild calls addpredict on line: %d' |
258 |
USEQ_ERROR = 'Ebuild calls deprecated useq function on line: %d' |
259 |
-- |
260 |
1.7.8.6 |