From 40eaa80dce320c6e64e66d96ec28c9fc532c061c Mon Sep 17 00:00:00 2001 From: necoro <> Date: Sun, 15 Oct 2006 16:13:37 +0000 Subject: First implementation of "emerge --update world" --- geneticone/backend/__init__.py | 4 ++-- geneticone/backend/portage_helper.py | 28 ++++++++++++++++++++++ geneticone/gui/gui_helper.py | 39 ++++++++++++++++++++---------- geneticone/gui/windows.py | 46 +++++++++++++++++++++++++++++++++--- 4 files changed, 100 insertions(+), 17 deletions(-) diff --git a/geneticone/backend/__init__.py b/geneticone/backend/__init__.py index 5238765..dbebd17 100644 --- a/geneticone/backend/__init__.py +++ b/geneticone/backend/__init__.py @@ -19,8 +19,8 @@ import gentoolkit import portage # this is set to "var/lib/portage/world" by default - so we add the leading / -portage.WORLD_FILE = "/"+portage.WORLD_FILE -portage.settings = None +portage.WORLD_FILE = portage.settings["ROOT"]+portage.WORLD_FILE +portage.settings = None # we use our own one ... # portage tree vars porttree = gentoolkit.porttree diff --git a/geneticone/backend/portage_helper.py b/geneticone/backend/portage_helper.py index 37a2b91..df0275f 100644 --- a/geneticone/backend/portage_helper.py +++ b/geneticone/backend/portage_helper.py @@ -236,6 +236,34 @@ def reload_settings (): """Reloads portage.""" gentoolkit.settings = portage.config(config_incrementals = copy.deepcopy(gentoolkit.settings.incrementals)) +def update_world (newuse = False, deep = False): + """Calculates the packages to get updated in an update world. + + @param newuse: Checks if a use-flag has a different state then to install time. + @type newuse: boolean + @param deep: Not only check world packages but also there dependencies. + @type deep: boolean + @returns: a list containing of the tuple (new_package, old_package) + @rtype: (backend.Package, backend.Package)[]""" + + world = open(portage.WORLD_FILE) + packages = [] + for line in world: + line = line.strip() + if not len(line): continue # empty line + if line[0] == "#": continue + packages.append(find_best_match(line)) + world.close() + + 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 + updating.append((p, old)) + + return updating + use_descs = {} local_use_descs = {} def get_use_desc (flag, package = None): diff --git a/geneticone/gui/gui_helper.py b/geneticone/gui/gui_helper.py index 08d1926..7171b67 100644 --- a/geneticone/gui/gui_helper.py +++ b/geneticone/gui/gui_helper.py @@ -280,7 +280,7 @@ class EmergeQueue: return pkg - def update_tree (self, it, cpv, unmask = False, options = ""): + def update_tree (self, it, cpv, unmask = False, options = []): """This updates the tree recursivly, or? Isn't it? Bjorn! @param it: iterator where to append @@ -290,7 +290,7 @@ class EmergeQueue: @param unmask: True if we are allowed to look for masked packages @type unmask: boolean @param options: options to append to the tree - @type options: string + @type options: string[] @raises backend.BlockedException: When occured during dependency-calculation. @raises backend.PackageNotFoundException: If no package could be found - normally it is existing but masked.""" @@ -308,7 +308,7 @@ class EmergeQueue: raise e # add iter - subIt = self.tree.append(it, [cpv, ""+options+""]) + subIt = self.tree.append(it, [cpv, ""+" ".join(options)+""]) self.iters.update({cpv: subIt}) # get dependencies @@ -324,7 +324,7 @@ class EmergeQueue: self.remove_with_children(subIt) raise e - def append (self, cpv, unmerge = False, update = False, forceUpdate = False, unmask = False, oneshot = False): + def append (self, cpv, unmerge = False, update = False, forceUpdate = False, unmask = False, oneshot = False, options = []): """Appends a cpv either to the merge queue or to the unmerge-queue. Also updates the tree-view. @@ -340,6 +340,8 @@ class EmergeQueue: @type unmask: boolean @param oneshot: True if this package should not be added to the world-file. @type oneshot: boolean + @param options: additional options to get showed in tree + @param options: string[] @raises geneticone.backend.PackageNotFoundException: if trying to add a package which does not exist""" @@ -355,17 +357,16 @@ class EmergeQueue: else: hasBeenInQueue = (cpv in self.mergequeue or cpv in self.oneshotmerge) parentIt = self.tree.iter_parent(self.iters[cpv]) - options = "" # delete it out of the tree - but NOT the changed flags self.remove_with_children(self.iters[cpv], removeNewFlags = False) if hasBeenInQueue: # package has been in queue before - options = self._queue_append(cpv, oneshot) + options += self._queue_append(cpv, oneshot) self.update_tree(parentIt, cpv, unmask, options = options) else: # not update - options = self._queue_append(cpv, oneshot) + options += self._queue_append(cpv, oneshot) if self.emergeIt: self.update_tree(self.emergeIt, cpv, unmask, options) @@ -388,14 +389,14 @@ class EmergeQueue: @type oneshot: boolean @returns: options set - @rtype: string""" + @rtype: string[]""" - options = "" + options = [] if not oneshot: self.mergequeue.append(cpv) else: self.oneshotmerge.append(cpv) - options="oneshot" + options.append("oneshot") return options @@ -433,7 +434,7 @@ class EmergeQueue: process = Popen(["/usr/bin/python","/usr/bin/emerge"]+options+packages, stdout = slave, stderr = STDOUT, shell = False) # start thread waiting for the stop of emerge - Thread(target=self._update_packages, args=(packages, process)).start() + Thread(target=self._update_packages, args=(packages+self.deps.keys(), process)).start() # remove for i in it: @@ -487,10 +488,24 @@ class EmergeQueue: # set options s = ["-C"] - if not force: s = ["-Cpv"] + if not force: s += ["-pv"] self._emerge(s,list, [self.unmergeIt]) + def update_world(self, force = False, newuse = False, deep = False): + """Does an update world. newuse and deep are the arguments handed to emerge. + + @param force: If False, '-pv' is send to emerge. Default: False. + @type force: boolean""" + + options = ["--update"] + + if newuse: options += ["--newuse"] + if deep: options += ["--deep"] + if not force: options += ["-pv"] + + self._emerge(options, ["world"], [self.emergeIt]) + def remove_with_children (self, it, removeNewFlags = True): """Convenience function which removes all children of an iterator and than the iterator itself. diff --git a/geneticone/gui/windows.py b/geneticone/gui/windows.py index 4861b89..fedd1b7 100644 --- a/geneticone/gui/windows.py +++ b/geneticone/gui/windows.py @@ -581,6 +581,9 @@ class MainWindow: if gtk.gdk.screen_height() <= 800: mHeight = 600 self.window.set_geometry_hints (self.window, min_width = 600, min_height = mHeight, max_height = gtk.gdk.screen_height(), max_width = gtk.gdk.screen_width()) + # booleans + self.doUpdate = False + # package db self.db = Database() self.db.populate() @@ -594,6 +597,8 @@ class MainWindow: self.emergeAction.connect("activate", self.cb_emerge_clicked) self.unmergeAction = gtk.Action("Unmerge", "_Unmerge", None, None) self.unmergeAction.connect("activate", self.cb_emerge_clicked) + self.updateAction = gtk.Action("UpdateWorld", "Update _World", None, None) + self.updateAction.connect("activate", self.cb_update_clicked) # main vb vb = gtk.VBox(False, 1) @@ -664,15 +669,23 @@ class MainWindow: buttonBox = gtk.VButtonBox() buttonBox.set_layout(gtk.BUTTONBOX_SPREAD) queueHB.pack_start(buttonBox, False) + emergeBtn = gtk.Button() self.emergeAction.connect_proxy(emergeBtn) + + updateBtn = gtk.Button() + self.updateAction.connect_proxy(updateBtn) + unmergeBtn = gtk.Button() self.unmergeAction.connect_proxy(unmergeBtn) + removeBtn = gtk.Button("_Remove") removeBtn.connect("clicked", self.cb_remove_clicked) + buttonBox.pack_start(emergeBtn) - buttonBox.pack_start(removeBtn) buttonBox.pack_start(unmergeBtn) + buttonBox.pack_start(updateBtn) + buttonBox.pack_start(removeBtn) # the terminal term = vte.Terminal() @@ -718,6 +731,7 @@ class MainWindow: + @@ -739,6 +753,7 @@ class MainWindow: ("About", None, "_About", None, None, lambda x: AboutWindow(self.window))]) group.add_action(self.emergeAction) group.add_action(self.unmergeAction) + group.add_action(self.updateAction) um.insert_action_group(group,0) group = gtk.ActionGroup("PopupActions") @@ -835,33 +850,58 @@ class MainWindow: if model.iter_n_children(iter) > 0: # and has children which can be removed :) if remove_queue_dialog() == gtk.RESPONSE_YES : self.queue.remove_children(iter) + self.doUpdate = False elif model.iter_parent(model.iter_parent(iter)): # this is in the 3rd level => dependency remove_deps_dialog() else: self.queue.remove_children(iter) # remove children first self.queue.remove(iter) + self.doUpdate = False return True - def cb_emerge_clicked (self, action, data = None): + def cb_emerge_clicked (self, action): """Do emerge or unemerge.""" + self.notebook.set_current_page(1) + if action == self.emergeAction: if len(flags.newUseFlags) > 0: changed_flags_dialog("use flags") flags.write_use_flags() + if len(flags.new_masked)>0 or len(flags.new_unmasked)>0 or len(flags.newTesting)>0: changed_flags_dialog("masking keywords") flags.write_masked() flags.write_testing() backend.reload_settings() - self.queue.emerge(force=True) + + if not self.doUpdate: + self.queue.emerge(force=True) + else: + self.queue.update_world(force=True, deep = False, newuse = False) + self.doUpdate = False + elif action == self.unmergeAction: self.queue.unmerge(force=True) return True + def cb_update_clicked (self, action): + if not backend.am_i_root(): + not_root_dialog() + + else: + updating = backend.update_world(newuse = False, deep = False) + debug("updating list:", updating) + for pkg, old_pkg in updating: + self.queue.append(pkg.get_cpv(), options=["update from "+old_pkg.get_version()]) + + if len(updating): self.doUpdate = True + + return True + def cb_search_clicked (self, button, data = None): """Do a search.""" if self.searchEntry.get_text() != "": -- cgit v1.2.3-70-g09d2