コード例 #1
0
	def check(self, path: str) -> None:
		""" the real check """
		super(UniventionPackageCheck, self).check(path)

		tester = uub.UPCFileTester()
		tester.addTest(
			re.compile(r'''(?:(?<=['" \t])|^)(?:/usr/sbin/)?univention-admin(?=['" \t]|$)'''),
			'0016-2', 'Use of deprecated "univention-admin"', cntmax=0)
		tester.addTest(
			re.compile(r'''(?:(?<=['" \t])|^)(?:/usr/sbin/)?univention-baseconfig(?=["' \t]|$)'''),
			'0016-3', 'Use of deprecated "univention-baseconfig"', cntmax=0)
		tester.addTest(
			re.compile(r'''\bfrom\b.+\bunivention_baseconfig\b.+\bimport\b|\bimport\b.+\bunivention_baseconfig\b'''),
			'0016-4', 'Use of deprecated "univention_baseconfig"', cntmax=0)
		tester.addTest(
			re.compile(r'''@%@BCWARNING=.+?@%@'''),
			'0016-5', 'Use of deprecated "@%@BCWARNING=@%@"', cntmax=0)

		ignore_suffixes = ('.1', '.2', '.3', '.4', '.5', '.6', '.7', '.8', '.txt')
		ignore_files = ('changelog', 'README')
		for fn in uub.FilteredDirWalkGenerator(path, ignore_suffixes=ignore_suffixes, ignore_files=ignore_files):
			tester.open(fn)
			msglist = tester.runTests()
			self.msg.extend(msglist)

		for fn in uub.FilteredDirWalkGenerator(os.path.join(path, 'debian'), suffixes=('.univention-baseconfig',)):
			self.addmsg('0016-6', 'Use of deprecated "debian/*.univention-baseconfig"', fn)
コード例 #2
0
	def check(self, path: str) -> None:
		""" the real check """
		super(UniventionPackageCheck, self).check(path)

		self.check_py(python_files(path))
		self.check_po(uub.FilteredDirWalkGenerator(path, suffixes=('.po',)))
		self.check_names(uub.FilteredDirWalkGenerator(
			path,
			ignore_suffixes=uub.FilteredDirWalkGenerator.BINARY_SUFFIXES | uub.FilteredDirWalkGenerator.DOCUMENTATION_SUFFIXES,
		))
コード例 #3
0
 def find_python_files(self, base):
     pathes = set(
         list(uub.FilteredDirWalkGenerator(base, suffixes=['.py'])) + list(
             uub.FilteredDirWalkGenerator(base,
                                          ignore_suffixes=['.py'],
                                          reHashBang=self.PYTHON_HASH_BANG))
     )
     for path in pathes:
         if not self.ignore_path(path):
             yield path
コード例 #4
0
	def check(self, path):
		""" the real check """
		super(UniventionPackageCheck, self).check(path)

		files = []
		# scan directory only
		for dir in ['debian']:
			for fn in os.listdir(os.path.join(path, dir)):
				self.debug(os.path.join(path, dir, fn))
				if not os.path.isdir(os.path.join(path, dir, fn)):
					files.append(os.path.join(path, dir, fn))

		# scan directory recursively
		for dir in ['conffiles']:
			for fn in uub.FilteredDirWalkGenerator(os.path.join(path, dir)):
				files.append(fn)

		for fn in files:
			try:
				content = open(fn, 'r').read()
			except (OSError, IOError):
				self.addmsg('0002-1', 'failed to open and read file', fn)
				continue

			for txt in ['dc=univention,dc=local', 'dc=univention,dc=qa', 'dc=univention,dc=test']:
				for line in self._searchString(content, txt):
					self.addmsg('0002-2', 'contains invalid basedn', fn, line)

			for txt in ['univention.local', 'univention.qa', 'univention.test']:
				for line in self._searchString(content, txt):
					self.addmsg('0002-3', 'contains invalid domainname', fn, line)
コード例 #5
0
    def check(self, path: str) -> None:
        """ the real check """
        super(UniventionPackageCheck, self).check(path)

        for fn in uub.FilteredDirWalkGenerator(
                path,
                ignore_suffixes=uub.FilteredDirWalkGenerator.BINARY_SUFFIXES):
            try:
                with open(fn, 'r') as fd:
                    for row, line in enumerate(fd, start=1):
                        origline = line
                        if self.RE_WHITELINE.match(line):
                            continue
                        for match in RE_UNIVENTION.finditer(line):
                            found = match.group(0)
                            if self.RE_WHITEWORD.match(found):
                                continue
                            self.debug('%s:%d: found="%s"  origline="%s"' %
                                       (fn, row, found, origline))
                            self.addmsg(
                                '0015-2',
                                'univention is incorrectly spelled: %s' %
                                found, fn, row)
            except UnicodeDecodeError:
                # Silently skip binary files
                pass
