From 9aa48e3335d9fbaa4a447ce8c0ff4137482b5974 Mon Sep 17 00:00:00 2001 From: Faik Uygur Date: Tue, 12 Jun 2007 12:18:56 +0000 Subject: [PATCH] - Replacement... not tested yet --- pisi/conflict.py | 64 ++++---------------------------------- pisi/dependency.py | 66 +++++----------------------------------- pisi/operations.py | 17 ++++++++++- pisi/packagedb.py | 30 ++++++++++++++++++ pisi/specfile.py | 3 +- tests/dependencytests.py | 12 ++++---- 6 files changed, 67 insertions(+), 125 deletions(-) diff --git a/pisi/conflict.py b/pisi/conflict.py index e7723a46..21f72746 100644 --- a/pisi/conflict.py +++ b/pisi/conflict.py @@ -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 diff --git a/pisi/dependency.py b/pisi/dependency.py index a6388b33..539591a7 100644 --- a/pisi/dependency.py +++ b/pisi/dependency.py @@ -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: diff --git a/pisi/operations.py b/pisi/operations.py index 60bbc32d..5e9ef053 100644 --- a/pisi/operations.py +++ b/pisi/operations.py @@ -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 diff --git a/pisi/packagedb.py b/pisi/packagedb.py index 5e9d7686..70afc6ee 100644 --- a/pisi/packagedb.py +++ b/pisi/packagedb.py @@ -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) diff --git a/pisi/specfile.py b/pisi/specfile.py index 4884e734..918112df 100644 --- a/pisi/specfile.py +++ b/pisi/specfile.py @@ -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] diff --git a/tests/dependencytests.py b/tests/dependencytests.py index 8e5d10ba..25452fc2 100644 --- a/tests/dependencytests.py +++ b/tests/dependencytests.py @@ -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)