From da6d3bb8357445a228a797046eb0b76dbbbaada0 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 23 May 2012 15:06:19 -0400 Subject: repoman: add a mini framework for checking eclasses, and fill it out Rather than copying & pasting the same behavior for the different eclass checks, add a common class for them to extend. This makes adding more eclass checks trivial, and keeps down bitrot. This does abuse the checking interface slightly -- the eclass will change its category between unused and missing based on the checks. URL: https://bugs.gentoo.org/417159 URL: https://bugs.gentoo.org/417231 Signed-off-by: Mike Frysinger --- pym/repoman/checks.py | 161 +++++++++++++++++++++++++++++++++++--------------- pym/repoman/errors.py | 1 - 2 files changed, 113 insertions(+), 49 deletions(-) (limited to 'pym/repoman') diff --git a/pym/repoman/checks.py b/pym/repoman/checks.py index a413968e8..35225c229 100644 --- a/pym/repoman/checks.py +++ b/pym/repoman/checks.py @@ -332,24 +332,6 @@ class EbuildQuotedA(LineCheck): if match: return "Quoted \"${A}\" on line: %d" -class EprefixifyDefined(LineCheck): - """ Check that prefix.eclass is inherited if needed""" - - repoman_check_name = 'eprefixify.defined' - - _eprefixify_re = re.compile(r'\beprefixify\b') - _inherit_prefix_re = re.compile(r'^\s*inherit\s(.*\s)?prefix\b') - - def new(self, pkg): - self._prefix_inherited = False - - def check(self, num, line): - if self._eprefixify_re.search(line) is not None: - if not self._prefix_inherited: - return errors.EPREFIXIFY_MISSING_INHERIT - elif self._inherit_prefix_re.search(line) is not None: - self._prefix_inherited = True - class NoOffsetWithHelpers(LineCheck): """ Check that the image location, the alternate root offset, and the offset prefix (D, ROOT, ED, EROOT and EPREFIX) are not used with @@ -465,43 +447,124 @@ class InheritDeprecated(LineCheck): (eclass, replacement) del self._indirect_deprecated -class InheritAutotools(LineCheck): +class InheritEclass(LineCheck): """ - Make sure appropriate functions are called in - ebuilds that inherit autotools.eclass. + Base class for checking for missing inherits, as well as excess inherits. + + Args: + _eclass: Set to the name of your eclass. + _funcs: A tuple of functions that this eclass provides. + _comprehensive: Is the list of functions complete? + _exempt_eclasses: If these eclasses are inherited, disable the missing + inherit check. """ - repoman_check_name = 'inherit.autotools' - _inherit_autotools_re = re.compile(r'^\s*inherit\s(.*\s)?autotools(\s|$)') - _autotools_funcs = ( - "eaclocal", "eautoconf", "eautoheader", - "eautomake", "eautoreconf", "_elibtoolize") - _autotools_func_re = re.compile(r'\b(' + \ - "|".join(_autotools_funcs) + r')\b') - # Exempt eclasses: - # git - An EGIT_BOOTSTRAP variable may be used to call one of - # the autotools functions. - # subversion - An ESVN_BOOTSTRAP variable may be used to call one of - # the autotools functions. - _exempt_eclasses = frozenset(["git", "subversion"]) + def __init__(self): + self._inherit_re = re.compile(r'^\s*inherit\s(.*\s)?%s(\s|$)' % self._eclass) + self._func_re = re.compile(r'\b(' + '|'.join(self._funcs) + r')\b') def new(self, pkg): - self._inherit_autotools = None - self._autotools_func_call = None - self._disabled = self._exempt_eclasses.intersection(pkg.inherited) + self.repoman_check_name = 'inherit.missing' + # We can't use pkg.inherited because that tells us all the eclass that + # have been inherited and not just the ones we inherit directly. + self._inherit = False + self._func_call = False + if hasattr(self, '_exempt_eclasses'): + self._disabled = self._exempt_eclasses.intersection(pkg.inherited) + else: + self._disabled = False def check(self, num, line): - if self._disabled: - return - if self._inherit_autotools is None: - self._inherit_autotools = self._inherit_autotools_re.match(line) - if self._inherit_autotools is not None and \ - self._autotools_func_call is None: - self._autotools_func_call = self._autotools_func_re.search(line) + if not self._inherit: + self._inherit = self._inherit_re.match(line) + if not self._inherit: + if self._disabled: + return + s = self._func_re.search(line) + if s: + self._func_call = True + return '%s.eclass is not inherited, but "%s" found at line: %s' % \ + (self._eclass, s.group(0), '%d') + elif not self._func_call: + self._func_call = self._func_re.search(line) def end(self): - if self._inherit_autotools and self._autotools_func_call is None: - yield 'no eauto* function called' + if self._comprehensive and self._inherit and not self._func_call: + self.repoman_check_name = 'inherit.unused' + yield 'no function called from %s.eclass; please drop' % self._eclass + +class InheritAutotools(InheritEclass): + _eclass = 'autotools' + _funcs = ( + 'eaclocal', 'eautoconf', 'eautoheader', + 'eautomake', 'eautoreconf', '_elibtoolize', + 'eautopoint' + ) + _comprehensive = True + + # Exempt eclasses: + # git - An EGIT_BOOTSTRAP variable may be used to call one of + # the autotools functions. + # subversion - An ESVN_BOOTSTRAP variable may be used to call one of + # the autotools functions. + _exempt_eclasses = frozenset(['git', 'subversion', 'autotools-utils']) + +class InheritEutils(InheritEclass): + _eclass = 'eutils' + _funcs = ( + 'estack_push', 'estack_pop', 'eshopts_push', 'eshopts_pop', + 'eumask_push', 'eumask_pop', 'epatch', 'epatch_user', + 'emktemp', 'edos2unix', 'in_iuse', 'use_if_iuse', 'usex', + 'makeopts_jobs' + ) + _comprehensive = False + + # These are "eclasses are the whole ebuild" type thing. + _exempt_eclasses = frozenset(['toolchain', 'toolchain-binutils']) + +class InheritFlagOMatic(InheritEclass): + _eclass = 'flag-o-matic' + _funcs = ( + 'filter-(ld)?flags', 'strip-flags', 'strip-unsupported-flags', + 'append-((ld|c(pp|xx)?))?flags', 'append-libs', + ) + _comprehensive = False + +class InheritLibtool(InheritEclass): + _eclass = 'libtool' + _funcs = ( + 'elibtoolize', + ) + _comprehensive = True + +class InheritMultilib(InheritEclass): + _eclass = 'multilib' + _funcs = ( + 'get_libdir', + ) + _comprehensive = False + +class InheritPrefix(InheritEclass): + _eclass = 'prefix' + _funcs = ( + 'eprefixify', + ) + _comprehensive = True + +class InheritToolchainFuncs(InheritEclass): + _eclass = 'toolchain-funcs' + _funcs = ( + 'gen_usr_ldscript', + ) + _comprehensive = False + +class InheritUser(InheritEclass): + _eclass = 'user' + _funcs = ( + 'enewuser', 'enewgroup', + 'egetent', 'egethome', 'egetshell' + ) + _comprehensive = True class IUseUndefined(LineCheck): """ @@ -680,8 +743,10 @@ _constant_checks = tuple((c() for c in ( EbuildHeader, EbuildWhitespace, EbuildBlankLine, EbuildQuote, EbuildAssignment, Eapi3EbuildAssignment, EbuildUselessDodoc, EbuildUselessCdS, EbuildNestedDie, - EbuildPatches, EbuildQuotedA, EapiDefinition, EprefixifyDefined, - ImplicitRuntimeDeps, InheritAutotools, InheritDeprecated, IUseUndefined, + EbuildPatches, EbuildQuotedA, EapiDefinition, + ImplicitRuntimeDeps, InheritAutotools, InheritDeprecated, InheritEutils, + InheritFlagOMatic, InheritMultilib, InheritLibtool, InheritPrefix, + InheritToolchainFuncs, InheritUser, IUseUndefined, EMakeParallelDisabled, EMakeParallelDisabledViaMAKEOPTS, NoAsNeeded, DeprecatedBindnowFlags, SrcUnpackPatches, WantAutoDefaultValue, SrcCompileEconf, Eapi3DeprecatedFuncs, NoOffsetWithHelpers, diff --git a/pym/repoman/errors.py b/pym/repoman/errors.py index 320924316..c515502c4 100644 --- a/pym/repoman/errors.py +++ b/pym/repoman/errors.py @@ -19,7 +19,6 @@ EAPI_DEFINED_AFTER_INHERIT = 'EAPI defined after inherit on line: %d' NO_AS_NEEDED = 'Upstream asneeded linking bug (no-as-needed on line: %d)' PRESERVE_OLD_LIB = 'Upstream ABI change workaround on line: %d' BUILT_WITH_USE = 'built_with_use on line: %d' -EPREFIXIFY_MISSING_INHERIT = "prefix.eclass is not inherited, but eprefixify is used on line: %d" NO_OFFSET_WITH_HELPERS = "Helper function is used with D, ROOT, ED, EROOT or EPREFIX on line :%d" SANDBOX_ADDPREDICT = 'Ebuild calls addpredict on line: %d' USEQ_ERROR = 'Ebuild calls deprecated useq function on line: %d' -- cgit v1.2.3-1-g7c22