From afa1de13f0576ace6dcbb0176490fd20922950cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Tue, 2 Sep 2008 13:01:17 +0200 Subject: Switch from tabs to 4 spaces --- plugins/etc_proposals.py | 42 +- plugins/exception.py | 2 +- plugins/gpytage.py | 14 +- plugins/new_version.py | 94 +- plugins/notify.py | 48 +- plugins/reload_portage.py | 18 +- portato.py | 118 +- portato/TEST_helper.py | 36 +- portato/__init__.py | 62 +- portato/backend/__init__.py | 64 +- portato/backend/exceptions.py | 16 +- portato/backend/flags.py | 1308 ++++++------ portato/backend/package.py | 786 +++---- portato/backend/portage/__init__.py | 8 +- portato/backend/portage/package.py | 572 +++--- portato/backend/portage/package_22.py | 10 +- portato/backend/portage/sets.py | 168 +- portato/backend/portage/settings.py | 78 +- portato/backend/portage/settings_22.py | 12 +- portato/backend/portage/system.py | 768 +++---- portato/backend/portage/system_22.py | 60 +- portato/backend/system_interface.py | 492 ++--- portato/config_parser.py | 958 ++++----- portato/dependency.py | 260 +-- portato/gui/__init__.py | 18 +- portato/gui/dialogs.py | 134 +- portato/gui/exception_handling.py | 196 +- portato/gui/queue.py | 1234 +++++------ portato/gui/session.py | 16 +- portato/gui/updater.py | 200 +- portato/gui/utils.py | 530 ++--- portato/gui/views.py | 214 +- portato/gui/windows/about.py | 16 +- portato/gui/windows/basic.py | 180 +- portato/gui/windows/mailinfo.py | 106 +- portato/gui/windows/main.py | 3482 ++++++++++++++++---------------- portato/gui/windows/plugin.py | 316 +-- portato/gui/windows/preference.py | 384 ++-- portato/gui/windows/search.py | 98 +- portato/gui/windows/splash.py | 60 +- portato/gui/windows/update.py | 188 +- portato/gui/wrapper.py | 622 +++--- portato/helper.py | 214 +- portato/plistener.py | 222 +- portato/plugin.py | 966 ++++----- portato/session.py | 202 +- portato/waiting_queue.py | 88 +- setup.py | 28 +- 48 files changed, 7854 insertions(+), 7854 deletions(-) diff --git a/plugins/etc_proposals.py b/plugins/etc_proposals.py index c32c8f3..5b4f67a 100644 --- a/plugins/etc_proposals.py +++ b/plugins/etc_proposals.py @@ -16,26 +16,26 @@ import os from subprocess import Popen class EtcProposals (Plugin): - __author__ = "René 'Necoro' Neumann" - __description__ = "Adds support for etc-proposals, a graphical etc-update replacement." - __dependency__ = ["app-portage/etc-proposals"] - - def init (self): - self.prog = ["/usr/sbin/etc-proposals"] - self.add_call("after_emerge", self.hook, type = "after") - self.add_menu("Et_c-Proposals", self.menu) - - def launch (self, options = []): - if os.getuid() == 0: - Popen(self.prog+options) - else: - error("ETC_PROPOSALS :: %s",_("Cannot start etc-proposals. Not root!")) - - def hook (self, *args, **kwargs): - """Entry point for this plugin.""" - self.launch(["--fastexit"]) - - def menu (self, *args): - self.launch() + __author__ = "René 'Necoro' Neumann" + __description__ = "Adds support for etc-proposals, a graphical etc-update replacement." + __dependency__ = ["app-portage/etc-proposals"] + + def init (self): + self.prog = ["/usr/sbin/etc-proposals"] + self.add_call("after_emerge", self.hook, type = "after") + self.add_menu("Et_c-Proposals", self.menu) + + def launch (self, options = []): + if os.getuid() == 0: + Popen(self.prog+options) + else: + error("ETC_PROPOSALS :: %s",_("Cannot start etc-proposals. Not root!")) + + def hook (self, *args, **kwargs): + """Entry point for this plugin.""" + self.launch(["--fastexit"]) + + def menu (self, *args): + self.launch() register(EtcProposals) diff --git a/plugins/exception.py b/plugins/exception.py index e653853..ff5a8e9 100644 --- a/plugins/exception.py +++ b/plugins/exception.py @@ -11,7 +11,7 @@ # Written by René 'Necoro' Neumann def throw (*args, **kwargs): - raise Exception, "As requested, Sir!" + raise Exception, "As requested, Sir!" p = Plugin() p.__name__ = "ExceptionThrower" diff --git a/plugins/gpytage.py b/plugins/gpytage.py index d8c2831..5ebd6b4 100644 --- a/plugins/gpytage.py +++ b/plugins/gpytage.py @@ -13,14 +13,14 @@ from subprocess import Popen class GPytage (Plugin): - __author__ = "René 'Necoro' Neumann" - __description__ = "Adds a menu entry to directly start gpytage, a config editor." - __dependency__ = ["app-portage/gpytage"] + __author__ = "René 'Necoro' Neumann" + __description__ = "Adds a menu entry to directly start gpytage, a config editor." + __dependency__ = ["app-portage/gpytage"] - def init (self): - self.add_menu("Config _Editor", self.menu) + def init (self): + self.add_menu("Config _Editor", self.menu) - def menu (self, *args): - Popen(["/usr/bin/gpytage"]) + def menu (self, *args): + Popen(["/usr/bin/gpytage"]) register(GPytage) diff --git a/plugins/new_version.py b/plugins/new_version.py index f3479b4..5391507 100644 --- a/plugins/new_version.py +++ b/plugins/new_version.py @@ -11,9 +11,9 @@ # Written by René 'Necoro' Neumann try: - from bzrlib import plugin, branch + from bzrlib import plugin, branch except ImportError: - plugin = branch = None + plugin = branch = None import gobject from portato.helper import debug, warning @@ -22,59 +22,59 @@ from portato.constants import VERSION, APP_ICON, APP from portato.gui.utils import GtkThread class NewVersionFinder(Plugin): - """ - Checks for a new version of portato every 30 minutes and on startup. - """ - __author__ = "René 'Necoro' Neumann" - __dependency__ = ["dev-util/bzr"] + """ + Checks for a new version of portato every 30 minutes and on startup. + """ + __author__ = "René 'Necoro' Neumann" + __dependency__ = ["dev-util/bzr"] - def init (self): - self.add_call("main", self.run) - self.add_menu("Check for new _versions", self.menu) + def init (self): + self.add_call("main", self.run) + self.add_menu("Check for new _versions", self.menu) - def find_version (self, rev): - try: - b = branch.Branch.open("lp:portato") - except Exception, e: - warning("NEW_VERSION :: Exception occured while accessing the remote branch: %s", str(e)) - return + def find_version (self, rev): + try: + b = branch.Branch.open("lp:portato") + except Exception, e: + warning("NEW_VERSION :: Exception occured while accessing the remote branch: %s", str(e)) + return - debug("NEW_VERSION :: Installed rev: %s - Current rev: %s", rev, b.revno()) - if int(rev) < int(b.revno()): - def callback(): - get_listener().send_notify(base = "New Portato Live Version Found", descr = "You have rev. %s, but the most recent revision is %s." % (rev, b.revno()), icon = APP_ICON) - return False - - gobject.idle_add(callback) + debug("NEW_VERSION :: Installed rev: %s - Current rev: %s", rev, b.revno()) + if int(rev) < int(b.revno()): + def callback(): + get_listener().send_notify(base = "New Portato Live Version Found", descr = "You have rev. %s, but the most recent revision is %s." % (rev, b.revno()), icon = APP_ICON) + return False + + gobject.idle_add(callback) - def start_thread(self, rev): - t = GtkThread(target = self.find_version, name = "Version Updater Thread", args = (rev,)) - t.setDaemon(True) - t.start() - return True + def start_thread(self, rev): + t = GtkThread(target = self.find_version, name = "Version Updater Thread", args = (rev,)) + t.setDaemon(True) + t.start() + return True - def menu (self, *args, **kwargs): - """ - Run the thread once. - """ - v = VERSION.split() - if len(v) != 3 or v[0] != "9999": - return None + def menu (self, *args, **kwargs): + """ + Run the thread once. + """ + v = VERSION.split() + if len(v) != 3 or v[0] != "9999": + return None - rev = v[-1] + rev = v[-1] - plugin.load_plugins() # to have lp: addresses parsed - - self.start_thread(rev) - return rev + plugin.load_plugins() # to have lp: addresses parsed + + self.start_thread(rev) + return rev - def run (self, *args, **kwargs): - """ - Run the thread once and add a 30 minutes timer. - """ - rev = self.menu() + def run (self, *args, **kwargs): + """ + Run the thread once and add a 30 minutes timer. + """ + rev = self.menu() - if rev is not None: - gobject.timeout_add(30*60*1000, self.start_thread, rev) # call it every 30 minutes + if rev is not None: + gobject.timeout_add(30*60*1000, self.start_thread, rev) # call it every 30 minutes register(NewVersionFinder, (branch is None)) diff --git a/plugins/notify.py b/plugins/notify.py index 6446812..7a3776a 100644 --- a/plugins/notify.py +++ b/plugins/notify.py @@ -13,9 +13,9 @@ disable = False try: - import pynotify + import pynotify except ImportError: - disable = True + disable = True from portato import get_listener @@ -23,27 +23,27 @@ from portato.helper import warning, error, debug from portato.constants import APP_ICON, APP class Notify (Plugin): - __author__ = "René 'Necoro' Neumann" - __description__ = "Show notifications when an emerge process finishes." - __dependency__ = ["dev-python/notify-python"] - - def init (self): - self.add_call("after_emerge", self.notify) - - def notify (self, retcode, **kwargs): - if retcode is None: - warning("NOTIFY :: %s", _("Notify called while process is still running!")) - else: - icon = APP_ICON - if retcode == 0: - text = _("Emerge finished!") - descr = "" - urgency = pynotify.URGENCY_NORMAL - else: - text = _("Emerge failed!") - descr = _("Error Code: %d") % retcode - urgency = pynotify.URGENCY_CRITICAL - - get_listener().send_notify(base = text, descr = descr, icon = icon, urgency = urgency) + __author__ = "René 'Necoro' Neumann" + __description__ = "Show notifications when an emerge process finishes." + __dependency__ = ["dev-python/notify-python"] + + def init (self): + self.add_call("after_emerge", self.notify) + + def notify (self, retcode, **kwargs): + if retcode is None: + warning("NOTIFY :: %s", _("Notify called while process is still running!")) + else: + icon = APP_ICON + if retcode == 0: + text = _("Emerge finished!") + descr = "" + urgency = pynotify.URGENCY_NORMAL + else: + text = _("Emerge failed!") + descr = _("Error Code: %d") % retcode + urgency = pynotify.URGENCY_CRITICAL + + get_listener().send_notify(base = text, descr = descr, icon = icon, urgency = urgency) register(Notify, disable) diff --git a/plugins/reload_portage.py b/plugins/reload_portage.py index 280bd92..1aea01f 100644 --- a/plugins/reload_portage.py +++ b/plugins/reload_portage.py @@ -13,15 +13,15 @@ from portato.backend import system class ReloadPortage (Plugin): - __author__ = "René 'Necoro' Neumann" - __description__ = """Reloads portage when an emerge process has finished. + __author__ = "René 'Necoro' Neumann" + __description__ = """Reloads portage when an emerge process has finished. This can take some time, but sometimes it is necessairy.""" - - def init(self): - self.add_call("after_emerge", self.hook, type = "after", dep = "EtcProposals") - self.status = self.STAT_DISABLED # disable by default - - def hook (self, *args, **kwargs): - system.reload_settings() + + def init(self): + self.add_call("after_emerge", self.hook, type = "after", dep = "EtcProposals") + self.status = self.STAT_DISABLED # disable by default + + def hook (self, *args, **kwargs): + system.reload_settings() register(ReloadPortage) diff --git a/portato.py b/portato.py index cc973be..c2b861e 100755 --- a/portato.py +++ b/portato.py @@ -25,73 +25,73 @@ from portato.helper import debug, info from portato.constants import VERSION, LOCALE_DIR, APP, SU_COMMAND def main (): - # set gettext stuff - locale.setlocale(locale.LC_ALL, '') - gettext.install(APP, LOCALE_DIR, unicode = True) + # set gettext stuff + locale.setlocale(locale.LC_ALL, '') + gettext.install(APP, LOCALE_DIR, unicode = True) - # build the parser - desc = "Portato - A Portage GUI." - usage = "%prog [options] [frontend]" - vers = "%%prog v. %s" % VERSION + # build the parser + desc = "Portato - A Portage GUI." + usage = "%prog [options] [frontend]" + vers = "%%prog v. %s" % VERSION - parser = OptionParser(version = vers, prog = "Portato", description = desc, usage = usage) - - parser.add_option("--shm", action = "store", nargs = 3, type="long", dest = "shm", - help = SUPPRESS_HELP) + parser = OptionParser(version = vers, prog = "Portato", description = desc, usage = usage) + + parser.add_option("--shm", action = "store", nargs = 3, type="long", dest = "shm", + help = SUPPRESS_HELP) - parser.add_option("-F", "--no-fork", "-L", action = "store_true", dest = "nofork", default = False, - help = _("do not fork off as root") + (" (%s)" % _("-L is deprecated"))) + parser.add_option("-F", "--no-fork", "-L", action = "store_true", dest = "nofork", default = False, + help = _("do not fork off as root") + (" (%s)" % _("-L is deprecated"))) - # run parser - (options, args) = parser.parse_args() + # run parser + (options, args) = parser.parse_args() - # close listener at exit - atexit.register(get_listener().close) + # close listener at exit + atexit.register(get_listener().close) - if options.nofork or os.getuid() == 0: # start GUI - from portato.gui import run - info("%s v. %s", _("Starting Portato"), VERSION) - - if options.shm: - get_listener().set_send(*options.shm) - else: - get_listener().set_send() - - try: - run() - except KeyboardInterrupt: - debug("Got KeyboardInterrupt.") - - else: # start us again in root modus and launch listener - - import shm_wrapper as shm + if options.nofork or os.getuid() == 0: # start GUI + from portato.gui import run + info("%s v. %s", _("Starting Portato"), VERSION) + + if options.shm: + get_listener().set_send(*options.shm) + else: + get_listener().set_send() + + try: + run() + except KeyboardInterrupt: + debug("Got KeyboardInterrupt.") + + else: # start us again in root modus and launch listener + + import shm_wrapper as shm - mem = shm.create_memory(1024, permissions=0600) - sig = shm.create_semaphore(InitialValue = 0, permissions = 0600) - rw = shm.create_semaphore(InitialValue = 1, permissions = 0600) - - # start listener - lt = threading.Thread(target=get_listener().set_recv, args = (mem, sig, rw)) - lt.setDaemon(False) - lt.start() - - # set DBUS_SESSION_BUS_ADDRESS to "" to make dbus work as root ;) - env = os.environ.copy() - env.update(DBUS_SESSION_BUS_ADDRESS="") - cmd = SU_COMMAND.split() - - sp = subprocess.Popen(cmd+["%s --no-fork --shm %ld %ld %ld" % (sys.argv[0], mem.key, sig.key, rw.key)], env = env) + mem = shm.create_memory(1024, permissions=0600) + sig = shm.create_semaphore(InitialValue = 0, permissions = 0600) + rw = shm.create_semaphore(InitialValue = 1, permissions = 0600) + + # start listener + lt = threading.Thread(target=get_listener().set_recv, args = (mem, sig, rw)) + lt.setDaemon(False) + lt.start() + + # set DBUS_SESSION_BUS_ADDRESS to "" to make dbus work as root ;) + env = os.environ.copy() + env.update(DBUS_SESSION_BUS_ADDRESS="") + cmd = SU_COMMAND.split() + + sp = subprocess.Popen(cmd+["%s --no-fork --shm %ld %ld %ld" % (sys.argv[0], mem.key, sig.key, rw.key)], env = env) - # wait for process to finish - try: - sp.wait() - debug("Subprocess finished") - except KeyboardInterrupt: - debug("Got KeyboardInterrupt.") + # wait for process to finish + try: + sp.wait() + debug("Subprocess finished") + except KeyboardInterrupt: + debug("Got KeyboardInterrupt.") - if lt.isAlive(): - debug("Listener is still running. Close it.") - get_listener().close() + if lt.isAlive(): + debug("Listener is still running. Close it.") + get_listener().close() if __name__ == "__main__": - main() + main() diff --git a/portato/TEST_helper.py b/portato/TEST_helper.py index cce0b61..f0b069b 100644 --- a/portato/TEST_helper.py +++ b/portato/TEST_helper.py @@ -5,28 +5,28 @@ import helper class HelperTest (unittest.TestCase): - def testFlatten(self): - list = [[1,2],[3,4],[[5],[6,7,8], 9]] - flist = helper.flatten(list) - self.assertEqual(flist, [1,2,3,4,5,6,7,8,9], "List not flattend correctly.") + def testFlatten(self): + list = [[1,2],[3,4],[[5],[6,7,8], 9]] + flist = helper.flatten(list) + self.assertEqual(flist, [1,2,3,4,5,6,7,8,9], "List not flattend correctly.") - def testUniqueArray(self): + def testUniqueArray(self): - def equal (l1, l2): - for i in l1: - if i not in l2: - return False - l2.remove(i) - return True + def equal (l1, l2): + for i in l1: + if i not in l2: + return False + l2.remove(i) + return True - list1 = [1,4,5,2,1,7,9,11,2,4,7,12] - result1 = [1,4,5,2,7,9,11,12] + list1 = [1,4,5,2,1,7,9,11,2,4,7,12] + result1 = [1,4,5,2,7,9,11,12] - list2 = [[x] for x in list1] - result2 = [[x] for x in result1] + list2 = [[x] for x in list1] + result2 = [[x] for x in result1] - self.assert_(equal(helper.unique_array(list1), result1), "Make hashable list unique does not work.") - self.assert_(equal(helper.unique_array(list2), result2), "Make unhashable list unique does not work.") + self.assert_(equal(helper.unique_array(list1), result1), "Make hashable list unique does not work.") + self.assert_(equal(helper.unique_array(list2), result2), "Make unhashable list unique does not work.") if __name__ == "__main__": - unittest.main() + unittest.main() diff --git a/portato/__init__.py b/portato/__init__.py index 4b6a808..b5a9859 100644 --- a/portato/__init__.py +++ b/portato/__init__.py @@ -18,36 +18,36 @@ import os class OutputFormatter (logging.Formatter): - colors = { - "blue" : 34, - "green" : 32, - "red" : 31, - "yellow": 33 - } + colors = { + "blue" : 34, + "green" : 32, + "red" : 31, + "yellow": 33 + } - def __init__(self, *args, **kwargs): - logging.Formatter.__init__(self, *args, **kwargs) + def __init__(self, *args, **kwargs): + logging.Formatter.__init__(self, *args, **kwargs) - for key, value in self.colors.iteritems(): - self.colors[key] = "\x1b[01;%02dm*\x1b[39;49;00m" % value + for key, value in self.colors.iteritems(): + self.colors[key] = "\x1b[01;%02dm*\x1b[39;49;00m" % value - def format (self, record): - string = logging.Formatter.format(self, record) - color = None + def format (self, record): + string = logging.Formatter.format(self, record) + color = None - if os.isatty(sys.stderr.fileno()): - if record.levelno <= logging.DEBUG: - color = self.colors["blue"] - elif record.levelno <= logging.INFO: - color = self.colors["green"] - elif record.levelno <= logging.WARNING: - color = self.colors["yellow"] - else: - color = self.colors["red"] - else: - color = "%s:" % record.levelname + if os.isatty(sys.stderr.fileno()): + if record.levelno <= logging.DEBUG: + color = self.colors["blue"] + elif record.levelno <= logging.INFO: + color = self.colors["green"] + elif record.levelno <= logging.WARNING: + color = self.colors["yellow"] + else: + color = self.colors["red"] + else: + color = "%s:" % record.levelname - return "%s %s" % (color, string) + return "%s %s" % (color, string) # set the whole logging stuff formatter = OutputFormatter("%(message)s (%(filename)s:%(lineno)s)") @@ -61,9 +61,9 @@ logging.getLogger("portatoLogger").propagate = False __listener = None def get_listener(): - global __listener - if __listener is None: - from .plistener import PListener - __listener = PListener() - - return __listener + global __listener + if __listener is None: + from .plistener import PListener + __listener = PListener() + + return __listener diff --git a/portato/backend/__init__.py b/portato/backend/__init__.py index b2a5a43..1f62d6b 100644 --- a/portato/backend/__init__.py +++ b/portato/backend/__init__.py @@ -20,52 +20,52 @@ SYSTEM = "portage" # the name of the current system _sys = None # the SystemInterface-instance class _Package (object): - """Wrapping class from which L{portato.backend.Package} inherits. This is used by the flags module to check - whether an object is a package. It cannot use the normal Package class as this results in cyclic dependencies.""" + """Wrapping class from which L{portato.backend.Package} inherits. This is used by the flags module to check + whether an object is a package. It cannot use the normal Package class as this results in cyclic dependencies.""" - def __init__ (self): - raise TypeError, "Calling __init__ on portato.backend._Package objects is not allowed." + def __init__ (self): + raise TypeError, "Calling __init__ on portato.backend._Package objects is not allowed." class SystemWrapper (SystemInterface): - """This is a wrapper to the different system interfaces, allowing the direct import via C{from portato.backend import system}. - With this wrapper a change of the system is propagated to all imports.""" - - def __getattribute__ (self, name): - """Just pass all attribute accesses directly to _sys.""" - return getattr(_sys, name) + """This is a wrapper to the different system interfaces, allowing the direct import via C{from portato.backend import system}. + With this wrapper a change of the system is propagated to all imports.""" + + def __getattribute__ (self, name): + """Just pass all attribute accesses directly to _sys.""" + return getattr(_sys, name) def set_system (new_sys): - """Sets the current system to a new one. + """Sets the current system to a new one. - @param new_sys: the name of the system to take - @type new_sys: string""" + @param new_sys: the name of the system to take + @type new_sys: string""" - global SYSTEM - if new_sys != SYSTEM: - SYSTEM = new_sys - load_system() + global SYSTEM + if new_sys != SYSTEM: + SYSTEM = new_sys + load_system() def load_system (): - """Loads the current chosen system. + """Loads the current chosen system. - @raises InvalidSystemError: if an inappropriate system is set""" - - global _sys + @raises InvalidSystemError: if an inappropriate system is set""" + + global _sys - if SYSTEM == "portage": - debug("Setting Portage System") - from .portage import PortageSystem - _sys = PortageSystem () - elif SYSTEM == "catapult": - debug("Setting Catapult System") - from .catapult import CatapultSystem - _sys = CatapultSystem() - else: - raise InvalidSystemError, SYSTEM + if SYSTEM == "portage": + debug("Setting Portage System") + from .portage import PortageSystem + _sys = PortageSystem () + elif SYSTEM == "catapult": + debug("Setting Catapult System") + from .catapult import CatapultSystem + _sys = CatapultSystem() + else: + raise InvalidSystemError, SYSTEM system = SystemWrapper() def is_package(what): - return isinstance(what, _Package) + return isinstance(what, _Package) load_system() diff --git a/portato/backend/exceptions.py b/portato/backend/exceptions.py index 42f9d44..37e9bda 100644 --- a/portato/backend/exceptions.py +++ b/portato/backend/exceptions.py @@ -11,17 +11,17 @@ # Written by René 'Necoro' Neumann class BlockedException (Exception): - """An exception marking, that some package is blocking another one.""" - pass + """An exception marking, that some package is blocking another one.""" + pass class PackageNotFoundException (Exception): - """An exception marking that a package could not be found.""" - pass + """An exception marking that a package could not be found.""" + pass class DependencyCalcError (Exception): - """An error occured during dependency calculation.""" - pass + """An error occured during dependency calculation.""" + pass class InvalidSystemError (Exception): - """An invalid system is set.""" - pass + """An invalid system is set.""" + pass diff --git a/portato/backend/flags.py b/portato/backend/flags.py index b151665..4aa6b8e 100644 --- a/portato/backend/flags.py +++ b/portato/backend/flags.py @@ -20,738 +20,738 @@ from . import system, is_package from ..helper import debug, error, unique_array CONFIG = { - "usefile" : "portato", - "maskfile" : "portato", - "testingfile" : "portato", - "usePerVersion" : True, - "maskPerVersion" : True, - "testingPerVersion" : True - } + "usefile" : "portato", + "maskfile" : "portato", + "testingfile" : "portato", + "usePerVersion" : True, + "maskPerVersion" : True, + "testingPerVersion" : True + } class Constants: - def __init__ (self): - self.clear() - - def clear (self): - self._use_path = None - self._mask_path = None - self._unmask_path = None - self._testing_path = None - self._use_path_is_dir = None - self._mask_path_is_dir = None - self._unmask_path_is_dir = None - self._testing_path_is_dir = None + def __init__ (self): + self.clear() + + def clear (self): + self._use_path = None + self._mask_path = None + self._unmask_path = None + self._testing_path = None + self._use_path_is_dir = None + self._mask_path_is_dir = None + self._unmask_path_is_dir = None + self._testing_path_is_dir = None - def __get (self, name, path): - if self.__dict__[name] is None: - self.__dict__[name] = os.path.join(system.get_config_path(), path) + def __get (self, name, path): + if self.__dict__[name] is None: + self.__dict__[name] = os.path.join(system.get_config_path(), path) - return self.__dict__[name] + return self.__dict__[name] - def __is_dir(self, path): - name = "_" + path + "_is_dir" - if self.__dict__[name] is None: - self.__dict__[name] = os.path.isdir(self.__class__.__dict__[path](self)) - return self.__dict__[name] - - def use_path (self): - return self.__get("_use_path", "package.use") + def __is_dir(self, path): + name = "_" + path + "_is_dir" + if self.__dict__[name] is None: + self.__dict__[name] = os.path.isdir(self.__class__.__dict__[path](self)) + return self.__dict__[name] + + def use_path (self): + return self.__get("_use_path", "package.use") - def use_path_is_dir (self): - return self.__is_dir("use_path") + def use_path_is_dir (self): + return self.__is_dir("use_path") - def mask_path (self): - return self.__get("_mask_path", "package.mask") + def mask_path (self): + return self.__get("_mask_path", "package.mask") - def mask_path_is_dir (self): - return self.__is_dir("mask_path") + def mask_path_is_dir (self): + return self.__is_dir("mask_path") - def unmask_path (self): - return self.__get("_unmask_path", "package.unmask") + def unmask_path (self): + return self.__get("_unmask_path", "package.unmask") - def unmask_path_is_dir (self): - return self.__is_dir("unmask_path") + def unmask_path_is_dir (self): + return self.__is_dir("unmask_path") - def testing_path (self): - return self.__get("_testing_path", "package.keywords") + def testing_path (self): + return self.__get("_testing_path", "package.keywords") - def testing_path_is_dir (self): - return self.__is_dir("testing_path") + def testing_path_is_dir (self): + return self.__is_dir("testing_path") CONST = Constants() ### GENERAL PART ### def grep (pkg, path): - """Grep runs "egrep" on a given path and looks for occurences of a given package. - @param pkg: the package - @type pkg: string (cpv) or L{backend.Package}-object - @param path: path to look in - @type path: string - - @returns: occurences of pkg in the format: "file:line-no:complete_line_found" - @rtype: string""" - - if not is_package(pkg): - pkg = system.new_package(pkg) # assume it is a cpv or a gentoolkit.Package - - if os.path.exists(path): - 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() - else: - return [] + """Grep runs "egrep" on a given path and looks for occurences of a given package. + @param pkg: the package + @type pkg: string (cpv) or L{backend.Package}-object + @param path: path to look in + @type path: string + + @returns: occurences of pkg in the format: "file:line-no:complete_line_found" + @rtype: string""" + + if not is_package(pkg): + pkg = system.new_package(pkg) # assume it is a cpv or a gentoolkit.Package + + if os.path.exists(path): + 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() + else: + return [] def get_data(pkg, path): - """This splits up the data of L{grep} and builds tuples in the format (file,line,criterion,list_of_flags). - @param pkg: package to find - @type pkg: string (cpv) or L{backend.Package}-object - @param path: path to look in - @type path: string - - @returns: a list of tuples in the form (file,line,criterion,list_of_flags) - @rtype: (string,string,string,string[])[]""" - - flags = [] - - # do grep - list = grep(pkg, path) - - for i in range(len(list)): - file, line, fl = tuple(list[i].split(":")) # get file, line and flag-list - fl = fl.split() - crit = fl[0] - fl = fl[1:] - # stop after first comment - for j in range(len(fl)): - if fl[j][0] == "#": # comment - stop here - fl = fl[:j] - break - flags.append((file,line,crit,fl)) - - return flags + """This splits up the data of L{grep} and builds tuples in the format (file,line,criterion,list_of_flags). + @param pkg: package to find + @type pkg: string (cpv) or L{backend.Package}-object + @param path: path to look in + @type path: string + + @returns: a list of tuples in the form (file,line,criterion,list_of_flags) + @rtype: (string,string,string,string[])[]""" + + flags = [] + + # do grep + list = grep(pkg, path) + + for i in range(len(list)): + file, line, fl = tuple(list[i].split(":")) # get file, line and flag-list + fl = fl.split() + crit = fl[0] + fl = fl[1:] + # stop after first comment + for j in range(len(fl)): + if fl[j][0] == "#": # comment - stop here + fl = fl[:j] + break + flags.append((file,line,crit,fl)) + + return flags def set_config (cfg): - """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""" + """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""" - for i in CONFIG.keys(): - if not i in cfg: - raise KeyError, "Missing keyword in config: "+i + for i in CONFIG.keys(): + if not i in cfg: + raise KeyError, "Missing keyword in config: "+i - for i in CONFIG: - CONFIG[i] = cfg[i] + for i in CONFIG: + 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 - - $(version) : version 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""" - - if exp.find("$(") != -1: - cat, pkg, ver, rev = system.split_cpv(cpv) - if rev != "r0": - ver = "%s-%s" % (ver, rev) - exp = exp.replace("$(cat)",cat).\ - replace("$(pkg)",pkg).\ - replace("$(cat-1)",cat.split("-")[0]).\ - replace("$(cat-2)",cat.split("-")[1]).\ - replace("$(version)",ver) - return 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 + - $(version) : version 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""" + + if exp.find("$(") != -1: + cat, pkg, ver, rev = system.split_cpv(cpv) + if rev != "r0": + ver = "%s-%s" % (ver, rev) + exp = exp.replace("$(cat)",cat).\ + replace("$(pkg)",pkg).\ + replace("$(cat-1)",cat.split("-")[0]).\ + replace("$(cat-2)",cat.split("-")[1]).\ + replace("$(version)",ver) + return exp ### USE FLAG PART ### useFlags = {} # useFlags in the file newUseFlags = {} # useFlags as we want them to be: format: cpv -> [(file, line, useflag, (true if removed from list / false if added))] def invert_use_flag (flag): - """Invertes a flag. - - >>> invert_use_flag("foo") - -foo - >>> invert_use_flag("-bar") - bar - - @param flag: the flag - @type flag: string - @returns: inverted flag - @rtype: string - """ - - if flag[0] == "-": - return flag[1:] - else: - return "-"+flag + """Invertes a flag. + + >>> invert_use_flag("foo") + -foo + >>> invert_use_flag("-bar") + bar + + @param flag: the flag + @type flag: string + @returns: inverted flag + @rtype: string + """ + + if flag[0] == "-": + return flag[1:] + else: + return "-"+flag def sort_use_flag_list (flaglist): - """ - Sorts a list of useflags. If a use flag starts with "+" or "-" this one is ignored for the matter of sorting. - This functions sorts the list itself - thus does not create a new one. But for convenience it returns the list too. - - @param flaglist: the list of useflags - @type flaglist: string[] - - @returns: the sorted list (Note: it is the same as the one passed in) - @rtype: string[] - """ - - def flag_key (flag): - if flag.startswith(("+","-")): - return flag[1:] - else: - return flag - - flaglist.sort(key = flag_key) - return flaglist + """ + Sorts a list of useflags. If a use flag starts with "+" or "-" this one is ignored for the matter of sorting. + This functions sorts the list itself - thus does not create a new one. But for convenience it returns the list too. + + @param flaglist: the list of useflags + @type flaglist: string[] + + @returns: the sorted list (Note: it is the same as the one passed in) + @rtype: string[] + """ + + def flag_key (flag): + if flag.startswith(("+","-")): + return flag[1:] + else: + return flag + + flaglist.sort(key = flag_key) + return flaglist def filter_defaults (flaglist): - """ - Removes "+" and "-" from IUSE defaults. + """ + Removes "+" and "-" from IUSE defaults. - @param flaglist: the list of useflags - @type flaglist: string + @param flaglist: the list of useflags + @type flaglist: string - @returns: the "cleaned" list - @rtype: string - """ + @returns: the "cleaned" list + @rtype: string + """ - for flag in flaglist: - if flag.startswith(("+","-")): - yield flag[1:] - else: - yield flag + for flag in flaglist: + if flag.startswith(("+","-")): + yield flag[1:] + else: + yield flag def set_use_flag (pkg, flag): - """Sets the useflag for a given package. - - @param pkg: the package - @type pkg: string (cpv) or L{backend.Package}-object - @param flag: the flag to set - @type flag: string""" - - global useFlags, newUseFlags - - if not is_package(pkg): - pkg = system.new_package(pkg) # assume cpv or gentoolkit.Package - - cpv = pkg.get_cpv() - invFlag = invert_use_flag(flag) - - # if not saved in useFlags, get it by calling get_data() which calls grep() - data = None - if not cpv in useFlags: - data = get_data(pkg, CONST.use_path()) - useFlags[cpv] = data - else: - data = useFlags[cpv] - - if not cpv in newUseFlags: - newUseFlags[cpv] = [] - - debug("data: %s", str(data)) - # add a useflag / delete one - added = False - for file, line, crit, flags in data: - if pkg.matches(crit): - # we have the inverted flag in the uselist/newuselist --> delete it - if invFlag in flags or (file, line, invFlag, False) in newUseFlags[cpv] or (file, line, flag, True) in newUseFlags[cpv]: - if added: del newUseFlags[-1] # we currently added it as an extra option - delete it - added = True - jumpOut = False - for t in ((file, line, invFlag, False),(file, line, flag, True)): - if t in newUseFlags[cpv]: - newUseFlags[cpv].remove(t) - jumpOut = True - # break # don't break as both cases can be valid (see below) - if not jumpOut: - newUseFlags[cpv].append((file, line, invFlag, True)) - - # we removed the inverted from package.use - but it is still enabled somewhere else - # so set it explicitly here - if invFlag in pkg.get_actual_use_flags(): - newUseFlags[cpv].append((file, line, flag, False)) - break - - # we want to duplicate the flag --> ignore - elif flag in flags: - added = True # emulate adding - break - - # add as an extra flag - else: - if not added: newUseFlags[cpv].append((file, line, flag, False)) - added = True - - # create a new line - if not added: - path = CONST.use_path() - if CONST.use_path_is_dir(): - path = os.path.join(CONST.use_path(), generate_path(cpv, CONFIG["usefile"])) - try: - newUseFlags[cpv].remove((path, -1, invFlag, False)) - except ValueError: # not in UseFlags - newUseFlags[cpv].append((path, -1, flag, False)) - - newUseFlags[cpv] = unique_array(newUseFlags[cpv]) - debug("newUseFlags: %s", str(newUseFlags)) + """Sets the useflag for a given package. + + @param pkg: the package + @type pkg: string (cpv) or L{backend.Package}-object + @param flag: the flag to set + @type flag: string""" + + global useFlags, newUseFlags + + if not is_package(pkg): + pkg = system.new_package(pkg) # assume cpv or gentoolkit.Package + + cpv = pkg.get_cpv() + invFlag = invert_use_flag(flag) + + # if not saved in useFlags, get it by calling get_data() which calls grep() + data = None + if not cpv in useFlags: + data = get_data(pkg, CONST.use_path()) + useFlags[cpv] = data + else: + data = useFlags[cpv] + + if not cpv in newUseFlags: + newUseFlags[cpv] = [] + + debug("data: %s", str(data)) + # add a useflag / delete one + added = False + for file, line, crit, flags in data: + if pkg.matches(crit): + # we have the inverted flag in the uselist/newuselist --> delete it + if invFlag in flags or (file, line, invFlag, False) in newUseFlags[cpv] or (file, line, flag, True) in newUseFlags[cpv]: + if added: del newUseFlags[-1] # we currently added it as an extra option - delete it + added = True + jumpOut = False + for t in ((file, line, invFlag, False),(file, line, flag, True)): + if t in newUseFlags[cpv]: + newUseFlags[cpv].remove(t) + jumpOut = True + # break # don't break as both cases can be valid (see below) + if not jumpOut: + newUseFlags[cpv].append((file, line, invFlag, True)) + + # we removed the inverted from package.use - but it is still enabled somewhere else + # so set it explicitly here + if invFlag in pkg.get_actual_use_flags(): + newUseFlags[cpv].append((file, line, flag, False)) + break + + # we want to duplicate the flag --> ignore + elif flag in flags: + added = True # emulate adding + break + + # add as an extra flag + else: + if not added: newUseFlags[cpv].append((file, line, flag, False)) + added = True + + # create a new line + if not added: + path = CONST.use_path() + if CONST.use_path_is_dir(): + path = os.path.join(CONST.use_path(), generate_path(cpv, CONFIG["usefile"])) + try: + newUseFlags[cpv].remove((path, -1, invFlag, False)) + except ValueError: # not in UseFlags + newUseFlags[cpv].append((path, -1, flag, False)) + + newUseFlags[cpv] = unique_array(newUseFlags[cpv]) + debug("newUseFlags: %s", str(newUseFlags)) def remove_new_use_flags (cpv): - """Removes all new use-flags for a specific package. - - @param cpv: the package for which to remove the flags - @type cpv: string (cpv) or L{backend.Package}-object""" - - if is_package(cpv): - cpv = cpv.get_cpv() - - try: - del newUseFlags[cpv] - except KeyError: - pass + """Removes all new use-flags for a specific package. + + @param cpv: the package for which to remove the flags + @type cpv: string (cpv) or L{backend.Package}-object""" + + if is_package(cpv): + cpv = cpv.get_cpv() + + try: + del newUseFlags[cpv] + except KeyError: + pass def get_new_use_flags (cpv): - """Gets all the new use-flags for a specific package. - - @param cpv: the package from which to get the flags - @type cpv: string (cpv) or L{backend.Package}-object - @returns: list of flags - @rtype: string[]""" - - if is_package(cpv): - cpv = cpv.get_cpv() - - list2return = set() - try: - for file, line, flag, remove in newUseFlags[cpv]: - if remove: - list2return.add("~"+invert_use_flag(flag)) - else: - list2return.add(flag) - except KeyError: - pass - - return list(list2return) + """Gets all the new use-flags for a specific package. + + @param cpv: the package from which to get the flags + @type cpv: string (cpv) or L{backend.Package}-object + @returns: list of flags + @rtype: string[]""" + + if is_package(cpv): + cpv = cpv.get_cpv() + + list2return = set() + try: + for file, line, flag, remove in newUseFlags[cpv]: + if remove: + list2return.add("~"+invert_use_flag(flag)) + else: + list2return.add(flag) + except KeyError: + pass + + return list(list2return) def write_use_flags (): - """This writes our changed useflags into the file.""" - global newUseFlags, useFlags - - def insert (flag, list): - """Shortcut for inserting a new flag right after the package-name.""" - list.insert(1,flag) - - def remove (flag, list): - """Removes a flag.""" - try: - list.remove(flag) - except ValueError: # flag is given as flag\n - list.remove(flag+"\n") - list.append("\n") #re-insert the newline - - # no more flags there - comment it out - if len(list) == 1 or list[1][0] in ("#","\n"): - list[0] = "#"+list[0] - insert("#removed by portato#",list) - - file_cache = {} # cache for having to read the file only once: name->[lines] - for cpv in newUseFlags: - flagsToAdd = [] # this is used for collecting the flags to be inserted in a _new_ line - - newUseFlags[cpv].sort(key = lambda x: x[3]) # now the flags are sorted in a manner, that removal comes after appending - - for file, line, flag, delete in newUseFlags[cpv]: - line = int(line) # it is saved as a string so far! - # add new line - if line == -1: - flagsToAdd.append(flag) - # change a line - else: - if not file in file_cache: - # read file - with open(file, "r") as f: - lines = [] - i = 1 - while i < line: # stop at the given line - lines.append(f.readline()) - i += 1 - l = f.readline().split(" ") - - # delete or insert - if delete: - remove(flag,l) - else: - insert(flag,l) - lines.append(" ".join(l)) - - # read the rest - lines.extend(f.readlines()) - - file_cache[file] = lines - - else: # in cache - l = file_cache[file][line-1].split(" ") - if delete: - remove(flag, l) - else: - insert(flag,l) - file_cache[file][line-1] = " ".join(l) - - if flagsToAdd: - # write new lines - msg = "\n#portato update#\n" - if CONFIG["usePerVersion"]: # add on a per-version-base - msg += "=%s %s\n" % (cpv, ' '.join(flagsToAdd)) - else: # add on a per-package-base - list = system.split_cpv(cpv) - msg += "%s/%s %s\n" % (list[0], list[1], ' '.join(flagsToAdd)) - if not file in file_cache: - f = open(file, "a") - f.write(msg) - f.close() - else: - file_cache[file].append(msg) - - # write to disk - for file in file_cache.keys(): - f = open(file, "w") - f.writelines(file_cache[file]) - f.close() - # reset - useFlags = {} - newUseFlags = {} - system.reload_settings() + """This writes our changed useflags into the file.""" + global newUseFlags, useFlags + + def insert (flag, list): + """Shortcut for inserting a new flag right after the package-name.""" + list.insert(1,flag) + + def remove (flag, list): + """Removes a flag.""" + try: + list.remove(flag) + except ValueError: # flag is given as flag\n + list.remove(flag+"\n") + list.append("\n") #re-insert the newline + + # no more flags there - comment it out + if len(list) == 1 or list[1][0] in ("#","\n"): + list[0] = "#"+list[0] + insert("#removed by portato#",list) + + file_cache = {} # cache for having to read the file only once: name->[lines] + for cpv in newUseFlags: + flagsToAdd = [] # this is used for collecting the flags to be inserted in a _new_ line + + newUseFlags[cpv].sort(key = lambda x: x[3]) # now the flags are sorted in a manner, that removal comes after appending + + for file, line, flag, delete in newUseFlags[cpv]: + line = int(line) # it is saved as a string so far! + # add new line + if line == -1: + flagsToAdd.append(flag) + # change a line + else: + if not file in file_cache: + # read file + with open(file, "r") as f: + lines = [] + i = 1 + while i < line: # stop at the given line + lines.append(f.readline()) + i += 1 + l = f.readline().split(" ") + + # delete or insert + if delete: + remove(flag,l) + else: + insert(flag,l) + lines.append(" ".join(l)) + + # read the rest + lines.extend(f.readlines()) + + file_cache[file] = lines + + else: # in cache + l = file_cache[file][line-1].split(" ") + if delete: + remove(flag, l) + else: + insert(flag,l) + file_cache[file][line-1] = " ".join(l) + + if flagsToAdd: + # write new lines + msg = "\n#portato update#\n" + if CONFIG["usePerVersion"]: # add on a per-version-base + msg += "=%s %s\n" % (cpv, ' '.join(flagsToAdd)) + else: # add on a per-package-base + list = system.split_cpv(cpv) + msg += "%s/%s %s\n" % (list[0], list[1], ' '.join(flagsToAdd)) + if not file in file_cache: + f = open(file, "a") + f.write(msg) + f.close() + else: + file_cache[file].append(msg) + + # write to disk + for file in file_cache.keys(): + f = open(file, "w") + f.writelines(file_cache[file]) + f.close() + # reset + useFlags = {} + newUseFlags = {} + system.reload_settings() ### MASKING PART ### new_masked = {} new_unmasked = {} def set_masked (pkg, masked = True): - """Sets the masking status of the package. - - @param pkg: the package from which to get the flags - @type pkg: string (cpv) or L{backend.Package}-object - @param masked: if True: mask it; if False: unmask it - @type masked: boolean""" - - global new_masked, newunmasked - - if not is_package(pkg): - pkg = system.new_package(pkg) - - cpv = pkg.get_cpv() - - if not cpv in new_unmasked: - new_unmasked[cpv] = [] - if not cpv in new_masked: - new_masked[cpv] = [] - - if masked: - link_neq = new_masked - link_eq = new_unmasked - path = CONST.unmask_path() - else: - link_neq = new_unmasked - link_eq = new_masked - path = CONST.mask_path() - - copy = link_eq[cpv][:] - for file, line in copy: - if line == "-1": - link_eq[cpv].remove((file, line)) - - copy = link_neq[cpv][:] - for file, line in copy: - if line != "-1": - link_neq[cpv].remove((file, line)) - - if masked == pkg.is_masked(): - return - - data = get_data(pkg, path) - debug("data: %s", str(data)) - done = False - for file, line, crit, flags in data: - if pkg.matches(crit): - link_eq[cpv].append((file, line)) - done = True - - if done: return - - if masked: - is_dir = CONST.mask_path_is_dir() - path = CONST.mask_path() - else: - is_dir = CONST.unmask_path_is_dir() - path = CONST.unmask_path() - - if is_dir: - file = os.path.join(path, generate_path(cpv, CONFIG["maskfile"])) - else: - file = path - - link_neq[cpv].append((file, "-1")) - link_neq[cpv] = unique_array(link_neq[cpv]) - debug("new_(un)masked: %s",str(link_neq)) + """Sets the masking status of the package. + + @param pkg: the package from which to get the flags + @type pkg: string (cpv) or L{backend.Package}-object + @param masked: if True: mask it; if False: unmask it + @type masked: boolean""" + + global new_masked, newunmasked + + if not is_package(pkg): + pkg = system.new_package(pkg) + + cpv = pkg.get_cpv() + + if not cpv in new_unmasked: + new_unmasked[cpv] = [] + if not cpv in new_masked: + new_masked[cpv] = [] + + if masked: + link_neq = new_masked + link_eq = new_unmasked + path = CONST.unmask_path() + else: + link_neq = new_unmasked + link_eq = new_masked + path = CONST.mask_path() + + copy = link_eq[cpv][:] + for file, line in copy: + if line == "-1": + link_eq[cpv].remove((file, line)) + + copy = link_neq[cpv][:] + for file, line in copy: + if line != "-1": + link_neq[cpv].remove((file, line)) + + if masked == pkg.is_masked(): + return + + data = get_data(pkg, path) + debug("data: %s", str(data)) + done = False + for file, line, crit, flags in data: + if pkg.matches(crit): + link_eq[cpv].append((file, line)) + done = True + + if done: return + + if masked: + is_dir = CONST.mask_path_is_dir() + path = CONST.mask_path() + else: + is_dir = CONST.unmask_path_is_dir() + path = CONST.unmask_path() + + if is_dir: + file = os.path.join(path, generate_path(cpv, CONFIG["maskfile"])) + else: + file = path + + link_neq[cpv].append((file, "-1")) + link_neq[cpv] = unique_array(link_neq[cpv]) + debug("new_(un)masked: %s",str(link_neq)) def remove_new_masked (cpv): - if is_package(cpv): - cpv = cpv.get_cpv() - - try: - del new_masked[cpv] - except KeyError: - pass - - try: - del new_unmasked[cpv] - except KeyError: - pass + if is_package(cpv): + cpv = cpv.get_cpv() + + try: + del new_masked[cpv] + except KeyError: + pass + + try: + del new_unmasked[cpv] + except KeyError: + pass def new_masking_status (cpv): - if is_package(cpv): - cpv = cpv.get_cpv() - - def get(list): - ret = None - if cpv in list and list[cpv] != []: - for file, line in list[cpv]: - _ret = (int(line) == -1) - if ret is not None and _ret != ret: - error(_("Conflicting values for masking status: %s"), list) - else: - ret = _ret - return ret - - masked = get(new_masked) - if masked is None: - masked = get(new_unmasked) - if masked is not None: - masked = not masked # revert for new_unmasked - - if masked is not None: - if masked: return "masked" - else: return "unmasked" - else: - return None + if is_package(cpv): + cpv = cpv.get_cpv() + + def get(list): + ret = None + if cpv in list and list[cpv] != []: + for file, line in list[cpv]: + _ret = (int(line) == -1) + if ret is not None and _ret != ret: + error(_("Conflicting values for masking status: %s"), list) + else: + ret = _ret + return ret + + masked = get(new_masked) + if masked is None: + masked = get(new_unmasked) + if masked is not None: + masked = not masked # revert for new_unmasked + + if masked is not None: + if masked: return "masked" + else: return "unmasked" + else: + return None def is_locally_masked (pkg, changes = True): - if not is_package(pkg): - pkg = system.new_package(pkg) # assume it is a cpv or a gentoolkit.Package + if not is_package(pkg): + pkg = system.new_package(pkg) # assume it is a cpv or a gentoolkit.Package - if changes: - if new_masking_status(pkg) == "masked": # we masked it ourselves, but did not save it yet - # but sometimes, new_masking_status() returns "masked" if a package's unmask is removed - # then it is masked by the system but not locally (except rarely exotic cases) - if pkg.get_cpv() in new_unmasked: - if new_unmasked[pkg.get_cpv()]: return False # assume that there only exists one entry for this package - # else new_masking_status should have printed an error - return True + if changes: + if new_masking_status(pkg) == "masked": # we masked it ourselves, but did not save it yet + # but sometimes, new_masking_status() returns "masked" if a package's unmask is removed + # then it is masked by the system but not locally (except rarely exotic cases) + if pkg.get_cpv() in new_unmasked: + if new_unmasked[pkg.get_cpv()]: return False # assume that there only exists one entry for this package + # else new_masking_status should have printed an error + return True - if new_masking_status(pkg) == "unmasked": # we unmasked it - return False - - list = get_data(pkg, CONST.mask_path()) + if new_masking_status(pkg) == "unmasked": # we unmasked it + return False + + list = get_data(pkg, CONST.mask_path()) - if not list: return False + if not list: return False - for file, line, crit, fl in list: - if pkg.matches(crit): - return True + for file, line, crit, fl in list: + if pkg.matches(crit): + return True - return False - + return False + def write_masked (): - global new_unmasked, new_masked - file_cache = {} - - def write(cpv, file, line): - line = int(line) - # add new line - if line == -1: - msg = "\n#portato update#\n" - if CONFIG["maskPerVersion"]: - msg += "=%s\n" % cpv - else: - list = system.split_cpv(cpv) - msg += "%s/%s\n" % (list[0],list[1]) - if not file in file_cache: - f = open(file, "a") - f.write(msg) - f.close() - else: - file_cache[file].append(msg) - # change a line - else: - if not file in file_cache: - # read file - f = open(file, "r") - lines = [] - i = 1 - while i < line: # stop at the given line - lines.append(f.readline()) - i = i+1 - # delete - l = f.readline() - l = "#"+l[:-1]+" # removed by portato\n" - lines.append(l) - - # read the rest - lines.extend(f.readlines()) - - file_cache[file] = lines - f.close() - else: # in cache - l = file_cache[file][line-1] - # delete: - l = "#"+l[:-1]+" # removed by portato\n" - file_cache[file][line-1] = l - - - for cpv in new_masked: - for file, line in new_masked[cpv]: - write(cpv, file, line) - - for cpv in new_unmasked: - for file, line in new_unmasked[cpv]: - write(cpv, file, line) - - # write to disk - for file in file_cache.keys(): - f = open(file, "w") - f.writelines(file_cache[file]) - f.close() - # reset - new_masked = {} - new_unmasked = {} - system.reload_settings() + global new_unmasked, new_masked + file_cache = {} + + def write(cpv, file, line): + line = int(line) + # add new line + if line == -1: + msg = "\n#portato update#\n" + if CONFIG["maskPerVersion"]: + msg += "=%s\n" % cpv + else: + list = system.split_cpv(cpv) + msg += "%s/%s\n" % (list[0],list[1]) + if not file in file_cache: + f = open(file, "a") + f.write(msg) + f.close() + else: + file_cache[file].append(msg) + # change a line + else: + if not file in file_cache: + # read file + f = open(file, "r") + lines = [] + i = 1 + while i < line: # stop at the given line + lines.append(f.readline()) + i = i+1 + # delete + l = f.readline() + l = "#"+l[:-1]+" # removed by portato\n" + lines.append(l) + + # read the rest + lines.extend(f.readlines()) + + file_cache[file] = lines + f.close() + else: # in cache + l = file_cache[file][line-1] + # delete: + l = "#"+l[:-1]+" # removed by portato\n" + file_cache[file][line-1] = l + + + for cpv in new_masked: + for file, line in new_masked[cpv]: + write(cpv, file, line) + + for cpv in new_unmasked: + for file, line in new_unmasked[cpv]: + write(cpv, file, line) + + # write to disk + for file in file_cache.keys(): + f = open(file, "w") + f.writelines(file_cache[file]) + f.close() + # reset + new_masked = {} + new_unmasked = {} + system.reload_settings() ### TESTING PART ### newTesting = {} arch = "" def remove_new_testing (cpv): - if is_package(cpv): - cpv = cpv.get_cpv() - - try: - del newTesting[cpv] - except KeyError: - pass + if is_package(cpv): + cpv = cpv.get_cpv() + + try: + del newTesting[cpv] + except KeyError: + pass def new_testing_status (cpv): - if is_package(cpv): - cpv = cpv.get_cpv() + if is_package(cpv): + cpv = cpv.get_cpv() - if cpv in newTesting: - for file, line in newTesting[cpv]: - if line == "-1": return False - else: return True + if cpv in newTesting: + for file, line in newTesting[cpv]: + if line == "-1": return False + else: return True - return None + return None def set_testing (pkg, enable): - """Enables the package for installing when it is marked as testing (~ARCH). - @param pkg: the package - @type pkg: string (cpv) or L{backend.Package}-object - @param enable: controls whether to enable (True) or disable (False) for test-installing - @type enable: boolean""" - - global arch, newTesting - if not is_package(pkg): - pkg = system.new_package(pkg) - - arch = pkg.get_global_settings("ARCH") - cpv = pkg.get_cpv() - if not cpv in newTesting: - newTesting[cpv] = [] - - for file, line in newTesting[cpv]: - if (enable and line != "-1") or (not enable and line == "-1"): - newTesting[cpv].remove((file, line)) - - if (enable and not pkg.is_testing()) or (not enable and pkg.is_testing()): - return - - if not enable: - test = get_data(pkg, CONST.testing_path()) - debug("data (test): %s", str(test)) - for file, line, crit, flags in test: - if pkg.matches(crit) and flags[0] == "~"+arch: - newTesting[cpv].append((file, line)) - else: - if CONST.testing_path_is_dir(): - file = os.path.join(CONST.testing_path(), generate_path(cpv, CONFIG["testingfile"])) - else: - file = CONST.testing_path() - newTesting[cpv].append((file, "-1")) - - newTesting[cpv] = unique_array(newTesting[cpv]) - debug("newTesting: %s",str(newTesting)) + """Enables the package for installing when it is marked as testing (~ARCH). + @param pkg: the package + @type pkg: string (cpv) or L{backend.Package}-object + @param enable: controls whether to enable (True) or disable (False) for test-installing + @type enable: boolean""" + + global arch, newTesting + if not is_package(pkg): + pkg = system.new_package(pkg) + + arch = pkg.get_global_settings("ARCH") + cpv = pkg.get_cpv() + if not cpv in newTesting: + newTesting[cpv] = [] + + for file, line in newTesting[cpv]: + if (enable and line != "-1") or (not enable and line == "-1"): + newTesting[cpv].remove((file, line)) + + if (enable and not pkg.is_testing()) or (not enable and pkg.is_testing()): + return + + if not enable: + test = get_data(pkg, CONST.testing_path()) + debug("data (test): %s", str(test)) + for file, line, crit, flags in test: + if pkg.matches(crit) and flags[0] == "~"+arch: + newTesting[cpv].append((file, line)) + else: + if CONST.testing_path_is_dir(): + file = os.path.join(CONST.testing_path(), generate_path(cpv, CONFIG["testingfile"])) + else: + file = CONST.testing_path() + newTesting[cpv].append((file, "-1")) + + newTesting[cpv] = unique_array(newTesting[cpv]) + debug("newTesting: %s",str(newTesting)) def write_testing (): - global arch, newTesting - file_cache = {} - - for cpv in newTesting: - for file, line in newTesting[cpv]: - line = int(line) - # add new line - if line == -1: - msg = "\n#portato update#\n" - if CONFIG["testingPerVersion"