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 --- 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 +- 40 files changed, 7672 insertions(+), 7672 deletions(-) (limited to 'portato') 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"]: - msg += "=%s ~%s\n" % (cpv, arch) - else: - list = system.split_cpv(cpv) - msg += "%s/%s ~%s\n" % (list[0],list[1],arch) - 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 - - # write to disk - for file in file_cache.keys(): - f = open(file, "w") - f.writelines(file_cache[file]) - f.close() - # reset - newTesting = {} - system.reload_settings() + 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"]: + msg += "=%s ~%s\n" % (cpv, arch) + else: + list = system.split_cpv(cpv) + msg += "%s/%s ~%s\n" % (list[0],list[1],arch) + 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 + + # write to disk + for file in file_cache.keys(): + f = open(file, "w") + f.writelines(file_cache[file]) + f.close() + # reset + newTesting = {} + system.reload_settings() diff --git a/portato/backend/package.py b/portato/backend/package.py index 6d73a42..e4b2082 100644 --- a/portato/backend/package.py +++ b/portato/backend/package.py @@ -18,396 +18,396 @@ from ..dependency import DependencyTree from . import _Package, system, flags class Package (_Package): - """This is a class abstracting a normal package which can be installed.""" - - def __init__ (self, cpv): - """Constructor. - - @param cpv: The cpv which describes the package to create. - @type cpv: string (cat/pkg-ver)""" - - self._cpv = cpv - - # - # implemented - # - - def set_testing(self, enable = True): - """Sets the actual testing status of the package. - - @param enable: if True it is masked as stable; if False it is marked as testing - @type enable: boolean""" - - flags.set_testing(self, enable) - - def remove_new_testing(self): - """Removes possible changed testing status.""" - - flags.remove_new_testing(self.get_cpv()) - - def set_masked (self, masking = False): - """Sets the masking status of the package. - - @param masking: if True: mask it; if False: unmask it - @type masking: boolean""" - - flags.set_masked(self, masked = masking) - - def remove_new_masked (self): - """Removes possible changed masking status.""" - - flags.remove_new_masked(self.get_cpv()) - - def is_locally_masked (self): - """Checks whether the package is masked by the user. - - @returns: True if masked by the user; False if not - @rtype: bool""" - - return flags.is_locally_masked(self) - - def get_new_use_flags (self): - """Returns a list of the new useflags, i.e. these flags which are not written to the portage-system yet. - - @returns: list of flags or [] - @rtype: string[]""" - - return flags.get_new_use_flags(self) - - def get_actual_use_flags (self): - """This returns all currently set use-flags including the new ones. - - @return: list of flags - @rtype: string[]""" - - i_flags = self.get_global_settings("USE", installed = False).split() - m_flags = system.get_global_settings("USE").split() - for f in self.get_new_use_flags(): - removed = False - - if f[0] == "~": - f = f[1:] - removed = True - - invf = flags.invert_use_flag(f) - - if f[0] == '-': - if invf in i_flags and not (removed and invf in m_flags): - i_flags.remove(invf) - - elif f not in i_flags: - if not (removed and invf in m_flags): - i_flags.append(f) - - return i_flags - - def set_use_flag (self, flag): - """Set a use-flag. - - @param flag: the flag to set - @type flag: string""" - - flags.set_use_flag(self, flag) - - def remove_new_use_flags (self): - """Remove all the new use-flags.""" - - flags.remove_new_use_flags(self) - - def use_expanded (self, flag, suggest = None): - """Tests whether a useflag is an expanded one. If it is, this method returns the USE_EXPAND-value. - - @param flag: the flag to check - @type flag: string - @param suggest: try this suggestion first - @type suggest: string - @returns: USE_EXPAND-value on success - @rtype: string or None""" - - if suggest is not None: - if flag.startswith(suggest.lower()): - return suggest - - for exp in self.get_global_settings("USE_EXPAND").split(): - lexp = exp.lower() - if flag.startswith(lexp): - return exp - - return None - - def get_cpv(self): - """Returns full Category/Package-Version string. - - @returns: the cpv - @rtype: string""" - - return self._cpv - - def get_cp (self): - """Returns the cp-string. - - @returns: category/package. - @rtype: string""" - - return self.get_category()+"/"+self.get_name() - - def get_slot_cp (self): - """Returns the current cp followed by a colon and the slot-number. - - @returns: cp:slot - @rtype: string""" - - return ("%s:%s" % (self.get_cp(), self.get_package_settings("SLOT"))) - - def get_package_path(self): - """Returns the path to where the ChangeLog, Manifest, .ebuild files reside. - - @returns: path to the package files - @rtype: string""" - - p = self.get_ebuild_path() - sp = p.split("/") - if sp: - return "/".join(sp[:-1]) - - def get_dependencies (self): - """ - Returns the tree of dependencies that this package needs. - - @rtype: L{DependencyTree} - """ - deps = " ".join(map(self.get_package_settings, ("RDEPEND", "PDEPEND", "DEPEND"))) - deps = paren_reduce(deps) - - tree = DependencyTree() - - def add (tree, deps): - it = iter(deps) - for dep in it: - if hasattr(dep, "__iter__"): - debug("Following dep is an unsupposed list: %s", dep) - assert(len(dep) == 1) - dep = dep[0] - if dep.endswith("?"): - ntree = tree.add_flag(dep[:-1]) - n = it.next() - if not hasattr(n, "__iter__"): - n = (n,) - add(ntree, n) - - elif dep == "||": - n = it.next() # skip - if not hasattr(n, "__iter__"): - n = [n] - else: - n = list(n) - - tree.add_or(n) - - else: - tree.add(dep) - - add(tree, deps) - return tree - - # - # Not implemented - # - - def get_name(self): - """Returns base name of package, no category nor version. - - @returns: base-name - @rtype: string""" - - raise NotImplementedError - - def get_version(self): - """Returns version of package, with (optional) revision number. - - @returns: version-rev - @rtype: string""" - - raise NotImplementedError - - def get_category(self): - """Returns category of package. - - @returns: category - @rtype: string""" - - raise NotImplementedError - - def is_installed(self): - """Returns true if this package is installed (merged). - @rtype: boolean""" - - raise NotImplementedError - - def is_in_overlay(self): - """Returns true if the package is in an overlay. - @rtype: boolean""" - - raise NotImplementedError - - def get_overlay_path(self): - """Returns the path to the current overlay. - @rtype: string""" - - raise NotImplementedError - - def is_in_system (self): - """Returns False if the package could not be found in the portage system. - - @return: True if in portage system; else False - @rtype: boolean""" - - raise NotImplementedError - - def is_missing_keyword(self): - """Returns True if the package is missing the needed keyword. - - @return: True if keyword is missing; else False - @rtype: boolean""" - - raise NotImplementedError - - def is_testing(self, use_keywords = True): - """Checks whether a package is marked as testing. - - @param use_keywords: Controls whether possible keywords are taken into account or not. - @type use_keywords: boolean - @returns: True if the package is marked as testing; else False. - @rtype: boolean""" - - raise NotImplementedError - - def is_masked (self, use_changed = True): - """Returns True if either masked by package.mask or by profile. - - @param use_changed: Controls, whether changes applied to masking keywords are taken into account. - @type use_changed: boolean - @returns: True if masked / False otherwise - @rtype: boolean""" - - raise NotImplementedError - - def get_masking_reason (self): - """Returns the reason for masking the package. If this is not possible for the system, return None. - - @returns: the reason for masking the package - @rtype: string""" - - def get_iuse_flags (self, installed = False, removeForced = True): - """Returns a list of _all_ useflags for this package, i.e. all useflags you can set for this package. - - @param installed: do not take the ones stated in the ebuild, but the ones it has been installed with - @type installed: boolean - @param removeForced: remove forced flags (i.e. usemask / useforce) from the iuse flags as they cannot be set from the user - @type removeForced: boolean - - @returns: list of use-flags - @rtype: string[]""" - - raise NotImplementedError - - def get_matched_dep_packages (self, depvar): - """This function looks for all dependencies which are resolved. In normal case it makes only sense for installed packages, but should work for uninstalled ones too. - - @param depvar: the dependency variables (RDEPEND, PDEPEND, DEPEND) to use - @type depvar: string[] - - @returns: unique list of dependencies resolved (with elements like "<=net-im/foobar-1.2.3") - @rtype: string[] - - @raises portato.DependencyCalcError: when an error occured during executing portage.dep_check()""" - - raise NotImplementedError - - def get_dep_packages (self, depvar = ["RDEPEND", "PDEPEND", "DEPEND"], with_criterions = False): - """Returns a cpv-list of packages on which this package depends and which have not been installed yet. This does not check the dependencies in a recursive manner. - - @param depvar: the dependency variables (RDEPEND, PDEPEND, DEPEND) to use - @type depvar: string[] - @param with_criterions: return also the criterions - @type with_criterions: boolean - - @returns: list of cpvs on which the package depend (and if wanted also the criterions) - @rtype: string[] or (string, string)[] - - @raises portato.BlockedException: when a package in the dependency-list is blocked by an installed one - @raises portato.PackageNotFoundException: when a package in the dependency list could not be found in the system - @raises portato.DependencyCalcError: when an error occured during executing portage.dep_check()""" - - raise NotImplementedError - - def get_global_settings(self, key, installed = True): - """Returns the value of a global setting, i.e. ARCH, USE, ROOT, DISTDIR etc. - - @param key: the setting to return - @type key: string - @param installed: get the installed settings or the ebuild settings - @type installed: boolean - @returns: the value of this setting - @rtype: string""" - - raise NotImplementedError - - def get_ebuild_path(self): - """Returns the complete path to the .ebuild file. - - @rtype: string""" - - raise NotImplementedError - - def get_files (self): - """ - Returns an iterator over the installed files of a package. - If the package is not installed, the iterator should be "empty". - - @returns: the installed files - @rtype: string - """ - - raise NotImplementedError - - def get_package_settings(self, var, installed = True): - """Returns a package specific setting, such as DESCRIPTION, SRC_URI, IUSE ... - - @param var: the setting to get - @type var: string - @param installed: take the vartree or the porttree - @type installed: boolean - - @returns: the value of the setting - @rtype: string""" - - raise NotImplementedError - - def get_installed_use_flags(self): - """Returns _all_ (not only the package-specific) useflags which were set at the installation time of the package. - - @returns: list of use flags - @rtype: string[]""" - - raise NotImplementedError - - def compare_version(self, other): - """Compares this package's version to another's CPV; returns -1, 0, 1. - - @param other: the other package - @type other: Package - @returns: -1, 0 or 1 - @rtype: int""" - - raise NotImplementedError - - def matches (self, criterion): - """This checks, whether this package matches a specific versioning criterion - e.g.: "<=net-im/foobar-1.2". - - @param criterion: the criterion to match against - @type criterion: string - @returns: True if matches; False if not - @rtype: boolean""" - - raise NotImplementedError + """This is a class abstracting a normal package which can be installed.""" + + def __init__ (self, cpv): + """Constructor. + + @param cpv: The cpv which describes the package to create. + @type cpv: string (cat/pkg-ver)""" + + self._cpv = cpv + + # + # implemented + # + + def set_testing(self, enable = True): + """Sets the actual testing status of the package. + + @param enable: if True it is masked as stable; if False it is marked as testing + @type enable: boolean""" + + flags.set_testing(self, enable) + + def remove_new_testing(self): + """Removes possible changed testing status.""" + + flags.remove_new_testing(self.get_cpv()) + + def set_masked (self, masking = False): + """Sets the masking status of the package. + + @para