- Replacement... not tested yet
This commit is contained in:
+6
-58
@@ -16,72 +16,20 @@ import gettext
|
||||
__trans = gettext.translation('pisi', fallback=True)
|
||||
_ = __trans.ugettext
|
||||
|
||||
import pisi.context as ctx
|
||||
import pisi.version
|
||||
import pisi.pxml.autoxml as autoxml
|
||||
import pisi.itembyrepodb
|
||||
import pisi.relation
|
||||
|
||||
class Conflict:
|
||||
|
||||
__metaclass__ = autoxml.autoxml
|
||||
|
||||
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
|
||||
""" Conflict relation """
|
||||
class Conflict(pisi.relation.Relation):
|
||||
pass
|
||||
|
||||
def installed_package_conflicts(confinfo):
|
||||
"""determine if an installed package in *repository* conflicts with
|
||||
given conflicting spec"""
|
||||
pkg_name = confinfo.package
|
||||
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)
|
||||
return pisi.relation.installed_package_satisfies(confinfo)
|
||||
|
||||
def package_conflicts(pkg, 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 None
|
||||
|
||||
+7
-59
@@ -17,57 +17,11 @@ __trans = gettext.translation('pisi', fallback=True)
|
||||
_ = __trans.ugettext
|
||||
|
||||
import pisi.context as ctx
|
||||
#import pisi.packagedb as packagedb
|
||||
import pisi.version
|
||||
import pisi.pxml.autoxml as autoxml
|
||||
import pisi.itembyrepodb
|
||||
import pisi.relation
|
||||
|
||||
class Dependency:
|
||||
|
||||
__metaclass__ = autoxml.autoxml
|
||||
|
||||
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
|
||||
""" Dependency relation """
|
||||
class Dependency(pisi.relation.Relation):
|
||||
pass
|
||||
|
||||
def dict_satisfies_dep(dict, depinfo):
|
||||
"""determine if a package in a dictionary satisfies given dependency spec"""
|
||||
@@ -77,18 +31,12 @@ def dict_satisfies_dep(dict, depinfo):
|
||||
else:
|
||||
pkg = dict[pkg_name]
|
||||
(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):
|
||||
"""determine if a package in *repository* satisfies given
|
||||
dependency spec"""
|
||||
pkg_name = depinfo.package
|
||||
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)
|
||||
return pisi.relation.installed_package_satisfies(depinfo)
|
||||
|
||||
def repo_satisfies_dep(depinfo):
|
||||
"""determine if a package in *repository* satisfies given
|
||||
@@ -99,7 +47,7 @@ dependency spec"""
|
||||
else:
|
||||
pkg = ctx.packagedb.get_package(pkg_name)
|
||||
(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):
|
||||
for dep in deps:
|
||||
|
||||
+16
-1
@@ -280,8 +280,12 @@ def is_upgradable(name, ignore_build = False):
|
||||
pkg = ctx.packagedb.get_package(name)
|
||||
except KeyboardInterrupt:
|
||||
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
|
||||
|
||||
if ignore_build or (not build) or (not pkg.build):
|
||||
return pisi.version.Version(release) < pisi.version.Version(pkg.release)
|
||||
else:
|
||||
@@ -416,6 +420,8 @@ def upgrade_pkg_names(A = []):
|
||||
# if A is empty, then upgrade all packages
|
||||
A = ctx.installdb.list_installed()
|
||||
|
||||
replaced = []
|
||||
|
||||
A_0 = A = set(A)
|
||||
|
||||
Ap = []
|
||||
@@ -429,6 +435,10 @@ def upgrade_pkg_names(A = []):
|
||||
(version, release, build) = ctx.installdb.get_version(x)
|
||||
if ctx.packagedb.has_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:
|
||||
ctx.ui.info(_('Package %s is not available in repositories.') % x, True)
|
||||
continue
|
||||
@@ -505,6 +515,10 @@ def upgrade_pkg_names(A = []):
|
||||
if conflicts:
|
||||
remove_conflicting_packages(conflicts)
|
||||
|
||||
# remove replaced or obsoleted packages
|
||||
if replaced:
|
||||
remove(replaced, ignore_dep=True, ignore_safety=True)
|
||||
|
||||
for path in paths:
|
||||
ctx.ui.info(util.colorize(_("Installing %d / %d") % (paths.index(path)+1, len(paths)), "yellow"))
|
||||
install_op = atomicoperations.Install(path, ignore_file_conflicts = True)
|
||||
@@ -545,6 +559,7 @@ def plan_upgrade(A):
|
||||
else:
|
||||
ctx.ui.error(_('Dependency %s of %s cannot be satisfied') % (dep, x))
|
||||
raise Error(_("Upgrade is not possible."))
|
||||
|
||||
B = Bp
|
||||
# now, search reverse dependencies to see if anything
|
||||
# should be upgraded
|
||||
|
||||
@@ -40,14 +40,17 @@ class PackageDB(object):
|
||||
def __init__(self):
|
||||
self.d = pisi.itembyrepodb.ItemByRepoDB('package')
|
||||
self.dr = pisi.itembyrepodb.ItemByRepoDB('revdep')
|
||||
self.drp = pisi.itembyrepodb.ItemByRepoDB('replacement')
|
||||
|
||||
def close(self):
|
||||
self.d.close()
|
||||
self.dr.close()
|
||||
self.drp.close()
|
||||
|
||||
def destroy(self):
|
||||
self.d.destroy()
|
||||
self.dr.destroy()
|
||||
self.drp.destroy()
|
||||
|
||||
def has_package(self, name, repo=None, txn = None):
|
||||
return self.d.has_key(name, repo, txn=txn)
|
||||
@@ -77,6 +80,25 @@ class PackageDB(object):
|
||||
else:
|
||||
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):
|
||||
return self.d.list(repo)
|
||||
|
||||
@@ -94,6 +116,10 @@ class PackageDB(object):
|
||||
self.dr.add_item(dep_name, revdep, repo, txn)
|
||||
else:
|
||||
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
|
||||
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.
|
||||
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
|
||||
ctx.componentdb.remove_package(package_info.partOf, package_info.name, repo, txn)
|
||||
|
||||
|
||||
+2
-1
@@ -29,6 +29,7 @@ import pisi.pxml.xmlfile as xmlfile
|
||||
import pisi.pxml.autoxml as autoxml
|
||||
import pisi.context as ctx
|
||||
import pisi.dependency
|
||||
import pisi.replace
|
||||
import pisi.conflict
|
||||
import pisi.component as component
|
||||
import pisi.util as util
|
||||
@@ -171,8 +172,8 @@ class Package:
|
||||
t_ComponentDependencies = [ [autoxml.String], autoxml.optional, "RuntimeDependencies/Component"]
|
||||
t_Files = [ [Path], autoxml.optional]
|
||||
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_RequiresComar = [ [autoxml.String], autoxml.mandatory, "Requires/COMAR"]
|
||||
t_AdditionalFiles = [ [AdditionalFile], autoxml.optional]
|
||||
t_History = [ [Update], autoxml.optional]
|
||||
|
||||
|
||||
@@ -21,27 +21,27 @@ class DependencyTestCase(unittest.TestCase):
|
||||
gtkmmdep = Dependency()
|
||||
gtkmmdep.versionFrom = '1.9.1'
|
||||
gtkmmdep.package = 'atk'
|
||||
self.assert_( not gtkmmdep.satisfies('atk', '1.8.0', '1') )
|
||||
self.assert_( gtkmmdep.satisfies('atk', '1.9.1', '2') )
|
||||
self.assert_( gtkmmdep.satisfies('atk', '1.10.5', '3') )
|
||||
self.assert_( not gtkmmdep.satisfies_relation('atk', '1.8.0', '1') )
|
||||
self.assert_( gtkmmdep.satisfies_relation('atk', '1.9.1', '2') )
|
||||
self.assert_( gtkmmdep.satisfies_relation('atk', '1.10.5', '3') )
|
||||
|
||||
def testReleaseFrom(self):
|
||||
# releaseFrom isn't taken into account #2294
|
||||
dep = Dependency()
|
||||
dep.releaseFrom = '121'
|
||||
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):
|
||||
dep = Dependency()
|
||||
dep.releaseTo = '22'
|
||||
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):
|
||||
dep = Dependency()
|
||||
dep.release = '42'
|
||||
dep.package = 'dbus'
|
||||
self.assert_(dep.satisfies('dbus', '1.2', '42'))
|
||||
self.assert_(dep.satisfies_relation('dbus', '1.2', '42'))
|
||||
|
||||
suite = unittest.makeSuite(DependencyTestCase)
|
||||
|
||||
Reference in New Issue
Block a user