diff options
-rw-r--r-- | geneticone/backend/package.py | 186 | ||||
-rw-r--r-- | geneticone/backend/portage_helper.py | 128 |
2 files changed, 160 insertions, 154 deletions
diff --git a/geneticone/backend/package.py b/geneticone/backend/package.py index 522ca08..da2a131 100644 --- a/geneticone/backend/package.py +++ b/geneticone/backend/package.py @@ -32,19 +32,32 @@ class Package (gentoolkit.Package): self._status = portage.getmaskingstatus(self.get_cpv(), settings = gentoolkit.settings) 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""" + if "missing keyword" in self._status: return True return False def is_testing(self, allowed = False): + """Checks whether a package is marked as testing. + + @param allowed: Controls whether possible keywords are taken into account or not. + @type allowed: boolean + @returns: True if the package is marked as testing; else False. + @rtype: boolean""" + testArch = "~" + self.get_settings("ARCH") - if not allowed: + if not allowed: # keywords are NOT taken into account if testArch in self.get_env_var("KEYWORDS").split(): return True return False - else: + + else: # keywords are taken into account status = flags.new_testing_status(self.get_cpv()) - if status == None: + if status == None: # we haven't changed it in any way if testArch+" keyword" in self._status: return True return False @@ -52,38 +65,53 @@ class Package (gentoolkit.Package): return status 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 is_masked (self): """Returns True if either masked by package.mask or by profile. - @returns: mask-status + + @returns: True if masked / False otherwise @rtype: boolean""" - # XXX: Better solution than string comparison? + status = flags.new_masking_status(self.get_cpv()) - if status != None: + if status != None: # we have locally changed it if status == "masked": return True elif status == "unmasked": return False else: - debug("BUG in flags.new_masking_status. It returns "+status) - else: + debug("BUG in flags.new_masking_status. It returns",status) + else: # we have not touched the status if "profile" in self._status or "package.mask" in self._status: return True return False 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 get_all_use_flags (self): """Returns a list of _all_ useflags for this package, i.e. all useflags you can set for this package. @returns: list of use-flags - @rtype: list""" + @rtype: string[]""" return unique_array(self.get_env_var("IUSE").split()) @@ -91,10 +119,11 @@ class Package (gentoolkit.Package): """Returns a list of the useflags enabled at installation time. If package is not installed, it returns an empty list. @returns: list of useflags enabled at installation time or an empty list - @rtype: list""" + @rtype: string[]""" + if self.is_installed(): - uses = self.get_use_flags().split() - iuses = self.get_all_use_flags() + uses = self.get_use_flags().split() # all set at installation time + iuses = self.get_all_use_flags() # all you can set for the package set = [] for u in iuses: if u in uses: @@ -107,20 +136,23 @@ class Package (gentoolkit.Package): """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: list""" + @rtype: string[]""" + return flags.get_new_use_flags(self) def get_actual_use_flags (self): """This returns the result of installed_use_flags + new_use_flags. If the package is not installed, it returns only the new flags. @return: list of flags - @rtype: list""" + @rtype: string[]""" if self.is_installed(): i_flags = self.get_installed_use_flags() for f in self.get_new_use_flags(): + if flags.invert_flag(f) in i_flags: i_flags.remove(flags.invert_flag(f)) + elif f not in i_flags: i_flags.append(f) return i_flags @@ -132,24 +164,27 @@ class Package (gentoolkit.Package): @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 get_dep_packages (self): """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. @returns: list of cpvs on which the package depend - @rtype: list + @rtype: string[] + @raises geneticone.BlockedException: when a package in the dependency-list is blocked by an installed one @raises geneticone.PackageNotFoundException: when a package in the dependency list could not be found in the system @raises geneticone.DependencyCalcError: when an error occured during executing portage.dep_check()""" dep_pkgs = [] # the package list - # check whether we got use-flags which are not visible for portage yet + # change the useflags, because we have internally changed some, but not made them visible for portage newUseFlags = self.get_new_use_flags() actual = self.get_settings("USE").split() if newUseFlags: @@ -164,7 +199,7 @@ class Package (gentoolkit.Package): # pay attention to any changes here deps = portage.dep_check (self.get_env_var("RDEPEND")+" "+self.get_env_var("DEPEND")+" "+self.get_env_var("PDEPEND"), vartree.dbapi, self._settings, myuse = actual) - if not deps: # what is the difference to [1, []] ? + if not deps: # FIXME: what is the difference to [1, []] ? return [] if deps[0] == 0: # error @@ -203,124 +238,21 @@ class Package (gentoolkit.Package): def get_cp (self): """Returns the cp-string. + @returns: category/package. @rtype: string""" + return self.get_category()+"/"+self.get_name() def matches (self, criterion): """This checks, whether this package matches a specific verisioning criterion - e.g.: "<=net-im/foobar-1.2". + @param criterion: the criterion to match against - @type criterion: string""" + @type criterion: string + @returns: True if matches; False if not + @rtype: boolean""" + if portage.match_from_list(criterion, [self.get_cpv()]) == []: return False else: return True -# -# OBSOLETE DEPENDENCY-CALCULATION-METHODS - kept in the case the above ones do not work -# - - #def own_get_dep_packages (self, old_cpv_dict = {}): - # # XXX: after having finished this, i realized, that there is already a portage function -.- ; - # """Returns a list of all packages (i.e. package-cpvs) which this package depends on and which not have been installed yet. - # Param old_cpv_dict is a {cp: version}-dictionary holding already found deps. - # Raises a BlockedException if the package is being blocked by another installed package.""" - # # XXX: This won't find blocking dependencies - # # XXX: Has some problems with modular X (this has a very strange ebuild) ... we should enhance _parse_deps - # print "Actual: "+self._cpv # debug output - # - # uses = [] # list of actual useflags / useflags the package has been installed with - # dep_packages = [] # list of packages returned - # dep_cpv_dict = {} # all dependencies are inserted here - # - # # get useflags - # if self.is_installed(): - # uses = self.get_installed_use_flags() - # else: - # uses = self.get_settings("USE") - # - # # cycle through dependencies - # for (comp, flags, dep_cpv) in self.get_all_deps(): - - # # find blocking packages - # if comp and comp[0] == '!': - # blocked = find_installed_packages(comp[1:]+dep_cpv) - # if blocked != []: - # raise BlockedException, blocked[0].get_cpv() - # else: # next flag - # continue - # - # # look whether this package is really required - # needDep = True - # for flag in flags: - # if (flag[0] == '!' and flag[1:] in uses) or (flag[0] != '!' and flag not in uses): - # needDep = False - # break - - # if needDep: # it is ... - # if find_installed_packages(comp+dep_cpv) == []: # ... and not installed yet - # d = find_best_match(comp+dep_cpv) - # if not d: # no package found - # raise PackageNotFoundException, dep_cpv - # if d.get_cp() not in old_cpv_dict: # ... and not found already by an other package - # dep_cpv_dict[d.get_cp()] = d.get_version() - # print "Dep: "+d.get_cpv() # debug - # dep_packages.append(d.get_cpv()) - # - # for dep in dep_packages: # find dependencies for each package - # old_cpv_dict.update(dep_cpv_dict) - # old_cpv_dict.update({self.get_cp() : self.get_version()}) - # dep_packages += find_packages("="+dep)[0].own_get_dep_packages(old_cpv_dict) - - # return unique_array(dep_packages) - - #def get_all_deps (self): - # """Returns a linearised list of all first-level dependencies for this package, on - # the form [(comparator, [use flags], cpv), ...]""" - # return unique_array(self.get_compiletime_deps()+self.get_runtime_deps()+self.get_postmerge_deps()) - - #def _parse_deps(self,deps,curuse=[],level=0): - # """Modified method "_parse_deps" of gentoolkit.Package. - # Do NOT ignore blocks.""" - # # store (comparator, [use predicates], cpv) - # r = [] - # comparators = ["~","<",">","=","<=",">="] - # end = len(deps) - # i = 0 - # while i < end: - # blocked = False - # tok = deps[i] - # if tok == ')': - # return r,i - # if tok[-1] == "?": - # tok = tok.replace("?","") - # sr,l = self._parse_deps(deps[i+2:],curuse=curuse+[tok],level=level+1) - # r += sr - # i += l + 3 - # continue - # if tok == "||": - # sr,l = self._parse_deps(deps[i+2:],curuse,level=level+1) - # r += sr - # i += l + 3 - # continue - # # conjonction, like in "|| ( ( foo bar ) baz )" => recurse - # if tok == "(": - # sr,l = self._parse_deps(deps[i+1:],curuse,level=level+1) - # r += sr - # i += l + 2 - # continue - # # pkg block "!foo/bar" => ignore it - # if tok[0] == "!": - # #i += 1 - # #continue - # blocked = True # added - # tok = tok[1:] # added - # # pick out comparator, if any - # cmp = "" - # for c in comparators: - # if tok.find(c) == 0: - # cmp = c - # if blocked: cmp = "!"+cmp # added - # tok = tok[len(cmp):] - # r.append((cmp,curuse,tok)) - # i += 1 - # return r,i diff --git a/geneticone/backend/portage_helper.py b/geneticone/backend/portage_helper.py index 23172e5..37a2b91 100644 --- a/geneticone/backend/portage_helper.py +++ b/geneticone/backend/portage_helper.py @@ -19,12 +19,14 @@ import package def find_lambda (name): """Returns the function needed by all the find_all_*-functions. Returns None if no name is given. + @param name: name to build the function of @type name: string @returns: 1. None if no name is given 2. a lambda function @rtype: function""" + if name != None: return lambda x: re.match(".*"+name+".*",x) else: @@ -32,10 +34,12 @@ def find_lambda (name): def geneticize_list (list_of_packages): """Convertes a list of gentoolkit.Packages into L{backend.Package}s. + @param list_of_packages: the list of packages @type list_of_packages: list of gentoolkit.Packages @returns: converted list - @rtype: list of geneticone.backend.Packages""" + @rtype: backend.Package[]""" + return [package.Package(x) for x in list_of_packages] def find_best_match (search_key, only_installed = False): @@ -47,7 +51,7 @@ def find_best_match (search_key, only_installed = False): @type only_installed: boolean @returns: the package found or None - @rtype: backend.Package or None""" + @rtype: backend.Package""" t = None if not only_installed: @@ -60,39 +64,59 @@ def find_best_match (search_key, only_installed = False): def find_packages (search_key, masked=False): """This returns a list of packages which have to fit exactly. Additionally ranges like '<,>,=,~,!' et. al. are possible. + @param search_key: the key to look for @type search_key: string @param masked: if True, also look for masked packages @type masked: boolean + @returns: list of found packages - @rtype: list of backend.Package""" + @rtype: backend.Package[]""" return geneticize_list(gentoolkit.find_packages(search_key, masked)) def find_installed_packages (search_key, masked=False): """This returns a list of packages which have to fit exactly. Additionally ranges like '<,>,=,~,!' et. al. are possible. + @param search_key: the key to look for @type search_key: string @param masked: if True, also look for masked packages @type masked: boolean + @returns: list of found packages - @rtype: list of backend.Package""" + @rtype: backend.Package[]""" return geneticize_list(gentoolkit.find_installed_packages(search_key, masked)) def find_system_packages (): - """Returns a list-tuple (resolved_packages, unresolved_packages) for all system packages.""" + """Looks for all packages saved as "system-packages". + + @returns: a tuple of (resolved_packages, unresolved_packages). + @rtype: (backend.Package[], backend.Package[])""" + list = gentoolkit.find_system_packages() return (geneticize_list(list[0]), geneticize_list(list[1])) def find_world_packages (): - """Returns a list-tuple (resolved_packages, unresolved_packages) for all packages in the world-file.""" + """Looks for all packages saved in the world-file. + + @returns: a tuple of (resolved_packages, unresolved_packages). + @rtype: (backend.Package[], backend.Package[])""" + list = gentoolkit.find_world_packages() return geneticize_list(list[0]),geneticize_list(list[1]) def find_all_installed_packages (name=None, withVersion=True): - """Returns a list of all installed packages matching ".*name.*". - Returns ALL installed packages if name is None.""" + """Finds all installed packages matching a name or all if no name is specified. + + @param name: the name to look for - it is expanded to .*name.* ; if None, all packages are returned + @type name: string or None + @param withVersion: if True version-specific packages are returned; else only the cat/package-strings a delivered + @type withVersion: boolean + + @returns: all packages/cp-strings found + @rtype: backend.Package[] or cp-string[]""" + if withVersion: return geneticize_list(gentoolkit.find_all_installed_packages(find_lambda(name))) else: @@ -102,13 +126,26 @@ def find_all_installed_packages (name=None, withVersion=True): return t def find_all_uninstalled_packages (name=None): - """Returns a list of all uninstalled packages matching ".*name.*". - Returns ALL uninstalled packages if name is None.""" + """Finds all uninstalled packages matching a name or all if no name is specified. + + @param name: the name to look for - it is expanded to .*name.* ; if None, all packages are returned + @type name: string or None + @returns: all packages found + @rtype: backend.Package[]""" + return geneticize_list(gentoolkit.find_all_uninstalled_packages(find_lambda(name))) -def find_all_packages (name=None, withVersion = True): - """Returns a list of all packages matching ".*name.*". - Returns ALL packages if name is None.""" +def find_all_packages (name=None, withVersion=True): + """Finds all packages matching a name or all if no name is specified. + + @param name: the name to look for - it is expanded to .*name.* ; if None, all packages are returned + @type name: string or None + @param withVersion: if True version-specific packages are returned; else only the cat/package-strings a delivered + @type withVersion: boolean + + @returns: all packages/cp-strings found + @rtype: backend.Package[] or cp-string[]""" + if (withVersion): return geneticize_list(gentoolkit.find_all_packages(find_lambda(name))) else: @@ -120,25 +157,37 @@ def find_all_packages (name=None, withVersion = True): return t def find_all_world_packages (name=None): - """Returns a list of all world packages matching ".*name.*". - Returns ALL world packages if name is None.""" + """Finds all world packages matching a name or all if no name is specified. + + @param name: the name to look for - it is expanded to .*name.* ; if None, all packages are returned + @type name: string or None + @returns: all packages found + @rtype: backend.Package[]""" + world = filter(find_lambda(name), [x.get_cpv() for x in find_world_packages()[0]]) world = unique_array(world) - return [package.Package(x) for x in world] + return geneticize_list(world) def find_all_system_packages (name=None): - """Returns a list of all system packages matching ".*name.*". - Returns ALL system packages if name is None.""" + """Finds all system packages matching a name or all if no name is specified. + + @param name: the name to look for - it is expanded to .*name.* ; if None, all packages are returned + @type name: string or None + @returns: all packages found + @rtype: backend.Package[]""" + sys = filter(find_lambda(name), [x.get_cpv() for x in find_system_packages()[0]]) sys = unique_array(sys) - return [package.Package(x) for x in sys] + return geneticize_list(sys) def get_all_versions (cp): """Returns all versions of a certain package. + @param cp: the package @type cp: string (cat/pkg) @returns: the list of found packages - @rtype: list of backend.Package""" + @rtype: backend.Package[]""" + t = porttree.dbapi.cp_list(cp) t += vartree.dbapi.cp_list(cp) t = unique_array(t) @@ -146,25 +195,41 @@ def get_all_versions (cp): def get_all_installed_versions (cp): """Returns all installed versions of a certain package. + @param cp: the package @type cp: string (cat/pkg) @returns: the list of found packages - @rtype: list of backend.Package""" + @rtype: backend.Package[]""" + return geneticize_list(vartree.dbapi.cp_list(cp)) def list_categories (name=None): - """Returns a list of categories matching ".*name.*" or all categories.""" + """Finds all categories matching a name or all if no name is specified. + + @param name: the name to look for - it is expanded to .*name.* ; if None, all categories are returned + @type name: string or None + @returns: all categories found + @rtype: string[]""" + categories = gentoolkit.settings.categories return filter(find_lambda(name), categories) def split_package_name (name): - """Returns a list in the form [category, name, version, revision]. Revision will - be 'r0' if none can be inferred. Category and version will be empty, if none can - be inferred.""" + """Splits a package name in its elements. + + @param name: name to split + @type name: string + @returns: list: [category, name, version, rev] whereby rev is "r0" if not specified in the name + @rtype: string[]""" + return gentoolkit.split_package_name(name) def sort_package_list(pkglist): - """Sorts a package list in the same manner portage does.""" + """Sorts a package list in the same manner portage does. + + @param pkglist: list to sort + @type pkglist: Packages[]""" + return gentoolkit.sort_package_list(pkglist) def reload_settings (): @@ -176,7 +241,16 @@ local_use_descs = {} def get_use_desc (flag, package = None): """Returns the description of a specific useflag or None if no desc was found. If a package is given (in the <cat>/<name> format) the local use descriptions are searched too. - In the first run the dictionaries 'use_descs' and 'local_use_descs' are filled.""" + + @param flag: flag to get the description for + @type flag: string + @param package: name of a package: if given local use descriptions are searched too + @type package: cp-string + @returns: found description + @rtype: string""" + + # In the first run the dictionaries 'use_descs' and 'local_use_descs' are filled. + # fill cache if needed if use_descs == {} or local_use_descs == {}: # read use.desc |