def plan_remove(A): # try to construct a pisi graph of packages to # install / reinstall G_f = pgraph.PGraph(packagedb) # construct G_f # find the (install closure) graph of G_f by package # set A using packagedb for x in A: G_f.add_package(x) B = A while len(B) > 0: Bp = set() for x in B: pkg = packagedb.get_package(x) rev_deps = packagedb.get_rev_deps(x) for (rev_dep, depinfo) in rev_deps: # we don't deal with unsatisfied dependencies if packagedb.has_package(rev_dep) and \ dependency.installed_satisfies_dep(depinfo): if not rev_dep in G_f.vertices(): Bp.add(rev_dep) G_f.add_plain_dep(rev_dep, x) B = Bp if ctx.config.get_option('debug'): G_f.write_graphviz(sys.stdout) order = G_f.topological_sort() return G_f, order
def repo_satisfies_dep(depinfo): """determine if a package in *repository* satisfies given dependency spec""" pkg_name = depinfo.package if not packagedb.has_package(pkg_name): return False else: pkg = packagedb.get_package(pkg_name) (version, release) = (pkg.version, pkg.release) return depinfo.satisfies(pkg_name, version, release)
def installable(pkg): """calculate if pkg name is installable currently which means it has to satisfy both install and runtime dependencies""" if not packagedb.has_package(pkg): ctx.ui.info(_("Package %s is not present in the package database") % pkg); return False elif satisfies_runtime_deps(pkg): return True else: return False
def remove(A): """remove set A of packages from system (A is a list of package names)""" # filter packages that are not installed A_0 = A = set(A) Ap = [] for x in A: if ctx.installdb.is_installed(x): Ap.append(x) else: ctx.ui.info(_('Package %s does not exist. Cannot remove.') % x) A = set(Ap) if len(A)==0: ctx.ui.info(_('No packages to remove.')) return # try to construct a pisi graph of packages to # install / reinstall G_f = pgraph.PGraph(packagedb) # construct G_f # find the (install closure) graph of G_f by package # set A using packagedb for x in A: G_f.add_package(x) B = A while len(B) > 0: Bp = set() for x in B: pkg = packagedb.get_package(x) rev_deps = packagedb.get_rev_deps(x) for (rev_dep, depinfo) in rev_deps: # we don't deal with unsatisfied dependencies if packagedb.has_package(rev_dep) and \ dependency.installed_satisfies_dep(depinfo): if not rev_dep in G_f.vertices(): Bp.add(rev_dep) G_f.add_plain_dep(rev_dep, x) B = Bp if ctx.config.get_option('debug'): G_f.write_graphviz(sys.stdout) order = G_f.topological_sort() ctx.ui.info(_("""The following minimal list of packages will be removed in the respective order to satisfy dependencies: """) + util.strlist(order)) if len(order) > len(A_0): if not ctx.ui.confirm('Do you want to continue?'): ctx.ui.warning(_('Package removal declined')) return False for x in order: if ctx.installdb.is_installed(x): atomicoperations.remove_single(x) else: ctx.ui.info(_('Package %s is not installed. Cannot remove.') % x)
def info_package(self, arg): if arg.endswith(ctx.const.package_suffix): metadata, files = pisi.api.info_file(arg) ctx.ui.info(_('Package file: %s') % arg) self.print_pkginfo(metadata, files) else: if ctx.installdb.is_installed(arg, True): metadata, files = pisi.api.info_name(arg) ctx.ui.info(_('Installed package:')) self.print_pkginfo(metadata, files) if packagedb.has_package(arg): metadata, files = pisi.api.info_name(arg, False) ctx.ui.info(_('Package found in repository:')) self.print_pkginfo(metadata, files)
def check_relations(self): # check if package is in database # If it is not, put it into 3rd party packagedb if not packagedb.has_package(self.pkginfo.name): db = packagedb.thirdparty_packagedb db.add_package(self.pkginfo) # check conflicts for pkg in self.metadata.package.conflicts: if ctx.installdb.is_installed(self.pkginfo): raise InstallError("Package conflicts " + pkg) # check dependencies if not dependency.installable(self.pkginfo.name): ctx.ui.error("Dependencies for " + self.pkginfo.name + " not satisfied") raise InstallError("Package not installable")
def info_name(package_name): """fetch package information for a package""" if packagedb.has_package(package_name): package = packagedb.get_package(package_name) from pisi.metadata import MetaData metadata = MetaData() metadata.package = package #FIXME: get it from sourcedb metadata.source = None #TODO: fetch the files from server if possible if ctx.installdb.is_installed(package.name): files = ctx.installdb.files(package.name) else: files = None return metadata, files else: raise Error(_('Package %s not found') % package_name)
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) # check dependencies if not ctx.config.get_option('ignore_dependency'): if not self.pkginfo.installable(): ctx.ui.error(_('Dependencies for %s not satisfied') % self.pkginfo.name) raise Error(_("Package not installable")) # check if package is in database # If it is not, put it into 3rd party packagedb if not packagedb.has_package(self.pkginfo.name): db = packagedb.thirdparty_packagedb db.add_package(self.pkginfo)
def plan_upgrade(A): # try to construct a pisi graph of packages to # install / reinstall packagedb = ctx.packagedb G_f = pgraph.PGraph(packagedb) # construct G_f # find the "install closure" graph of G_f by package # set A using packagedb for x in A: G_f.add_package(x) B = A def upgradable(dep): #pre dep.package is installed (v,r,b) = ctx.installdb.get_version(dep.package) rep_pkg = packagedb.get_package(dep.package) (vp,rp,bp) = (rep_pkg.version, rep_pkg.release, rep_pkg.build) if ignore_build or (not b) or (not bp): # if we can't look at build if r >= rp: # installed already new return False elif b and bp and b >= bp: return False return True # TODO: conflicts while len(B) > 0: Bp = set() for x in B: pkg = packagedb.get_package(x) for dep in pkg.runtimeDependencies(): # add packages that can be upgraded if dependency.repo_satisfies_dep(dep): #TODO: distinguish must upgrade and upgradable if ctx.installdb.is_installed(dep.package): if not ctx.get_option('eager'): if dependency.installed_satisfies_dep(dep): continue else: if not upgradable(dep): continue if not dep.package in G_f.vertices(): Bp.add(str(dep.package)) G_f.add_dep(x, dep) else: raise Error(_("Reverse dependency %s cannot be satisfied") % rev_dep) B = Bp # now, search reverse dependencies to see if anything # should be upgraded B = A while len(B) > 0: Bp = set() for x in B: pkg = packagedb.get_package(x) rev_deps = packagedb.get_rev_deps(x) for (rev_dep, depinfo) in rev_deps: if not ctx.get_option('eager'): # add unsatisfied reverse dependencies if packagedb.has_package(rev_dep) and \ (not dependency.installed_satisfies_dep(depinfo)): if not dependency.repo_satisfies_dep(depinfo): raise Error(_("Reverse dependency %s cannot be satisfied") % rev_dep) if not rev_dep in G_f.vertices(): Bp.add(rev_dep) G_f.add_plain_dep(rev_dep, x) else: if not rev_dep in G_f.vertices(): Bp.add(rev_dep) G_f.add_plain_dep(rev_dep, x) B = Bp if ctx.config.get_option('debug'): G_f.write_graphviz(sys.stdout) order = G_f.topological_sort() order.reverse() check_conflicts(order, ctx.packagedb) return G_f, order
def upgrade_pkg_names(A = []): """Re-installs packages from the repository, trying to perform a maximum number of upgrades.""" ignore_build = ctx.config.options and ctx.config.options.ignore_build_no if not A: # if A is empty, then upgrade all packages A = ctx.installdb.list_installed() # filter packages that are not upgradable A_0 = A = set(A) Ap = [] for x in A: if x.endswith('.pisi'): ctx.ui.debug(_("Warning: package *name* ends with '.pisi'")) if not ctx.installdb.is_installed(x): ctx.ui.info(_('Package %s is not installed.') % x) continue (version, release, build) = ctx.installdb.get_version(x) pkg = packagedb.get_package(x) # First check version. If they are same, check release. Again # if releases are same and checking buildno is premitted, # check build number. if version < pkg.version: Ap.append(x) elif version == pkg.version: if release < pkg.release: Ap.append(x) if release == pkg.release and build and not ignore_build: if build < pkg.build: Ap.append(x) else: #ctx.ui.info('Package %s cannot be upgraded. ' % x) ctx.ui.info(_('Package %s is already at its latest \ version %s, release %s, build %s.') % (x, pkg.version, pkg.release, pkg.build)) A = set(Ap) if len(A)==0: ctx.ui.info(_('No packages to upgrade.')) return True ctx.ui.debug('A = %s' % str(A)) # try to construct a pisi graph of packages to # install / reinstall G_f = pgraph.PGraph(packagedb) # construct G_f # find the "install closure" graph of G_f by package # set A using packagedb for x in A: G_f.add_package(x) B = A def upgradable(dep): #pre dep.package is installed (v,r,b) = ctx.installdb.get_version(dep.package) rep_pkg = packagedb.get_package(dep.package) (vp,rp,bp) = (rep_pkg.version, rep_pkg.release, rep_pkg.build) if ignore_build or (not b) or (not bp): # if we can't look at build if r >= rp: # installed already new return False elif b and bp and b >= bp: return False return True # TODO: conflicts while len(B) > 0: Bp = set() for x in B: pkg = packagedb.get_package(x) for dep in pkg.runtimeDependencies: # add packages that can be upgraded if dependency.repo_satisfies_dep(dep): #TODO: distinguish must upgrade and upgradable if ctx.installdb.is_installed(dep.package): if not ctx.get_option('eager'): if dependency.installed_satisfies_dep(dep): continue else: if not upgradable(dep): continue if not dep.package in G_f.vertices(): Bp.add(str(dep.package)) G_f.add_dep(x, dep) else: raise Error(_("Reverse dependency %s cannot be satisfied") % rev_dep) B = Bp # now, search reverse dependencies to see if anything # should be upgraded B = A while len(B) > 0: Bp = set() for x in B: pkg = packagedb.get_package(x) rev_deps = packagedb.get_rev_deps(x) for (rev_dep, depinfo) in rev_deps: if not ctx.get_option('eager'): # add unsatisfied reverse dependencies if packagedb.has_package(rev_dep) and \ (not dependency.installed_satisfies_dep(depinfo)): if not dependency.repo_satisfies_dep(dep): raise Error(_("Reverse dependency %s cannot be satisfied") % rev_dep) if not rev_dep in G_f.vertices(): Bp.add(rev_dep) G_f.add_plain_dep(rev_dep, x) else: if not rev_dep in G_f.vertices(): Bp.add(rev_dep) G_f.add_plain_dep(rev_dep, x) B = Bp if ctx.config.get_option('debug'): G_f.write_graphviz(sys.stdout) order = G_f.topological_sort() order.reverse() check_conflicts(order) ctx.ui.info(_("""The following packages will be upgraded:\n""") + util.strlist(order)) if len(order) > len(A_0): if not ctx.ui.confirm('Do you want to continue?'): return False for x in order: atomicoperations.install_single_name(x, True)