summaryrefslogtreecommitdiff
path: root/portato/backend
diff options
context:
space:
mode:
authornecoro <>2006-12-29 01:48:41 +0000
committernecoro <>2006-12-29 01:48:41 +0000
commitf268e6d065e3cbb2d694889e37373c8fc3d55198 (patch)
tree9e132541981309a10a8719b5b738da50d14b03c8 /portato/backend
parente24a27421f04df124425499babe660db15246985 (diff)
downloadportato-f268e6d065e3cbb2d694889e37373c8fc3d55198.tar.gz
portato-f268e6d065e3cbb2d694889e37373c8fc3d55198.tar.bz2
portato-f268e6d065e3cbb2d694889e37373c8fc3d55198.zip
enhancement for the settings-handling (better reloading-support, moving into a class), enhanced update_world-check
Diffstat (limited to '')
-rw-r--r--portato/backend/__init__.py43
-rw-r--r--portato/backend/package.py85
-rw-r--r--portato/backend/portage_helper.py85
3 files changed, 121 insertions, 92 deletions
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 <necoro@necoro.net>
-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 <necoro@necoro.net>
-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] != '#':