Store dependencies, provides etc as (name, flags, (epoch, version, release)) internally.

git-svn-id: svn+ssh://rpmlint.zarb.org/home/projects/rpmlint/svn/trunk@1764 9bc8b190-ac0f-0410-8968-dc7d1f502856
This commit is contained in:
Ville Skyttä 2010-04-15 21:42:11 +00:00
parent 0e92ba80d4
commit ac7151ea51
2 changed files with 75 additions and 64 deletions

63
Pkg.py
View File

@ -264,8 +264,8 @@ def rangeCompare(reqtuple, provtuple):
return 0
# from yum 3.2.23, rpmUtils.miscutils
def formatRequire (name, version, flags):
# from yum 3.2.23, rpmUtils.miscutils, with rpmlint modifications
def formatRequire(name, flags, evr):
s = name
if flags:
@ -278,23 +278,33 @@ def formatRequire (name, version, flags):
s = s + ">"
if flags & rpm.RPMSENSE_EQUAL:
s = s + "="
if version:
s = "%s %s" %(s, version)
s = "%s %s" % (s, versionToString(evr))
return s
# from yum 3.2.23, rpmUtils.miscutils
def versionToString(evr):
if not isinstance(evr, tuple) and not isinstance(evr, list):
# assume string
return evr
ret = ""
if evr[0] is not None and evr[0] != "":
ret += str(evr[0]) + ":"
ret += evr[1]
if evr[2] is not None and evr[2] != "":
ret += "-" + evr[2]
return ret
# from yum 3.2.23, rpmUtils.miscutils, with some rpmlint modifications
def stringToVersion(verstring):
if verstring in [None, '']:
return (None, None, None)
epoch = None
i = verstring.find(':')
if i != -1:
try:
epoch = str(long(verstring[:i]))
except ValueError:
# look, garbage in the epoch field, how fun, kill it
epoch = '0' # this is our fallback, deal
else:
epoch = '0'
# garbage in epoch, ignore it
pass
j = verstring.find('-')
if j != -1:
if verstring[i + 1:j] == '':
@ -546,14 +556,20 @@ class Pkg:
# API to access dependency information
def obsoletes(self):
"""Get package Obsoletes as list of
(name, flags, (epoch, version, release)) tuples."""
self._gatherDepInfo()
return self._obsoletes
def requires(self):
"""Get package Requires as list of
(name, flags, (epoch, version, release)) tuples."""
self._gatherDepInfo()
return self._requires
def prereq(self):
"""Get package PreReqs as list of
(name, flags, (epoch, version, release)) tuples."""
self._gatherDepInfo()
return self._prereq
@ -577,27 +593,32 @@ class Pkg:
return False
def conflicts(self):
"""Get package Conflicts as list of
(name, flags, (epoch, version, release)) tuples."""
self._gatherDepInfo()
return self._conflicts
def provides(self):
"""Get package Provides as list of
(name, flags, (epoch, version, release)) tuples."""
self._gatherDepInfo()
return self._provides
# internal function to gather dependency info used by the above ones
def _gather_aux(self, header, list, nametag, versiontag, flagstag,
def _gather_aux(self, header, list, nametag, flagstag, versiontag,
prereq = None):
names = header[nametag]
versions = header[versiontag]
flags = header[flagstag]
versions = header[versiontag]
if versions:
for loop in range(len(versions)):
evr = stringToVersion(versions[loop])
if prereq is not None and flags[loop] & PREREQ_FLAG:
prereq.append((names[loop], versions[loop],
flags[loop] & (~PREREQ_FLAG)))
prereq.append((names[loop], flags[loop] & (~PREREQ_FLAG),
evr))
else:
list.append((names[loop], versions[loop], flags[loop]))
list.append((names[loop], flags[loop], evr))
def _gatherDepInfo(self):
if self._requires is None:
@ -609,21 +630,21 @@ class Pkg:
self._gather_aux(self.header, self._requires,
rpm.RPMTAG_REQUIRENAME,
rpm.RPMTAG_REQUIREVERSION,
rpm.RPMTAG_REQUIREFLAGS,
rpm.RPMTAG_REQUIREVERSION,
self._prereq)
self._gather_aux(self.header, self._conflicts,
rpm.RPMTAG_CONFLICTNAME,
rpm.RPMTAG_CONFLICTVERSION,
rpm.RPMTAG_CONFLICTFLAGS)
rpm.RPMTAG_CONFLICTFLAGS,
rpm.RPMTAG_CONFLICTVERSION)
self._gather_aux(self.header, self._provides,
rpm.RPMTAG_PROVIDENAME,
rpm.RPMTAG_PROVIDEVERSION,
rpm.RPMTAG_PROVIDEFLAGS)
rpm.RPMTAG_PROVIDEFLAGS,
rpm.RPMTAG_PROVIDEVERSION)
self._gather_aux(self.header, self._obsoletes,
rpm.RPMTAG_OBSOLETENAME,
rpm.RPMTAG_OBSOLETEVERSION,
rpm.RPMTAG_OBSOLETEFLAGS)
rpm.RPMTAG_OBSOLETEFLAGS,
rpm.RPMTAG_OBSOLETEVERSION)
def getInstalledPkgs(name):
"""Get list of installed package objects by name."""

View File

