rpmlint/verify-buildrequires.diff

106 lines
4.4 KiB
Diff

--- SpecCheck.py
+++ SpecCheck.py
@@ -45,7 +45,8 @@
biarch_package_regex = re.compile(DEFAULT_BIARCH_PACKAGES)
hardcoded_lib_path_exceptions_regex = re.compile(Config.getOption('HardcodedLibPathExceptions', DEFAULT_HARDCODED_LIB_PATH_EXCEPTIONS))
prereq_regex = re.compile('^PreReq(\(.*\))?:\s*(.+?)\s*$', re.IGNORECASE)
-buildprereq_regex = re.compile('^BuildPreReq:\s*(.+?)\s*$', re.IGNORECASE)
+buildprereq_regex = re.compile('^BuildPreReq\s*:\s*(.+)\s*$', re.IGNORECASE)
+buildrequires_regex = re.compile('^\s*BuildRequires\s*:\s*(.+)\s*$', re.IGNORECASE)
use_utf8 = Config.getOption('UseUTF8', Config.USEUTF8_DEFAULT)
macro_regex = re.compile('(%+)[{(]?(\w+)')
libdir_regex = re.compile('%{?_lib(?:dir)?\}?\\b')
@@ -126,6 +127,25 @@
res.append(tok)
return res
+def find_reverse_requires():
+ reverse_requires = dict()
+ try:
+ f = file("/.builtinfo/rpmdeps", "r")
+ except:
+ return reverse_requires
+
+ for line in f:
+ if line.startswith('R:'):
+ package = "-".join(line.split(':')[1].split('-')[:-3])
+ deps = deptokens(line.split(':')[2])
+ for dep in deps:
+ name = dep.split(' ')[0]
+ if name.startswith('/') or name.find('(') != -1 or name == dep:
+ continue
+ reverse_requires.setdefault(name, set()).add(package)
+
+ return reverse_requires
+
def contains_buildroot(line):
'''Check if the given line contains use of rpm buildroot.'''
res = rpm_buildroot_regex.search(line)
@@ -188,6 +208,8 @@
indent_tabs = 0
files_has_defattr = 0
section = {}
+ buildrequires = set()
+
for sec in ['description', 'prep', 'build', 'install', 'clean',
'files', 'changelog', 'package', 'check']:
section[sec] = {
@@ -348,6 +370,14 @@
if res:
printError(pkg, 'buildprereq-use', res.group(1))
+ res = buildrequires_regex.search(line)
+ if not if_depth and res:
+ for r in deptokens(res.group(1)):
+ name = r.split(' ')[0]
+ if name in buildrequires:
+ printWarning(pkg, 'duplicate-buildrequires', name)
+ buildrequires.add(name)
+
if scriptlet_requires_regex.search(line):
printError(pkg, 'broken-syntax-in-scriptlet-requires', string.strip(line))
@@ -420,6 +450,24 @@
'(spaces: line %d, tab: line %d)' %
(indent_spaces, indent_tabs))
+ reverse_requires = find_reverse_requires()
+ for r in buildrequires:
+ if r in reverse_requires:
+ for rev in reverse_requires[r]:
+ if rev in buildrequires:
+ printWarning(pkg, 'unnecessary-buildrequires', r, 'already included by', rev)
+
+ if not r.endswith("-devel"):
+ develr = [ r + "-devel" ]
+ # libfoo-4_2 -> libfoo-devel
+ dr2 = re.sub(r'-?[0-9_]+$', '', r) + "-devel"
+ if dr2 != develr[0]:
+ develr.append(dr2);
+ for dr in develr:
+ if r in reverse_requires and dr in reverse_requires[r] \
+ and not dr in buildrequires:
+ printWarning(pkg, "non-devel-buildrequires", r, "- did you mean", dr, "?")
+
# process gathered info
for p in patches.keys():
if p in applied_patches_ifarch:
@@ -557,6 +605,17 @@
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'.''',
+'unnecessary-buildrequires',
+''' The specfile contains a buildrequires entry that seems to be already
+requires by one of the other buildrequires. Please consider reducing your
+buildrequires definitions in case this is a real implicit dependency.''',
+
+'non-devel-buildrequires',
+'''The specfile contains a buildrequires entry that has a -devel package.
+Please carefully check if you want to buildrequire the -devel subpackage or if
+this is an unnecessary dependency that is already required by one of the other
+buildrequires.''',
+
'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