コード例 #6
0
    def check(self, path):
        """ the real check """
        super(UniventionPackageCheck, self).check(path)

        fz = tre.Fuzzyness(maxerr=2)
        pt = tre.compile("\<univention\>", tre.EXTENDED | tre.ICASE)

        for fn in uub.FilteredDirWalkGenerator(path):
            fd = open(fn, 'r')
            try:
                for lnr, line in enumerate(fd, start=1):
                    origline = line
                    if UniventionPackageCheck.RE_WHITELINE.match(line):
                        continue
                    pos = 0
                    while True:
                        m = pt.search(line[pos:], fz)
                        if m:
                            if not UniventionPackageCheck.RE_WHITEWORD.match(
                                    m[0]):
                                self.debug('%s:%d: found="%s"  origline="%s"' %
                                           (fn, lnr, m[0], origline))
                                self.addmsg(
                                    '0015-2',
                                    'univention is incorrectly spelled: %s' %
                                    m[0],
                                    filename=fn,
                                    line=lnr)
                            pos += m.groups()[0][1]
                        else:
                            break
            finally:
                fd.close()
	def check(self, path: str) -> None:
		""" the real check """
		super(UniventionPackageCheck, self).check(path)

		tester = uub.UPCFileTester()
		tester.addTest(re.compile(r'dc=univention,dc=(?:local|qa|test)'), '0002-2', 'contains invalid basedn', cntmax=0)
		tester.addTest(re.compile(r'univention\.(?:local|qa|test)'), '0002-3', 'contains invalid domainname', cntmax=0)

		for fn in chain(
			uub.FilteredDirWalkGenerator(join(path, 'conffiles')),
			uub.FilteredDirWalkGenerator(join(path, 'debian')),
		):
			try:
				tester.open(fn)
			except EnvironmentError:
				self.addmsg('0002-1', 'failed to open and read file', fn)
			else:
				self.msg += tester.runTests()
コード例 #8
0
	def check(self, path):
		""" the real check """
		super(UniventionPackageCheck, self).check(path)

		py_files = []
		for fn in uub.FilteredDirWalkGenerator(path):
			if fn.endswith('.py'):  # add all files to list that end with ".py"
				py_files.append(fn)
				continue

			try:
				content = open(fn, 'r').read(100)  # add all files that contain a hashbang in first line
			except (IOError, OSError):
				self.debug('Failed to read 100 bytes from %r' % (fn,))
			else:
				if content.startswith('#!'):
					py_files.append(fn)

		tester = uub.UPCFileTester()
		tester.addTest(re.compile('.has_key\s*\('), '0009-5', 'dict.has_key is deprecated in python3 - please use "if key in dict:"', cntmax=0)
		tester.addTest(re.compile(r'''\braise\s*(?:'[^']+'|"[^"]+")'''), '0009-6', 'raise "text" is deprecated in python3', cntmax=0)
		tester.addTest(re.compile(r"""\b(?:if|while)\b.*(?:(?:!=|<>|==)\s*None\b|\bNone\s*(?:!=|<>|==)).*:"""), '0009-7', 'fragile comparison with None', cntmax=0)
		tester.addTest(re.compile(
			r'''(?:baseConfig|configRegistry|ucr)(?:\[.+\]|\.get\(.+\)).*\bin\s*
			[[(]
			(?:\s*(['"])(?:yes|no|1|0|true|false|on|off|enabled?|disabled?)\1\s*,?\s*){3,}
			[])]''', re.VERBOSE | re.IGNORECASE),
			'0009-8', 'use ucr.is_true() or .is_false()', cntmax=0)
		for fn in py_files:
			try:
				content = open(fn, 'r').read(100)
			except (IOError, OSError):
				self.addmsg('0009-1', 'failed to open and read file', filename=fn)
				continue
			self.debug('testing %s' % fn)

			if not content:
				continue

			tester.open(fn)
			msglist = tester.runTests()
			self.msg.extend(msglist)

			firstline = content.splitlines()[0]
			match = UniventionPackageCheck.RE_HASHBANG.match(firstline)
			if match:
				version, space, option, tail = match.groups()
				if not version:
					self.addmsg('0009-2', 'file does not specify python version in hashbang', filename=fn)
				elif version != '2.7':
					self.addmsg('0009-3', 'file specifies wrong python version in hashbang', filename=fn)
				if space and not option:
					self.addmsg('0009-4', 'file contains whitespace after python command', filename=fn)
				if tail:
					self.addmsg('0009-9', 'hashbang contains more than one option', filename=fn)
