* upgrade komutunun ilk halini programla

- upgrade komutu verilen paket kumesinden yola cikarak, bagimlilik
    iliskilerini izler, ve maximum sayida bagimliligi kattigi paket
    kumesini gunceller.
* ekrana daha cok aciklama bas
* specfile'dan dependency'e ilgili class'i tasi
This commit is contained in:
Eray Özkural
2005-08-09 13:40:32 +00:00
parent 6c57708ae3
commit 5c1cfe9896
6 changed files with 159 additions and 73 deletions
+1 -1
View File
@@ -208,7 +208,7 @@ You may use filenames, URIs or package names for packages. If you have
specified a package name, it should exist in a specified repository. specified a package name, it should exist in a specified repository.
""" """
def __init__(self): def __init__(self):
super(Install, self).__init__() super(Upgrade, self).__init__()
def run(self): def run(self):
if not self.args: if not self.args:
+68 -2
View File
@@ -16,9 +16,66 @@ from installdb import installdb
import packagedb import packagedb
from ui import ui from ui import ui
from version import Version from version import Version
from xmlext import *
from xmlfile import XmlFile
def satisfiesDep(pkg_name, depinfo): class DepInfo:
"""determine if package satisfies given dependency spec in installdb""" def __init__(self, node = None):
if node:
self.package = getNodeText(node).strip()
self.versionFrom = getNodeAttribute(node, "versionFrom")
self.versionTo = getNodeAttribute(node, "versionTo")
self.releaseFrom = getNodeAttribute(node, "releaseFrom")
self.releaseTo = getNodeAttribute(node, "releaseTo")
else:
self.versionFrom = self.versionTo = None
self.releaseFrom = self.releaseFrom = None
def elt(self, xml):
node = xml.newNode("Dependency")
xml.addText(node, self.package)
if self.versionFrom:
node.setAttribute("versionFrom", self.versionFrom)
if self.versionTo:
node.setAttribute("versionTo", self.versionTo)
if self.releaseFrom:
node.setAttribute("releaseFrom", self.versionFrom)
if self.releaseTo:
node.setAttribute("releaseTo", self.versionTo)
return node
def verify(self):
if not self.package: return False
return True
def satisfies(self, pkg_name, version, release):
"""determine if a package ver. satisfies given dependency spec"""
ret = True
from version import Version
if self.versionFrom:
ret &= Version(version) >= Version(self.versionFrom)
if self.versionTo:
ret &= Version(version) <= Version(self.versionTo)
if self.releaseFrom:
ret &= Version(release) <= Version(self.releaseFrom)
if self.releaseTo:
ret &= Version(release) <= Version(self.releaseTo)
return ret
def __str__(self):
s = self.package
if self.versionFrom:
s += 'ver >= ' + self.versionFrom
if self.versionTo:
s += 'ver <= ' + self.versionTo
if self.releaseFrom:
s += 'rel >= ' + self.releaseFrom
if self.releaseTo:
s += 'rel <= ' + self.releaseTo
return s
def upgradableDep(pkg_name, depinfo):
"""determine if package in *repository* satisfies given dependency spec in installdb"""
if not installdb.is_installed(depinfo.package): if not installdb.is_installed(depinfo.package):
return False return False
else: else:
@@ -26,6 +83,15 @@ def satisfiesDep(pkg_name, depinfo):
(version, release) = (pkg.version, pkg.release) (version, release) = (pkg.version, pkg.release)
return depinfo.satisfies(pkg_name, version, release) return depinfo.satisfies(pkg_name, version, release)
def satisfiesDep(pkg_name, depinfo):
"""determine if an *already installed* package can be upgraded given dependency spec in installdb"""
if not installdb.is_installed(depinfo.package):
return False
else:
pkg = packagedb.inst_packagedb.get_package(pkg_name)
(version, release) = (pkg.version, pkg.release)
return depinfo.satisfies(pkg_name, version, release)
def satisfiesDeps(pkg, deps): def satisfiesDeps(pkg, deps):
for dep in deps: for dep in deps:
if not satisfiesDep(pkg, dep): if not satisfiesDep(pkg, dep):
+10 -5
View File
@@ -44,8 +44,12 @@ class Installer:
self.files = self.package.files self.files = self.package.files
self.pkginfo = self.metadata.package self.pkginfo = self.metadata.package
def install(self): def install(self, ask_reinstall = True):
"entry point" "entry point"
ui.info('Installing %s, version %s, release %s, build %s\n' %
(self.pkginfo.name, self.pkginfo.version,
self.pkginfo.release, self.pkginfo.build))
self.ask_reinstall = ask_reinstall
self.check_requirements() self.check_requirements()
self.check_relations() self.check_relations()
self.reinstall() self.reinstall()
@@ -88,6 +92,7 @@ class Installer:
(iversion, irelease) = installdb.get_version(pkg.name) (iversion, irelease) = installdb.get_version(pkg.name)
if pkg.version == iversion and pkg.release == irelease: if pkg.version == iversion and pkg.release == irelease:
if self.ask_reinstall:
if not ui.confirm('Re-install same version package?'): if not ui.confirm('Re-install same version package?'):
raise InstallError('Package re-install declined') raise InstallError('Package re-install declined')
else: else:
@@ -102,7 +107,7 @@ class Installer:
upgrade = True upgrade = True
# is this a downgrade? confirm this action. # is this a downgrade? confirm this action.
if not upgrade: if self.ask_reinstall and (not upgrade):
if pkg.version < iversion: if pkg.version < iversion:
x = 'Downgrade to old upstream version?' x = 'Downgrade to old upstream version?'
elif pkg.release < irelease: elif pkg.release < irelease:
@@ -116,17 +121,17 @@ class Installer:
def extractInstall(self): def extractInstall(self):
"unzip package in place" "unzip package in place"
ui.info('Extracting files\n') ui.info('Extracting files,\n')
self.package.extract_dir_flat('install', config.destdir) self.package.extract_dir_flat('install', config.destdir)
def storePisiFiles(self): def storePisiFiles(self):
"""put files.xml, metadata.xml, actions.py and COMAR scripts """put files.xml, metadata.xml, actions.py and COMAR scripts
somewhere in the file system. We'll need these in future...""" somewhere in the file system. We'll need these in future..."""
ui.info('Storing %s\n' % const.files_xml) ui.info('Storing %s, ' % const.files_xml)
self.package.extract_file(const.files_xml, self.package.pkg_dir()) self.package.extract_file(const.files_xml, self.package.pkg_dir())
ui.info('Storing %s\n' % const.metadata_xml) ui.info('%s.\n' % const.metadata_xml)
self.package.extract_file(const.metadata_xml, self.package.pkg_dir()) self.package.extract_file(const.metadata_xml, self.package.pkg_dir())
for pcomar in self.metadata.package.providesComar: for pcomar in self.metadata.package.providesComar:
+9 -8
View File
@@ -28,7 +28,7 @@ def remove_single(package_name):
#TODO: check dependencies #TODO: check dependencies
ui.info('Removing package %s\n' % package_name) ui.info('Removing package %s' % package_name)
if not installdb.is_installed(package_name): if not installdb.is_installed(package_name):
raise Exception('Trying to remove nonexistent package ' raise Exception('Trying to remove nonexistent package '
+ package_name) + package_name)
@@ -47,24 +47,25 @@ def remove_single(package_name):
if comard: if comard:
# FIXME: (return value)... # FIXME: (return value)...
comard.remove(package_name) comard.remove(package_name)
ui.info('.\n')
def install_single(pkg): def install_single(pkg, upgrade = False):
"""install a single package from URI or ID""" """install a single package from URI or ID"""
url = PUrl(pkg) url = PUrl(pkg)
# Check if we are dealing with a remote file or a real path of # Check if we are dealing with a remote file or a real path of
# package filename. Otherwise we'll try installing a package from # package filename. Otherwise we'll try installing a package from
# the package repository. # the package repository.
if url.isRemoteFile() or os.path.exists(url.uri): if url.isRemoteFile() or os.path.exists(url.uri):
install_single_file(pkg) install_single_file(pkg, upgrade)
else: else:
install_single_name(pkg) install_single_name(pkg, upgrade)
def install_single_file(pkg_location): def install_single_file(pkg_location, upgrade = False):
"""install a package file""" """install a package file"""
from install import Installer from install import Installer
Installer(pkg_location).install() Installer(pkg_location).install(not upgrade)
def install_single_name(name): def install_single_name(name, upgrade = False):
"""install a single package from ID""" """install a single package from ID"""
# find package in repository # find package in repository
repo = packagedb.which_repo(name) repo = packagedb.which_repo(name)
@@ -84,7 +85,7 @@ def install_single_name(name):
ui.debug("Package URI: %s\n" % pkg_path) ui.debug("Package URI: %s\n" % pkg_path)
# Package will handle remote file for us! # Package will handle remote file for us!
install_single_file(pkg_path) install_single_file(pkg_path, upgrade)
else: else:
ui.error("Package %s not found in the repository file.\n" % pkg) ui.error("Package %s not found in the repository file.\n" % pkg)
+1 -54
View File
@@ -24,6 +24,7 @@ from os.path import basename
from xmlext import * from xmlext import *
from xmlfile import XmlFile from xmlfile import XmlFile
from ui import ui from ui import ui
from dependency import DepInfo
class PackagerInfo: class PackagerInfo:
def __init__(self, node = None): def __init__(self, node = None):
@@ -102,60 +103,6 @@ class PatchInfo:
s += ' level:' + self.level s += ' level:' + self.level
return s return s
class DepInfo:
def __init__(self, node = None):
if node:
self.package = getNodeText(node).strip()
self.versionFrom = getNodeAttribute(node, "versionFrom")
self.versionTo = getNodeAttribute(node, "versionTo")
self.releaseFrom = getNodeAttribute(node, "releaseFrom")
self.releaseTo = getNodeAttribute(node, "releaseTo")
else:
self.versionFrom = self.versionTo = None
self.releaseFrom = self.releaseFrom = None
def elt(self, xml):
node = xml.newNode("Dependency")
xml.addText(node, self.package)
if self.versionFrom:
node.setAttribute("versionFrom", self.versionFrom)
if self.versionTo:
node.setAttribute("versionTo", self.versionTo)
if self.releaseFrom:
node.setAttribute("releaseFrom", self.versionFrom)
if self.releaseTo:
node.setAttribute("releaseTo", self.versionTo)
return node
def verify(self):
if not self.package: return False
return True
def satisfies(self, pkg_name, version, release):
"""determine if a package ver. satisfies given dependency spec"""
ret = True
from version import Version
if self.versionFrom:
ret &= Version(version) >= Version(self.versionFrom)
if self.versionTo:
ret &= Version(version) <= Version(self.versionTo)
if self.releaseFrom:
ret &= Version(release) <= Version(self.releaseFrom)
if self.releaseTo:
ret &= Version(release) <= Version(self.releaseTo)
return ret
def __str__(self):
s = self.package
if self.versionFrom:
s += 'ver >= ' + self.versionFrom
if self.versionTo:
s += 'ver <= ' + self.versionTo
if self.releaseFrom:
s += 'rel >= ' + self.releaseFrom
if self.releaseTo:
s += 'rel <= ' + self.releaseTo
return s
class UpdateInfo: class UpdateInfo:
def __init__(self, node = None): def __init__(self, node = None):
+68 -1
View File
@@ -45,7 +45,7 @@ def install(packages):
except packagedb.PackageDBError, e: except packagedb.PackageDBError, e:
ui.error("PackageDBError: (%s)\n" % e) ui.error("PackageDBError: (%s)\n" % e)
ui.error("Package is not installable. Its very likely a dependency problem.\n") ui.error("Package is not installable.\n")
except Exception, e: except Exception, e:
print e print e
@@ -95,6 +95,7 @@ def install_pkg_names(A):
installs""" installs"""
if len(A)==0: if len(A)==0:
ui.info('No packages to install.\n')
return True return True
# try to construct a pisi graph of packages to # try to construct a pisi graph of packages to
@@ -131,6 +132,72 @@ def install_pkg_names(A):
return True # everything went OK :) return True # everything went OK :)
def upgrade(A):
upgrade_pkg_names(A)
def upgrade_pkg_names(A):
"""Re-installs packages from the repository, trying to perform
a maximum number of upgrades."""
# filter packages that are not installed
Ap = []
for x in A:
if not installdb.is_installed(x):
ui.info('Package %s is not installed.\n' % x)
continue
(version, release) = installdb.get_version(x)
(versionp, releasep) = (packagedb.get_package(x).version,
packagedb.get_package(x).release)
# BUG: we should use build instead of release
if release < releasep:
Ap.append(x)
else:
#ui.info('Package %s cannot be upgraded. ' % x)
# BUG: where is build no?
ui.info('Package %s is already at its latest version %s,\
release %s, build ?.\n'
% (x, versionp, releasep))
A = Ap
if len(A)==0:
ui.info('No packages to upgrade.\n')
return True
# try to construct a pisi graph of packages to
# install / reinstall
G_f = pgraph.PGraph() # construct G_f
# find the "install closure" graph of G_f by package
# set A using packagedb
print A
for x in A:
G_f.add_package(x)
B = A
#state = {}
while len(B) > 0:
Bp = set()
for x in B:
pkg = packagedb.get_package(x)
print pkg
for dep in pkg.runtimeDeps:
print 'checking ', dep
# add packages that can be upgraded
if not dependency.upgradableDep(x, dep):
if not dep.package in G_f.vertices():
Bp.add(str(dep.package))
G_f.add_dep(x, dep)
B = Bp
G_f.write_graphviz(sys.stdout)
l = G_f.topological_sort()
l.reverse()
print l
for x in l:
operations.install_single_name(x, True)
return True # everything went OK :)
def remove(A): def remove(A):
"""remove set A of packages from system (A is a list of package names)""" """remove set A of packages from system (A is a list of package names)"""