* 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:
Faik Uygur
2006-10-26 08:15:37 +00:00
parent 668b2481ba
commit 1d313bb5a9
8 changed files with 169 additions and 96 deletions
+4 -3
View File
@@ -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'):
+84
View File
@@ -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
View File
@@ -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)
+11
View File
@@ -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)
+17
View File
@@ -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
View File
@@ -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]
+34
View File
@@ -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()
-83
View File
@@ -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)