@ -549,22 +549,21 @@ class TagsCheck(AbstractCheck.AbstractCheck):
if epoch is None:
if use_epoch:
printError(pkg, 'no-epoch-tag')
elif epoch > 99:
printWarning(pkg, 'unreasonable-epoch', epoch)
else:
if epoch > 99:
printWarning(pkg, 'unreasonable-epoch', epoch)
epoch = str(epoch)
if use_epoch:
for o in pkg.obsoletes():
if o[1] and not epoch_regex.search(o[1]):
printWarning(pkg, 'no-epoch-in-obsoletes',
apply(Pkg.formatRequire, o))
for c in pkg.conflicts():
if c[1] and not epoch_regex.search(c[1]):
printWarning(pkg, 'no-epoch-in-conflicts',
apply(Pkg.formatRequire, c))
for p in pkg.provides():
if p[1] and not epoch_regex.search(p[1]):
printWarning(pkg, 'no-epoch-in-provides',
apply(Pkg.formatRequire, p))
for o in (x for x in pkg.obsoletes() if x[1] and x[2][0] is None):
printWarning(pkg, 'no-epoch-in-obsoletes',
apply(Pkg.formatRequire, o))
for c in (x for x in pkg.conflicts() if x[1] and x[2][0] is None):
printWarning(pkg, 'no-epoch-in-conflicts',
apply(Pkg.formatRequire, c))
for p in (x for x in pkg.provides() if x[1] and x[2][0] is None):
printWarning(pkg, 'no-epoch-in-provides',
apply(Pkg.formatRequire, p))
name = pkg.name
deps = pkg.requires() + pkg.prereq()
@ -573,8 +572,8 @@ class TagsCheck(AbstractCheck.AbstractCheck):
is_source = pkg.isSource()
for d in deps:
value = apply(Pkg.formatRequire, d)
if use_epoch and d[1] and d[0][0:7] != 'rpmlib(' and \
not epoch_regex.search(d[1]):
if use_epoch and d[1] and d[2][0] is None \
and d[0][0:7] != 'rpmlib(':
printWarning(pkg, 'no-epoch-in-dependency', value)
for r in INVALID_REQUIRES:
if r.search(d[0]):
@ -593,7 +592,7 @@ class TagsCheck(AbstractCheck.AbstractCheck):
res = lib_package_regex.search(d[0])
if res and not res.group(1) and not d[1]:
printError(pkg, 'explicit-lib-dependency', d[0])
if d[2] == rpm.RPMSENSE_EQUAL and '-' in d[1]:
if d[1] == rpm.RPMSENSE_EQUAL and d[2][2] is not None:
printWarning(pkg, 'requires-on-release', value)
self._unexpanded_macros(pkg, 'dependency %s' % (value,), value)
@ -621,18 +620,18 @@ class TagsCheck(AbstractCheck.AbstractCheck):
if not dep:
printWarning(pkg, 'no-dependency-on', base_or_libs)
elif version:
if epoch is not None: # regardless of use_epoch
expected = str(epoch) + ":" + version
else:
expected = version
if dep[1][:len(expected)] != expected:
if dep[1] != '':
printWarning(pkg,
'incoherent-version-dependency-on',
base_or_libs, dep[1], expected)
else:
printWarning(pkg, 'no-version-dependency-on',
base_or_libs, expected)
exp = (epoch, version, None)
sexp = Pkg.versionToString(exp)
if not dep[1]:
printWarning(pkg, 'no-version-dependency-on',
base_or_libs, sexp)
elif dep[2][:2] != exp[:2]:
printWarning(pkg,
'incoherent-version-dependency-on',
base_or_libs,
Pkg.versionToString(dep[2][0],
dep[2][1], None),
sexp)
res = devel_number_regex.search(name)
if not res:
printWarning(pkg, 'no-major-in-name', name)
@ -717,8 +716,7 @@ class TagsCheck(AbstractCheck.AbstractCheck):
if use_utf8 and not Pkg.is_utf8_str(' '.join(changelog)):
printError(pkg, 'tag-not-utf8', '%changelog')
# provides = pkg.provides()
# for (provide_name, provide_version, provide_flags) in provides:
# for provide_name in (x[0] for x in pkg.provides()):
# if name == provide_name:
# printWarning(pkg, 'package-provides-itself')
# break
@ -785,23 +783,15 @@ class TagsCheck(AbstractCheck.AbstractCheck):
value = apply(Pkg.formatRequire, c)
self._unexpanded_macros(pkg, 'Conflicts %s' % (value,), value)
obss = [(x[0], x[2], Pkg.stringToVersion(x[1]))
for x in pkg.obsoletes()]
obss = pkg.obsoletes()
if obss:
provs = [(x[0], x[2], Pkg.stringToVersion(x[1]))
for x in pkg.provides()]
i = 0
provs = pkg.provides()
for prov in provs:
j = 0
pp = pkg.provides()[i]
for obs in obss:
if Pkg.rangeCompare(obs, prov):
oo = pkg.obsoletes()[j]
printWarning(pkg, 'self-obsoletion', '%s obsoletes %s' %
(apply(Pkg.formatRequire, oo),
apply(Pkg.formatRequire, pp)))
j += 1
i += 1
(apply(Pkg.formatRequire, obs),
apply(Pkg.formatRequire, prov)))
expfmt = rpm.expandMacro("%{_build_name_fmt}")
if pkg.isSource():