* conflict versioning.
conflicttests.py removed for now. it is difficult to write a test scenario by code now, Conflict is not a string any more. Tested this with scenario scripts. Added a simple one. Had to work on to create unittest for this stuff.
This commit is contained in:
@@ -23,6 +23,7 @@ import pisi
|
|||||||
import pisi.context as ctx
|
import pisi.context as ctx
|
||||||
import pisi.packagedb as packagedb
|
import pisi.packagedb as packagedb
|
||||||
import pisi.dependency as dependency
|
import pisi.dependency as dependency
|
||||||
|
import pisi.conflict
|
||||||
import pisi.util as util
|
import pisi.util as util
|
||||||
from pisi.specfile import *
|
from pisi.specfile import *
|
||||||
from pisi.metadata import MetaData
|
from pisi.metadata import MetaData
|
||||||
@@ -141,9 +142,9 @@ class Install(AtomicOperation):
|
|||||||
|
|
||||||
def check_relations(self):
|
def check_relations(self):
|
||||||
# check conflicts
|
# check conflicts
|
||||||
for pkg in self.metadata.package.conflicts:
|
for conf in self.metadata.package.conflicts:
|
||||||
if ctx.installdb.is_installed(self.pkginfo):
|
if pisi.conflict.installed_package_conflicts(conf):
|
||||||
raise Error(_("Package conflicts %s") % pkg)
|
raise Error(_("Package conflicts %s") % conf)
|
||||||
|
|
||||||
# check dependencies
|
# check dependencies
|
||||||
if not ctx.config.get_option('ignore_dependency'):
|
if not ctx.config.get_option('ignore_dependency'):
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright (C) 2005, TUBITAK/UEKAE
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it under
|
||||||
|
# the terms of the GNU General Public License as published by the Free
|
||||||
|
# Software Foundation; either version 2 of the License, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# Please read the COPYING file.
|
||||||
|
#
|
||||||
|
|
||||||
|
"""conflict analyzer"""
|
||||||
|
|
||||||
|
import gettext
|
||||||
|
__trans = gettext.translation('pisi', fallback=True)
|
||||||
|
_ = __trans.ugettext
|
||||||
|
|
||||||
|
import pisi.context as ctx
|
||||||
|
from pisi.version import Version
|
||||||
|
import pisi.pxml.autoxml as autoxml
|
||||||
|
from pisi.util import Checks
|
||||||
|
import pisi.itembyrepodb
|
||||||
|
|
||||||
|
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.releaseFrom:
|
||||||
|
s += _(" release >= ") + self.releaseFrom
|
||||||
|
if self.releaseTo:
|
||||||
|
s += _(" release <= ") + self.releaseTo
|
||||||
|
return s
|
||||||
|
|
||||||
|
def conflicts(self, pkg_name, version, release):
|
||||||
|
"""determine if a package ver. conflicts with given conflicting spec"""
|
||||||
|
ret = True
|
||||||
|
v = Version(version)
|
||||||
|
if self.version:
|
||||||
|
ret &= v == Version(self.version)
|
||||||
|
if self.versionFrom:
|
||||||
|
ret &= v >= Version(self.versionFrom)
|
||||||
|
if self.versionTo:
|
||||||
|
ret &= v <= Version(self.versionTo)
|
||||||
|
r = Version(release)
|
||||||
|
if self.release:
|
||||||
|
ret &= r == Version(self.release)
|
||||||
|
if self.releaseFrom:
|
||||||
|
ret &= r >= Version(self.releaseFrom)
|
||||||
|
if self.releaseTo:
|
||||||
|
ret &= r <= Version(self.releaseTo)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
def package_conflicts(pkg, confs):
|
||||||
|
for c in confs:
|
||||||
|
if pkg.name == c.package and c.conflicts(pkg.name, pkg.version, pkg.release):
|
||||||
|
return c
|
||||||
|
|
||||||
|
return None
|
||||||
+17
-9
@@ -22,6 +22,7 @@ import pisi.context as ctx
|
|||||||
from pisi.uri import URI
|
from pisi.uri import URI
|
||||||
import pisi.util as util
|
import pisi.util as util
|
||||||
import pisi.dependency as dependency
|
import pisi.dependency as dependency
|
||||||
|
import pisi.conflict
|
||||||
import pisi.pgraph as pgraph
|
import pisi.pgraph as pgraph
|
||||||
import pisi.packagedb as packagedb
|
import pisi.packagedb as packagedb
|
||||||
import pisi.repodb
|
import pisi.repodb
|
||||||
@@ -194,11 +195,11 @@ in the respective order to satisfy extra dependencies:
|
|||||||
upgrade_pisi()
|
upgrade_pisi()
|
||||||
|
|
||||||
def check_conflict(pkg):
|
def check_conflict(pkg):
|
||||||
conflicts = []
|
conflicts = {}
|
||||||
|
|
||||||
for c in pkg.conflicts:
|
for c in pkg.conflicts:
|
||||||
if ctx.installdb.is_installed(c):
|
if pisi.conflict.installed_package_conflicts(c):
|
||||||
conflicts.append(c)
|
conflicts[c.package] = str(c)
|
||||||
|
|
||||||
return conflicts
|
return conflicts
|
||||||
|
|
||||||
@@ -209,16 +210,23 @@ def calculate_conflicts(order, packagedb):
|
|||||||
|
|
||||||
for x in order:
|
for x in order:
|
||||||
pkg = packagedb.get_package(x)
|
pkg = packagedb.get_package(x)
|
||||||
B_p = set(check_conflict(pkg))
|
B_p = check_conflict(pkg)
|
||||||
if B_p:
|
if B_p:
|
||||||
pkg_conflicts[x] = B_p
|
pkg_conflicts[x] = B_p.values()
|
||||||
C = C.union(B_p)
|
C = C.union(B_p.keys())
|
||||||
|
|
||||||
B_i = B_0.intersection(set(pkg.conflicts))
|
B_i = B_0.intersection(set(map(lambda p:p.package, pkg.conflicts)))
|
||||||
|
D_i = set()
|
||||||
# check if there are any conflicts within the packages that are
|
# check if there are any conflicts within the packages that are
|
||||||
# going to be installed
|
# going to be installed
|
||||||
if B_i:
|
for p in map(lambda x:packagedb.get_package(x), B_i):
|
||||||
D = D.union(B_i)
|
# check if they are really conflicting
|
||||||
|
conflicted = pisi.conflict.package_conflicts(p, pkg.conflicts)
|
||||||
|
if conflicted:
|
||||||
|
D_i.add(str(conflicted))
|
||||||
|
|
||||||
|
if D_i:
|
||||||
|
D = D.union(D_i)
|
||||||
D.add(pkg.name)
|
D.add(pkg.name)
|
||||||
|
|
||||||
return (C, D, pkg_conflicts)
|
return (C, D, pkg_conflicts)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
from pisi.specfile import SpecFile, Package, Update, Path
|
from pisi.specfile import SpecFile, Package, Update, Path
|
||||||
from pisi.dependency import Dependency
|
from pisi.dependency import Dependency
|
||||||
|
from pisi.conflict import Conflict
|
||||||
from pisi.pxml.autoxml import LocalText
|
from pisi.pxml.autoxml import LocalText
|
||||||
|
|
||||||
class Pspec:
|
class Pspec:
|
||||||
@@ -71,6 +72,16 @@ class Pspec:
|
|||||||
self.package.packageDependencies.remove(dep)
|
self.package.packageDependencies.remove(dep)
|
||||||
|
|
||||||
def add_conflicts(self, conflicts):
|
def add_conflicts(self, conflicts):
|
||||||
|
# special case of given one conflict package
|
||||||
|
# with conflict versioning info [**kw, name]
|
||||||
|
# [{"versionFrom":"0.4.2"}, "udev"]
|
||||||
|
if type(conflicts[0]) == dict:
|
||||||
|
conf = Conflict()
|
||||||
|
(kw, conf.package) = conflicts
|
||||||
|
conf.__dict__[kw.keys()[0]] = kw.values()[0]
|
||||||
|
self.package.conflicts.append(conf)
|
||||||
|
return
|
||||||
|
|
||||||
for con in conflicts:
|
for con in conflicts:
|
||||||
self.package.conflicts.append(con)
|
self.package.conflicts.append(con)
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,23 @@ def with_added_dependencies(*deps):
|
|||||||
def with_removed_dependencies(*deps):
|
def with_removed_dependencies(*deps):
|
||||||
return with_action(DEPENDENCY, REMOVED, deps)
|
return with_action(DEPENDENCY, REMOVED, deps)
|
||||||
|
|
||||||
|
def with_added_conflict(package, **kw):
|
||||||
|
assert len(kw) <= 1
|
||||||
|
|
||||||
|
if not len(kw):
|
||||||
|
return with_action(CONFLICT, ADDED, [package])
|
||||||
|
|
||||||
|
if (kw.has_key("versionFrom") or
|
||||||
|
kw.has_key("versionTo") or
|
||||||
|
kw.has_key("version") or
|
||||||
|
kw.has_key("releaseFrom") or
|
||||||
|
kw.has_key("releaseTo") or
|
||||||
|
kw.has_key("release")):
|
||||||
|
return with_action(CONFLICT, ADDED, [kw, package])
|
||||||
|
|
||||||
|
# pass other keywords.
|
||||||
|
return with_action(CONFLICT, ADDED, [package])
|
||||||
|
|
||||||
def with_added_dependency(package, **kw):
|
def with_added_dependency(package, **kw):
|
||||||
assert len(kw) <= 1
|
assert len(kw) <= 1
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -28,6 +28,7 @@ from pisi.pxml.xmlfile import XmlFile
|
|||||||
import pisi.pxml.autoxml as autoxml
|
import pisi.pxml.autoxml as autoxml
|
||||||
import pisi.context as ctx
|
import pisi.context as ctx
|
||||||
from pisi.dependency import Dependency
|
from pisi.dependency import Dependency
|
||||||
|
from pisi.conflict import Conflict
|
||||||
import pisi.dependency
|
import pisi.dependency
|
||||||
import pisi.component as component
|
import pisi.component as component
|
||||||
from pisi.util import Checks
|
from pisi.util import Checks
|
||||||
@@ -173,7 +174,7 @@ class Package:
|
|||||||
t_PackageDependencies = [ [Dependency], autoxml.optional, "RuntimeDependencies/Dependency"]
|
t_PackageDependencies = [ [Dependency], autoxml.optional, "RuntimeDependencies/Dependency"]
|
||||||
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 = [ [autoxml.String], autoxml.optional, "Conflicts/Package"]
|
t_Conflicts = [ [Conflict], autoxml.optional, "Conflicts/Package"]
|
||||||
t_ProvidesComar = [ [ComarProvide], autoxml.optional, "Provides/COMAR"]
|
t_ProvidesComar = [ [ComarProvide], autoxml.optional, "Provides/COMAR"]
|
||||||
#t_RequiresComar = [ [autoxml.String], autoxml.mandatory, "Requires/COMAR"]
|
#t_RequiresComar = [ [autoxml.String], autoxml.mandatory, "Requires/COMAR"]
|
||||||
t_AdditionalFiles = [ [AdditionalFile], autoxml.optional]
|
t_AdditionalFiles = [ [AdditionalFile], autoxml.optional]
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Scenario : bug3865scen.py
|
||||||
|
#
|
||||||
|
# Source : http://bugs.pardus.org.tr/show_bug.cgi?id=3865
|
||||||
|
#
|
||||||
|
# Problem : A need arised between the packages libmp4v2 and faad2 that libmp4v2 has to
|
||||||
|
# define that it only conflicts with the faad2 until release 3.
|
||||||
|
#
|
||||||
|
# Problem Description:
|
||||||
|
#
|
||||||
|
# PiSi is incapable to define conflict versioning info. libmp4v2 only conflicts with faad2
|
||||||
|
# package's release no 3. But because PiSi does not understand that, two packages can not
|
||||||
|
# be installed together.
|
||||||
|
#
|
||||||
|
# Expected:
|
||||||
|
#
|
||||||
|
# Versioning info can be defined as in dependency informations.
|
||||||
|
|
||||||
|
|
||||||
|
from pisi.scenarioapi.scenario import *
|
||||||
|
|
||||||
|
LIBMP4V2 = "libmp4v2"
|
||||||
|
FAAD2 = "faad2"
|
||||||
|
|
||||||
|
let_repo_had(LIBMP4V2)
|
||||||
|
let_repo_had(FAAD2, with_version("0.2.1"))
|
||||||
|
|
||||||
|
let_pisi_had(LIBMP4V2, FAAD2)
|
||||||
|
|
||||||
|
def run():
|
||||||
|
repo_version_bumped(LIBMP4V2, with_added_conflict(FAAD2))
|
||||||
|
repo_updated_index()
|
||||||
|
pisi_upgraded()
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
# Copyright (C) 2006, TUBITAK/UEKAE
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
|
||||||
# the terms of the GNU General Public License as published by the Free
|
|
||||||
# Software Foundation; either version 2 of the License, or (at your option)
|
|
||||||
# any later version.
|
|
||||||
#
|
|
||||||
# Please read the COPYING file.
|
|
||||||
#
|
|
||||||
# Author: Faik Uygur <faik@pardus.org.tr>
|
|
||||||
|
|
||||||
import unittest
|
|
||||||
import pisi.context as ctx
|
|
||||||
import pisi.api
|
|
||||||
import pisi
|
|
||||||
|
|
||||||
import testcase
|
|
||||||
|
|
||||||
class ConflictTestCase(testcase.TestCase):
|
|
||||||
def setUp(self):
|
|
||||||
testcase.TestCase.setUp(self)
|
|
||||||
|
|
||||||
d_t = {}
|
|
||||||
|
|
||||||
# instx are the conflicting packages that are installed on the system.
|
|
||||||
# notinstx are conflicting packages that are not installed on the system.
|
|
||||||
# a-j are the packages to be installed.
|
|
||||||
packages = {"a": ["notinst1", "notinst2", "b"],
|
|
||||||
"b": ["a", "e", "f"],
|
|
||||||
"c": ["g", "h"],
|
|
||||||
"d": [],
|
|
||||||
"e": ["j"],
|
|
||||||
"f" : ["inst1", "notinst2", "f", "inst3", "notinst3"],
|
|
||||||
"g" : ["inst4", "notinst1"],
|
|
||||||
"h" : ["inst2", "inst3", "inst4", "notinst2"],
|
|
||||||
"i" : ["notinst2", "inst1"],
|
|
||||||
"j" : []}
|
|
||||||
|
|
||||||
# packages that are installed on the system
|
|
||||||
ctx.installdb.purge('inst1')
|
|
||||||
ctx.installdb.purge('inst2')
|
|
||||||
ctx.installdb.purge('inst3')
|
|
||||||
ctx.installdb.purge('inst4')
|
|
||||||
ctx.installdb.install('inst1', '1.2', '2', '3')
|
|
||||||
ctx.installdb.install('inst2', '2.4', '2', '3')
|
|
||||||
ctx.installdb.install('inst3', '5.2', '2', '3')
|
|
||||||
ctx.installdb.install('inst4', '2.1', '2', '3')
|
|
||||||
|
|
||||||
for name in packages.keys():
|
|
||||||
pkg = pisi.specfile.Package()
|
|
||||||
pkg.name = name
|
|
||||||
pkg.conflicts = packages[name]
|
|
||||||
d_t[name] = pkg
|
|
||||||
|
|
||||||
class PackageDB:
|
|
||||||
def get_package(self, key):
|
|
||||||
return d_t[str(key)]
|
|
||||||
|
|
||||||
self.packagedb = PackageDB()
|
|
||||||
|
|
||||||
def tearDown(self, ):
|
|
||||||
pisi.api.finalize()
|
|
||||||
|
|
||||||
def testConflictWithEachOther(self):
|
|
||||||
packages = ["a", "b", "c", "d", "e"]
|
|
||||||
(C, D, pkg_conflicts) = pisi.operations.calculate_conflicts(packages, self.packagedb)
|
|
||||||
self.assert_(set(['a', 'b', 'e']) == D)
|
|
||||||
|
|
||||||
def testConflictWithInstalled(self):
|
|
||||||
packages = ["g", "h", "i"]
|
|
||||||
(C, D, pkg_conflicts) = pisi.operations.calculate_conflicts(packages, self.packagedb)
|
|
||||||
self.assert_(not D)
|
|
||||||
self.assert_(set(['inst1', 'inst2', 'inst3', 'inst4']) == C)
|
|
||||||
self.assert_("notinst1" not in pkg_conflicts["g"])
|
|
||||||
|
|
||||||
def testConflictWithEachOtherAndInstalled(self):
|
|
||||||
packages = ["a", "b", "g", "h", "i"]
|
|
||||||
(C, D, pkg_conflicts) = pisi.operations.calculate_conflicts(packages, self.packagedb)
|
|
||||||
self.assert_(set(['a', 'b']) == D)
|
|
||||||
self.assert_(set(['inst1', 'inst2', 'inst3', 'inst4']) == C)
|
|
||||||
self.assert_(set(['inst2', 'inst3', 'inst4']) == pkg_conflicts["h"])
|
|
||||||
|
|
||||||
suite = unittest.makeSuite(ConflictTestCase)
|
|
||||||
Reference in New Issue
Block a user