コード例 #9
0
    def check(self, path):
        """ the real check """
        super(UniventionPackageCheck, self).check(path)

        for fn in uub.FilteredDirWalkGenerator(
                path,
                ignore_suffixes=['~', '.py', '.bak', '.po'],
                reHashBang=re.compile('^#![ \t]*/bin/(?:d?a)?sh')):
            self.debug('Testing file %s' % fn)
            self.check_bashism(fn)
            self.check_unquoted_local(fn)
コード例 #10
0
ファイル: 0017-Shell.py プロジェクト: bopopescu/smart-1
    def check(self, path):
        """ the real check """
        super(UniventionPackageCheck, self).check(path)

        #
        # search shell scripts and execute test
        #
        for fn in uub.FilteredDirWalkGenerator(path):
            if fn.endswith('.sh') or containsHashBang(fn):
                self.tester.open(fn)
                msglist = self.tester.runTests()
                self.msg.extend(msglist)
コード例 #11
0
    def check(self, path: str) -> None:
        """ the real check """
        super(UniventionPackageCheck, self).check(path)

        for fn in uub.FilteredDirWalkGenerator(path,
                                               ignore_suffixes=['.po'],
                                               reHashBang=RE_HASHBANG_SHELL):
            self.debug('Testing file %s' % fn)
            try:
                self.check_bashism(fn)
                self.check_unquoted_local(fn)
            except (EnvironmentError, UnicodeDecodeError):
                self.addmsg('0013-1', 'failed to open file', fn)
コード例 #12
0
    def check_dirs(self, path: str) -> None:
        dirs = {}  # type: Dict[str, Set[str]]
        debianpath = join(path, 'debian')

        for fp in uub.FilteredDirWalkGenerator(debianpath,
                                               suffixes=['install']):
            package, suffix = self.split_pkg(fp)
            pkg = dirs.setdefault(package, Dirs(package))
            # ~/doc/2018-04-11-ApiDoc/pymerge
            for row, line in self.lines(fp):
                dst = ''
                for src, dst in self.process_install(line):
                    self.debug('%s:%d Installs %s to %s' % (fp, row, src, dst))
                    pkg.add(dst)

                if self.RE_PYTHONPATHS.match(dst):
                    self.addmsg(
                        '0018-4',
                        'Use debian/*.pyinstall to install Python modules', fp,
                        row)

        for fp in uub.FilteredDirWalkGenerator(debianpath,
                                               suffixes=['pyinstall']):
            package, suffix = self.split_pkg(fp)
            pkg = dirs.setdefault(package, Dirs(package))
            for row, line in self.lines(fp):
                for src, dst in self.process_pyinstall(line):
                    self.debug('%s:%d Installs %s to %s' % (fp, row, src, dst))
                    pkg.add(dst)

        for fp in uub.FilteredDirWalkGenerator(debianpath, suffixes=['dirs']):
            package, suffix = self.split_pkg(fp)
            pkg = dirs.setdefault(package, Dirs(package))
            for row, line in self.lines(fp):
                line = line.strip('/')
                if line in pkg:
                    self.addmsg('0018-2', 'Unneeded directory %r' % (line, ),
                                fp, row)
コード例 #13
0
    def check(self, path):
        """ the real check """
        super(UniventionPackageCheck, self).check(path)

        py_files = []
        po_files = []
        for fn in uub.FilteredDirWalkGenerator(path, suffixes=('.py', '.po')):
            if fn.endswith('.py'):
                py_files.append(fn)
            if fn.endswith('.po'):
                po_files.append(fn)

        self.check_py(py_files)
        self.check_po(po_files)
コード例 #14
0
    def check(self, path: str) -> None:
        """ the real check """
        super(UniventionPackageCheck, self).check(path)

        #
        # search shell scripts and execute test
        #
        for fn in uub.FilteredDirWalkGenerator(path,
                                               suffixes=['.sh'],
                                               reHashBang=RE_HASHBANG_SHELL):
            try:
                self.tester.open(fn)
            except EnvironmentError:
                continue
            else:
                msglist = self.tester.runTests()
                self.msg.extend(msglist)
コード例 #15
0
	def check_conffiles(self, python: str) -> List[str]:
		errors = []  # type: List[str]
		header_length = len(UCR_HEADER.splitlines()) + 1
		for conffile in uub.FilteredDirWalkGenerator('conffiles'):
			with open(conffile, 'r') as fd:
				text = fd.read()

			for match in EXECUTE_TOKEN.findall(text):
				leading_lines = len(text[:text.index(match)].splitlines())
				match = match.rstrip() + '\n'  # prevent "blank line at end of file" and "blank line contains whitespace" false positives
				for error in self.flake8(python, ['-'], self.DEFAULT_IGNORE, UCR_HEADER + match):
					try:
						errno, filename, row, col, descr = error.split(' ', 4)
						row = str(int(row) - header_length + leading_lines)
					except ValueError as ex:
						# flake8 --show-source provides 2 extra lines
						self.debug('%s: %s' % (ex, error))
						continue
					errors.append(' '.join((errno, conffile, row, col, descr)))
		return errors
