- Replacement... not tested yet

This commit is contained in:
Faik Uygur
2007-06-12 12:18:56 +00:00
parent ab5f7b4315
commit 9aa48e3335
6 changed files with 67 additions and 125 deletions
+6 -58
View File
@@ -16,72 +16,20 @@ import gettext
__trans = gettext.translation('pisi', fallback=True) __trans = gettext.translation('pisi', fallback=True)
_ = __trans.ugettext _ = __trans.ugettext
import pisi.context as ctx import pisi.relation
import pisi.version
import pisi.pxml.autoxml as autoxml
import pisi.itembyrepodb
class Conflict: """ Conflict relation """
class Conflict(pisi.relation.Relation):
__metaclass__ = autoxml.autoxml pass
s_Package = [autoxml.String, autoxml.mandatory]
a_version = [autoxml.String, autoxml.optional]
a_versionFrom = [autoxml.String, autoxml.optional]
a_versionTo = [autoxml.String, autoxml.optional]
a_release = [autoxml.String, autoxml.optional]
a_releaseFrom = [autoxml.String, autoxml.optional]
a_releaseTo = [autoxml.String, autoxml.optional]
def __str__(self):
s = self.package
if self.versionFrom:
s += _(" version >= ") + self.versionFrom
if self.versionTo:
s += _(" version <= ") + self.versionTo
if self.version:
s += _(" version ") + self.version
if self.releaseFrom:
s += _(" release >= ") + self.releaseFrom
if self.releaseTo:
s += _(" release <= ") + self.releaseTo
if self.release:
s += _(" release ") + self.release
return s
def conflicts(self, pkg_name, version, release):
"""determine if a package ver. conflicts with given conflicting spec"""
ret = True
v = pisi.version.Version(version)
if self.version:
ret &= v == pisi.version.Version(self.version)
if self.versionFrom:
ret &= v >= pisi.version.Version(self.versionFrom)
if self.versionTo:
ret &= v <= pisi.version.Version(self.versionTo)
r = pisi.version.Version(release)
if self.release:
ret &= r == pisi.version.Version(self.release)
if self.releaseFrom:
ret &= r >= pisi.version.Version(self.releaseFrom)
if self.releaseTo:
ret &= r <= pisi.version.Version(self.releaseTo)
return ret
def installed_package_conflicts(confinfo): def installed_package_conflicts(confinfo):
"""determine if an installed package in *repository* conflicts with """determine if an installed package in *repository* conflicts with
given conflicting spec""" given conflicting spec"""
pkg_name = confinfo.package return pisi.relation.installed_package_satisfies(confinfo)
if not ctx.installdb.is_installed(pkg_name):
return False
else:
pkg = ctx.packagedb.get_package(pkg_name, pisi.itembyrepodb.installed)
(version, release) = (pkg.version, pkg.release)
return confinfo.conflicts(pkg_name, version, release)
def package_conflicts(pkg, confs): def package_conflicts(pkg, confs):
for c in confs: for c in confs:
if pkg.name == c.package and c.conflicts(pkg.name, pkg.version, pkg.release): if pkg.name == c.package and c.satisfies_relation(pkg.name, pkg.version, pkg.release):
return c return c
return None return None
+7 -59
View File
@@ -17,57 +17,11 @@ __trans = gettext.translation('pisi', fallback=True)
_ = __trans.ugettext _ = __trans.ugettext
import pisi.context as ctx import pisi.context as ctx
#import pisi.packagedb as packagedb import pisi.relation
import pisi.version
import pisi.pxml.autoxml as autoxml
import pisi.itembyrepodb
class Dependency: """ Dependency relation """
class Dependency(pisi.relation.Relation):
__metaclass__ = autoxml.autoxml pass
s_Package = [autoxml.String, autoxml.mandatory]
a_version = [autoxml.String, autoxml.optional]
a_versionFrom = [autoxml.String, autoxml.optional]
a_versionTo = [autoxml.String, autoxml.optional]
a_release = [autoxml.String, autoxml.optional]
a_releaseFrom = [autoxml.String, autoxml.optional]
a_releaseTo = [autoxml.String, autoxml.optional]
def __str__(self):
s = self.package
if self.versionFrom:
s += _(" version >= ") + self.versionFrom
if self.versionTo:
s += _(" version <= ") + self.versionTo
if self.version:
s += _(" version ") + self.version
if self.releaseFrom:
s += _(" release >= ") + self.releaseFrom
if self.releaseTo:
s += _(" release <= ") + self.releaseTo
if self.release:
s += _(" release ") + self.release
return s
def satisfies(self, pkg_name, version, release):
"""determine if a package ver. satisfies given dependency spec"""
ret = True
v = pisi.version.Version(version)
if self.version:
ret &= v == pisi.version.Version(self.version)
if self.versionFrom:
ret &= v >= pisi.version.Version(self.versionFrom)
if self.versionTo:
ret &= v <= pisi.version.Version(self.versionTo)
r = pisi.version.Version(release)
if self.release:
ret &= r == pisi.version.Version(self.release)
if self.releaseFrom:
ret &= r >= pisi.version.Version(self.releaseFrom)
if self.releaseTo:
ret &= r <= pisi.version.Version(self.releaseTo)
return ret
def dict_satisfies_dep(dict, depinfo): def dict_satisfies_dep(dict, depinfo):
"""determine if a package in a dictionary satisfies given dependency spec""" """determine if a package in a dictionary satisfies given dependency spec"""
@@ -77,18 +31,12 @@ def dict_satisfies_dep(dict, depinfo):
else: else:
pkg = dict[pkg_name] pkg = dict[pkg_name]
(version, release) = (pkg.version, pkg.release) (version, release) = (pkg.version, pkg.release)
return depinfo.satisfies(pkg_name, version, release) return depinfo.satisfies_relation(pkg_name, version, release)
def installed_satisfies_dep(depinfo): def installed_satisfies_dep(depinfo):
"""determine if a package in *repository* satisfies given """determine if a package in *repository* satisfies given
dependency spec""" dependency spec"""
pkg_name = depinfo.package return pisi.relation.installed_package_satisfies(depinfo)
if not ctx.installdb.is_installed(pkg_name):
return False
else:
pkg = ctx.packagedb.get_package(pkg_name, pisi.itembyrepodb.installed)
(version, release) = (pkg.version, pkg.release)
return depinfo.satisfies(pkg_name, version, release)
def repo_satisfies_dep(depinfo): def repo_satisfies_dep(depinfo):
"""determine if a package in *repository* satisfies given """determine if a package in *repository* satisfies given
@@ -99,7 +47,7 @@ dependency spec"""
else: else:
pkg = ctx.packagedb.get_package(pkg_name) pkg = ctx.packagedb.get_package(pkg_name)
(version, release) = (pkg.version, pkg.release) (version, release) = (pkg.version, pkg.release)
return depinfo.satisfies(pkg_name, version, release) return depinfo.satisfies_relation(pkg_name, version, release)
def satisfies_dependencies(pkg, deps, sat = installed_satisfies_dep): def satisfies_dependencies(pkg, deps, sat = installed_satisfies_dep):
for dep in deps: for dep in deps:
+16 -1
View File
@@ -280,8 +280,12 @@ def is_upgradable(name, ignore_build = False):
pkg = ctx.packagedb.get_package(name) pkg = ctx.packagedb.get_package(name)
except KeyboardInterrupt: except KeyboardInterrupt:
raise raise
except Exception: #FIXME: what exception could we catch here, replace with that. except pisi.itembyrepodb.NotfoundError:
# it may be a replaced package
if ctx.packagedb.has_replacement(name):
return True
return False return False
if ignore_build or (not build) or (not pkg.build): if ignore_build or (not build) or (not pkg.build):
return pisi.version.Version(release) < pisi.version.Version(pkg.release) return pisi.version.Version(release) < pisi.version.Version(pkg.release)
else: else:
@@ -416,6 +420,8 @@ def upgrade_pkg_names(A = []):
# if A is empty, then upgrade all packages # if A is empty, then upgrade all packages
A = ctx.installdb.list_installed() A = ctx.installdb.list_installed()
replaced = []
A_0 = A = set(A) A_0 = A = set(A)
Ap = [] Ap = []
@@ -429,6 +435,10 @@ def upgrade_pkg_names(A = []):
(version, release, build) = ctx.installdb.get_version(x) (version, release, build) = ctx.installdb.get_version(x)
if ctx.packagedb.has_package(x): if ctx.packagedb.has_package(x):
pkg = ctx.packagedb.get_package(x) pkg = ctx.packagedb.get_package(x)
elif ctx.packagedb.has_replacement(x):
Ap.append(ctx.packagedb.get_replacement(x))
replaced.append(x)
continue
else: else:
ctx.ui.info(_('Package %s is not available in repositories.') % x, True) ctx.ui.info(_('Package %s is not available in repositories.') % x, True)
continue continue
@@ -505,6 +515,10 @@ def upgrade_pkg_names(A = []):
if conflicts: if conflicts:
remove_conflicting_packages(conflicts) remove_conflicting_packages(conflicts)
# remove replaced or obsoleted packages
if replaced:
remove(replaced, ignore_dep=True, ignore_safety=True)
for path in paths: for path in paths:
ctx.ui.info(util.colorize(_("Installing %d / %d") % (paths.index(path)+1, len(paths)), "yellow")) ctx.ui.info(util.colorize(_("Installing %d / %d") % (paths.index(path)+1, len(paths)), "yellow"))
install_op = atomicoperations.Install(path, ignore_file_conflicts = True) install_op = atomicoperations.Install(path, ignore_file_conflicts = True)
@@ -545,6 +559,7 @@ def plan_upgrade(A):
else: else:
ctx.ui.error(_('Dependency %s of %s cannot be satisfied') % (dep, x)) ctx.ui.error(_('Dependency %s of %s cannot be satisfied') % (dep, x))
raise Error(_("Upgrade is not possible.")) raise Error(_("Upgrade is not possible."))
B = Bp B = Bp
# now, search reverse dependencies to see if anything # now, search reverse dependencies to see if anything
# should be upgraded # should be upgraded
+30
View File
@@ -40,14 +40,17 @@ class PackageDB(object):
def __init__(self): def __init__(self):
self.d = pisi.itembyrepodb.ItemByRepoDB('package') self.d = pisi.itembyrepodb.ItemByRepoDB('package')
self.dr = pisi.itembyrepodb.ItemByRepoDB('revdep') self.dr = pisi.itembyrepodb.ItemByRepoDB('revdep')
self.drp = pisi.itembyrepodb.ItemByRepoDB('replacement')
def close(self): def close(self):
self.d.close() self.d.close()
self.dr.close() self.dr.close()
self.drp.close()
def destroy(self): def destroy(self):
self.d.destroy() self.d.destroy()
self.dr.destroy() self.dr.destroy()
self.drp.destroy()
def has_package(self, name, repo=None, txn = None): def has_package(self, name, repo=None, txn = None):
return self.d.has_key(name, repo, txn=txn) return self.d.has_key(name, repo, txn=txn)
@@ -77,6 +80,25 @@ class PackageDB(object):
else: else:
return [] return []
# If an installed package is replaced by any package in repository, mark this
# package for replacement in a later upgrade operation.
# @pkg: The package that replaces other packages
def mark_replaced_packages(self, pkg, repo, txn=None):
for repinfo in pkg.replaces:
# test if the package from this repo replaces an installed package
if pisi.replace.installed_package_replaced(repinfo):
replacedBy = pkg.name
self.drp.add_item(repinfo.package, replacedBy, repo, txn)
def has_replacement(self, name, repo=None, txn=None):
return self.drp.has_key(name, repo, txn=txn)
def get_replacement(self, name, repo=None, txn=None):
try:
return self.drp.get_item(name, repo, txn=txn)
except pisi.itembyrepodb.NotfoundError:
raise Error(_('Package %s has no replacement found in repository') % name)
def list_packages(self, repo=None): def list_packages(self, repo=None):
return self.d.list(repo) return self.d.list(repo)
@@ -94,6 +116,10 @@ class PackageDB(object):
self.dr.add_item(dep_name, revdep, repo, txn) self.dr.add_item(dep_name, revdep, repo, txn)
else: else:
self.dr.add_item(dep_name, [ (name, dep) ], repo, txn) self.dr.add_item(dep_name, [ (name, dep) ], repo, txn)
if package_info.replaces:
mark_replaced_packages(self, package_info, repo, txn=None)
# add component # add component
ctx.componentdb.add_package(package_info.partOf, package_info.name, repo, txn) ctx.componentdb.add_package(package_info.partOf, package_info.name, repo, txn)
@@ -123,6 +149,10 @@ class PackageDB(object):
# all the list members are removed. # all the list members are removed.
self.dr.remove_item(dep_name, repo, txn=txn) self.dr.remove_item(dep_name, repo, txn=txn)
# remove replace marker info for this package
if self.drp.has_key(name, repo, txn):
self.drp.remove_item(name, repo, txn=txn)
# remove from component # remove from component
ctx.componentdb.remove_package(package_info.partOf, package_info.name, repo, txn) ctx.componentdb.remove_package(package_info.partOf, package_info.name, repo, txn)
+2 -1
View File
@@ -29,6 +29,7 @@ import pisi.pxml.xmlfile as xmlfile
import pisi.pxml.autoxml as autoxml import pisi.pxml.autoxml as autoxml
import pisi.context as ctx import pisi.context as ctx
import pisi.dependency import pisi.dependency
import pisi.replace
import pisi.conflict import pisi.conflict
import pisi.component as component import pisi.component as component
import pisi.util as util import pisi.util as util
@@ -171,8 +172,8 @@ class Package:
t_ComponentDependencies = [ [autoxml.String], autoxml.optional, "RuntimeDependencies/Component"] t_ComponentDependencies = [ [autoxml.String], autoxml.optional, "RuntimeDependencies/Component"]
t_Files = [ [Path], autoxml.optional] t_Files = [ [Path], autoxml.optional]
t_Conflicts = [ [pisi.conflict.Conflict], autoxml.optional, "Conflicts/Package"] t_Conflicts = [ [pisi.conflict.Conflict], autoxml.optional, "Conflicts/Package"]
t_Replaces = [ [pisi.replace.Replace], autoxml.optional, "Replaces/Package"]
t_ProvidesComar = [ [ComarProvide], autoxml.optional, "Provides/COMAR"] t_ProvidesComar = [ [ComarProvide], autoxml.optional, "Provides/COMAR"]
#t_RequiresComar = [ [autoxml.String], autoxml.mandatory, "Requires/COMAR"]
t_AdditionalFiles = [ [AdditionalFile], autoxml.optional] t_AdditionalFiles = [ [AdditionalFile], autoxml.optional]
t_History = [ [Update], autoxml.optional] t_History = [ [Update], autoxml.optional]
+6 -6
View File
@@ -21,27 +21,27 @@ class DependencyTestCase(unittest.TestCase):
gtkmmdep = Dependency() gtkmmdep = Dependency()
gtkmmdep.versionFrom = '1.9.1' gtkmmdep.versionFrom = '1.9.1'
gtkmmdep.package = 'atk' gtkmmdep.package = 'atk'
self.assert_( not gtkmmdep.satisfies('atk', '1.8.0', '1') ) self.assert_( not gtkmmdep.satisfies_relation('atk', '1.8.0', '1') )
self.assert_( gtkmmdep.satisfies('atk', '1.9.1', '2') ) self.assert_( gtkmmdep.satisfies_relation('atk', '1.9.1', '2') )
self.assert_( gtkmmdep.satisfies('atk', '1.10.5', '3') ) self.assert_( gtkmmdep.satisfies_relation('atk', '1.10.5', '3') )
def testReleaseFrom(self): def testReleaseFrom(self):
# releaseFrom isn't taken into account #2294 # releaseFrom isn't taken into account #2294
dep = Dependency() dep = Dependency()
dep.releaseFrom = '121' dep.releaseFrom = '121'
dep.package = 'dbus' dep.package = 'dbus'
self.assert_(not dep.satisfies('dbus', '1.2', '2')) self.assert_(not dep.satisfies_relation('dbus', '1.2', '2'))
def testReleaseTo(self): def testReleaseTo(self):
dep = Dependency() dep = Dependency()
dep.releaseTo = '22' dep.releaseTo = '22'
dep.package = 'dbus' dep.package = 'dbus'
self.assert_(not dep.satisfies('dbus', '1.2', '25')) self.assert_(not dep.satisfies_relation('dbus', '1.2', '25'))
def testReleaseIs(self): def testReleaseIs(self):
dep = Dependency() dep = Dependency()
dep.release = '42' dep.release = '42'
dep.package = 'dbus' dep.package = 'dbus'
self.assert_(dep.satisfies('dbus', '1.2', '42')) self.assert_(dep.satisfies_relation('dbus', '1.2', '42'))
suite = unittest.makeSuite(DependencyTestCase) suite = unittest.makeSuite(DependencyTestCase)