commit: fb1afecc6583a10ff477d4f9be600d4252c67b06 Author: Brian Dolbec <dolsen <AT> gentoo <DOT> org> AuthorDate: Sat Jul 15 00:20:37 2017 +0000 Commit: Brian Dolbec <dolsen <AT> gentoo <DOT> org> CommitDate: Mon Sep 11 16:13:14 2017 +0000 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=fb1afecc
repoman: New linechecks module, eapi .../repoman/modules/linechecks/eapi/__init__.py | 51 +++++++++++++ .../pym/repoman/modules/linechecks/eapi/checks.py | 83 ++++++++++++++++++++++ .../repoman/modules/linechecks/eapi/definition.py | 36 ++++++++++ 3 files changed, 170 insertions(+) diff --git a/repoman/pym/repoman/modules/linechecks/eapi/__init__.py b/repoman/pym/repoman/modules/linechecks/eapi/__init__.py new file mode 100644 index 000000000..e598fdfe3 --- /dev/null +++ b/repoman/pym/repoman/modules/linechecks/eapi/__init__.py @@ -0,0 +1,51 @@ +# Copyright 2015-2016 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +doc = """Eapi plug-in module for repoman LineChecks. +Performs eapi dependant checks on ebuilds.""" +__doc__ = doc[:] + + +module_spec = { + 'name': 'eapi', + 'description': doc, + 'provides':{ + 'definition-check': { + 'name': "definition", + 'sourcefile': "definition", + 'class': "EapiDefinition", + 'description': doc, + }, + 'srcprepare-check': { + 'name': "srcprepare", + 'sourcefile': "checks", + 'class': "UndefinedSrcPrepareSrcConfigurePhases", + 'description': doc, + }, + 'eapi3deprecated-check': { + 'name': "eapi3deprecated", + 'sourcefile': "checks", + 'class': "Eapi3DeprecatedFuncs", + 'description': doc, + }, + 'pkgpretend-check': { + 'name': "pkgpretend", + 'sourcefile': "checks", + 'class': "UndefinedPkgPretendPhase", + 'description': doc, + }, + 'eapi4incompatible-check': { + 'name': "eapi4incompatible", + 'sourcefile': "checks", + 'class': "Eapi4IncompatibleFuncs", + 'description': doc, + }, + 'eapi4gonevars-check': { + 'name': "eapi4gonevars", + 'sourcefile': "checks", + 'class': "Eapi4GoneVars", + 'description': doc, + }, + } +} + diff --git a/repoman/pym/repoman/modules/linechecks/eapi/checks.py b/repoman/pym/repoman/modules/linechecks/eapi/checks.py new file mode 100644 index 000000000..de899c061 --- /dev/null +++ b/repoman/pym/repoman/modules/linechecks/eapi/checks.py @@ -0,0 +1,83 @@ + +import re + +from portage.eapi import ( + eapi_has_src_prepare_and_src_configure, eapi_has_dosed_dohard, + eapi_exports_AA, eapi_has_pkg_pretend) +from repoman.modules.linechecks.base import LineCheck + + +# EAPI <2 checks +class UndefinedSrcPrepareSrcConfigurePhases(LineCheck): + repoman_check_name = 'EAPI.incompatible' + src_configprepare_re = re.compile(r'\s*(src_configure|src_prepare)\s*\(\)') + + def check_eapi(self, eapi): + return not eapi_has_src_prepare_and_src_configure(eapi) + + def check(self, num, line): + m = self.src_configprepare_re.match(line) + if m is not None: + return ("'%s'" % m.group(1)) + \ + " phase is not defined in EAPI < 2 on line: %d" + + +# EAPI-3 checks +class Eapi3DeprecatedFuncs(LineCheck): + repoman_check_name = 'EAPI.deprecated' + deprecated_commands_re = re.compile(r'^\s*(check_license)\b') + + def check_eapi(self, eapi): + return eapi not in ('0', '1', '2') + + def check(self, num, line): + m = self.deprecated_commands_re.match(line) + if m is not None: + return ("'%s'" % m.group(1)) + \ + " has been deprecated in EAPI=3 on line: %d" + + +# EAPI <4 checks +class UndefinedPkgPretendPhase(LineCheck): + repoman_check_name = 'EAPI.incompatible' + pkg_pretend_re = re.compile(r'\s*(pkg_pretend)\s*\(\)') + + def check_eapi(self, eapi): + return not eapi_has_pkg_pretend(eapi) + + def check(self, num, line): + m = self.pkg_pretend_re.match(line) + if m is not None: + return ("'%s'" % m.group(1)) + \ + " phase is not defined in EAPI < 4 on line: %d" + + +# EAPI-4 checks +class Eapi4IncompatibleFuncs(LineCheck): + repoman_check_name = 'EAPI.incompatible' + banned_commands_re = re.compile(r'^\s*(dosed|dohard)') + + def check_eapi(self, eapi): + return not eapi_has_dosed_dohard(eapi) + + def check(self, num, line): + m = self.banned_commands_re.match(line) + if m is not None: + return ("'%s'" % m.group(1)) + \ + " has been banned in EAPI=4 on line: %d" + + +class Eapi4GoneVars(LineCheck): + repoman_check_name = 'EAPI.incompatible' + undefined_vars_re = re.compile( + r'.*\$(\{(AA|KV|EMERGE_FROM)\}|(AA|KV|EMERGE_FROM))') + + def check_eapi(self, eapi): + # AA, KV, and EMERGE_FROM should not be referenced in EAPI 4 or later. + return not eapi_exports_AA(eapi) + + def check(self, num, line): + m = self.undefined_vars_re.match(line) + if m is not None: + return ("variable '$%s'" % m.group(1)) + \ + " is gone in EAPI=4 on line: %d" diff --git a/repoman/pym/repoman/modules/linechecks/eapi/definition.py b/repoman/pym/repoman/modules/linechecks/eapi/definition.py new file mode 100644 index 000000000..410bad1c7 --- /dev/null +++ b/repoman/pym/repoman/modules/linechecks/eapi/definition.py @@ -0,0 +1,36 @@ + +from repoman.modules.linechecks.base import LineCheck +from repoman._portage import portage + + +class EapiDefinition(LineCheck): + """ + Check that EAPI assignment conforms to PMS section 7.3.1 + (first non-comment, non-blank line). + """ + repoman_check_name = 'EAPI.definition' + ignore_comment = True + _eapi_re = portage._pms_eapi_re + + def new(self, pkg): + self._cached_eapi = pkg.eapi + self._parsed_eapi = None + self._eapi_line_num = None + + def check(self, num, line): + if self._eapi_line_num is None and line.strip(): + self._eapi_line_num = num + 1 + m = self._eapi_re.match(line) + if m is not None: + self._parsed_eapi = m.group(2) + + def end(self): + if self._parsed_eapi is None: + if self._cached_eapi != "0": + yield "valid EAPI assignment must occur on or before line: %s" % \ + self._eapi_line_num + elif self._parsed_eapi != self._cached_eapi: + yield ( + "bash returned EAPI '%s' which does not match " + "assignment on line: %s" % + (self._cached_eapi, self._eapi_line_num))