コード例 #16
0
    def check(self, path):
        """ the real check """
        super(UniventionPackageCheck, self).check(path)

        for fn in uub.FilteredDirWalkGenerator(
                path, ignore_suffixes=self.BINARY_SUFFIXES):
            with open(fn, 'r') as fd:
                for lnr, line in enumerate(fd, start=1):
                    origline = line
                    if UniventionPackageCheck.RE_WHITELINE.match(line):
                        continue
                    for match in RE_UNIVENTION.finditer(line):
                        found = match.group(0)
                        if UniventionPackageCheck.RE_WHITEWORD.match(found):
                            continue
                        self.debug('%s:%d: found="%s"  origline="%s"' %
                                   (fn, lnr, found, origline))
                        self.addmsg('0015-2',
                                    'univention is incorrectly spelled: %s' %
                                    found,
                                    filename=fn,
                                    line=lnr)
コード例 #17
0
	def check_conffiles(self, path: str) -> Dict[str, Any]:
		"""Analyze UCR templates below :file:`conffiles/`."""
		conffiles = {}  # type: Dict[str, Dict[str, Any]]

		confdir = os.path.join(path, 'conffiles')
		for fn in uub.FilteredDirWalkGenerator(confdir, ignore_suffixes=uub.FilteredDirWalkGenerator.BINARY_SUFFIXES):
			checks = {
				'headerfound': False,
				'variables': [],  # List[str] # Python code
				'placeholder': [],  # List[str] # @%@
				'ucrwarning': False,
				'pythonic': False,
				'preinst': False,
				'postinst': False,
				'handler': False,
				'custom_user': False,
				'custom_group': False,
			}  # type: Dict[str, Any]
			conffiles[fn] = checks

			match = self.RE_PYTHON_FNAME.match(os.path.relpath(fn, confdir))
			if match:
				checks['pythonic'] = True

			try:
				content = open(fn, 'r').read()
			except EnvironmentError:
				self.addmsg('0004-27', 'cannot open/read file', fn)
				continue
			except UnicodeDecodeError as ex:
				self.addmsg('0004-30', 'contains invalid characters', fn, ex.start)
				continue

			match = self.RE_FUNC_PREINST.search(content)
			if match:
				checks['preinst'] = True
			match = self.RE_FUNC_POSTINST.search(content)
			if match:
				checks['postinst'] = True
			match = self.RE_FUNC_HANDLER.search(content)
			if match:
				checks['handler'] = True
			match = self.RE_FUNC_CUSTOM_USER.search(content)
			if match:
				checks['custom_user'] = True
			match = self.RE_FUNC_CUSTOM_GROUP.search(content)
			if match:
				checks['custom_group'] = True

			warning_pos = 0
			for match in self.RE_UCR_PLACEHOLDER_VAR1.finditer(content):
				var = match.group(1)
				if var.startswith('BCWARNING=') or var.startswith('UCRWARNING=') or var.startswith('UCRWARNING_ASCII='):
					checks['ucrwarning'] = True
					warning_pos = warning_pos or match.start() + 1
				elif var not in checks['placeholder']:
					checks['placeholder'].append(var)
			if checks['placeholder']:
				self.debug('found UCR placeholder variables in %s\n- %s' % (fn, '\n- '.join(checks['placeholder'])))

			match = self.RE_IDENTIFIER.search(content, 0)
			if warning_pos and match:
				identifier = match.group()
				pos = match.start()
				self.debug('Identifier "%s" found at %d' % (identifier, pos))
				if warning_pos < pos:
					self.addmsg('0004-34', 'UCR warning before file type magic "%s"' % (identifier,), fn)

			#
			# subcheck: check if UCR header is present
			#
			if 'Warning: This file is auto-generated and might be overwritten by' in content and \
				'Warnung: Diese Datei wurde automatisch generiert und kann durch' in content:
				checks['headerfound'] = True

			for regEx in self.RE_UCR_VARLIST:
				for match in regEx.finditer(content):
					var = match.group(1)
					if var not in checks['variables']:
						checks['variables'].append(var)
			if checks['variables']:
				self.debug('found UCR variables in %s\n- %s' % (fn, '\n- '.join(checks['variables'])))

			if checks['headerfound']:
				#
				# subcheck: check if path in UCR header is correct
				#
				match = self.RE_UCR_HEADER_FILE.search(content)
				if match:
					fname = fn[fn.find('/conffiles/') + 10:]
					if match.group(2) != fname:
						self.addmsg('0004-1', 'Path in UCR header seems to be incorrect.\n      - template filename = /etc/univention/templates/files%s\n      - path in header    = %s' % (fname, match.group(1)), fn)

		self.debug('found conffiles: %s' % conffiles.keys())

		return conffiles
