summaryrefslogtreecommitdiff
path: root/geneticone
diff options
context:
space:
mode:
authornecoro <>2006-10-15 16:13:37 +0000
committernecoro <>2006-10-15 16:13:37 +0000
commit40eaa80dce320c6e64e66d96ec28c9fc532c061c (patch)
tree400c9ca8565ca9d8d6622b1405891f9f528fa9b0 /geneticone
parentd7f6eeadf843200a56cf21a018fc2a5afc8c7bcb (diff)
downloadportato-40eaa80dce320c6e64e66d96ec28c9fc532c061c.tar.gz
portato-40eaa80dce320c6e64e66d96ec28c9fc532c061c.tar.bz2
portato-40eaa80dce320c6e64e66d96ec28c9fc532c061c.zip
First implementation of "emerge --update world"
Diffstat (limited to 'geneticone')
-rw-r--r--geneticone/backend/__init__.py4
-rw-r--r--geneticone/backend/portage_helper.py28
-rw-r--r--geneticone/gui/gui_helper.py39
-rw-r--r--geneticone/gui/windows.py46
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, "<i>"+options+"</i>"])
+ subIt = self.tree.append(it, [cpv, "<i>"+" ".join(options)+"</i>"])
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:
<menu action="EmergeMenu">
<menuitem action="Emerge" />
<menuitem action="Unmerge" />
+ <menuitem action="UpdateWorld" />
</menu>
<menu action="Help">
<menuitem action="About" />
@@ -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() != "":