Gentoo Archives: gentoo-portage-dev

From: Mike Frysinger <vapier@g.o>
To: gentoo-portage-dev@l.g.o
Subject: [gentoo-portage-dev] [PATCH v2] repoman: add a mini framework for checking eclasses, and fill it out
Date: Thu, 24 May 2012 21:15:21
Message-Id: 1337887213-29058-1-git-send-email-vapier@gentoo.org
In Reply to: [gentoo-portage-dev] [PATCH] repoman: add a mini framework for checking eclasses, and fill it out by Mike Frysinger
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

Replies