コード例 #18
0
    def check(self, path: str) -> None:
        """ the real check """
        super(UniventionPackageCheck, self).check(path)

        fnlist_joinscripts = {}

        #
        # search join scripts
        #
        for f in os.listdir(path):
            if not f[0:2].isdigit():
                continue
            fn = os.path.join(path, f)
            if f.endswith('.inst'):
                fnlist_joinscripts[fn] = CALLED
            elif f.endswith('.uinst'):
                fnlist_joinscripts[fn] = CALLED | COPIED
            else:
                continue
            self.debug('found %s' % fn)

        #
        # check if join scripts use versioning
        #
        for js in fnlist_joinscripts:
            self.check_join_script(js)

        #
        # check if join scripts are present in debian/rules || debian/*.install
        #
        found = {}  # type: Dict[str, int]
        debianpath = os.path.join(path, 'debian')
        # get all .install files
        fnlist = list(
            uub.FilteredDirWalkGenerator(debianpath, suffixes=['.install']))
        # append debian/rules
        fn_rules = os.path.join(path, 'debian', 'rules')
        fnlist.append(fn_rules)

        # Look for dh-umc-modules-install
        try:
            content = open(fn_rules, 'r').read()
        except EnvironmentError:
            self.addmsg('0001-9', 'failed to open and read file', fn_rules)
        else:
            if self.RE_DH_JOIN.search(content):
                self.debug('Detected use of univention-install-joinscript')
                try:
                    fn_control = os.path.join(path, 'debian', 'control')
                    parser = uub.ParserDebianControl(fn_control)
                except uub.UCSLintException:
                    self.debug('Errors in debian/control. Skipping here')
                else:
                    for binary_package in parser.binary_sections:
                        package = binary_package['Package']
                        for js in fnlist_joinscripts:
                            if re.match(
                                    r'^\./\d\d%s\.u?inst$' %
                                    re.escape(package), js):
                                self.debug(
                                    'univention-install-joinscript will take care of %s'
                                    % js)
                                fnlist_joinscripts[js] = 0
                                found[js] = found.get(js, 0) + 1

            if self.RE_DH_UMC.search(content):
                self.debug('Detected use of dh-umc-module-install')
                for fn in uub.FilteredDirWalkGenerator(
                        debianpath, suffixes=['.umc-modules']):
                    package = os.path.basename(fn)[:-len('.umc-modules')]
                    inst = '%s.inst' % (package, )
                    uinst = '%s.uinst' % (package, )
                    for js in fnlist_joinscripts:
                        if js.endswith(inst) or js.endswith(uinst):
                            self.debug(
                                '%s installed by dh-umc-module-install' %
                                (js, ))
                            found[js] = found.get(js, 0) + 1
                            fnlist_joinscripts[js] = 0

        for fn in fnlist:
            try:
                content = open(fn, 'r').read()
            except EnvironmentError:
                self.addmsg('0001-9', 'failed to open and read file', fn)
                continue

            for js in fnlist_joinscripts:
                name = os.path.basename(js)
                self.debug('looking for %s in %s' % (name, fn))
                if name in content:
                    self.debug('found %s in %s' % (name, fn))
                    found[js] = found.get(js, 0) + 1

        for js in fnlist_joinscripts:
            if found.get(js, 0) == 0:
                self.addmsg(
                    '0001-6',
                    'join script is not mentioned in debian/rules or *.install files',
                    js)

        #
        # check if join scripts are present in debian/*{pre,post}{inst,rm}
        #
        for f in os.listdir(os.path.join(path, 'debian')):
            if '.debhelper.' in f:
                continue

            if f.endswith('.postinst') or f == 'postinst':
                bit = CALLED
            elif f.endswith('.prerm') or f == 'prerm':
                bit = COPIED
            elif f.endswith('.postrm') or f == 'postrm':
                bit = CALLED
            else:
                continue

            fn = os.path.join(path, 'debian', f)
            self.debug('loading %s' % (fn))
            try:
                content = open(fn, 'r').read()
            except EnvironmentError:
                self.addmsg('0001-9', 'failed to open and read file', fn)
                continue

            set_e = self.RE_LINE_CONTAINS_SET_E.search(content)
            if set_e:
                self.debug('found "set -e" in %s' % fn)

            for js in fnlist_joinscripts:
                name = os.path.basename(js)
                self.debug('looking for %s in %s' % (name, fn))
                if name in content:
                    fnlist_joinscripts[js] &= ~bit
                    self.debug('found %s in %s' % (name, fn))

                    if set_e:
                        for row, line in enumerate(content.splitlines(),
                                                   start=1):
                            if name in line:
                                match = self.RE_LINE_ENDS_WITH_TRUE.search(
                                    line)
                                if not match:
                                    self.addmsg(
                                        '0001-8',
                                        'the join script %s is not called with "|| true" but "set -e" is set'
                                        % (name, ),
                                        fn,
                                        row,
                                        line=line)

        for js, missing in fnlist_joinscripts.items():
            if missing & CALLED and js.endswith('.inst'):
                self.addmsg(
                    '0001-7',
                    'Join script is not mentioned in debian/*.postinst', js)
            if missing & CALLED and js.endswith('.uinst'):
                self.addmsg(
                    '0001-17',
                    'Unjoin script seems not to be called in any postrm file',
                    js)
            if missing & COPIED and js.endswith('.uinst'):
                self.addmsg(
                    '0001-18',
                    'Unjoin script seems not to be copied in any prerm file',
                    js)
