Make the same package preferred for a requirement resolution

This commit is contained in:
Alexander Lakhin 2014-02-17 17:43:46 +04:00
parent 183ad8fef6
commit 6e1cc15160

View file

@ -230,84 +230,86 @@ SELECT packages.id AS package_id, packages.name AS package_name, packages.nvra,
in_repodirs = ','.join(str(id) for id in search_repodirs) in_repodirs = ','.join(str(id) for id in search_repodirs)
# print 'package requires count: ', len(package_requires) # print 'package requires count: ', len(package_requires)
broken_dep = 0 broken_dep = 0
requires_cache = {}
# TODO: Reuse the cache for dependent repositories???
for packreq in package_requires: for packreq in package_requires:
(cpackage_id, package_nvra, requires_id, requires_name, requires_flags, requires_version) = \ (cpackage_id, package_nvra, requires_id, requires_name, requires_flags, requires_version) = \
(packreq[0], packreq[2], packreq[3], packreq[4], packreq[5], packreq[6]) (packreq[0], packreq[2], packreq[3], packreq[4], packreq[5], packreq[6])
requirement_uid = requires_name + '\x00' + str(requires_flags) + '\x00' + requires_version req_res = []
req_res = requires_cache.get(requirement_uid, None) if (re.match(r'\A(rpmlib|executable)\(.+\)\Z', requires_name)):
if req_res is None: # see if($N=~/\A(rpmlib|executable)\(.+\)\Z/) in urpm_repoclosure.pl
req_res = [] req_res.append({})
if (re.match(r'\A(rpmlib|executable)\(.+\)\Z', requires_name)): else:
# see if($N=~/\A(rpmlib|executable)\(.+\)\Z/) in urpm_repoclosure.pl depend_candidates = dbc.execute("""
req_res.append({})
else:
depend_candidates = dbc.execute("""
SELECT packages.id AS package_id, packages.name AS package_name, packages.nvra, SELECT packages.id AS package_id, packages.name AS package_name, packages.nvra,
prov.id, prov.name, flags, prov.version prov.id, prov.name, flags, prov.version
FROM packages, rpm_provides AS prov FROM packages, rpm_provides AS prov
WHERE prov.package_id = packages.id AND repodir_id IN (%s) AND prov.name = ? WHERE prov.package_id = packages.id AND repodir_id IN (%s) AND prov.name = ?
ORDER by packages.name, packages.nvra ORDER by packages.name, packages.nvra
""" % in_repodirs, [requires_name]).fetchall() """ % in_repodirs, [requires_name]).fetchall()
preferred_version = None preferred_version = None
for dep_cand in depend_candidates:
(pkg_id, provides_id,
provides_flags, provides_version) = \
(dep_cand[0], dep_cand[3],
dep_cand[5], dep_cand[6])
if provides_flags & RPMSENSE_SENSEMASK == 0:
if not provides_version:
provides_version = '*'
else:
raise Exception('Invalid provides version '
'(flags = %d, version = %s)!' %
(provides_flags, provides_version))
if version_ok(requires_version,
requires_flags & RPMSENSE_SENSEMASK,
provides_version):
if pkg_id == cpackage_id:
# the same package is preferred over any other
req_res.append({'prov_id': provides_id,
'pkg_id': pkg_id})
preferred_version = None
break
better_version = preferred_version is None or \
provides_version == '*'
if not better_version:
better_version = version_ok(provides_version,
RPMSENSE_GREATER,
preferred_version)
if better_version:
preferred_version = provides_version
if preferred_version is not None:
for dep_cand in depend_candidates: for dep_cand in depend_candidates:
(provides_flags, provides_version) = \ (pkg_id, provides_id, provides_version) = \
(dep_cand[5], dep_cand[6]) (dep_cand[0], dep_cand[3], dep_cand[6])
#print 'provides_version: ', provides_flags, ' ', provides_version if provides_version == preferred_version or \
if provides_flags & RPMSENSE_SENSEMASK == 0: version_ok(provides_version, RPMSENSE_EQUAL,
if not provides_version: preferred_version):
provides_version = '*' req_res.append({'prov_id': provides_id,
else: 'pkg_id': pkg_id})
raise Exception('Invalid provides version '
'(flags = %d, version = %s)!' %
(provides_flags, provides_version))
if version_ok(requires_version,
requires_flags & RPMSENSE_SENSEMASK,
provides_version):
better_version = preferred_version is None or \
provides_version == '*'
if not better_version:
better_version = version_ok(provides_version,
RPMSENSE_GREATER,
preferred_version)
if better_version:
preferred_version = provides_version
if preferred_version is not None:
for dep_cand in depend_candidates:
(pkg_id, provides_id, provides_version) = \
(dep_cand[0], dep_cand[3], dep_cand[6])
if provides_version == preferred_version or \
version_ok(provides_version, RPMSENSE_EQUAL,
preferred_version):
req_res.append({'prov_id': provides_id,
'pkg_id': pkg_id})
if len(req_res) == 0 and requires_name.startswith('/'): # file dependency if len(req_res) == 0 and requires_name.startswith('/'): # file dependency
if (requires_flags & (RPMSENSE_SCRIPT_POST | if (requires_flags & (RPMSENSE_SCRIPT_POST |
RPMSENSE_SCRIPT_PREUN | RPMSENSE_SCRIPT_PREUN |
RPMSENSE_SCRIPT_POSTUN)) != 0: RPMSENSE_SCRIPT_POSTUN)) != 0:
int_files_cnt = dbc.execute(""" int_files_cnt = dbc.execute("""
SELECT COUNT(1) FROM package_files WHERE package_id = ? AND path = ? SELECT COUNT(1) FROM package_files WHERE package_id = ? AND path = ?
""", [cpackage_id, requires_name]).fetchone() """, [cpackage_id, requires_name]).fetchone()
if int_files_cnt[0] > 0: if int_files_cnt[0] > 0:
req_res.append({}) req_res.append({})
else: else:
#TODO: Check file dependencies (/usr/bin/python (required by ant-scripts-1.7.1-7.0.6.noarch), /usr/sbin/useradd (required by tomcat5-5.5.28-0.5.2.noarch))? #TODO: Check file dependencies (/usr/bin/python (required by ant-scripts-1.7.1-7.0.6.noarch), /usr/sbin/useradd (required by tomcat5-5.5.28-0.5.2.noarch))?
files_deps = dbc.execute(""" files_deps = dbc.execute("""
SELECT package_id FROM package_files SELECT package_id FROM package_files
WHERE path = ? AND WHERE path = ? AND
package_id in (SELECT id FROM packages WHERE repodir_id IN (%s)) package_id in (SELECT id FROM packages WHERE repodir_id IN (%s))
""" % in_repodirs, [requires_name]).fetchall() """ % in_repodirs, [requires_name]).fetchall()
for file_dep in files_deps: for file_dep in files_deps:
req_res.append({'pkg_id': file_dep[0]}) req_res.append({'pkg_id': file_dep[0]})
if len(req_res) == 0 and (requires_flags & RPMSENSE_MISSINGOK) != 0: if len(req_res) == 0 and (requires_flags & RPMSENSE_MISSINGOK) != 0:
req_res.append({}) req_res.append({})
if len(req_res) > 0: if len(req_res) > 0:
for res_rec in req_res: for res_rec in req_res:
@ -319,7 +321,6 @@ VALUES (?, ?, ?, ?)
else: else:
print requires_name, ' ', requires_version, ' (required by %s)' % package_nvra, ' not found!!!' print requires_name, ' ', requires_version, ' (required by %s)' % package_nvra, ' not found!!!'
broken_dep += 1 broken_dep += 1
requires_cache[requirement_uid] = req_res
n = n + 1 n = n + 1
#print "n = ", n #print "n = ", n
# if n == 60000: # if n == 60000: