diff options
author | necoro <> | 2006-09-29 19:15:41 +0000 |
---|---|---|
committer | necoro <> | 2006-09-29 19:15:41 +0000 |
commit | 74e6944a93674636b9ae5826a27218c30be335b5 (patch) | |
tree | 6ca9009eb1cebbffb45c2c103add5ac05cebb8ea /geneticone/backend/package.py | |
parent | 196d7959b4a28cce680154277a764d8799238453 (diff) | |
download | portato-74e6944a93674636b9ae5826a27218c30be335b5.tar.gz portato-74e6944a93674636b9ae5826a27218c30be335b5.tar.bz2 portato-74e6944a93674636b9ae5826a27218c30be335b5.zip |
Moved backend stuff into own backend-package
Diffstat (limited to 'geneticone/backend/package.py')
-rw-r--r-- | geneticone/backend/package.py | 293 |
1 files changed, 293 insertions, 0 deletions
diff --git a/geneticone/backend/package.py b/geneticone/backend/package.py new file mode 100644 index 0000000..73355ed --- /dev/null +++ b/geneticone/backend/package.py @@ -0,0 +1,293 @@ +# +# File: geneticone/package.py +# This file is part of the Genetic/One-Project, a graphical portage-frontend. +# +# Copyright (C) 2006 Necoro d.M. +# This is free software. You may redistribute copies of it under the terms of +# the GNU General Public License version 2. +# There is NO WARRANTY, to the extent permitted by law. +# +# Written by Necoro d.M. <necoro@necoro.net> + +from geneticone import * +from geneticone import flags +import geneticone + +import gentoolkit +import portage +from portage_util import unique_array + +class Package (gentoolkit.Package): + """This is a subclass of the gentoolkit.Package-class which a lot of additional functionality we need in Genetic/One.""" + + def __init__ (self, cpv): + """Constructor. + + @param cpv: The cpv or gentoolkit.Package which describes the package to create. + @type cpv: string (cat/pkg-ver) or gentoolkit.Package-object.""" + + if isinstance(cpv, gentoolkit.Package): + cpv = cpv.get_cpv() + gentoolkit.Package.__init__(self, cpv) + + def get_mask_status(self): + """Gets the numeric mask status of a package. The return value can be translated as a string when taking the following list of modes: [ " ", " ~", " -", "M ", "M~", "M-" ] + + This method adapted from equery 0.1.4 + Original author: Karl Trygve Kalleberg <karltk@gentoo.org> + + @returns: mask status + @rtype: int""" + + pkgmask = 0 + if self.is_masked(): + pkgmask = pkgmask + 3 + keywords = self.get_env_var("KEYWORDS").split() + if "~" + gentoolkit.settings["ARCH"] in keywords: + pkgmask = pkgmask + 1 + elif "-*" in keywords or "-" + gentoolkit.settings["ARCH"] in keywords: + pkgmask = pkgmask + 2 + return pkgmask + + 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""" + + return unique_array(self.get_env_var("IUSE").split()) + + def get_installed_use_flags (self): + """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""" + if self.is_installed(): + uses = self.get_use_flags().split() + iuses = self.get_all_use_flags() + set = [] + for u in iuses: + if u in uses: + set.append(u) + return set + else: + return [] + + 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: list""" + 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""" + + 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 + else: + return self.get_new_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 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 + @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 + newUseFlags = self.get_new_use_flags() + actual = self.get_settings("USE").split() + if newUseFlags: + depUses = [] + for u in newUseFlags: + if u[0] == "-" and flags.invert_use_flag(u) in actual: + actual.remove(flags.invert_use_flag(u)) + elif u not in actual: + actual.append(u) + + # let portage do the main stuff ;) + # 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, []] ? + return [] + + if deps[0] == 0: # error + raise DependencyCalcError, deps[1] + + deps = deps[1] + + for dep in deps: + if dep[0] == '!': # blocking sth + blocked = find_installed_packages(dep[1:]) + if blocked != []: + raise BlockedException, blocked[0].get_cpv() + else: # next flag + continue + + pkg = find_best_match(dep) + if not dep: + raise PackageNotFoundException, dep + else: + dep_pkgs.append(pkg.get_cpv()) + + return dep_pkgs + + def get_cp (self): + """Returns the cp-string. + @returns: category/package. + @rtype: string""" + return self.get_category()+"/"+self.get_name() + + def is_masked (self): + """Returns True if either masked by package.mask or by profile. + @returns: mask-status + @rtype: boolean""" + # XXX: Better solution than string comparison? + status = portage.getmaskingstatus(self._cpv) + if "profile" in status or "package.mask" in status: + return True + return False + + 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""" + 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 |