コード例 #19
0
    def check_scripts(self, path: str) -> None:
        debianpath = join(path, 'debian')
        version = self.get_debian_version(path)
        for script_path in uub.FilteredDirWalkGenerator(debianpath,
                                                        suffixes=self.SCRIPTS):
            package, suffix = self.split_pkg(script_path)

            other_scripts = self.SCRIPTS - {suffix}
            other_actions = set(action for actions in self.ACTIONS.values()
                                for action in actions) - self.ACTIONS[suffix]
            self.debug('script=%s' % suffix)
            self.debug('actions=%s' % ' '.join(sorted(self.ACTIONS[suffix])))
            self.debug('other_script=%s' % ' '.join(sorted(other_scripts)))
            self.debug('other_actions=%s' % ' '.join(sorted(other_actions)))

            with open(script_path, 'r') as script_file:
                content = script_file.read()

            for row, line in enumerate(content.splitlines(), start=1):
                if not line.startswith('#'):
                    break
                for script_name in other_scripts:
                    if script_name in line:
                        self.addmsg('0018-1',
                                    'wrong script name: %r' % (line.strip(), ),
                                    script_path,
                                    row,
                                    line=line)

            for row, line in enumerate(content.splitlines(), start=1):
                if line.startswith('#'):
                    continue
                for match in self.RE_TEST.finditer(line):
                    try:
                        actions = self.parse_test(split(
                            match.group('cond'))) & other_actions
                    except ValueError as ex:
                        self.debug('Failed %s:%d: %s in %s' %
                                   (script_path, row, ex, line))
                        continue
                    if actions:
                        self.addmsg(
                            '0018-3',
                            'Invalid actions "%s" in Debian maintainer script'
                            % (','.join(actions), ),
                            script_path,
                            row,
                            line=line)

                for match in self.RE_COMPARE_VERSIONS.finditer(line):
                    ver_a, op, ver_b = match.groups()
                    for arg in (ver_a, ver_b):
                        if self.RE_ARG2.match(arg):
                            continue
                        if not RE_DEBIAN_PACKAGE_VERSION.match(arg):
                            self.debug("%s:%d: Unknown argument %r" %
                                       (script_path, row, arg))
                            continue

                        ver = Version(arg)
                        self.debug("%s << %s?" % (ver, version))
                        if ver.numeric and version.numeric and ver.numeric[
                                0] < version.numeric[0] - 1:
                            self.addmsg(
                                '0018-5',
                                'Maintainer script contains old upgrade code for %s << %s'
                                % (ver, version), script_path, row,
                                match.start(0), line)

            for row, col, match in uub.line_regexp(content, self.RE_CASE):
                for cases in match.group('cases').split(';;'):
                    cases = cases.lstrip('\t\n\r (')
                    cases = cases.split(')', 1)[0]
                    actions = set(action for case in cases.split('|')
                                  for action in split(case)) & other_actions
                    if actions:
                        self.addmsg(
                            '0018-3',
                            'Invalid actions "%s" in Debian maintainer script'
                            % (','.join(actions), ),
                            script_path,
                            row,
                            col,
                            line=line)
