From 48fa7e6ef10bcc87e263f1c52d7430bafa23fe21 Mon Sep 17 00:00:00 2001 From: necoro <> Date: Sun, 15 Oct 2006 21:42:18 +0000 Subject: Second level of "emerge --update" --- etc/geneticone.cfg | 2 ++ geneticone/backend/package.py | 57 ++++++++++++++++++++++++++++++++++-- geneticone/backend/portage_helper.py | 33 ++++++++++++++++++--- geneticone/gui/gui_helper.py | 4 ++- geneticone/gui/windows.py | 39 +++++++++++++++++++----- 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("""For the following options, you might use these placeholders: $(cat) = category $(pkg) = 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()]) -- cgit v1.2.3