diff options
Diffstat (limited to 'SpecCheck.py')
-rw-r--r-- | SpecCheck.py | 845 |
1 files changed, 0 insertions, 845 deletions
diff --git a/SpecCheck.py b/SpecCheck.py deleted file mode 100644 index 6b74e7f..0000000 --- a/SpecCheck.py +++ /dev/null @@ -1,845 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################# -# File : SpecCheck.py -# Package : rpmlint -# Author : Frederic Lepied -# Created on : Thu Oct 7 17:06:14 1999 -# Purpose : check the spec file of a source rpm. -############################################################################# - -import re -import sys -try: - from urlparse import urlparse -except ImportError: # Python 3 - from urllib.parse import urlparse - -import rpm - -import AbstractCheck -import Config -from Filter import addDetails, printError, printWarning -import Pkg -from TagsCheck import VALID_GROUPS - -# Don't check for hardcoded library paths in biarch packages -DEFAULT_BIARCH_PACKAGES = '^(gcc|glibc)' - -# Don't check for hardcoded library paths in packages which can have -# their noarch files in /usr/lib/<package>/*, or packages that can't -# be installed on biarch systems -DEFAULT_HARDCODED_LIB_PATH_EXCEPTIONS = r'/lib/(modules|cpp|perl5|rpm|hotplug|firmware|systemd)($|[\s/,])' - - -def re_tag_compile(tag): - r = r"^%s\s*:\s*(\S.*?)\s*$" % tag - return re.compile(r, re.IGNORECASE) - - -patch_regex = re_tag_compile(r'Patch(\d*)') -applied_patch_regex = re.compile(r"^%patch(\d*)") -applied_patch_p_regex = re.compile(r"\s-P\s+(\d+)\b") -applied_patch_pipe_regex = re.compile(r'\s%\{PATCH(\d+)\}\s*\|\s*(%\{?__)?patch\b') -applied_patch_i_regex = re.compile(r"(?:%\{?__)?patch\}?.*?\s+(?:<|-i)\s+%\{PATCH(\d+)\}") -source_dir_regex = re.compile(r"^[^#]*(\$RPM_SOURCE_DIR|%{?_sourcedir}?)") -obsolete_tags_regex = re_tag_compile(r'(?:Serial|Copyright)') -buildroot_regex = re_tag_compile('BuildRoot') -prefix_regex = re_tag_compile('Prefix') -packager_regex = re_tag_compile('Packager') -buildarch_regex = re_tag_compile('BuildArch(?:itectures)?') -buildprereq_regex = re_tag_compile('BuildPreReq') -prereq_regex = re_tag_compile(r'PreReq(\(.*\))') - -make_check_regex = re.compile(r'(^|\s|%{?__)make}?\s+(check|test)') -rm_regex = re.compile(r'(^|\s)((.*/)?rm|%{?__rm}?) ') -rpm_buildroot_regex = re.compile(r'^[^#]*(?:(\\\*)\${?RPM_BUILD_ROOT}?|(%+){?buildroot}?)') -configure_libdir_spec_regex = re.compile(r'ln |\./configure[^#]*--libdir=(\S+)[^#]*') -lib_package_regex = re.compile(r'^%package.*\Wlib') -ifarch_regex = re.compile(r'^\s*%ifn?arch\s') -if_regex = re.compile(r'^\s*%if\s') -endif_regex = re.compile(r'^\s*%endif\b') -biarch_package_regex = re.compile(DEFAULT_BIARCH_PACKAGES) -hardcoded_lib_path_exceptions_regex = re.compile(Config.getOption('HardcodedLibPathExceptions', DEFAULT_HARDCODED_LIB_PATH_EXCEPTIONS)) -use_utf8 = Config.getOption('UseUTF8', Config.USEUTF8_DEFAULT) -libdir_regex = re.compile(r'%{?_lib(?:dir)?\}?\b') -section_regexs = dict( - ([x, re.compile('^%' + x + r'(?:\s|$)')] - for x in ('build', 'changelog', 'check', 'clean', 'description', 'files', - 'install', 'package', 'prep') + Pkg.RPM_SCRIPTLETS)) -deprecated_grep_regex = re.compile(r'\b[ef]grep\b') - -# Only check for /lib, /usr/lib, /usr/X11R6/lib -# TODO: better handling of X libraries and modules. -hardcoded_library_paths = '(/lib|/usr/lib|/usr/X11R6/lib/(?!([^/]+/)+)[^/]*\\.([oa]|la|so[0-9.]*))' -hardcoded_library_path_regex = re.compile(r'^[^#]*((^|\s+|\.\./\.\.|\${?RPM_BUILD_ROOT}?|%{?buildroot}?|%{?_prefix}?)' + hardcoded_library_paths + r'(?=[\s;/])([^\s,;]*))') - -# Requires(pre,post) is broken in some rpm versions, see -# https://bugzilla.redhat.com/118780 and bugs linked to that one. -scriptlet_requires_regex = re.compile(r'^(PreReq|Requires)\([^\)]*,', re.IGNORECASE) - -DEFINE_RE = r'(^|\s)%(define|global)\s+' -depscript_override_regex = re.compile(DEFINE_RE + r'__find_(requires|provides)\s') -depgen_disable_regex = re.compile(DEFINE_RE + r'_use_internal_dependency_generator\s+0') -patch_fuzz_override_regex = re.compile(DEFINE_RE + r'_default_patch_fuzz\s+(\d+)') - -# See https://bugzilla.redhat.com/488146 for details -indent_spaces_regex = re.compile('( \t|(^|\t)([^\t]{8})*[^\t]{4}[^\t]?([^\t][^\t.!?]|[^\t]?[.!?] ) )') - -requires_regex = re.compile(r'^(?:Build)?(?:Pre)?Req(?:uires)?(?:\([^\)]+\))?:\s*(.*)', re.IGNORECASE) -provides_regex = re.compile(r'^Provides(?:\([^\)]+\))?:\s*(.*)', re.IGNORECASE) -obsoletes_regex = re.compile(r'^Obsoletes:\s*(.*)', re.IGNORECASE) -conflicts_regex = re.compile(r'^(?:Build)?Conflicts:\s*(.*)', re.IGNORECASE) - -compop_regex = re.compile(r'[<>=]') - -setup_regex = re.compile(r'%setup\b') # intentionally no whitespace before! -setup_q_regex = re.compile(r' -[A-Za-z]*q') -setup_t_regex = re.compile(r' -[A-Za-z]*T') -setup_ab_regex = re.compile(r' -[A-Za-z]*[ab]') -autosetup_regex = re.compile(r'^\s*%autosetup(\s.*|$)') -autosetup_n_regex = re.compile(r' -[A-Za-z]*N') -autopatch_regex = re.compile(r'^\s*%autopatch(?:\s|$)') - -filelist_regex = re.compile(r'\s+-f\s+\S+') -pkgname_regex = re.compile(r'\s+(?:-n\s+)?(\S+)') -tarball_regex = re.compile(r'\.(?:t(?:ar|[glx]z|bz2?)|zip)\b', re.IGNORECASE) - -UNICODE_NBSP = u'\xa0' - - -def unversioned(deps): - '''Yield unversioned dependency names from the given list.''' - for dep in deps: - if not dep[1]: - yield dep[0] - - -def contains_buildroot(line): - '''Check if the given line contains use of rpm buildroot.''' - res = rpm_buildroot_regex.search(line) - if res and \ - (not res.group(1) or len(res.group(1)) % 2 == 0) and \ - (not res.group(2) or len(res.group(2)) % 2 != 0): - return True - return False - - -class SpecCheck(AbstractCheck.AbstractCheck): - - def __init__(self): - AbstractCheck.AbstractCheck.__init__(self, "SpecCheck") - self._spec_file = None - self._spec_name = None - - def check_source(self, pkg): - wrong_spec = False - - # lookup spec file - for fname, pkgfile in pkg.files().items(): - if fname.endswith('.spec'): - self._spec_file = pkgfile.path - self._spec_name = pkgfile.name - if fname == pkg.name + ".spec": - wrong_spec = False - break - else: - wrong_spec = True - if not self._spec_file: - printError(pkg, "no-spec-file") - else: - if wrong_spec: - printError(pkg, "invalid-spec-name") - - # check content of spec file - self.check_spec(pkg, self._spec_file) - - def check_spec(self, pkg, spec_file, spec_lines=None): - self._spec_file = spec_file - spec_only = isinstance(pkg, Pkg.FakePkg) - if not spec_lines: - spec_lines = Pkg.readlines(spec_file) - patches = {} - applied_patches = [] - applied_patches_ifarch = [] - patches_auto_applied = False - source_dir = False - buildroot = False - configure_linenum = None - configure_cmdline = "" - mklibname = False - is_lib_pkg = False - if_depth = 0 - ifarch_depth = -1 - current_section = 'package' - buildroot_clean = {'clean': False, 'install': False} - depscript_override = False - depgen_disabled = False - patch_fuzz_override = False - indent_spaces = 0 - indent_tabs = 0 - section = {} - # None == main package - current_package = None - package_noarch = {} - - is_utf8 = False - if self._spec_file and use_utf8: - if Pkg.is_utf8(self._spec_file): - is_utf8 = True - else: - printError(pkg, "non-utf8-spec-file", - self._spec_name or self._spec_file) - - # gather info from spec lines - - pkg.current_linenum = 0 - - nbsp = UNICODE_NBSP if is_utf8 else chr(0xA0) - do_unicode = is_utf8 and sys.version_info[0] <= 2 - - for line in spec_lines: - - pkg.current_linenum += 1 - - if do_unicode: - line = unicode(line, "utf-8", "replace") # noqa false positive - - char = line.find(nbsp) - if char != -1: - printWarning(pkg, "non-break-space", "line %s, char %d" % - (pkg.current_linenum, char)) - - section_marker = False - for sec, regex in section_regexs.items(): - res = regex.search(line) - if res: - current_section = sec - section_marker = True - section[sec] = section.get(sec, 0) + 1 - if sec in ('package', 'files'): - rest = filelist_regex.sub('', line[res.end() - 1:]) - res = pkgname_regex.search(rest) - if res: - current_package = res.group(1) - else: - current_package = None - break - - if section_marker: - - if not is_lib_pkg and lib_package_regex.search(line): - is_lib_pkg = True - - continue - - if (current_section in Pkg.RPM_SCRIPTLETS + ('prep', 'build') and - contains_buildroot(line)): - printWarning(pkg, 'rpm-buildroot-usage', '%' + current_section, - line[:-1].strip()) - - if make_check_regex.search(line) and current_section not in \ - ('check', 'changelog', 'package', 'description'): - printWarning(pkg, 'make-check-outside-check-section', - line[:-1]) - - if current_section in buildroot_clean and \ - not buildroot_clean[current_section] and \ - contains_buildroot(line) and rm_regex.search(line): - buildroot_clean[current_section] = True - - if ifarch_regex.search(line): - if_depth = if_depth + 1 - ifarch_depth = if_depth - - if if_regex.search(line): - if_depth = if_depth + 1 - - if setup_regex.match(line): - if not setup_q_regex.search(line): - # Don't warn if there's a -T without -a or -b - if setup_t_regex.search(line): - if setup_ab_regex.search(line): - printWarning(pkg, 'setup-not-quiet') - else: - printWarning(pkg, 'setup-not-quiet') - if current_section != 'prep': - printWarning(pkg, 'setup-not-in-prep') - elif autopatch_regex.search(line): - patches_auto_applied = True - if current_section != 'prep': - printWarning(pkg, '%autopatch-not-in-prep') - else: - res = autosetup_regex.search(line) - if res: - if not autosetup_n_regex.search(res.group(1)): - patches_auto_applied = True - if current_section != 'prep': - printWarning(pkg, '%autosetup-not-in-prep') - - if endif_regex.search(line): - if ifarch_depth == if_depth: - ifarch_depth = -1 - if_depth = if_depth - 1 - - res = applied_patch_regex.search(line) - if res: - pnum = res.group(1) or 0 - for tmp in applied_patch_p_regex.findall(line) or [pnum]: - pnum = int(tmp) - applied_patches.append(pnum) - if ifarch_depth > 0: - applied_patches_ifarch.append(pnum) - else: - res = applied_patch_pipe_regex.search(line) - if res: - pnum = int(res.group(1)) - applied_patches.append(pnum) - if ifarch_depth > 0: - applied_patches_ifarch.append(pnum) - else: - res = applied_patch_i_regex.search(line) - if res: - pnum = int(res.group(1)) - applied_patches.append(pnum) - if ifarch_depth > 0: - applied_patches_ifarch.append(pnum) - if not res and not source_dir: - res = source_dir_regex.search(line) - if res: - source_dir = True - printError(pkg, "use-of-RPM_SOURCE_DIR") - - if configure_linenum: - if configure_cmdline[-1] == "\\": - configure_cmdline = configure_cmdline[:-1] + line.strip() - else: - res = configure_libdir_spec_regex.search(configure_cmdline) - if not res: - # Hack to get the correct (start of ./configure) line - # number displayed: - real_linenum = pkg.current_linenum - pkg.current_linenum = configure_linenum - printWarning(pkg, "configure-without-libdir-spec") - pkg.current_linenum = real_linenum - elif res.group(1): - res = re.match(hardcoded_library_paths, res.group(1)) - if res: - printError(pkg, "hardcoded-library-path", - res.group(1), "in configure options") - configure_linenum = None - - hashPos = line.find("#") - - if current_section != 'changelog': - cfgPos = line.find('./configure') - if cfgPos != -1 and (hashPos == -1 or hashPos > cfgPos): - # store line where it started - configure_linenum = pkg.current_linenum - configure_cmdline = line.strip() - - res = hardcoded_library_path_regex.search(line) - if current_section != 'changelog' and res and not \ - (biarch_package_regex.match(pkg.name) or - hardcoded_lib_path_exceptions_regex.search( - res.group(1).lstrip())): - printError(pkg, "hardcoded-library-path", "in", - res.group(1).lstrip()) - - if '%mklibname' in line: - mklibname = True - - if current_section == 'package': - - # Would be cleaner to get sources and patches from the - # specfile parsed in Python (see below), but we want to - # catch %ifarch'd etc ones as well, and also catch these when - # the specfile is not parseable. - - res = patch_regex.search(line) - if res: - pnum = int(res.group(1) or 0) - patches[pnum] = res.group(2) - - res = obsolete_tags_regex.search(line) - if res: - printWarning(pkg, "obsolete-tag", res.group(1)) - - res = buildroot_regex.search(line) - if res: - buildroot = True - if res.group(1).startswith('/'): - printWarning(pkg, 'hardcoded-path-in-buildroot-tag', - res.group(1)) - - res = buildarch_regex.search(line) - if res: - if res.group(1) != "noarch": - printError(pkg, - 'buildarch-instead-of-exclusivearch-tag', - res.group(1)) - else: - package_noarch[current_package] = True - - res = packager_regex.search(line) - if res: - printWarning(pkg, 'hardcoded-packager-tag', res.group(1)) - - res = prefix_regex.search(line) - if res: - if not res.group(1).startswith('%'): - printWarning(pkg, 'hardcoded-prefix-tag', res.group(1)) - - res = prereq_regex.search(line) - if res: - printError(pkg, 'prereq-use', res.group(2)) - - res = buildprereq_regex.search(line) - if res: - printError(pkg, 'buildprereq-use', res.group(1)) - - if scriptlet_requires_regex.search(line): - printError(pkg, 'broken-syntax-in-scriptlet-requires', - line.strip()) - - res = requires_regex.search(line) - if res: - reqs = Pkg.parse_deps(res.group(1)) - for req in unversioned(reqs): - if compop_regex.search(req): - printWarning(pkg, - 'comparison-operator-in-deptoken', - req) - - res = provides_regex.search(line) - if res: - provs = Pkg.parse_deps(res.group(1)) - for prov in unversioned(provs): - if not prov.startswith('/'): - printWarning(pkg, 'unversioned-explicit-provides', - prov) - if compop_regex.search(prov): - printWarning(pkg, - 'comparison-operator-in-deptoken', - prov) - - res = obsoletes_regex.search(line) - if res: - obses = Pkg.parse_deps(res.group(1)) - for obs in unversioned(obses): - if not obs.startswith('/'): - printWarning(pkg, 'unversioned-explicit-obsoletes', - obs) - if compop_regex.search(obs): - printWarning(pkg, - 'comparison-operator-in-deptoken', - obs) - - res = conflicts_regex.search(line) - if res: - confs = Pkg.parse_deps(res.group(1)) - for conf in unversioned(confs): - if compop_regex.search(conf): - printWarning(pkg, - 'comparison-operator-in-deptoken', - conf) - - if current_section == 'changelog': - for match in AbstractCheck.macro_regex.findall(line): - res = re.match('%+', match) - if len(res.group(0)) % 2: - printWarning(pkg, 'macro-in-%changelog', match) - else: - if not depscript_override: - depscript_override = \ - depscript_override_regex.search(line) is not None - if not depgen_disabled: - depgen_disabled = \ - depgen_disable_regex.search(line) is not None - if not patch_fuzz_override: - patch_fuzz_override = \ - patch_fuzz_override_regex.search(line) is not None - - if current_section == 'files': - # TODO: check scriptlets for these too? - if package_noarch.get(current_package) or \ - (current_package not in package_noarch and - package_noarch.get(None)): - res = libdir_regex.search(line) - if res: - pkgname = current_package - if pkgname is None: - pkgname = '(main package)' - printWarning(pkg, 'libdir-macro-in-noarch-package', - pkgname, line.rstrip()) - - if not indent_tabs and '\t' in line: - indent_tabs = pkg.current_linenum - if not indent_spaces and indent_spaces_regex.search(line): - indent_spaces = pkg.current_linenum - - # Check if egrep or fgrep is used - if current_section not in \ - ('package', 'changelog', 'description', 'files'): - greps = deprecated_grep_regex.findall(line) - if greps: - printWarning(pkg, "deprecated-grep", greps) - - # If not checking spec file only, we're checking one inside a - # SRPM -> skip this check to avoid duplicate warnings (#167) - if spec_only and VALID_GROUPS and \ - line.lower().startswith("group:"): - group = line[6:].strip() - if group not in VALID_GROUPS: - printWarning(pkg, 'non-standard-group', group) - - # Test if there are macros in comments - if hashPos != -1 and \ - (hashPos == 0 or line[hashPos - 1] in (" ", "\t")): - for match in AbstractCheck.macro_regex.findall( - line[hashPos + 1:]): - res = re.match('%+', match) - if len(res.group(0)) % 2: - printWarning(pkg, 'macro-in-comment', match) - - # Last line read is not useful after this point - pkg.current_linenum = None - - for sect in (x for x in buildroot_clean if not buildroot_clean[x]): - printWarning(pkg, 'no-cleaning-of-buildroot', '%' + sect) - - if not buildroot: - printWarning(pkg, 'no-buildroot-tag') - - for sec in ('prep', 'build', 'install', 'clean'): - if not section.get(sec): - printWarning(pkg, 'no-%%%s-section' % sec) - for sec in ('changelog',): - # prep, build, install, clean, check prevented by rpmbuild 4.4 - if section.get(sec, 0) > 1: - printWarning(pkg, 'more-than-one-%%%s-section' % sec) - - if is_lib_pkg and not mklibname: - printError(pkg, 'lib-package-without-%mklibname') - - if depscript_override and not depgen_disabled: - printWarning(pkg, 'depscript-without-disabling-depgen') - - if patch_fuzz_override: - printWarning(pkg, 'patch-fuzz-is-changed') - - if indent_spaces and indent_tabs: - pkg.current_linenum = max(indent_spaces, indent_tabs) - printWarning(pkg, 'mixed-use-of-spaces-and-tabs', - '(spaces: line %d, tab: line %d)' % - (indent_spaces, indent_tabs)) - pkg.current_linenum = None - - # process gathered info - if not patches_auto_applied: - for pnum, pfile in patches.items(): - if pnum in applied_patches_ifarch: - printWarning(pkg, "%ifarch-applied-patch", - "Patch%d:" % pnum, pfile) - if pnum not in applied_patches: - printWarning(pkg, "patch-not-applied", - "Patch%d:" % pnum, pfile) - - # Rest of the checks require a real spec file - if not self._spec_file: - return - - # We'd like to parse the specfile only once using python bindings, - # but it seems errors from rpmlib get logged to stderr and we can't - # capture and print them nicely, so we do it once each way :P - - out = Pkg.getstatusoutput( - ('rpm', '-q', '--qf=', '-D', '_sourcedir %s' % pkg.dirName(), '--specfile', self._spec_file)) - parse_error = False - for line in out[1].splitlines(): - # No such file or dir hack: https://bugzilla.redhat.com/487855 - if 'No such file or directory' not in line: - parse_error = True - printError(pkg, 'specfile-error', line) - - if not parse_error: - # grab sources and patches from parsed spec object to get - # them with macros expanded for URL checking - - spec_obj = None - rpm.addMacro('_sourcedir', pkg.dirName()) - try: - ts = rpm.TransactionSet() - spec_obj = ts.parseSpec(self._spec_file) - except (ValueError, rpm.error): - # errors logged above already - pass - rpm.delMacro('_sourcedir') - if spec_obj: - try: - # rpm < 4.8.0 - sources = spec_obj.sources() - except TypeError: - # rpm >= 4.8.0 - sources = spec_obj.sources - for src in sources: - (url, num, flags) = src - (scheme, netloc) = urlparse(url)[0:2] - if flags & 1: # rpmspec.h, rpm.org ticket #123 - srctype = "Source" - else: - srctype = "Patch" - tag = '%s%s' % (srctype, num) - if scheme and netloc: - info = self.check_url(pkg, tag, url) - if not info or not hasattr(pkg, 'files'): - continue - clen = info.get("Content-Length") - if clen is not None: - clen = int(clen) - cmd5 = info.get("Content-MD5") - if cmd5 is not None: - cmd5 = cmd5.lower() - if clen is not None or cmd5 is not None: - # Not using path from urlparse results to match how - # rpm itself parses the basename. - pkgfile = pkg.files().get(url.split("/")[-1]) - if pkgfile: - if clen is not None and pkgfile.size != clen: - printWarning(pkg, 'file-size-mismatch', - '%s = %s, %s = %s' % - (pkgfile.name, pkgfile.size, - url, clen)) - # pkgfile.md5 could be some other digest than - # MD5, treat as MD5 only if it's 32 chars long - if cmd5 and len(pkgfile.md5) == 32 \ - and pkgfile.md5 != cmd5: - printWarning(pkg, 'file-md5-mismatch', - '%s = %s, %s = %s' % - (pkgfile.name, pkgfile.md5, - url, cmd5)) - elif srctype == "Source" and tarball_regex.search(url): - printWarning(pkg, 'invalid-url', '%s:' % tag, url) - - -# Create an object to enable the auto registration of the test -check = SpecCheck() - -# Add information about checks -addDetails( -'no-spec-file', -'''No spec file was specified in your RPM building. Please specify a valid -SPEC file to build a valid RPM package.''', - -'invalid-spec-name', -'''The spec file name (without the .spec suffix) must match the package name -("Name:" tag). Either rename your package or the specfile.''', - -'non-utf8-spec-file', -'''The character encoding of the spec file is not UTF-8. Convert it for -example using iconv(1).''', - -'use-of-RPM_SOURCE_DIR', -'''You use $RPM_SOURCE_DIR or %{_sourcedir} in your spec file. If you have to -use a directory for building, use $RPM_BUILD_ROOT instead.''', - -'patch-not-applied', -'''A patch is included in your package but was not applied. Refer to the -patches documentation to see what's wrong.''', - -'obsolete-tag', -'''The following tags are obsolete: Copyright and Serial. They must -be replaced by License and Epoch respectively.''', - -'deprecated-grep', -'''Direct use of grep as egrep or fgrep is deprecated in GNU grep and -historical in POSIX, use grep -E and grep -F instead.''', - -'no-buildroot-tag', -'''The BuildRoot tag isn't used in your spec. It must be used in order to -allow building the package as non root on some systems. For some rpm versions -(e.g. rpm.org >= 4.6) the BuildRoot tag is not necessary in specfiles and is -ignored by rpmbuild; if your package is only going to be built with such rpm -versions you can ignore this warning.''', - -'hardcoded-path-in-buildroot-tag', -'''A path is hardcoded in your Buildroot tag. It should be replaced -by something like %{_tmppath}/%{name}-%{version}-build.''', - -'hardcoded-packager-tag', -'''The Packager tag is hardcoded in your spec file. It should be removed, so -as to use rebuilder's own defaults.''', - -'buildarch-instead-of-exclusivearch-tag', -'''Use ExclusiveArch instead of BuildArch (or BuildArchitectures) -to restrict build on some specific architectures. -Only use BuildArch with noarch''', - -'hardcoded-prefix-tag', -'''The Prefix tag is hardcoded in your spec file. It should be removed, so as -to allow package relocation.''', - -'hardcoded-library-path', -'''A library path is hardcoded to one of the following paths: /lib, -/usr/lib. It should be replaced by something like /%{_lib} or %{_libdir}.''', - -'configure-without-libdir-spec', -'''A configure script is run without specifying the libdir. configure -options must be augmented with something like --libdir=%{_libdir} whenever -the script supports it.''', - -'no-%prep-section', -'''The spec file does not contain a %prep section. Even if some packages don't -directly need it, section markers may be overridden in rpm's configuration -to provide additional "under the hood" functionality. Add the section, even -if empty.''', - -'no-%build-section', -'''The spec file does not contain a %build section. Even if some packages -don't directly need it, section markers may be overridden in rpm's -configuration to provide additional "under the hood" functionality, such as -injection of automatic -debuginfo subpackages. Add the section, even if -empty.''', - -'no-%install-section', -'''The spec file does not contain an %install section. Even if some packages -don't directly need it, section markers may be overridden in rpm's -configuration to provide additional "under the hood" functionality. Add the -section, even if empty.''', - -'no-%clean-section', -'''The spec file doesn't contain a %clean section to remove the files installed -by the %install section.''', - -'more-than-one-%changelog-section', -'''The spec file unnecessarily contains more than one %changelog section; -remove the extra ones.''', - -'lib-package-without-%mklibname', -'''The package name must be built using %mklibname to allow lib64 and lib32 -coexistence.''', - -'%ifarch-applied-patch', -'''A patch is applied inside an %ifarch block. Patches must be applied -on all architectures and may contain necessary configure and/or code -patch to be effective only on a given arch.''', - -'prereq-use', -'''The use of PreReq is deprecated. In the majority of cases, a plain Requires -is enough and the right thing to do. Sometimes Requires(pre), Requires(post), -Requires(preun) and/or Requires(postun) can also be used instead of PreReq.''', - -'buildprereq-use', -'''The use of BuildPreReq is deprecated, build dependencies are always required -before a package can be built. Use plain BuildRequires instead.''', - -'broken-syntax-in-scriptlet-requires', -'''Comma separated context marked dependencies are silently broken in some -versions of rpm. One way to work around it is to split them into several ones, -eg. replace "Requires(post,preun): foo" with "Requires(post): foo" and -"Requires(preun): foo".''', - -'setup-not-in-prep', -'''The %setup macro should only be used within the %prep section because it may -not expand to anything outside of it and can break the build in unpredictable -ways.''', - -'setup-not-quiet', -'''Use the -q option to the %setup macro to avoid useless build output from -unpacking the sources.''', - -'no-cleaning-of-buildroot', -'''You should clean $RPM_BUILD_ROOT in the %clean section and in the beginning -of the %install section. Use "rm -rf $RPM_BUILD_ROOT". Some rpm configurations -do this automatically; if your package is only going to be built in such -configurations, you can ignore this warning for the section(s) where your rpm -takes care of it.''', - -'rpm-buildroot-usage', -'''$RPM_BUILD_ROOT should not be touched during %build or %prep stage, as it -may break short circuit builds.''', - -'make-check-outside-check-section', -'''Make check or other automated regression test should be run in %check, as -they can be disabled with a rpm macro for short circuiting purposes.''', - -'macro-in-%changelog', -'''Macros are expanded in %changelog too, which can in unfortunate cases lead -to the package not building at all, or other subtle unexpected conditions that -affect the build. Even when that doesn\'t happen, the expansion results in -possibly "rewriting history" on subsequent package revisions and generally -odd entries eg. in source rpms, which is rarely wanted. Avoid use of macros -in %changelog altogether, or use two '%'s to escape them, like '%%foo'.''', - -'depscript-without-disabling-depgen', -'''In some common rpm configurations/versions, defining __find_provides and/or -__find_requires has no effect if rpm's internal dependency generator has not -been disabled for the build. %define _use_internal_dependency_generator to 0 -to disable it in the specfile, or don't define __find_provides/requires.''', - -'mixed-use-of-spaces-and-tabs', -'''The specfile mixes use of spaces and tabs for indentation, which is a -cosmetic annoyance. Use either spaces or tabs for indentation, not both.''', - -'unversioned-explicit-provides', -'''The specfile contains an unversioned Provides: token, which will match all -older, equal, and newer versions of the provided thing. This may cause -update problems and will make versioned dependencies, obsoletions and conflicts -on the provided thing useless -- make the Provides versioned if possible.''', - -'unversioned-explicit-obsoletes', -'''The specfile contains an unversioned Obsoletes: token, which will match all -older, equal and newer versions of the obsoleted thing. This may cause update -problems, restrict future package/provides naming, and may match something it -was originally not inteded to match -- make the Obsoletes versioned if -possible.''', - -'libdir-macro-in-noarch-package', -'''The %{_libdir} or %{_lib} macro was found in a noarch package in a section -that gets included in binary packages. This is most likely an error because -these macros are expanded on the build host and their values vary between -architectures, probably resulting in a package that does not work properly -on all architectures at runtime. Investigate whether the package is really -architecture independent or if some other dir/macro should be instead.''', - -'non-break-space', -'''The spec file contains a non-break space, which looks like a regular space -in some editors but can lead to obscure errors. It should be replaced by a -regular space.''', - -'non-standard-group', -'''The value of the Group tag in the package is not valid. Valid groups are: -"%s".''' % '", "'.join(VALID_GROUPS), - -'specfile-error', -'''This error occurred when rpmlint used rpm to query the specfile. The error -is output by rpm and the message should contain more information.''', - -'comparison-operator-in-deptoken', -'''This dependency token contains a comparison operator (<, > or =). This is -usually not intended and may be caused by missing whitespace between the -token's name, the comparison operator and the version string.''', - -'macro-in-comment', -'''There is a unescaped macro after a shell style comment in the specfile. -Macros are expanded everywhere, so check if it can cause a problem in this -case and escape the macro with another leading % if appropriate.''', - -'file-size-mismatch', -'''The size of the file in the package does not match the size indicated by -peeking at its URL. Verify that the file in the package has the intended -contents.''', - -'file-md5-mismatch', -'''The MD5 hash of the file in the package does not match the MD5 hash -indicated by peeking at its URL. Verify that the file in the package has the -intended contents.''', - -'patch-fuzz-is-changed', -'''The internal patch fuzz value was changed, and could hide patchs issues, or -could lead to applying a patch at the wrong location. Usually, this is often -the sign that someone didn't check if a patch is still needed and do not want -to rediff it. It is usually better to rediff the patch and try to send it -upstream.''' -) - -# SpecCheck.py ends here |