コード例 #20
0
    def check(self, path):
        """ the real check """
        super(UniventionPackageCheck, self).check(path)

        check_files = []

        # check if copyright file is missing
        fn = os.path.join(path, 'debian', 'copyright')
        if not os.path.exists(fn):
            self.addmsg('0010-5', 'file is missing', filename=fn)

        # looking for files below debian/
        for f in os.listdir(os.path.join(path, 'debian')):
            fn = os.path.join(path, 'debian', f)
            if f.endswith('.preinst') or f.endswith('.postinst') or f.endswith('.prerm') or f.endswith('.postrm') or \
              f in [ 'preinst', 'postinst', 'prerm', 'postrm', 'copyright' ]:
                check_files.append(fn)

        # looking for python files
        for fn in uub.FilteredDirWalkGenerator(path,
                                               reHashBang=re.compile('^#!'),
                                               readSize=100):
            check_files.append(fn)

        # Copyright (C) 2004, 2005, 2006 Univention GmbH
        # Copyright 2008 by
        reCopyrightVersion = re.compile(
            'Copyright(\s+\(C\))?\s+([0-9, -]+)\s+(by|Univention\s+GmbH)')

        # check files for copyright
        for fn in check_files:
            try:
                content = open(fn, 'r').read()
            except IOError:
                self.addmsg('0010-1',
                            'failed to open and read file',
                            filename=fn)
                continue
            self.debug('testing %s' % fn)

            if 'temporary wrapper script for' in content and 'Generated by ltmain.sh' in content:
                continue

            copyright_strings = (
                'under the terms of the GNU Affero General Public License version 3',
                'Binary versions of this',
                'provided by Univention to you as',
                'cryptographic keys etc. are subject to a license agreement between',
                'the terms of the GNU AGPL V3',
                'You should have received a copy of the GNU Affero General Public',
            )

            for teststr in copyright_strings:
                if not teststr in content:
                    self.debug('Missing copyright string: %s' % teststr)
                    self.addmsg('0010-2',
                                'file contains no copyright text block',
                                filename=fn)
                    break
            else:
                # copyright text block is present - lets check if it's outdated
                match = reCopyrightVersion.search(content)
                if not match:
                    self.addmsg('0010-4',
                                'cannot find copyright line containing year',
                                filename=fn)
                else:
                    years = match.group(2)
                    current_year = str(time.localtime()[0])
                    if not current_year in years:
                        self.debug('Current year=%s  years="%s"' %
                                   (current_year, years))
                        self.addmsg('0010-3',
                                    'copyright line seems to be outdated',
                                    filename=fn)
コード例 #21
0
    def check(self, path):
        """ the real check """
        super(UniventionPackageCheck, self).check(path)

        fnlist_joinscripts = {}

        #
        # search join scripts
        #
        for f in os.listdir(path):
            if f.endswith('.inst') and f[0:2].isdigit():
                fn = os.path.join(path, f)
                fnlist_joinscripts[fn] = False
                self.debug('found %s' % fn)

        #
        # check if join scripts use versioning
        #
        for js in fnlist_joinscripts.keys():
            self.check_join_script(js)

        #
        # check if join scripts are present in debian/rules || debian/*.install
        #
        found = {}
        debianpath = os.path.join(path, 'debian')
        # get all .install files
        fnlist = list(
            uub.FilteredDirWalkGenerator(debianpath, suffixes=['.install']))
        # append debian/rules
        fn_rules = os.path.join(path, 'debian', 'rules')
        fnlist.append(fn_rules)

        # Look for dh-umc-modules-install
        try:
            content = open(fn_rules, 'r').read()
        except IOError:
            self.addmsg('0001-9', 'failed to open and read file', fn_rules)
        else:
            if UniventionPackageCheck.RE_DH_JOIN.search(content):
                self.debug('Detected use of univention-install-joinscript')
                try:
                    fn_control = os.path.join(path, 'debian', 'control')
                    parser = uub.ParserDebianControl(fn_control)
                except uub.UCSLintException:
                    self.debug('Errors in debian/control. Skipping here')
                else:
                    for binary_package in parser.binary_sections:
                        package = binary_package.get('Package')
                        for js in fnlist_joinscripts.keys():
                            if re.match(
                                    r'^\./\d\d%s.inst$' % re.escape(package),
                                    js):
                                self.debug(
                                    'univention-install-joinscript will take care of %s'
                                    % js)
                                fnlist_joinscripts[js] = True
                                found[js] = found.get(js, 0) + 1
            if UniventionPackageCheck.RE_DH_UMC.search(content):
                self.debug('Detected use of dh-umc-module-install')
                for fn in uub.FilteredDirWalkGenerator(
                        debianpath, suffixes=['.umc-modules']):
                    package = os.path.basename(fn)[:-len('.umc-modules')]
                    inst = '%s.inst' % (package, )
                    for js in fnlist_joinscripts.keys():
                        if js.endswith(inst):
                            self.debug(
                                '%s installed by dh-umc-module-install' %
                                (js, ))
                            found[js] = found.get(js, 0) + 1
                            fnlist_joinscripts[js] = True

        for fn in fnlist:
            try:
                content = open(fn, 'r').read()
            except IOError:
                self.addmsg('0001-9', 'failed to open and read file', fn)

            for js in fnlist_joinscripts.keys():
                name = os.path.basename(js)
                self.debug('looking for %s in %s' % (name, fn))
                if name in content:
                    self.debug('found %s in %s' % (name, fn))
                    found[js] = found.get(js, 0) + 1

        for js in fnlist_joinscripts.keys():
            if found.get(js, 0) == 0:
                self.addmsg(
                    '0001-6',
                    'join script is not mentioned in debian/rules or *.install files',
                    js)

        #
        # check if join scripts are present in debian/*postinst
        #
        for f in os.listdir(os.path.join(path, 'debian')):
            if (f.endswith('.postinst') and
                    not f.endswith('.debhelper.postinst')) or (f
                                                               == 'postinst'):
                fn = os.path.join(path, 'debian', f)
                self.debug('loading %s' % (fn))
                try:
                    content = open(fn, 'r').read()
                except IOError:
                    self.addmsg('0001-9', 'failed to open and read file', fn)
                    continue

                for js in fnlist_joinscripts.keys():
                    name = os.path.basename(js)
                    self.debug('looking for %s in %s' % (name, fn))
                    if name in content:
                        fnlist_joinscripts[js] = True
                        self.debug('found %s in %s' % (name, fn))

                        match = UniventionPackageCheck.RE_LINE_CONTAINS_SET_E.search(
                            content)
                        if match:
                            self.debug('found "set -e" in %s' % fn)
                            for line in content.splitlines():
                                if name in line:
                                    match = UniventionPackageCheck.RE_LINE_ENDS_WITH_TRUE.search(
                                        line)
                                    if not match:
                                        self.addmsg(
                                            '0001-8',
                                            'the join script %s is not called with "|| true" but "set -e" is set'
                                            % (name, ), fn)

        for js, found in fnlist_joinscripts.items():
            if not found:
                self.addmsg(
                    '0001-7',
                    'Join script is not mentioned in debian/*.postinst', js)
