* 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.packagedb as packagedb
|
||||
import pisi.dependency as dependency
|
||||
import pisi.conflict
|
||||
import pisi.util as util
|
||||
from pisi.specfile import *
|
||||
from pisi.metadata import MetaData
|
||||
@@ -141,9 +142,9 @@ class Install(AtomicOperation):
|
||||
|
||||
def check_relations(self):
|
||||
# check conflicts
|
||||
for pkg in self.metadata.package.conflicts:
|
||||
if ctx.installdb.is_installed(self.pkginfo):
|
||||
raise Error(_("Package conflicts %s") % pkg)
|
||||
for conf in self.metadata.package.conflicts:
|
||||
if pisi.conflict.installed_package_conflicts(conf):
|
||||
raise Error(_("Package conflicts %s") % conf)
|
||||
|
||||
# check dependencies
|
||||
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
|
||||
import pisi.util as util
|
||||
import pisi.dependency as dependency
|
||||
import pisi.conflict
|
||||
import pisi.pgraph as pgraph
|
||||
import pisi.packagedb as packagedb
|
||||
import pisi.repodb
|
||||
@@ -194,11 +195,11 @@ in the respective order to satisfy extra dependencies:
|
||||
upgrade_pisi()
|
||||
|
||||
def check_conflict(pkg):
|
||||
conflicts = []
|
||||
conflicts = {}
|
||||
|
||||
for c in pkg.conflicts:
|
||||
if ctx.installdb.is_installed(c):
|
||||
conflicts.append(c)
|
||||
if pisi.conflict.installed_package_conflicts(c):
|
||||
conflicts[c.package] = str(c)
|
||||
|
||||
return conflicts
|
||||
|
||||
@@ -209,16 +210,23 @@ def calculate_conflicts(order, packagedb):
|
||||
|
||||
for x in order:
|
||||
pkg = packagedb.get_package(x)
|
||||
B_p = set(check_conflict(pkg))
|
||||
B_p = check_conflict(pkg)
|
||||
if B_p:
|
||||
pkg_conflicts[x] = B_p
|
||||
C = C.union(B_p)
|
||||
pkg_conflicts[x] = B_p.values()
|
||||
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
|
||||
# going to be installed
|
||||
if B_i:
|
||||
D = D.union(B_i)
|
||||
for p in map(lambda x:packagedb.get_package(x), 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)
|
||||
|
||||
return (C, D, pkg_conflicts)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
from pisi.specfile import SpecFile, Package, Update, Path
|
||||
from pisi.dependency import Dependency
|
||||
from pisi.conflict import Conflict
|
||||
from pisi.pxml.autoxml import LocalText
|
||||
|
||||
class Pspec:
|
||||
@@ -71,6 +72,16 @@ class Pspec:
|
||||
self.package.packageDependencies.remove(dep)
|
||||
|
||||
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:
|
||||
self.package.conflicts.append(con)
|
||||
|
||||
|
||||
@@ -49,6 +49,23 @@ def with_added_dependencies(*deps):
|
||||
def with_removed_dependencies(*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):
|
||||
assert len(kw) <= 1
|
||||
|
||||
|
||||
+2
-1
@@ -28,6 +28,7 @@ from pisi.pxml.xmlfile import XmlFile
|
||||
import pisi.pxml.autoxml as autoxml
|
||||
import pisi.context as ctx
|
||||
from pisi.dependency import Dependency
|
||||
from pisi.conflict import Conflict
|
||||
import pisi.dependency
|
||||
import pisi.component as component
|
||||
from pisi.util import Checks
|
||||
@@ -173,7 +174,7 @@ class Package:
|
||||
t_PackageDependencies = [ [Dependency], autoxml.optional, "RuntimeDependencies/Dependency"]
|
||||
t_ComponentDependencies = [ [autoxml.String], autoxml.optional, "RuntimeDependencies/Component"]
|
||||
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_RequiresComar = [ [autoxml.String], autoxml.mandatory, "Requires/COMAR"]
|
||||
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