summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/Changelog6
-rw-r--r--etc/geneticone.cfg8
-rw-r--r--geneticone/backend/flags.py55
-rw-r--r--geneticone/backend/package.py20
-rw-r--r--geneticone/backend/portage_helper.py52
-rw-r--r--geneticone/gui/dialogs.py55
-rw-r--r--geneticone/gui/gui_helper.py102
-rw-r--r--geneticone/gui/windows.py112
-rw-r--r--geneticone/helper.py8
9 files changed, 293 insertions, 125 deletions
diff --git a/doc/Changelog b/doc/Changelog
index ba091ef..1c197e7 100644
--- a/doc/Changelog
+++ b/doc/Changelog
@@ -1,3 +1,9 @@
+0.4.0:
+- smashed bugs
+- made testing and masking working (I hope)
+- allowed to unmask a whole queue
+- allowed to disable/enable debug-output
+
0.3.4:
- removed several minor and less minor bugs
- added preference window
diff --git a/etc/geneticone.cfg b/etc/geneticone.cfg
index c0b4d4e..a8c1bf3 100644
--- a/etc/geneticone.cfg
+++ b/etc/geneticone.cfg
@@ -1,4 +1,8 @@
[Main]
-usefile = geneticone
+keywordperversion = True
+debug = False
+maskfile = geneticone
+keywordfile = geneticone
+maskperversion = True
useperversion = True
-
+usefile = geneticone
diff --git a/geneticone/backend/flags.py b/geneticone/backend/flags.py
index 2da0a94..1d2f321 100644
--- a/geneticone/backend/flags.py
+++ b/geneticone/backend/flags.py
@@ -23,7 +23,10 @@ from portage_util import unique_array
CONFIG = {
"usefile" : "geneticone",
"maskfile" : "geneticone",
- "usePerVersion" : True
+ "testingfile" : "geneticone",
+ "usePerVersion" : True,
+ "maskPerVersion" : True,
+ "testingPerVersion" : True
}
### GENERAL PART ###
@@ -41,7 +44,7 @@ def grep (pkg, path):
if not isinstance(pkg, package.Package):
pkg = package.Package(pkg) # assume it is a cpv or a gentoolkit.Package
- command = "egrep -x -n -r -H '^[<>!=~]{0,2}%s(-[0-9].*)?[[:space:]]?.*$' %s"
+ command = "egrep -x -n -r -H '^[<>!=~]{0,2}%s(-[0-9].*)?[[:space:]]?.*$' %s" # %s is replaced in the next line ;)
return Popen((command % (pkg.get_cp(), path)), shell = True, stdout = PIPE).communicate()[0].splitlines()
def get_data(pkg, path):
@@ -66,7 +69,7 @@ def get_data(pkg, path):
fl = fl[1:]
# stop after first comment
for i in range(len(fl)):
- if fl[i][0] == "#": #comment - stop here
+ if fl[i][0] == "#": # comment - stop here
fl = fl[:i]
break
flags.append((file,line,crit,fl))
@@ -74,7 +77,7 @@ def get_data(pkg, path):
return flags
def set_config (cfg):
- """This function sets the CONFIG-variable for the whole module. Use this instead of modifying CONFIG directly.
+ """This function sets the CONFIG-variable for the whole module. Use this instead of modifying L{CONFIG} directly.
@param cfg: a dictionary with at least all the keys of the CONFIG-var
@type cfg: dict
@raises KeyError: if a keyword is missing in the new cfg"""
@@ -87,11 +90,27 @@ def set_config (cfg):
CONFIG[i] = cfg[i]
def generate_path (cpv, exp):
+ """Generates the correct path out of given wildcards.
+ These wildcards can be:
+ - $(cat) : category
+ - $(cat-1): first part of the category (e.g. "app")
+ - $(cat-2): second part of the category
+ - $(pkg) : name of the package
+
+ @param cpv: the cpv of the current package
+ @type cpv: string (cat/pkg-ver)
+ @param exp: the expression to render the path from
+ @type exp: string
+ @returns: rendered path
+ @rtype string"""
cat, pkg, ver, rev = split_package_name(cpv)
if exp.find("$(") != -1:
- exp = exp.replace("$(cat)",cat).replace("$(pkg)",pkg).replace("$(cat-1)",cat.split("-")[0]).replace("$(cat-2)",cat.split("-")[1])
+ exp = exp.replace("$(cat)",cat).\
+ replace("$(pkg)",pkg).\
+ replace("$(cat-1)",cat.split("-")[0]).\
+ replace("$(cat-2)",cat.split("-")[1])
return exp
### USE FLAG PART ###
@@ -284,9 +303,9 @@ def write_use_flags ():
# write new lines
msg = "\n#geneticone update#\n"
- if CONFIG["usePerVersion"]:
+ if CONFIG["usePerVersion"]: # add on a per-version-base
msg += "=%s %s\n" % (cpv, ' '.join(flagsToAdd))
- else:
+ else: # add on a per-package-base
list = split_package_name(cpv)
msg += "%s/%s %s\n" % (list[0], list[1], ' '.join(flagsToAdd))
if not file in file_cache:
@@ -305,11 +324,6 @@ def write_use_flags ():
useFlags = {}
newUseFlags = {}
-#
-#
-# NOTHING IS WORKING / IN USE BELOW THIS LINE
-#
-#
### MASKING PART ###
MASK_PATH = os.path.join(portage.USER_CONFIG_PATH,"package.mask")
UNMASK_PATH = os.path.join(portage.USER_CONFIG_PATH,"package.unmask")
@@ -321,6 +335,7 @@ new_unmasked = {}
def set_masked (pkg, masked = True):
global new_masked, newunmasked
+
if not isinstance(pkg, package.Package):
pkg = package.Package(pkg)
@@ -411,7 +426,12 @@ def write_masked ():
line = int(line)
# add new line
if line == -1:
- msg = "\n#geneticone update#\n=%s\n" % cpv
+ msg = "\n#geneticone update#\n"
+ if CONFIG["maskPerVersion"]:
+ msg += "=%s\n" % cpv
+ else:
+ list = split_package_name(cpv)
+ msg += "%s/%s\n" % (list[0],list[1])
if not file in file_cache:
f = open(file, "a")
f.write(msg)
@@ -519,7 +539,7 @@ def set_testing (pkg, enable):
newTesting[cpv].append((file, line))
else:
if TESTING_PATH_IS_DIR:
- file = os.path.join(TESTING_PATH, "geneticone")
+ file = os.path.join(TESTING_PATH, CONFIG["testingfile"])
else:
file = TESTING_PATH
newTesting[cpv].append((file, "-1"))
@@ -536,7 +556,12 @@ def write_testing ():
line = int(line)
# add new line
if line == -1:
- msg = "\n#geneticone update#\n=%s ~%s\n" % (cpv, arch)
+ msg = "\n#geneticone update#\n"
+ if CONFIG["testingPerVersion"]:
+ msg += "=%s ~%s\n" % (cpv, arch)
+ else:
+ list = split_package_name(cpv)
+ msg += "%s/%s ~%s\n" % (list[0],list[1],arch)
if not file in file_cache:
f = open(file, "a")
f.write(msg)
diff --git a/geneticone/backend/package.py b/geneticone/backend/package.py
index 7b917a8..522ca08 100644
--- a/geneticone/backend/package.py
+++ b/geneticone/backend/package.py
@@ -14,8 +14,7 @@ from geneticone.helper import *
from portage_helper import *
import flags
-import gentoolkit
-import portage
+import portage, gentoolkit
from portage_util import unique_array
class Package (gentoolkit.Package):
@@ -182,8 +181,21 @@ class Package (gentoolkit.Package):
continue
pkg = find_best_match(dep)
- if not dep:
- raise PackageNotFoundException, dep
+ if not pkg: # try to find masked ones
+ list = find_packages(dep, masked = True)
+ if not list:
+ raise PackageNotFoundException, dep
+
+ list = sort_package_list(list)
+ done = False
+ for i in range(len(list)-1,0,-1):
+ p = list[i]
+ if not p.is_masked():
+ dep_pkgs.append(p.get_cpv())
+ done = True
+ break
+ if not done:
+ dep_pkgs.append(list[-1].get_cpv())
else:
dep_pkgs.append(pkg.get_cpv())
diff --git a/geneticone/backend/portage_helper.py b/geneticone/backend/portage_helper.py
index aae7c19..23172e5 100644
--- a/geneticone/backend/portage_helper.py
+++ b/geneticone/backend/portage_helper.py
@@ -7,14 +7,11 @@
# the GNU General Public License version 2.
# There is NO WARRANTY, to the extent permitted by law.
#
-# Written by Necoro d.M. <necoro@necoro.net> et.al.
+# Written by Necoro d.M. <necoro@necoro.net>
-import re
-import os
-import copy
+import re, os, copy
-import gentoolkit
-import portage
+import portage, gentoolkit
from portage_util import unique_array
from geneticone.backend import *
@@ -42,7 +39,16 @@ def geneticize_list (list_of_packages):
return [package.Package(x) for x in list_of_packages]
def find_best_match (search_key, only_installed = False):
- """Finds the best match in the portage tree."""
+ """Finds the best match in the portage tree. It does not find masked packages!
+
+ @param search_key: the key to find in the portage tree
+ @type search_key: string
+ @param only_installed: if True, only installed packages are searched
+ @type only_installed: boolean
+
+ @returns: the package found or None
+ @rtype: backend.Package or None"""
+
t = None
if not only_installed:
t = porttree.dep_bestmatch(search_key)
@@ -53,14 +59,28 @@ def find_best_match (search_key, only_installed = False):
return None
def find_packages (search_key, masked=False):
- """This returns a list of packages which have to fit exactly. Additionally ranges like '<,>,=,~,!' et. al. are possible."""
+ """This returns a list of packages which have to fit exactly. Additionally ranges like '<,>,=,~,!' et. al. are possible.
+ @param search_key: the key to look for
+ @type search_key: string
+ @param masked: if True, also look for masked packages
+ @type masked: boolean
+ @returns: list of found packages
+ @rtype: list of backend.Package"""
+
return geneticize_list(gentoolkit.find_packages(search_key, masked))
def find_installed_packages (search_key, masked=False):
- """This returns a list of installed packages which have to fit exactly. Additionally ranges like '<,>,=,~,!' et. al. are possible."""
+ """This returns a list of packages which have to fit exactly. Additionally ranges like '<,>,=,~,!' et. al. are possible.
+ @param search_key: the key to look for
+ @type search_key: string
+ @param masked: if True, also look for masked packages
+ @type masked: boolean
+ @returns: list of found packages
+ @rtype: list of backend.Package"""
+
return geneticize_list(gentoolkit.find_installed_packages(search_key, masked))
-def find_system_packages (name=None):
+def find_system_packages ():
"""Returns a list-tuple (resolved_packages, unresolved_packages) for all system packages."""
list = gentoolkit.find_system_packages()
return (geneticize_list(list[0]), geneticize_list(list[1]))
@@ -114,12 +134,22 @@ def find_all_system_packages (name=None):
return [package.Package(x) for x in sys]
def get_all_versions (cp):
+ """Returns all versions of a certain package.
+ @param cp: the package
+ @type cp: string (cat/pkg)
+ @returns: the list of found packages
+ @rtype: list of backend.Package"""
t = porttree.dbapi.cp_list(cp)
t += vartree.dbapi.cp_list(cp)
t = unique_array(t)
return geneticize_list(t)
def get_all_installed_versions (cp):
+ """Returns all installed versions of a certain package.
+ @param cp: the package
+ @type cp: string (cat/pkg)
+ @returns: the list of found packages
+ @rtype: list of backend.Package"""
return geneticize_list(vartree.dbapi.cp_list(cp))
def list_categories (name=None):
@@ -138,7 +168,7 @@ def sort_package_list(pkglist):
return gentoolkit.sort_package_list(pkglist)
def reload_settings ():
- # XXX: what the hack are we doing here Oo
+ """Reloads portage."""
gentoolkit.settings = portage.config(config_incrementals = copy.deepcopy(gentoolkit.settings.incrementals))
use_descs = {}
diff --git a/geneticone/gui/dialogs.py b/geneticone/gui/dialogs.py
new file mode 100644
index 0000000..ddb9d52
--- /dev/null
+++ b/geneticone/gui/dialogs.py
@@ -0,0 +1,55 @@
+#
+# File: geneticone/gui/dialogs.py
+# This file is part of the Genetic/One-Project, a graphical portage-frontend.
+#
+# Copyright (C) 2006 Necoro d.M.
+# This is free software. You may redistribute copies of it under the terms of
+# the GNU General Public License version 2.
+# There is NO WARRANTY, to the extent permitted by law.
+#
+# Written by Necoro d.M. <necoro@necoro.net>
+
+import gtk
+
+def blocked_dialog (blocked, blocks):
+ dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, blocked+" is blocked by "+blocks+".\nPlease unmerge the blocking package.")
+ dialog.run()
+ dialog.destroy()
+
+def not_root_dialog ():
+ errorMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, "You cannot (un)merge without being root.")
+ errorMB.run()
+ errorMB.destroy()
+
+def masked_dialog (cpv):
+ dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, cpv+" seems to be masked.\nPlease edit the appropriate file(s) to unmask it and restart Genetic/One.\n")
+ dialog.run()
+ dialog.destroy()
+
+def unmask_dialog (cpv):
+ dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, cpv+" seems to be masked.\nDo you want to unmask it and its dependencies?.\n")
+ ret = dialog.run()
+ dialog.destroy()
+ return ret
+
+def nothing_found_dialog ():
+ dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, "Package not found!")
+ dialog.run()
+ dialog.destroy()
+
+def changed_flags_dialog (what = "flags"):
+ hintMB = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK,
+ "You have changed %s. Genetic/One will write these changes into the appropriate files. Please backup them if you think it is necessairy." % what)
+ hintMB.run()
+ hintMB.destroy()
+
+def remove_deps_dialog ():
+ infoMB = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, "You cannot remove dependencies. :)")
+ infoMB.run()
+ infoMB.destroy()
+
+def remove_queue_dialog ():
+ askMB = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, "Do you really want to clear the whole queue?")
+ ret = askMB.run()
+ askMB.destroy()
+ return ret
diff --git a/geneticone/gui/gui_helper.py b/geneticone/gui/gui_helper.py
index 2120ea3..203f7e7 100644
--- a/geneticone/gui/gui_helper.py
+++ b/geneticone/gui/gui_helper.py
@@ -12,9 +12,9 @@
from geneticone import backend
from geneticone.backend import flags
from geneticone.helper import *
-import windows
+import dialogs
-from subprocess import *
+from subprocess import Popen, PIPE, STDOUT
from threading import Thread
from ConfigParser import SafeConfigParser
@@ -26,7 +26,11 @@ class Config:
"main_sec" : "Main",
"usePerVersion_opt" : "usePerVersion",
"useFile_opt" : "usefile",
- "maskFile_opt" : "maskfile"
+ "maskFile_opt" : "maskfile",
+ "maskPerVersion_opt" : "maskPerVersion",
+ "testingFile_opt" : "keywordfile",
+ "testingPerVersion_opt" : "keywordperversion",
+ "debug_opt" : "debug"
}
def __init__ (self, cfgFile):
@@ -51,9 +55,15 @@ class Config:
flagCfg = {
"usefile": self.get(self.const["useFile_opt"]),
"usePerVersion" : self.get_boolean(self.const["usePerVersion_opt"]),
- "maskfile" : self.get(self.const["maskFile_opt"])}
+ "maskfile" : self.get(self.const["maskFile_opt"]),
+ "maskPerVersion" : self.get_boolean(self.const["maskPerVersion_opt"]),
+ "testingfile" : self.get(self.const["testingFile_opt"]),
+ "testingPerVersion" : self.get_boolean(self.const["testingPerVersion_opt"])}
flags.set_config(flagCfg)
+ def modify_debug_config (self):
+ set_debug(self.get_boolean(self.const["debug_opt"]))
+
def set(self, name, val, section=const["main_sec"]):
self._cfg.set(section, name, val)
@@ -61,6 +71,7 @@ class Config:
self._file = open(self._file.name,"w")
self._cfg.write(self._file)
self.modify_flags_config()
+ self.modify_debug_config()
class Database:
"""An internal database which holds a simple dictionary cat -> [package_list]."""
@@ -96,6 +107,7 @@ class Database:
try:
return self.db[cat]
except KeyError: # cat is in category list - but not in portage
+ debug("Catched KeyError =>", cat, "seems not to be an available category. Have you played with rsync-excludes?")
return []
def reload (self, cat):
@@ -133,8 +145,27 @@ class EmergeQueue:
else:
self.emergeIt = self.unmergeIt = None
- def update_tree (self, it, cpv):
- """This updates the tree recursivly.
+ def _get_pkg_from_cpv (self, cpv, unmask = False):
+ pkg = backend.Package(cpv)
+ if not pkg.is_masked() and not pkg.is_testing(allowed=True):
+ masked = True
+ else:
+ masked = False
+ pkg = backend.find_packages("="+cpv, masked = masked)
+ if pkg:
+ pkg = pkg[0]
+ elif unmask:
+ pkg = backend.find_packages("="+cpv, masked = True)[0]
+ if pkg.is_testing(allowed = True):
+ pkg.set_testing(True)
+ if pkg.is_masked():
+ pkg.set_masked()
+ else:
+ raise backend.PackageNotFoundException(cpv)
+ return pkg
+
+ def update_tree (self, it, cpv, unmask = False):
+ """This updates the tree recursivly, or? Isn't it? Bjorn!
@param it: iterator where to append
@type it: gtk.TreeIter
@@ -146,37 +177,35 @@ class EmergeQueue:
# get dependencies
if cpv in self.deps:
return # in list already
- else:
- if flags.new_masking_status(cpv) == "unmasked":
- masked = True
- else:
- masked = False
- pkg = backend.find_packages("="+cpv, masked = masked)
- if pkg:
- pkg = pkg[0]
- else:
- raise backend.PackageNotFoundException(cpv)
-
- deps = pkg.get_dep_packages()
- self.deps.update({cpv : deps})
- subIt = self.tree.append(it, [cpv])
+ try:
+ pkg = self._get_pkg_from_cpv(cpv, unmask)
+ except backend.PackageNotFoundException, e:
+ if self.tree.iter_parent(it):
+ while self.tree.iter_parent(it):
+ it = self.tree.iter_parent(it)
+ self.remove_children(it)
+ self.remove(it)
+ raise e
# add iter
+ subIt = self.tree.append(it, [cpv])
self.iters.update({cpv: subIt})
+ deps = pkg.get_dep_packages()
+ self.deps.update({cpv : deps})
+
# recursive call
for d in deps:
try:
- self.update_tree(subIt, d)
+ self.update_tree(subIt, d, unmask)
except backend.BlockedException, e:
- # remove the project
- while self.tree.iter_parent(subIt):
- subIt = self.tree.iter_parent(subIt)
+ debug("Something blocked:", e[0])
self.remove_children(subIt)
+ self.remove(subIt)
raise e
- def append (self, cpv, unmerge = False, update = False):
+ def append (self, cpv, unmerge = False, update = False, unmask = False):
"""Appends a cpv either to the merge queue or to the unmerge-queue.
Also updates the tree-view.
@@ -191,15 +220,7 @@ class EmergeQueue:
if not unmerge:
try:
# insert dependencies
- if flags.new_masking_status(cpv) == "unmasked":
- masked = True
- else:
- masked = False
- pkg = backend.find_packages("="+cpv, masked = masked)
- if pkg:
- pkg = pkg[0]
- else:
- raise backend.PackageNotFoundException(cpv)
+ pkg = self._get_pkg_from_cpv(cpv, unmask)
deps = pkg.get_dep_packages()
if update:
@@ -209,14 +230,14 @@ class EmergeQueue:
parentIt = self.tree.iter_parent(self.iters[cpv])
self.remove_children(self.iters[cpv], False) # this is needed to def delete everything
self.remove(self.iters[cpv], False)
- self.update_tree(parentIt, cpv)
+ self.update_tree(parentIt, cpv, unmask)
else: # not update
self.mergequeue.append(cpv)
- if self.emergeIt: self.update_tree(self.emergeIt, cpv)
+ if self.emergeIt: self.update_tree(self.emergeIt, cpv, unmask)
except backend.BlockedException, e : # there is sth blocked --> call blocked_dialog
blocks = e[0]
- windows.blocked_dialog(cpv, blocks)
+ dialogs.blocked_dialog(cpv, blocks)
return
else: # unmerge
self.unmergequeue.append(cpv)
@@ -323,11 +344,14 @@ class EmergeQueue:
cpv = self.tree.get_value(it,0)
if self.tree.get_string_from_iter(it).split(":")[0] == self.tree.get_string_from_iter(self.emergeIt): # in Emerge
del self.iters[cpv]
- del self.deps[cpv]
+ try:
+ del self.deps[cpv]
+ except KeyError: # this seems to be removed due to a BlockedException - so no deps here atm ;)
+ debug("Catched KeyError =>", cpv, "seems not to be in self.deps. Should be no harm in normal cases.")
try:
self.mergequeue.remove(cpv)
except ValueError: # this is a dependency - ignore
- pass
+ debug("Catched ValueError =>", cpv, "seems not to be in merge-queue. Should be no harm.")
if removeNewFlags:
flags.remove_new_use_flags(cpv)
flags.remove_new_masked(cpv)
diff --git a/geneticone/gui/windows.py b/geneticone/gui/windows.py
index 1837b99..031306b 100644
--- a/geneticone/gui/windows.py
+++ b/geneticone/gui/windows.py
@@ -9,7 +9,7 @@
#
# Written by Necoro d.M. <necoro@necoro.net>
-VERSION = "0.3.4"
+VERSION = "0.4.0"
CONFIG_LOCATION = "/etc/geneticone/geneticone.cfg"
MENU_EMERGE = 1
MENU_UNEMERGE = 2
@@ -24,7 +24,10 @@ import gobject
from geneticone.helper import *
from geneticone import backend
from geneticone.backend import flags
-from gui_helper import *
+
+# more GUI stuff
+from gui_helper import Database, Config, EmergeQueue
+from dialogs import *
# for the terminal
import pty
@@ -46,7 +49,7 @@ class AbstractDialog:
self.window.connect("key-press-event", self.cb_key_pressed)
def cb_key_pressed (self, widget, event):
- """Closes the window if esc is pressed."""
+ """Closes the window if ESC is pressed."""
keyname = gtk.gdk.keyval_name(event.keyval)
if keyname == "Escape":
self.window.destroy()
@@ -70,6 +73,8 @@ A Portage-GUI
This software is licensed under the terms of the GPLv2.
Copyright (C) 2006 Necoro d.M. &lt;necoro@necoro.net&gt;
+
+<small>Thanks to Fred for support and ideas :P</small>
""" % VERSION)
box.pack_start(label)
@@ -132,19 +137,13 @@ class PreferenceWindow (AbstractDialog):
box = gtk.VBox(True)
self.window.add(box)
- self.perVersionCb = gtk.CheckButton(label="Add to package.use on a per-version-base")
- self.perVersionCb.set_active(cfg.get_boolean(cfg.const["usePerVersion_opt"]))
- box.pack_start(self.perVersionCb, True, True)
-
- hBox = gtk.HBox()
- label = gtk.Label("File name to use if package.use is a directory:\n<small><b>$(cat)</b> = category\n<b>$(pkg)</b> = package-name\n<b>$(cat-1)</b>/<b>$(cat-2)</b> = first/second part of the category</small>")
- label.set_use_markup(True)
- self.editUsefile = gtk.Entry()
- self.editUsefile.set_text(cfg.get(cfg.const["useFile_opt"]))
- hBox.pack_start(label, False)
- hBox.pack_start(self.editUsefile, True, True, 5)
- box.pack_start(hBox, True, True)
+ 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.usePerVersionCb, self.useFileEdit = self.draw_cb_and_edit(box, "package.use", "usePerVersion_opt", "useFile_opt")
+ self.maskPerVersionCb, self.maskFileEdit = self.draw_cb_and_edit(box, "package.mask/package.unmask", "maskPerVersion_opt", "maskFile_opt")
+ self.testPerVersionCb, self.testFileEdit = self.draw_cb_and_edit(box, "package.keywords", "testingPerVersion_opt", "testingFile_opt")
# buttons
buttonHB = gtk.HButtonBox()
buttonHB.set_layout(gtk.BUTTONBOX_SPREAD)
@@ -160,9 +159,30 @@ class PreferenceWindow (AbstractDialog):
self.window.show_all()
+ def draw_cb_and_edit (self, box, string, cb_opt, edit_opt):
+ 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)
+
+ hBox = gtk.HBox()
+ label = gtk.Label(("File name to use if %s is a directory:\n<small><b>$(cat)</b> = category\n<b>$(pkg)</b> = package-name\n<b>$(cat-1)</b>/<b>$(cat-2)</b> = first/second part of the category</small>" % string))
+ label.set_use_markup(True)
+ edit = gtk.Entry()
+ edit.set_text(self.cfg.get(self.cfg.const[edit_opt]))
+ hBox.pack_start(label, False)
+ hBox.pack_start(edit, True, True, 5)
+ box.pack_start(hBox, True, True)
+
+ return (cb, edit)
+
def _save(self):
- self.cfg.set(self.cfg.const["usePerVersion_opt"], str(self.perVersionCb.get_active()))
- self.cfg.set(self.cfg.const["useFile_opt"], self.editUsefile.get_text())
+ self.cfg.set(self.cfg.const["usePerVersion_opt"], str(self.usePerVersionCb.get_active()))
+ self.cfg.set(self.cfg.const["useFile_opt"], self.useFileEdit.get_text())
+ self.cfg.set(self.cfg.const["maskPerVersion_opt"], str(self.maskPerVersionCb.get_active()))
+ self.cfg.set(self.cfg.const["maskFile_opt"], self.maskFileEdit.get_text())
+ 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()))
def cb_ok_clicked(self, button):
self._save()
@@ -328,6 +348,7 @@ class PackageWindow (AbstractDialog):
combo.set_active(i)
break
except AttributeError: # no package found
+ debug('catched AttributeError => no "best package" found. Selected first one.')
combo.set_active(0)
combo.connect("changed", self.cb_combo_changed)
@@ -397,7 +418,11 @@ class PackageWindow (AbstractDialog):
self.actual_package().remove_new_testing()
elif self.flagChanged:
if self.queue:
- self.queue.append(self.actual_package().get_cpv(), update = True)
+ try:
+ self.queue.append(self.actual_package().get_cpv(), update = True)
+ except backend.PackageNotFoundException, e:
+ if unmask_dialog(e[0]) == gtk.RESPONSE_YES:
+ self.queue.append(self.actual_package().get_cpv(), update = True, unmask = True)
self.window.destroy()
return True
@@ -408,9 +433,11 @@ class PackageWindow (AbstractDialog):
else:
try:
self.queue.append(self.actual_package().get_cpv(), unmerge = False)
+ self.window.destroy()
except backend.PackageNotFoundException, e:
- masked_dialog(e[0])
- self.window.destroy()
+ if unmask_dialog(e[0]) == gtk.RESPONSE_YES:
+ self.queue.append(self.actual_package().get_cpv(), unmerge = False, unmask = True)
+ self.window.destroy()
return True
def cb_unmerge_clicked (self, button, data = None):
@@ -480,6 +507,7 @@ class MainWindow:
# config
self.cfg = Config(CONFIG_LOCATION)
self.cfg.modify_flags_config()
+ self.cfg.modify_debug_config()
# main vb
vb = gtk.VBox(False, 1)
@@ -608,7 +636,7 @@ class MainWindow:
return store
def create_pkg_list (self, name = None, force = False):
- """Creates the package list. Gets the name of the category."""
+ """Creates the package list."""
store = gtk.ListStore(str)
self.fill_pkg_store(store,name)
@@ -684,15 +712,13 @@ class MainWindow:
if not model.iter_parent(iter): # top-level
if model.iter_n_children(iter) > 0: # and has children which can be removed :)
- askMB = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, "Do you really want to clear the whole queue?")
- if askMB.run() == gtk.RESPONSE_YES :
+ if remove_queue_dialog() == gtk.RESPONSE_YES :
self.queue.remove_children(iter)
- askMB.destroy()
+
elif model.iter_parent(model.iter_parent(iter)): # this is in the 3rd level => dependency
- infoMB = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, "You cannot remove dependencies. :)")
- infoMB.run()
- infoMB.destroy()
+ remove_deps_dialog()
else:
+ self.queue.remove_children(iter) # remove children first
self.queue.remove(iter)
return True
@@ -701,17 +727,12 @@ class MainWindow:
"""Do emerge or unemerge."""
if button == self.emergeBtn or button == MENU_EMERGE:
if len(flags.newUseFlags) > 0:
- hintMB = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK,
- "You have changed use flags. Genetic/One will write these changes into the appropriate files. Please backup them if you think it is necessairy.")
- hintMB.run()
- hintMB.destroy()
+ changed_flags_dialog("use flags")
flags.write_use_flags()
- if len(flags.new_masked)>0 or len(flags.new_unmasked)>0:
- hintMB = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK,
- "You have changed masking keywords. Genetic/One will write these changes into the appropriate files. Please backup them if you think it is necessairy.")
- hintMB.run()
- hintMB.destroy()
+ 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)
elif button == self.unmergeBtn or button == MENU_UNEMERGE:
@@ -725,9 +746,7 @@ class MainWindow:
packages = backend.find_all_packages(self.searchEntry.get_text(), withVersion = False)
if packages == []:
- dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, "Package not found!")
- dialog.run()
- dialog.destroy()
+ nothing_found_dialog()
else:
if len(packages) == 1:
self.jump_to(packages[0])
@@ -740,18 +759,3 @@ class MainWindow:
# now subthreads can run normally, but are not allowed to touch the GUI. If threads should change sth there - use gobject.idle_add().
# for more informations on threading and gtk: http://www.async.com.br/faq/pygtk/index.py?req=show&file=faq20.006.htp
gtk.main()
-
-def blocked_dialog (blocked, blocks):
- dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, blocked+" is blocked by "+blocks+".\nPlease unmerge the blocking package.")
- dialog.run()
- dialog.destroy()
-
-def not_root_dialog ():
- errorMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, "You cannot (un)merge without being root.")
- errorMB.run()
- errorMB.destroy()
-
-def masked_dialog (cpv):
- dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, cpv+" seems to be masked.\nPlease edit the appropriate file(s) to unmask it and restart Genetic/One.\n")
- dialog.run()
- dialog.destroy()
diff --git a/geneticone/helper.py b/geneticone/helper.py
index 4b2a207..a1acf42 100644
--- a/geneticone/helper.py
+++ b/geneticone/helper.py
@@ -11,6 +11,12 @@
import traceback, textwrap, os.path
+DEBUG = True
+
+def set_debug (d):
+ global DEBUG
+ DEBUG = d
+
def debug(*args, **kwargs):
"""Prints a debug message including filename and lineno.
A variable number of positional arguments are allowed.
@@ -22,6 +28,8 @@ def debug(*args, **kwargs):
(This function is adapted from Edward Jones as published under: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/279155)"""
+ if not DEBUG : return
+
stack = traceback.extract_stack()
a, b, c, d = stack[-2]
a = os.path.basename(a)