summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornecoro <>2007-02-19 23:04:14 +0000
committernecoro <>2007-02-19 23:04:14 +0000
commitfba60a84b9a838ad32def950210a6b62d9bcdbff (patch)
treed581e4fa141851323a05d4500ad95afe50ed6e02
parentb4c88233aa6dabd2d9301350a240b8ddcf09255a (diff)
downloadportato-fba60a84b9a838ad32def950210a6b62d9bcdbff.tar.gz
portato-fba60a84b9a838ad32def950210a6b62d9bcdbff.tar.bz2
portato-fba60a84b9a838ad32def950210a6b62d9bcdbff.zip
Back to our own revision solution as the eclass-one checks _before_ updating
-rw-r--r--doc/Changelog4
-rw-r--r--etc/portato.cfg11
-rwxr-xr-xportato.py17
-rw-r--r--portato/backend/__init__.py75
-rw-r--r--portato/backend/flags.py117
-rw-r--r--portato/backend/package.py447
-rw-r--r--portato/backend/portage/__init__.py14
-rw-r--r--portato/backend/portage/package.py234
-rw-r--r--portato/backend/portage/settings.py55
-rw-r--r--portato/backend/portage/system.py370
-rw-r--r--portato/backend/portage_helper.py467
-rw-r--r--portato/backend/system_interface.py283
-rw-r--r--portato/gui/gtk/TreeViewTooltips.py2
-rw-r--r--portato/gui/gtk/glade/portato.glade452
-rw-r--r--portato/gui/gtk/usetips.py4
-rw-r--r--portato/gui/gtk/windows.py56
-rw-r--r--portato/gui/gui_helper.py50
-rw-r--r--portato/helper.py37
-rw-r--r--setup.py2
19 files changed, 1440 insertions, 1257 deletions
diff --git a/doc/Changelog b/doc/Changelog
index 74333fb..197cb17 100644
--- a/doc/Changelog
+++ b/doc/Changelog
@@ -1,4 +1,6 @@
-0.5.3:
+0.6.0:
+- general support for different backend systems
+- removed asterisks as "installed" sign - using an image now
- added ebuild window
- added usetips
- allowed copying out of the console
diff --git a/etc/portato.cfg b/etc/portato.cfg
index 12a3a92..e177714 100644
--- a/etc/portato.cfg
+++ b/etc/portato.cfg
@@ -18,15 +18,20 @@
#
[Main]
+; controls the backend system to use
+; allowed values:
+; - portage
+system = portage
+
; controls debug output - boolean value
debug = True
; the command used for syncing portage - string value
-synccommand = emerge --sync
+synccommand = eix-sync
; control the same-named "emerge --update" options - boolean values
-newuse = False
-deep = False
+newuse = true
+deep = true
; control the name of the particular file if package.* is a directory - string values
; allowed placeholders:
diff --git a/portato.py b/portato.py
index 0d357ea..4db4b0e 100755
--- a/portato.py
+++ b/portato.py
@@ -16,11 +16,10 @@ from portato.constants import VERSION, FRONTENDS, STD_FRONTEND
import sys
if __name__ == "__main__":
-# import pychecker.checker
uimod = STD_FRONTEND
- if len(sys.argv) > 1:
- if sys.argv[1] in ("--help","--version","-h","-v"):
+ for arg in sys.argv[1:]:
+ if arg in ("--help","--version","-h","-v"):
print """Portato %s
Copyright (C) 2006-2007 René 'Necoro' Neumann
This is free software. You may redistribute copies of it under the terms of
@@ -29,8 +28,16 @@ There is NO WARRANTY, to the extent permitted by law.
Written by René 'Necoro' Neumann <necoro@necoro.net>""" % VERSION
sys.exit(0)
- else:
- uimod = sys.argv[1]
+
+ if arg == "--check": # run pychecker
+ import os
+ os.environ['PYCHECKER'] = "--limit 50"
+ import pychecker.checker
+ continue
+
+ uimod = arg
+ break
+
if uimod in FRONTENDS:
try:
exec ("from portato.gui.%s import run" % uimod)
diff --git a/portato/backend/__init__.py b/portato/backend/__init__.py
index a72923b..83ee1d6 100644
--- a/portato/backend/__init__.py
+++ b/portato/backend/__init__.py
@@ -10,67 +10,32 @@
#
# Written by René 'Necoro' Neumann <necoro@necoro.net>
-import os
-from threading import Lock
+from system_interface import SystemInterface
-# import portage
-import portage
+SYSTEM = "portage"
+_sys = None
-class PortageSettings:
- """Encapsulation of the portage settings.
-
- @ivar settings: portage settings
- @ivar settingslock: a simple Lock
- @ivar trees: a dictionary of the trees
- @ivar porttree: shortcut to C{trees[root]["porttree"]}
- @ivar vartree: shortcut to C{trees[root]["vartree"]}
- @ivar virtuals: shortcut to C{trees[root]["virtuals"]}"""
+class SystemWrapper (object, SystemInterface):
+ def __getattribute__ (self, name):
+ global _sys
+ return eval ("_sys.%s" % name)
- def __init__ (self):
- """Initializes the instance. Calls L{load()}."""
- self.settingslock = Lock()
- self.load()
-
- def load(self):
- """(Re)loads the portage settings and sets the variables."""
+def set_system (new_sys):
+ global SYSTEM
+ SYSTEM = new_sys
+ load_system()
- kwargs = {}
- for k, envvar in (("config_root", "PORTAGE_CONFIGROOT"), ("target_root", "ROOT")):
- kwargs[k] = os.environ.get(envvar, None)
- self.trees = portage.create_trees(trees=None, **kwargs)
+def load_system ():
+ global _sys
- self.settings = self.trees["/"]["vartree"].settings
+ if SYSTEM == "portage":
+ from portato.backend.portage import PortageSystem
+ _sys = PortageSystem ()
- for myroot in self.trees:
- if myroot != "/":
- self.settings = self.trees[myroot]["vartree"].settings
- break
+system = SystemWrapper()
- self.settings.unlock()
-
- root = self.settings["ROOT"]
-
- self.porttree = self.trees[root]["porttree"]
- self.vartree = self.trees[root]["vartree"]
- self.virtuals = self.trees[root]["virtuals"]
-
- portage.settings = None # we use our own one ...
-
-# portage tree vars
-portage_settings = PortageSettings()
-
-# for the moment ;)
-settingslock = portage_settings.settingslock
-settings = portage_settings.settings
-trees = portage_settings.trees
-porttree = portage_settings.porttree
-vartree = portage_settings.vartree
-virtuals = portage_settings.virtuals
+from exceptions import *
+from package import Package
-# this is set to "var/lib/portage/world" by default - so we add the leading /
-portage.WORLD_FILE = portage_settings.settings["ROOT"]+portage.WORLD_FILE
+load_system()
-# import our packages
-from exceptions import *
-from package import *
-from portage_helper import *
diff --git a/portato/backend/flags.py b/portato/backend/flags.py
index a7ba125..a7241ca 100644
--- a/portato/backend/flags.py
+++ b/portato/backend/flags.py
@@ -15,12 +15,9 @@ import os.path
from subprocess import Popen, PIPE # needed for grep
from portato.helper import *
-from portage_helper import split_package_name
+from portato.backend import system
import package
-import portage
-from portage_util import unique_array
-
CONFIG = {
"usefile" : "portato",
"maskfile" : "portato",
@@ -30,6 +27,59 @@ CONFIG = {
"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 __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]
+
+ 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 mask_path (self):
+ return self.__get("_mask_path", "package.mask")
+
+ 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_is_dir (self):
+ return self.__is_dir("unmask_path")
+
+ def testing_path (self):
+ return self.__get("_testing_path", "package.keywords")
+
+ def testing_path_is_dir (self):
+ return self.__is_dir("testing_path")
+
+CONST = Constants()
+
### GENERAL PART ###
def grep (pkg, path):
@@ -43,7 +93,7 @@ def grep (pkg, path):
@rtype: string"""
if not isinstance(pkg, package.Package):
- pkg = package.Package(pkg) # assume it is a cpv or a gentoolkit.Package
+ pkg = system.new_package(pkg) # assume it is a cpv or a gentoolkit.Package
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()
@@ -105,7 +155,7 @@ def generate_path (cpv, exp):
@returns: rendered path
@rtype string"""
- cat, pkg, ver, rev = split_package_name(cpv)
+ cat, pkg, ver, rev = system.split_cpv(cpv)
if exp.find("$(") != -1:
exp = exp.replace("$(cat)",cat).\
@@ -115,8 +165,6 @@ def generate_path (cpv, exp):
return exp
### USE FLAG PART ###
-USE_PATH = os.path.join(portage.USER_CONFIG_PATH,"package.use")
-USE_PATH_IS_DIR = os.path.isdir(USE_PATH)
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))]
@@ -150,7 +198,7 @@ def set_use_flag (pkg, flag):
global useFlags, newUseFlags
if not isinstance(pkg, package.Package):
- pkg = package.Package(pkg) # assume cpv or gentoolkit.Package
+ pkg = system.new_package(pkg) # assume cpv or gentoolkit.Package
cpv = pkg.get_cpv()
invFlag = invert_use_flag(flag)
@@ -158,7 +206,7 @@ def set_use_flag (pkg, 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, USE_PATH)
+ data = get_data(pkg, CONST.use_path())
useFlags[cpv] = data
else:
data = useFlags[cpv]
@@ -196,9 +244,9 @@ def set_use_flag (pkg, flag):
# create a new line
if not added:
- path = USE_PATH
- if USE_PATH_IS_DIR:
- path = os.path.join(USE_PATH, generate_path(cpv, CONFIG["usefile"]))
+ 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
@@ -313,7 +361,7 @@ def write_use_flags ():
if CONFIG["usePerVersion"]: # add on a per-version-base
msg += "=%s %s\n" % (cpv, ' '.join(flagsToAdd))
else: # add on a per-package-base
- list = split_package_name(cpv)
+ 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")
@@ -332,11 +380,6 @@ def write_use_flags ():
newUseFlags = {}
### MASKING PART ###
-MASK_PATH = os.path.join(portage.USER_CONFIG_PATH,"package.mask")
-UNMASK_PATH = os.path.join(portage.USER_CONFIG_PATH,"package.unmask")
-MASK_PATH_IS_DIR = os.path.isdir(MASK_PATH)
-UNMASK_PATH_IS_DIR = os.path.isdir(UNMASK_PATH)
-
new_masked = {}
new_unmasked = {}
@@ -351,7 +394,7 @@ def set_masked (pkg, masked = True):
global new_masked, newunmasked
if not isinstance(pkg, package.Package):
- pkg = package.Package(pkg)
+ pkg = system.new_package(pkg)
cpv = pkg.get_cpv()
@@ -363,13 +406,13 @@ def set_masked (pkg, masked = True):
if masked:
link_neq = new_masked
link_eq = new_unmasked
- path = UNMASK_PATH
+ path = CONST.unmask_path()
else:
link_neq = new_unmasked
link_eq = new_masked
- path = MASK_PATH
+ path = CONST.mask_path()
- copy = link_eq[cpv]
+ copy = link_eq[cpv][:]
for file, line in copy:
if line == "-1":
link_eq[cpv].remove((file, line))
@@ -393,11 +436,11 @@ def set_masked (pkg, masked = True):
if done: return
if masked:
- is_dir = MASK_PATH_IS_DIR
- path = MASK_PATH
+ is_dir = CONST.mask_path_is_dir()
+ path = CONST.mask_path()
else:
- is_dir = UNMASK_PATH_IS_DIR
- path = UNMASK_PATH
+ is_dir = CONST.unmask_path_is_dir()
+ path = CONST.unmask_path()
if is_dir:
file = os.path.join(path, generate_path(cpv, CONFIG["usefile"]))
@@ -426,9 +469,9 @@ def new_masking_status (cpv):
if isinstance(cpv, package.Package):
cpv = cpv.get_cpv()
- if cpv in new_masked and new_masked[cpv]:
+ if cpv in new_masked and new_masked[cpv] != []:
return "masked"
- elif cpv in new_unmasked and new_unmasked[cpv]:
+ elif cpv in new_unmasked and new_unmasked[cpv] != []:
return "unmasked"
else: return None
@@ -444,7 +487,7 @@ def write_masked ():
if CONFIG["maskPerVersion"]:
msg += "=%s\n" % cpv
else:
- list = split_package_name(cpv)
+ list = system.split_cpv(cpv)
msg += "%s/%s\n" % (list[0],list[1])
if not file in file_cache:
f = open(file, "a")
@@ -497,8 +540,6 @@ def write_masked ():
new_unmasked = {}
### TESTING PART ###
-TESTING_PATH = os.path.join(portage.USER_CONFIG_PATH, "package.keywords")
-TESTING_PATH_IS_DIR = os.path.isdir(TESTING_PATH)
newTesting = {}
arch = ""
@@ -531,7 +572,7 @@ def set_testing (pkg, enable):
global arch, newTesting
if not isinstance(pkg, package.Package):
- pkg = package.Package(pkg)
+ pkg = system.new_package(pkg)
arch = pkg.get_settings("ARCH")
cpv = pkg.get_cpv()
@@ -546,16 +587,16 @@ def set_testing (pkg, enable):
return
if not enable:
- test = get_data(pkg, TESTING_PATH)
+ test = get_data(pkg, CONST.testing_path())
debug("data (test): "+str(test))
for file, line, crit, flags in test:
if pkg.matches(crit) and flags[0] == "~"+arch:
newTesting[cpv].append((file, line))
else:
- if TESTING_PATH_IS_DIR:
- file = os.path.join(TESTING_PATH, CONFIG["testingfile"])
+ if CONST.testing_path_is_dir():
+ file = os.path.join(CONST.testing_path(), CONFIG["testingfile"])
else:
- file = TESTING_PATH
+ file = CONST.testing_path()
newTesting[cpv].append((file, "-1"))
newTesting[cpv] = unique_array(newTesting[cpv])
@@ -574,7 +615,7 @@ def write_testing ():
if CONFIG["testingPerVersion"]:
msg += "=%s ~%s\n" % (cpv, arch)
else:
- list = split_package_name(cpv)
+ 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")
diff --git a/portato/backend/package.py b/portato/backend/package.py
deleted file mode 100644
index 6ba47fe..0000000
--- a/portato/backend/package.py
+++ /dev/null
@@ -1,447 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# File: portato/backend/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.backend import portage_settings
-from portato.helper import *
-from portage_helper import *
-from exceptions import *
-import flags
-
-import portage, portage_dep
-from portage_util import unique_array
-
-import types
-import os.path
-
-class 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
- self._scpv = portage.catpkgsplit(self._cpv)
-
- if not self._scpv:
- raise ValueError("invalid cpv: %s" % cpv)
-
- self._settings = portage_settings.settings
- self._settingslock = portage_settings.settingslock
-
- self._trees = portage_settings.trees
-
- self.forced_flags = set()
- self.forced_flags.update(self._settings.usemask)
- self.forced_flags.update(self._settings.useforce)
-
- try:
- self._status = portage.getmaskingstatus(self.get_cpv(), settings = self._settings)
- except KeyError: # package is not located in the system
- self._status = None
-
- def is_installed(self):
- """Returns true if this package is installed (merged)
- @rtype: boolean"""
-
- return portage_settings.vartree.dbapi.cpv_exists(self._cpv)
-
- def is_overlay(self):
- """Returns true if the package is in an overlay.
- @rtype: boolean"""
-
- dir,ovl = portage_settings.porttree.dbapi.findname2(self._cpv)
- return ovl != self._settings["PORTDIR"]
-
- 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"""
-
- return (self._status != None)
-
- 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 self._status and "missing keyword" in self._status:
- return True
- return False
-
- def is_testing(self, use_keywords = False):
- """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"""
-
- 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 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: True if masked / False otherwise
- @rtype: boolean"""
-
- 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 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, installed = False):
- """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
-
- @returns: list of use-flags
- @rtype: string[]"""
-
- if installed or not self.is_in_system():
- tree = portage_settings.vartree
- else:
- tree = portage_settings.porttree
-
- return list(set(self.get_env_var("IUSE", tree = tree).split()).difference(self.forced_flags))
-
- 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: string[]"""
-
- if self.is_installed():
- uses = set(self.get_use_flags().split()) # all set at installation time
- iuses = set(self.get_all_use_flags(installed=True)) # all you can set for the package
-
- return list(uses.intersection(iuses))
- 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: 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: string[]"""
-
- if self.is_installed():
- i_flags = self.get_installed_use_flags()
- for f in self.get_new_use_flags():
-
- if flags.invert_use_flag(f) in i_flags:
- i_flags.remove(flags.invert_use_flag(f))
-
- elif f not in i_flags:
- i_flags.append(f)
- return i_flags
- else:
- return self.get_new_use_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 is_use_flag_enabled (self, flag):
- """Looks whether a given useflag is enabled for the package, taking all options
- (ie. even the new flags) into account.
-
- @param flag: the flag to check
- @type flag: string
- @returns: True or False
- @rtype: bool"""
-
- if self.is_installed() and flag in self.get_actual_use_flags(): # flags set during install
- return True
-
- elif (not self.is_installed()) and flag in self.get_settings("USE").split() \
- and not flags.invert_use_flag(flag) in self.get_new_use_flags(): # flags that would be set
- return True
-
- elif flag in self.get_new_use_flags():
- return True
-
- else:
- return False
-
- 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.
-
- @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()"""
-
- # 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, 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"]):
- """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: 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()"""
-
- 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, portage_settings.vartree.dbapi, self._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 = find_installed_packages(dep)
- if blocked != []:
- raise BlockedException, (self.get_cpv(), blocked[0].get_cpv())
- continue # finished with the blocking one -> next
-
- pkg = find_best_match(dep)
- if not pkg: # try to find masked ones
- list = find_packages(dep, masked = True)
- if not list:
- raise PackageNotFoundException, dep
-
- list = 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_cpv(self):
- """Returns full Category/Package-Version 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):
-
- return ("%s:%s" % (self.get_cp(), self.get_env_var("SLOT")))
-
- def get_name(self):
- """Returns base name of package, no category nor version"""
- return self._scpv[1]
-
- def get_version(self):
- """Returns version of package, with revision number"""
- v = self._scpv[2]
- if self._scpv[3] != "r0":
- v += "-" + self._scpv[3]
- return v
-
- def get_category(self):
- """Returns category of package"""
- return self._scpv[0]
-
- def get_settings(self, key):
- """Returns the value of the given key for this package (useful
- for package.* files)."""
- self._settingslock.acquire()
- self._settings.setcpv(self._cpv)
- v = self._settings[key]
- self._settingslock.release()
- return v
-
- def get_ebuild_path(self):
- """Returns the complete path to the .ebuild file"""
- return portage_settings.porttree.dbapi.findname(self._cpv)
-
- def get_package_path(self):
- """Returns the path to where the ChangeLog, Manifest, .ebuild files reside"""
- p = self.get_ebuild_path()
- sp = p.split("/")
- if len(sp):
- import string
- return string.join(sp[:-1],"/")
-
- def get_env_var(self, var, tree = None):
- """Returns one of the predefined env vars DEPEND, RDEPEND, SRC_URI,...."""
- if not tree:
- mytree = portage_settings.vartree
- if not self.is_installed():
- mytree = portage_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 = portage_settings.vartree)
- else: return ""
-
- def compare_version(self,other):
- """Compares this package's version to another's CPV; returns -1, 0, 1"""
- 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):
- """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
- @returns: True if matches; False if not
- @rtype: boolean"""
-
- if portage.match_from_list(criterion, [self.get_cpv()]) == []:
- return False
- else:
- return True
diff --git a/portato/backend/portage/__init__.py b/portato/backend/portage/__init__.py
new file mode 100644
index 0000000..e21278c
--- /dev/null
+++ b/portato/backend/portage/__init__.py
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*-
+#
+# File: portato/backend/portage/__init__.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 system import PortageSystem
+from package import PortagePackage
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:
+ re