From f268e6d065e3cbb2d694889e37373c8fc3d55198 Mon Sep 17 00:00:00 2001 From: necoro <> Date: Fri, 29 Dec 2006 01:48:41 +0000 Subject: enhancement for the settings-handling (better reloading-support, moving into a class), enhanced update_world-check --- portato/backend/__init__.py | 43 ++++++++++++++++---- portato/backend/package.py | 85 ++++++++++++++++++--------------------- portato/backend/portage_helper.py | 85 +++++++++++++++++++++------------------ 3 files changed, 121 insertions(+), 92 deletions(-) (limited to 'portato/backend') diff --git a/portato/backend/__init__.py b/portato/backend/__init__.py index ce244c5..5ee2e2a 100644 --- a/portato/backend/__init__.py +++ b/portato/backend/__init__.py @@ -10,19 +10,48 @@ # # Written by René 'Necoro' Neumann -import sys, copy +import sys, copy, os from threading import Lock # import portage import portage +class PortageSettings: + + def __init__ (self): + self.settingslock = Lock() + self.load() + + def load(self): + kwargs = {} + for k, envvar in (("config_root", "PORTAGE_CONFIGROOT"), ("target_root", "ROOT")): + kwargs[k] = os.environ.get(envvar, None) + self.trees = portage.create_trees(trees=None, **kwargs) + + self.settings = self.trees["/"]["vartree"].settings + + for myroot in self.trees: + if myroot != "/": + self.settings = self.trees[myroot]["vartree"].settings + break + + self.settings.unlock() + + root = self.settings["ROOT"] + + self.porttree = self.trees[root]["porttree"] + self.vartree = self.trees[root]["vartree"] + self.virtuals = self.trees[root]["virtuals"] + # portage tree vars -settingslock = Lock() -settings = portage.config(clone=portage.settings, config_incrementals = copy.deepcopy(portage.settings.incrementals)) -porttree = portage.db[portage.root]["porttree"] -vartree = portage.db[portage.root]["vartree"] -virtuals = portage.db[portage.root]["virtuals"] -trees = portage.db +portage_settings = PortageSettings() + +settingslock = portage_settings.settingslock +settings = portage_settings.settings +trees = portage_settings.trees +porttree = portage_settings.porttree +vartree = portage_settings.vartree +virtuals = portage_settings.virtuals # this is set to "var/lib/portage/world" by default - so we add the leading / portage.WORLD_FILE = portage.settings["ROOT"]+portage.WORLD_FILE diff --git a/portato/backend/package.py b/portato/backend/package.py index 225c06a..b053db4 100644 --- a/portato/backend/package.py +++ b/portato/backend/package.py @@ -10,9 +10,10 @@ # # Written by René 'Necoro' Neumann -from portato.backend import * +from portato.backend import portage_settings from portato.helper import * from portage_helper import * +from exceptions import * import flags import portage, portage_dep @@ -36,8 +37,10 @@ class Package: if not self._scpv: raise ValueError("invalid cpv: %s" % cpv) - self._settings = settings - self._settingslock = settingslock + self._settings = portage_settings.settings + self._settingslock = portage_settings.settingslock + + self._trees = portage_settings.trees self.forced_flags = set() self.forced_flags.update(self._settings.usemask) @@ -50,11 +53,11 @@ class Package: def is_installed(self): """Returns true if this package is installed (merged)""" - return vartree.dbapi.cpv_exists(self._cpv) + return portage_settings.vartree.dbapi.cpv_exists(self._cpv) def is_overlay(self): """Returns true if the package is in an overlay.""" - dir,ovl = portage.portdb.findname2(self._cpv) + dir,ovl = portage_settings.porttree.dbapi.findname2(self._cpv) return ovl != self._settings["PORTDIR"] def is_in_system (self): @@ -150,10 +153,10 @@ class Package: @returns: list of use-flags @rtype: string[]""" - if installed: - tree = vartree + if installed or not self.is_in_system(): + tree = portage_settings.vartree else: - tree = porttree + tree = portage_settings.porttree return list(set(self.get_env_var("IUSE", tree = tree).split()).difference(self.forced_flags)) @@ -211,11 +214,13 @@ class Package: flags.remove_new_use_flags(self) - def get_matched_dep_packages (self): + def get_matched_dep_packages (self, depvar): """This function looks for all dependencies which are resolved. In normal case it makes only sense for installed packages, but should work for uninstalled ones too. @returns: unique list of dependencies resolved (with elements like "<=net-im/foobar-1.2.3") - @rtype: string[]""" + @rtype: string[] + + @raises portato.DependencyCalcError: when an error occured during executing portage.dep_check()""" # change the useflags, because we have internally changed some, but not made them visible for portage newUseFlags = self.get_new_use_flags() @@ -227,41 +232,29 @@ class Package: elif u not in actual: actual.append(u) - # - # the following stuff is mostly adapted from portage.dep_check() - # - - depstring = self.get_env_var("RDEPEND")+" "+self.get_env_var("DEPEND")+" "+self.get_env_var("PDEPEND") - - # change the parentheses into lists - mysplit = portage_dep.paren_reduce(depstring) - - # strip off these deps we don't have a flag for - mysplit = portage_dep.use_reduce(mysplit, uselist = actual, masklist = [], matchall = False, excludeall = self.get_settings("ARCH")) + depstring = "" + for d in depvar: + depstring += self.get_env_var(d)+" " - # move the || (or) into the lists - mysplit = portage_dep.dep_opconvert(mysplit) + portage_dep._dep_check_strict = False + deps = portage.dep_check(depstring, None, self._settings, myuse = actual, trees = self._trees) + portage_dep._dep_check_strict = True - # turn virtuals into real packages - mysplit = portage.dep_virtual(mysplit, self._settings) + if not deps: # FIXME: what is the difference to [1, []] ? + return [] - mysplit_reduced= portage.dep_wordreduce(mysplit, self._settings, vartree.dbapi, mode = None) + if deps[0] == 0: # error + raise DependencyCalcError, deps[1] - retlist = [] - def add (list, red_list): - """Adds the packages to retlist.""" - for i in range(len(list)): - if type(list[i]) == types.ListType: - add(list[i], red_list[i]) - elif list[i] == "||": - continue - else: - if red_list[i]: - retlist.append(list[i]) + deps = deps[1] - add(mysplit, mysplit_reduced) + retlist = [] + + for d in retlist: + if not d[0] == "!": + retlist.append(d) - return unique_array(retlist) + return retlist def get_dep_packages (self): """Returns a cpv-list of packages on which this package depends and which have not been installed yet. This does not check the dependencies in a recursive manner. @@ -287,7 +280,7 @@ class Package: # let portage do the main stuff ;) # pay attention to any changes here - deps = portage.dep_check (self.get_env_var("RDEPEND")+" "+self.get_env_var("DEPEND")+" "+self.get_env_var("PDEPEND"), vartree.dbapi, self._settings, myuse = actual, trees = trees) + deps = portage.dep_check (self.get_env_var("RDEPEND")+" "+self.get_env_var("DEPEND")+" "+self.get_env_var("PDEPEND"), portage_settings.vartree.dbapi, self._settings, myuse = actual, trees = self._trees) if not deps: # FIXME: what is the difference to [1, []] ? return [] @@ -369,7 +362,7 @@ class Package: def get_ebuild_path(self): """Returns the complete path to the .ebuild file""" - return portage.portdb.findname(self._cpv) + return portage_settings.porttree.dbapi.findname(self._cpv) def get_package_path(self): """Returns the path to where the ChangeLog, Manifest, .ebuild files reside""" @@ -378,12 +371,12 @@ class Package: if len(sp): return string.join(sp[:-1],"/") - def get_env_var(self, var, tree=""): + def get_env_var(self, var, tree = None): """Returns one of the predefined env vars DEPEND, RDEPEND, SRC_URI,....""" - if tree == "": - mytree = vartree + if not tree: + mytree = portage_settings.vartree if not self.is_installed(): - mytree = porttree + mytree = portage_settings.porttree else: mytree = tree r = mytree.dbapi.aux_get(self._cpv,[var]) @@ -392,7 +385,7 @@ class Package: def get_use_flags(self): if self.is_installed(): - return self.get_env_var("USE", tree = vartree) + return self.get_env_var("USE", tree = portage_settings.vartree) else: return "" def compare_version(self,other): diff --git a/portato/backend/portage_helper.py b/portato/backend/portage_helper.py index af8f128..188d512 100644 --- a/portato/backend/portage_helper.py +++ b/portato/backend/portage_helper.py @@ -15,7 +15,7 @@ import re, os, copy import portage from portage_util import unique_array -from portato.backend import * +from portato.backend import portage_settings import package from portato.helper import debug @@ -62,9 +62,9 @@ def find_best_match (search_key, only_installed = False): t = None if not only_installed: - t = porttree.dep_bestmatch(search_key) + t = portage_settings.porttree.dep_bestmatch(search_key) else: - t = vartree.dep_bestmatch(search_key) + t = portage_settings.vartree.dep_bestmatch(search_key) if t: return package.Package(t) return None @@ -82,22 +82,22 @@ def find_packages (search_key, masked=False): try: if masked: - t = porttree.dbapi.xmatch("match-all", search_key) - t += vartree.dbapi.match(search_key) + t = portage_settings.porttree.dbapi.xmatch("match-all", search_key) + t += portage_settings.vartree.dbapi.match(search_key) else: - t = porttree.dbapi.match(search_key) - t += vartree.dbapi.match(search_key) + t = portage_settings.porttree.dbapi.match(search_key) + t += portage_settings.vartree.dbapi.match(search_key) # catch the "ambigous package" Exception except ValueError, e: if type(e[0]) == types.ListType: t = [] for cp in e[0]: if masked: - t += porttree.dbapi.xmatch("match-all", cp) - t += vartree.dbapi.match(cp) + t += portage_settings.porttree.dbapi.xmatch("match-all", cp) + t += portage_settings.vartree.dbapi.match(cp) else: - t += porttree.dbapi.match(cp) - t += vartree.dbapi.match(cp) + t += portage_settings.porttree.dbapi.match(cp) + t += portage_settings.vartree.dbapi.match(cp) else: raise ValueError(e) # Make the list of packages unique @@ -117,13 +117,13 @@ def find_installed_packages (search_key, masked=False): @rtype: backend.Package[]""" try: - t = vartree.dbapi.match(search_key) + t = portage_settings.vartree.dbapi.match(search_key) # catch the "ambigous package" Exception except ValueError, e: if type(e[0]) == types.ListType: t = [] for cp in e[0]: - t += vartree.dbapi.match(cp) + t += portage_settings.vartree.dbapi.match(cp) else: raise ValueError(e) @@ -180,13 +180,13 @@ def find_all_installed_packages (name=None, withVersion=True): @rtype: backend.Package[] or cp-string[]""" if withVersion: - t = vartree.dbapi.cpv_all() + t = portage_settings.vartree.dbapi.cpv_all() if name: t = filter(find_lambda(name),t) return geneticize_list(t) else: - t = vartree.dbapi.cp_all() + t = portage_settings.vartree.dbapi.cp_all() if name: t = filter(find_lambda(name),t) return t @@ -213,8 +213,8 @@ def find_all_packages (name=None, withVersion=True): @returns: all packages/cp-strings found @rtype: backend.Package[] or cp-string[]""" - t = porttree.dbapi.cp_all() - t += vartree.dbapi.cp_all() + t = portage_settings.porttree.dbapi.cp_all() + t += portage_settings.vartree.dbapi.cp_all() if name: t = filter(find_lambda(name),t) t = unique_array(t) @@ -222,8 +222,8 @@ def find_all_packages (name=None, withVersion=True): if (withVersion): t2 = [] for x in t: - t2 += porttree.dbapi.cp_list(x) - t2 += vartree.dbapi.cp_list(x) + t2 += portage_settings.porttree.dbapi.cp_list(x) + t2 += portage_settings.vartree.dbapi.cp_list(x) t2 = unique_array(t2) return geneticize_list(t2) else: @@ -261,7 +261,7 @@ def list_categories (name=None): @returns: all categories found @rtype: string[]""" - categories = settings.categories + categories = portage_settings.settings.categories return filter(find_lambda(name), categories) def split_package_name (name): @@ -294,8 +294,7 @@ def sort_package_list(pkglist): def reload_settings (): """Reloads portage.""" - global settings - settings = portage.config(config_incrementals = copy.deepcopy(settings.incrementals)) + portage_settings.load() def update_world (newuse = False, deep = False): """Calculates the packages to get updated in an update world. @@ -317,7 +316,7 @@ def update_world (newuse = False, deep = False): packages.append(line) world.close() - sys = settings.packages + sys = portage_settings.settings.packages for x in sys: if x[0] == "*": x = x[1:] @@ -357,7 +356,7 @@ def update_world (newuse = False, deep = False): checked = [] updating = [] raw_checked = [] - def check (p): + def check (p, warn_no_installed = True): """Checks whether a package is updated or not.""" if p.get_cp() in checked: return else: checked.append(p.get_cp()) @@ -370,8 +369,13 @@ def update_world (newuse = False, deep = False): if oldList: old = oldList[0] # we should only have one package here - else it is a bug else: - debug("Bug? Not found installed one:",p.get_cp()) - return + oldList = sort_package_list(find_installed_packages(p.get_cp())) + if not oldList: + if warn_no_installed: + debug("Bug? Not found installed one:",p.get_cp()) + return + old = oldList[-1] + updating.append((p, old)) appended = True p = old @@ -398,20 +402,23 @@ def update_world (newuse = False, deep = False): appended = True if deep or tempDeep: - for i in p.get_matched_dep_packages(): - if i not in raw_checked: - raw_checked.append(i) - bm = get_new_packages([i]) - if not bm: - debug("Bug? No best match could be found:",i) - else: - for p in bm: - if not p: continue - check(p) + states = [(["RDEPEND","PDEPEND"],True), (["DEPEND"], False)] + + for state in states: + for i in p.get_matched_dep_packages(state[0]): + if i not in raw_checked: + raw_checked.append(i) + bm = get_new_packages([i]) + if not bm: + debug("Bug? No best match could be found:",i) + else: + for pkg in bm: + if not pkg: continue + check(pkg, state[1]) for p in get_new_packages(packages): if not p: continue # if a masked package is installed we have "None" here - check(p) + check(p, True) return updating @@ -433,7 +440,7 @@ def get_use_desc (flag, package = None): # fill cache if needed if use_descs == {} or local_use_descs == {}: # read use.desc - fd = open(settings["PORTDIR"]+"/profiles/use.desc") + fd = open(portage_settings.settings["PORTDIR"]+"/profiles/use.desc") for line in fd.readlines(): line = line.strip() if line != "" and line[0] != '#': @@ -442,7 +449,7 @@ def get_use_desc (flag, package = None): use_descs[fields[0]] = fields[1] # read use.local.desc - fd = open(settings["PORTDIR"]+"/profiles/use.local.desc") + fd = open(portage_settings.settings["PORTDIR"]+"/profiles/use.local.desc") for line in fd.readlines(): line = line.strip() if line != "" and line[0] != '#': -- cgit v1.2.3-70-g09d2