summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--etc/geneticone.cfg2
-rw-r--r--geneticone/backend/package.py57
-rw-r--r--geneticone/backend/portage_helper.py33
-rw-r--r--geneticone/gui/gui_helper.py4
-rw-r--r--geneticone/gui/windows.py39
5 files changed, 120 insertions, 15 deletions
diff --git a/etc/geneticone.cfg b/etc/geneticone.cfg
index a8c1bf3..2041147 100644
--- a/etc/geneticone.cfg
+++ b/etc/geneticone.cfg
@@ -6,3 +6,5 @@ keywordfile = geneticone
maskperversion = True
useperversion = True
usefile = geneticone
+deep = True
+newuse = True
diff --git a/geneticone/backend/package.py b/geneticone/backend/package.py
index da2a131..8991117 100644
--- a/geneticone/backend/package.py
+++ b/geneticone/backend/package.py
@@ -14,9 +14,11 @@ from geneticone.helper import *
from portage_helper import *
import flags
-import portage, gentoolkit
+import portage, portage_dep, gentoolkit
from portage_util import unique_array
+import types
+
class Package (gentoolkit.Package):
"""This is a subclass of the gentoolkit.Package-class which a lot of additional functionality we need in Genetic/One."""
@@ -172,6 +174,58 @@ class Package (gentoolkit.Package):
flags.remove_new_use_flags(self)
+ def get_matched_dep_packages (self):
+ """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[]"""
+
+ # change the useflags, because we have internally changed some, but not made them visible for portage
+ newUseFlags = self.get_new_use_flags()
+ actual = self.get_settings("USE").split()
+ if newUseFlags:
+ for u in newUseFlags:
+ if u[0] == "-" and flags.invert_use_flag(u) in actual:
+ actual.remove(flags.invert_use_flag(u))
+ 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"))
+
+ # move the || (or) into the lists
+ mysplit = portage_dep.dep_opconvert(mysplit)
+
+ # turn virtuals into real packages
+ mysplit = portage.dep_virtual(mysplit, self._settings)
+
+ mysplit_reduced= portage.dep_wordreduce(mysplit, self._settings, vartree.dbapi, mode = None)
+
+ 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])
+
+ add(mysplit, mysplit_reduced)
+
+ return unique_array(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.
@@ -188,7 +242,6 @@ class Package (gentoolkit.Package):
newUseFlags = self.get_new_use_flags()
actual = self.get_settings("USE").split()
if newUseFlags:
- depUses = []
for u in newUseFlags:
if u[0] == "-" and flags.invert_use_flag(u) in actual:
actual.remove(flags.invert_use_flag(u))
diff --git a/geneticone/backend/portage_helper.py b/geneticone/backend/portage_helper.py
index df0275f..9faf953 100644
--- a/geneticone/backend/portage_helper.py
+++ b/geneticone/backend/portage_helper.py
@@ -17,6 +17,8 @@ from portage_util import unique_array
from geneticone.backend import *
import package
+from geneticone.helper import debug
+
def find_lambda (name):
"""Returns the function needed by all the find_all_*-functions. Returns None if no name is given.
@@ -246,6 +248,7 @@ def update_world (newuse = False, deep = False):
@returns: a list containing of the tuple (new_package, old_package)
@rtype: (backend.Package, backend.Package)[]"""
+ # read world file
world = open(portage.WORLD_FILE)
packages = []
for line in world:
@@ -255,13 +258,35 @@ def update_world (newuse = False, deep = False):
packages.append(find_best_match(line))
world.close()
+ checked = []
updating = []
- for p in packages:
- if not p: continue # if a masked package is installed we have "None" here
- if not p.is_installed():
- old = find_installed_packages(p.get_cp())[0] # assume we have only one there; FIXME: slotted packages
+ def check (p, deep = False):
+ """Checks whether a package is updated or not."""
+ if p.get_cp() in checked: return
+ else: checked.append(p.get_cp())
+
+ if not p.is_installed():
+ old = find_installed_packages(p.get_cp())
+ if old:
+ old = old[0] # assume we have only one there; FIXME: slotted packages
+ else:
+ debug("Bug? Not found installed one:",p.get_cp())
+ return
updating.append((p, old))
+ p = old
+
+ if deep:
+ for i in p.get_matched_dep_packages():
+ bm = find_best_match(i)
+ if not bm:
+ debug("Bug? No best match could be found:",i)
+ else:
+ check(bm, deep)
+ for p in packages:
+ if not p: continue # if a masked package is installed we have "None" here
+ check(p, deep)
+
return updating
use_descs = {}
diff --git a/geneticone/gui/gui_helper.py b/geneticone/gui/gui_helper.py
index 909c98f..5d93822 100644
--- a/geneticone/gui/gui_helper.py
+++ b/geneticone/gui/gui_helper.py
@@ -34,7 +34,9 @@ class Config:
"testingFile_opt" : "keywordfile",
"testingPerVersion_opt" : "keywordperversion",
"debug_opt" : "debug",
- "oneshot_opt" : "oneshot"
+ "oneshot_opt" : "oneshot",
+ "deep_opt" : "deep",
+ "newuse_opt" : "newuse"
}
def __init__ (self, cfgFile):
diff --git a/geneticone/gui/windows.py b/geneticone/gui/windows.py
index 4fff529..9af3e01 100644
--- a/geneticone/gui/windows.py
+++ b/geneticone/gui/windows.py
@@ -186,10 +186,14 @@ class PreferenceWindow (AbstractDialog):
self.window.add(box)
# En-/Disable Debugging
- self.debugCb = gtk.CheckButton(label="Debugging modus")
- self.debugCb.set_active(self.cfg.get_boolean(self.cfg.const["debug_opt"]))
- box.pack_start(self.debugCb, True, True)
+ self.debugCb = self.draw_cb(box, "Debugging modus", "debug_opt")
+ # --deep
+ self.deepCb = self.draw_cb(box, "--deep", "deep_opt")
+
+ # --newuse
+ self.newuseCb = self.draw_cb(box, "--newuse", "newuse_opt")
+
pHolderLabel = gtk.Label("""<u>For the following options, you might use these placeholders:</u>
<b>$(cat)</b> = category
<b>$(pkg)</b> = package-name
@@ -234,9 +238,7 @@ class PreferenceWindow (AbstractDialog):
@rtype: (gtk.CheckButton, gtk.Edit)"""
# check-button
- cb = gtk.CheckButton(label=("Add to %s on a per-version-base" % string))
- cb.set_active(self.cfg.get_boolean(self.cfg.const[cb_opt]))
- box.pack_start(cb, True, True)
+ cb = self.draw_cb(box, label=("Add to %s on a per-version-base" % string), opt = cb_opt)
# edit with label
hBox = gtk.HBox()
@@ -249,6 +251,24 @@ class PreferenceWindow (AbstractDialog):
return (cb, edit)
+ def draw_cb (self, box, label, opt):
+ """Draws a checkbox.
+
+ @param box: box to place the cb into
+ @type box: gtk.Box
+ @param label: Label to show
+ @type label: string
+ @param opt: the option string for the Config.const-dict
+ @type opt: string
+ @returns: the checkbox
+ @rtype: gtk.CheckButton"""
+
+ cb = gtk.CheckButton(label=label)
+ cb.set_active(self.cfg.get_boolean(self.cfg.const[opt]))
+ box.pack_start(cb, True, True)
+
+ return cb
+
def _save(self):
"""Sets all options in the Config-instance."""
self.cfg.set(self.cfg.const["usePerVersion_opt"], str(self.usePerVersionCb.get_active()))
@@ -258,6 +278,8 @@ class PreferenceWindow (AbstractDialog):
self.cfg.set(self.cfg.const["testingPerVersion_opt"], str(self.testPerVersionCb.get_active()))
self.cfg.set(self.cfg.const["testingFile_opt"], self.testFileEdit.get_text())
self.cfg.set(self.cfg.const["debug_opt"], str(self.debugCb.get_active()))
+ self.cfg.set(self.cfg.const["deep_opt"], str(self.deepCb.get_active()))
+ self.cfg.set(self.cfg.const["newuse_opt"], str(self.newuseCb.get_active()))
def cb_ok_clicked(self, button):
"""Saves, writes to config-file and closes the window."""
@@ -882,7 +904,7 @@ class MainWindow:
if not self.doUpdate:
self.queue.emerge(force=True)
else:
- self.queue.update_world(force=True, deep = False, newuse = False)
+ self.queue.update_world(force=True, newuse = self.cfg.get_boolean(self.cfg.const["newuse_opt"]), deep = self.cfg.get_boolean(self.cfg.const["deep_opt"]))
self.doUpdate = False
elif action == self.unmergeAction:
@@ -895,7 +917,8 @@ class MainWindow:
not_root_dialog()
else:
- updating = backend.update_world(newuse = False, deep = False)
+ updating = backend.update_world(newuse = self.cfg.get_boolean(self.cfg.const["newuse_opt"]), deep = self.cfg.get_boolean(self.cfg.const["deep_opt"]))
+
debug("updating list:", updating)
for pkg, old_pkg in updating:
self.queue.append(pkg.get_cpv(), options=["update from "+old_pkg.get_version()])