diff options
Diffstat (limited to 'portato')
40 files changed, 7672 insertions, 7672 deletions
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 <necoro@necoro.net> 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<iterator> + @param flaglist: the list of useflags + @type flaglist: string<iterator> - @returns: the "cleaned" list - @rtype: string<iterator> - """ + @returns: the "cleaned" list + @rtype: string<iterator> + """ - 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""" - |