Univention Bugzilla – Attachment 7891 Details for
Bug 37203
warn about dependencies on transitional packages
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
Updates 0014-Depends.py
0014-Depends.py (text/plain), 11.87 KB, created by
Philipp Hahn
on 2016-08-18 10:00:25 CEST
(
hide
)
Description:
Updates 0014-Depends.py
Filename:
MIME Type:
Creator:
Philipp Hahn
Created:
2016-08-18 10:00:25 CEST
Size:
11.87 KB
patch
obsolete
>#!/usr/bin/python ># -*- coding: utf-8 -*- ># vim:set fileencoding=utf-8 sw=4 ts=4 et: ># ># Copyright (C) 2008-2016 Univention GmbH ># ># http://www.univention.de/ ># ># All rights reserved. ># ># The source code of this program is made available ># under the terms of the GNU Affero General Public License version 3 ># (GNU AGPL V3) as published by the Free Software Foundation. ># ># Binary versions of this program provided by Univention to you as ># well as other copyrighted, protected or trademarked materials like ># Logos, graphics, fonts, specific documentations and configurations, ># cryptographic keys etc. are subject to a license agreement between ># you and Univention and not subject to the GNU AGPL V3. ># ># In the case you use this program under the terms of the GNU AGPL V3, ># the program is provided in the hope that it will be useful, ># but WITHOUT ANY WARRANTY; without even the implied warranty of ># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ># GNU Affero General Public License for more details. ># ># You should have received a copy of the GNU Affero General Public ># License with the Debian GNU/Linux or Univention distribution in file ># /usr/share/common-licenses/AGPL-3; if not, see ># <http://www.gnu.org/licenses/>. > >from os import listdir >from os.path import join, exists, curdir, splitext >import re >from glob import glob >try: > import univention.ucslint.base as uub >except ImportError: > import ucslint.base as uub >from apt import Cache > > >class UniventionPackageCheck(uub.UniventionPackageCheckDebian): > RE_FIELD = re.compile("([a-z0-9_]+)[ \t]*(?:(<<|<=|=|>=|>>)[ \t]*([-a-zA-Z0-9.+~]+))?") > RE_INIT = re.compile("^(?:File|Subfile): (etc/init.d/.+)$") > RE_TRANSITIONAL = re.compile(r'\b[Tt]ransition(?:al)?(?: dummy)? [Pp]ackage\b') # re.IGNORECASE > DEPS = { > 'uicr': (re.compile("(?:/usr/bin/)?univention-install-(?:config-registry(?:-info)?|service-info)"), set(('univention-config-dev',))), > 'umcb': (re.compile("(?:/usr/bin/)?dh-umc-module-build"), set(('univention-management-console-dev',))), > 'ucr': (re.compile("""(?:^|(?<=['";& \t]))(?:/usr/sbin/)?(?:univention-config-registry|ucr)(?:(?=['";& \t])|$)"""), set(('univention-config', '${misc:Depends}'))), > 'ial': (re.compile("/usr/share/univention-config-registry/init-autostart\.lib"), set(('univention-base-files',))), > } > > def __init__(self): > super(UniventionPackageCheck, self).__init__() > self.name = '0014-Depends' > self.apt = None > > def getMsgIds(self): > return { > '0014-0': [uub.RESULT_WARN, 'failed to open/read file'], > '0014-1': [uub.RESULT_ERROR, 'parsing error in debian/control'], > '0014-2': [uub.RESULT_ERROR, 'univention-install-... is used in debian/rules, but debian/control lacks a build-dependency on univention-config-dev.'], > '0014-3': [uub.RESULT_ERROR, 'dh-umc-module-build is used in debian/rules, but debian/control lacks a build-dependency on univention-management-console-dev.'], > '0014-4': [uub.RESULT_ERROR, 'univention-config-registry is used in a .preinst script, but the package lacks a pre-dependency on univention-config.'], > '0014-5': [uub.RESULT_ERROR, 'univention-config-registry is used in a maintainer script, but the package lacks a dependency on univention-config.'], > '0014-6': [uub.RESULT_WARN, 'init-autostart.lib is sourced by a script, but the package lacks an explicit dependency on univention-base-files.'], > '0014-7': [uub.RESULT_WARN, 'The source package contains debian/*.univention- files, but the package is not found in debian/control.'], > '0014-8': [uub.RESULT_WARN, 'unexpected UCR file'], > '0014-9': [uub.RESULT_WARN, 'depends on transitional package'], > } > > def postinit(self, path): > """Checks to be run before real check or to create pre-calculated data for several runs. Only called once!""" > try: > self.apt = Cache(memonly=True) > except Exception as ex: > self.debug('failed to load APT cache: %s' % (ex,)) > > def _split_field(self, s): > """Split control field into parts. Returns generator.""" > for con in s.split(','): > con = con.strip() > for dis in con.split('|'): > i = dis.find('(') > if i >= 0: > dis = dis[:i] > pkg = dis.strip() > if pkg: > yield pkg > > def _scan_script(self, fn): > """find calls to 'univention-install-', 'ucr' and use of 'init-autostart.lib' in file 'fn'.""" > need = set() > self.debug('Reading %s' % (fn,)) > try: > f = open(fn, 'r') > except (OSError, IOError): > self.addmsg('0014-0', 'failed to open and read file', filename=fn) > return need > try: > for l in f: > for (key, (regexp, pkgs)) in UniventionPackageCheck.DEPS.items(): > if regexp.search(l): > self.debug('Found %s in %s' % (key.upper(), fn)) > need.add(key) > finally: > f.close() > return need > > def check_source(self, source_section): > """Check source package for dependencies.""" > src_arch = source_section.get('Build-Depends', '') > src_arch = self._split_field(src_arch) > src_arch = set(src_arch) > self.debug('Build-Depends: %s' % (src_arch,)) > src_indep = source_section.get('Build-Depends-Indep', '') > src_indep = self._split_field(src_indep) > src_indep = set(src_indep) > self.debug('Build-Depends-Indep: %s' % (src_indep,)) > src_deps = src_arch | src_indep > > fn = join(self.path, 'debian', 'rules') > need = self._scan_script(fn) > uses_uicr = 'uicr' in need > uses_umcb = 'umcb' in need > > # Assert packages using "univention-install-" build-depens on "univention-config-dev" and depend on "univention-config" > if uses_uicr and not src_deps & UniventionPackageCheck.DEPS['uicr'][1]: > self.addmsg('0014-2', 'Missing Build-Depends: univention-config-dev', filename=fn) > if uses_umcb and not src_deps & UniventionPackageCheck.DEPS['umcb'][1]: > self.addmsg('0014-3', 'Missing Build-Depends: univention-management-console-dev', filename=fn) > > return src_deps > > def check_package(self, section): > """Check binary package for dependencies.""" > pkg = section['Package'] > self.debug('Package: %s' % (pkg,)) > > bin_pre = section.get('Pre-Depends', '') > bin_pre = self._split_field(bin_pre) > bin_pre = set(bin_pre) > self.debug('Pre-Depends: %s' % (bin_pre,)) > bin_dep = section.get('Depends', '') > bin_dep = self._split_field(bin_dep) > bin_dep = set(bin_dep) > self.debug('Depends: %s' % (bin_dep,)) > bin_rec = section.get('Recommends', '') > bin_rec = self._split_field(bin_rec) > bin_rec = set(bin_rec) > self.debug('Recommends: %s' % (bin_rec,)) > bin_sug = section.get('Suggests', '') > bin_sug = self._split_field(bin_sug) > bin_sug = set(bin_sug) > self.debug('Suggests: %s' % (bin_sug,)) > bin_deps = bin_pre | bin_dep > > # Assert packages using "ucr" in preinst pre-depend on "univention-config" > for ms in ('preinst',): > fn = join(self.path, 'debian', '%s.%s' % (pkg, ms)) > if not exists(fn): > continue > need = self._scan_script(fn) > if 'ucr' in need and not bin_pre & UniventionPackageCheck.DEPS['ucr'][1]: > self.addmsg('0014-4', 'Missing Pre-Depends: univention-config', filename=fn) > > # Assert packages using "ucr" depend on "univention-config" > for ms in ('postinst', 'prerm', 'postrm'): > fn = join(self.path, 'debian', '%s.%s' % (pkg, ms)) > if not exists(fn): > continue > need = self._scan_script(fn) > if 'ucr' in need and not bin_deps & UniventionPackageCheck.DEPS['ucr'][1]: > self.addmsg('0014-5', 'Missing Depends: univention-config, ${misc:Depends}', filename=fn) > p = join(self.path, '[0-9][0-9]%s.inst' % (pkg,)) > for fn in glob(p): > need = self._scan_script(fn) > if 'ucr' in need and not bin_deps & UniventionPackageCheck.DEPS['ucr'][1]: > self.addmsg('0014-4', 'Missing Depends: univention-config, ${misc:Depends}', filename=fn) > # FIXME: scan all other files for ucr as well? > > # Assert packages using "init-autostart.lib" depends on "univention-base-files" > init_files = set() > init_files.add(join(self.path, 'debian', '%s.init' % (pkg,))) > init_files.add(join(self.path, 'debian', '%s.init.d' % (pkg,))) > try: > fn = join(self.path, 'debian', '%s.univention-config-registry' % (pkg,)) > if exists(fn): > f = open(fn, 'r') > try: > for l in f: > m = UniventionPackageCheck.RE_INIT.match(l) > if m: > fn = join(self.path, 'conffiles', m.group(1)) > init_files.add(fn) > finally: > f.close() > except (IOError, OSError): > self.addmsg('0014-0', 'failed to open and read file', filename=fn) > for fn in init_files: > if not exists(fn): > continue > need = self._scan_script(fn) > if 'ial' in need and not bin_deps & UniventionPackageCheck.DEPS['ial'][1]: > self.addmsg('0014-6', 'Missing Depends: univention-base-files', filename=fn) > > return bin_deps | bin_rec | bin_sug > > def check(self, path): > """ the real check """ > super(UniventionPackageCheck, self).check(path) > > fn = join(path, 'debian', 'control') > self.debug('Reading %s' % (fn,)) > try: > parser = uub.ParserDebianControl(fn) > self.path = path > except uub.FailedToReadFile: > self.addmsg('0014-0', 'failed to open and read file', filename=fn) > return > except uub.UCSLintException: > self.addmsg('0014-1', 'parsing error', filename=fn) > return > > deps = self.check_source(parser.source_section) > for section in parser.binary_sections: > deps |= self.check_package(section) > > self.check_unknown(path, parser) > self.check_transitional(path, deps) > > def check_unknown(self, path, parser): > # Assert all files debian/$pkg.$suffix belong to a package $pkg declared in debian/control > SUFFIXES = ( > '.univention-config-registry', > '.univention-config-registry-variables', > '.univention-config-registry-categories', > '.univention-service', > ) > exists = set( > filename > for filename in listdir(join(path, 'debian')) > if splitext(filename)[1] in SUFFIXES > ) > known = set( > section['Package'] + suffix > for section in parser.binary_sections > for suffix in SUFFIXES > ) > for unowned in exists - known: > self.addmsg('0014-8', 'unexpected UCR file', filename=join(path, 'debian', unowned)) > > def check_transitional(self, path, deps): > if not self.apt: > return > > for dep in deps: > if dep.startswith('${'): > continue > try: > pkg = self.apt[dep] > cand = pkg.candidate > except LookupError as ex: > self.debug('not found %s: %s' % (dep, ex)) > continue > if self.RE_TRANSITIONAL.search(cand.summary): > self.addmsg('0014-8', 'depends on transitional package %s' % (dep,), filename=join(path, 'debian', 'control')) > > >if __name__ == '__main__': > upc = UniventionPackageCheck() > upc.check(curdir) > msglist = upc.result() > for msg in msglist: > print str(msg)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 37203
: 7891