summaryrefslogtreecommitdiff
path: root/portato/backend/portage/package.py
diff options
context:
space:
mode:
Diffstat (limited to 'portato/backend/portage/package.py')
-rw-r--r--portato/backend/portage/package.py234
1 files changed, 234 insertions, 0 deletions
diff --git a/portato/backend/portage/package.py b/portato/backend/portage/package.py
new file mode 100644
index 0000000..74a5107
--- /dev/null
+++ b/portato/backend/portage/package.py
@@ -0,0 +1,234 @@
+# -*- coding: utf-8 -*-
+#
+# File: portato/backend/portage/package.py
+# This file is part of the Portato-Project, a graphical portage-frontend.
+#
+# Copyright (C) 2006-2007 René 'Necoro' Neumann
+# 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 René 'Necoro' Neumann <necoro@necoro.net>
+
+from portato.helper import *
+from portato.backend.exceptions import *
+from portato.backend import flags, Package, system
+
+import portage, portage_dep
+from portage_util import unique_array
+
+import os.path
+
+class PortagePackage (Package):
+ """This is a class abstracting a normal package which can be installed for the portage-system."""
+
+ def __init__ (self, cpv):
+ """Constructor.
+
+ @param cpv: The cpv which describes the package to create.
+ @type cpv: string (cat/pkg-ver)"""
+
+ Package.__init__(self, cpv)
+ self._settings = system.settings
+ self._settingslock = system.settings.settingslock
+
+ self._trees = system.settings.trees
+
+ self.forced_flags = set()
+ self.forced_flags.update(self._settings.settings.usemask)
+ self.forced_flags.update(self._settings.settings.useforce)
+
+ try:
+ self._status = portage.getmaskingstatus(self.get_cpv(), settings = self._settings.settings)
+ except KeyError: # package is not located in the system
+ self._status = None
+
+ def is_installed(self):
+ return self._settings.vartree.dbapi.cpv_exists(self._cpv)
+
+ def is_overlay(self):
+ dir,ovl = self._settings.porttree.dbapi.findname2(self._cpv)
+ return ovl != self._settings.settings["PORTDIR"]
+
+ def is_in_system (self):
+ return (self._status != None)
+
+ def is_missing_keyword(self):
+ if self._status and "missing keyword" in self._status:
+ return True
+ return False
+
+ def is_testing(self, use_keywords = False):
+ testArch = "~" + self.get_settings("ARCH")
+ if not use_keywords: # keywords are NOT taken into account
+ if testArch in self.get_env_var("KEYWORDS").split():
+ return True
+ return False
+
+ else: # keywords are taken into account
+ status = flags.new_testing_status(self.get_cpv())
+ if status is None: # we haven't changed it in any way
+ if self._status and testArch+" keyword" in self._status:
+ return True
+ return False
+ else:
+ return status
+
+ def is_masked (self):
+ status = flags.new_masking_status(self.get_cpv())
+ 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: # we have not touched the status
+ if self._status and ("profile" in self._status or "package.mask" in self._status):
+ return True
+ return False
+
+ def get_all_use_flags (self, installed = False):
+ if installed or not self.is_in_system():
+ tree = self._settings.vartree
+ else:
+ tree = self._settings.porttree
+
+ return list(set(self.get_env_var("IUSE", tree = tree).split()).difference(self.forced_flags))
+
+ def get_matched_dep_packages (self, depvar):
+ # 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:
+ 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)
+
+ depstring = ""
+ for d in depvar:
+ depstring += self.get_env_var(d)+" "
+
+ portage_dep._dep_check_strict = False
+ deps = portage.dep_check(depstring, None, self._settings.settings, myuse = actual, trees = self._trees)
+ portage_dep._dep_check_strict = True
+
+ if not deps: # FIXME: what is the difference to [1, []] ?
+ return []
+
+ if deps[0] == 0: # error
+ raise DependencyCalcError, deps[1]
+
+ deps = deps[1]
+
+ retlist = []
+
+ for d in deps:
+ if not d[0] == "!":
+ retlist.append(d)
+
+ return retlist
+
+ def get_dep_packages (self, depvar = ["RDEPEND", "PDEPEND", "DEPEND"]):
+ dep_pkgs = [] # the package list
+
+ # 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:
+ 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)
+
+ depstring = ""
+ for d in depvar:
+ depstring += self.get_env_var(d)+" "
+
+ # let portage do the main stuff ;)
+ # pay attention to any changes here
+ deps = portage.dep_check (depstring, self._settings.vartree.dbapi, self._settings.settings, myuse = actual, trees = self._trees)
+
+ if not deps: # FIXME: 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
+ dep = dep[1:]
+ if dep != self.get_cp(): # not cpv, because a version might explicitly block another one
+ blocked = system.find_installed_packages(dep)
+ if blocked != []:
+ raise BlockedException, (self.get_cpv(), blocked[0].get_cpv())
+ continue # finished with the blocking one -> next
+
+ pkg = system.find_best_match(dep)
+ if not pkg: # try to find masked ones
+ list = system.find_packages(dep, masked = True)
+ if not list:
+ raise PackageNotFoundException, dep
+
+ list = system.sort_package_list(list)
+ done = False
+ for i in range(len(list)-1,0,-1):
+ p = list[i]
+ if not p.is_masked():
+ dep_pkgs.append(p.get_cpv())
+ done = True
+ break
+ if not done:
+ dep_pkgs.append(list[-1].get_cpv())
+ else:
+ dep_pkgs.append(pkg.get_cpv())
+
+ return dep_pkgs
+
+ def get_settings(self, key):
+ self._settingslock.acquire()
+ self._settings.settings.setcpv(self._cpv)
+ v = self._settings.settings[key]
+ self._settingslock.release()
+ return v
+
+ def get_ebuild_path(self):
+ return self._settings.porttree.dbapi.findname(self._cpv)
+
+ def get_env_var(self, var, tree = None):
+ if not tree:
+ mytree = self._settings.vartree
+ if not self.is_installed():
+ mytree = self._settings.porttree
+ else:
+ mytree = tree
+ r = mytree.dbapi.aux_get(self._cpv,[var])
+
+ return r[0]
+
+ def get_use_flags(self):
+ if self.is_installed():
+ return self.get_env_var("USE", tree = self._settings.vartree)
+ else: return ""
+
+ def compare_version(self,other):
+ v1 = self._scpv
+ v2 = portage.catpkgsplit(other.get_cpv())
+ # if category is different
+ if v1[0] != v2[0]:
+ return cmp(v1[0],v2[0])
+ # if name is different
+ elif v1[1] != v2[1]:
+ return cmp(v1[1],v2[1])
+ # Compare versions
+ else:
+ return portage.pkgcmp(v1[1:],v2[1:])
+
+ def matches (self, criterion):
+ if portage.match_from_list(criterion, [self.get_cpv()]) == []:
+ return False
+ else:
+ return True