コード例 #22
0
    def check(self, path: str) -> None:
        """ the real check """
        super(UniventionPackageCheck, self).check(path)

        check_files = []  # type: List[str]

        # check if copyright file is missing
        fn = os.path.join(path, 'debian', 'copyright')
        try:
            with open(fn, 'r') as stream:
                line = stream.readline().rstrip()
                if line != DEP5:
                    self.addmsg('0010-6', 'not machine-readable DEP-5', fn)
        except EnvironmentError:
            self.addmsg('0010-5', 'file is missing', fn)

        # looking for files below debian/
        for f in os.listdir(os.path.join(path, 'debian')):
            fn = os.path.join(path, 'debian', f)
            if f.endswith('.preinst') or f.endswith('.postinst') or f.endswith('.prerm') or f.endswith('.postrm') or \
             f in ['preinst', 'postinst', 'prerm', 'postrm', 'copyright']:
                check_files.append(fn)

        # looking for python files
        for fn in uub.FilteredDirWalkGenerator(path,
                                               reHashBang=RE_HASHBANG,
                                               readSize=100):
            check_files.append(fn)

        # check files for copyright
        for fn in check_files:
            try:
                content = open(fn, 'r').read()
            except (EnvironmentError, UnicodeDecodeError):
                self.addmsg('0010-1', 'failed to open and read file', fn)
                continue
            self.debug('testing %s' % fn)

            if RE_SKIP.search(content):
                continue

            copyright_strings = (
                'under the terms of the GNU Affero General Public License version 3',
                'Binary versions of this',
                'provided by Univention to you as',
                'cryptographic keys etc. are subject to a license agreement between',
                'the terms of the GNU AGPL V3',
                'You should have received a copy of the GNU Affero General Public',
            )

            for teststr in copyright_strings:
                if teststr not in content:
                    self.debug('Missing copyright string: %s' % teststr)
                    self.addmsg('0010-2',
                                'file contains no copyright text block', fn)
                    break
            else:
                # copyright text block is present - lets check if it's outdated
                match = RE_COPYRIGHT_VERSION.search(content)
                if not match:
                    self.addmsg('0010-4',
                                'cannot find copyright line containing year',
                                fn)
                else:
                    years = match.group(1)
                    current_year = str(time.localtime()[0])
                    if current_year not in years:
                        self.debug('Current year=%s  years="%s"' %
                                   (current_year, years))
                        self.addmsg('0010-3',
                                    'copyright line seems to be outdated', fn)