summaryrefslogtreecommitdiff
path: root/portato
diff options
context:
space:
mode:
Diffstat (limited to 'portato')
-rw-r--r--portato/backend/portage/package.py34
-rw-r--r--portato/dependency.py151
2 files changed, 167 insertions, 18 deletions
diff --git a/portato/backend/portage/package.py b/portato/backend/portage/package.py
index 6ac34ba..e54d1cd 100644
--- a/portato/backend/portage/package.py
+++ b/portato/backend/portage/package.py
@@ -17,6 +17,7 @@ from .. import flags
from .. import system
from ..exceptions import BlockedException, PackageNotFoundException, DependencyCalcError
from ...helper import debug, error, unique_array
+from ...dependency import DependencyTree
import portage, portage_dep
@@ -305,33 +306,30 @@ class PortagePackage (Package):
def get_dependencies (self):
deps = " ".join(map(self.get_package_settings, ("RDEPEND", "PDEPEND", "DEPEND")))
deps = portage_dep.paren_reduce(deps)
- depdir = {"global": set()}
+
+ tree = DependencyTree()
- def add (dir, deps):
+ def add (tree, deps):
iter = (x for x in deps)
for dep in iter:
if dep.endswith("?"):
- dep = dep[:-1]
- if dep not in dir:
- dir[dep] = {"global": set()}
+ ntree = tree.add_flag(dep[:-1])
n = iter.next()
- if isinstance(n, list):
- add(dir[dep], n)
- else:
- dir[dep]["global"].add(n)
- elif dep == "||":
- if not dep in dir:
- dir[dep] = set()
-
+ if not hasattr(n, "__iter__"):
+ n = (n,)
+ add(ntree, n)
+
+ elif dep == "||":
n = iter.next() # skip
- if not isinstance(n, list):
+ if not hasattr(n, "__iter__"):
n = tuple(n,)
else:
n = tuple(n)
- dir[dep].add(n)
+ tree.add_or(n)
+
else:
- dir["global"].add(dep)
+ tree.add(dep)
- add(depdir, deps)
- return depdir
+ add(tree, deps)
+ return tree
diff --git a/portato/dependency.py b/portato/dependency.py
new file mode 100644
index 0000000..718906f
--- /dev/null
+++ b/portato/dependency.py
@@ -0,0 +1,151 @@
+# -*- coding: utf-8 -*-
+#
+# File: portato/dependency.py
+# This file is part of the Portato-Project, a graphical portage-frontend.
+#
+# Copyright (C) 2008 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 __future__ import absolute_import, with_statement
+
+from .helper import debug
+
+"""
+Provides classes for the presentation of dependencies.
+"""
+__docformat__ = "restructuredtext"
+
+class Dependency (object):
+
+ """
+ A simple dependency as it also is noted inside ebuilds.
+
+ :IVariables:
+
+ dep : string
+ The dependency string. It is immutable.
+ """
+
+ def __init__ (self, dep):
+ """
+ Creates a dependency out of a dep string.
+
+ :param dep: dependency string
+ :type dep: string
+ """
+ self.__dep = dep
+
+ def __cmp__ (self, b):
+ return cmp(self.dep, b.dep)
+
+ def __hash__ (self):
+ return hash(self.dep)
+
+ def __str__ (self):
+ return "<Dependency '%s'>" % self.dep
+
+ __repr__ = __str__
+
+ def __get_dep (self):
+ return self.__dep
+
+ dep = property(__get_dep)
+
+class OrDependency (Dependency):
+
+ """
+ Dependency representing an "or".
+
+ :note: Order is important. ``|| ( a b )`` != ``|| ( b a )``
+
+ :IVariables:
+
+ dep : tuple(string,...)
+ The dependency strings. The tuple and the strings are immutable.
+ """
+
+ def __init__ (self, deps):
+ """
+ Creates an or-dependency out of a list (or tuple) of deps.
+
+ :param deps: The or'ed dependencies.
+ :type deps: iter<string>
+ """
+
+ self.__dep = tuple(Dependency(dep) for dep in deps)
+
+ def __str__ (self):
+ return "<|| %s>" % str(self.dep)
+
+ __repr__ = __str__
+
+class DependencyTree (object):
+
+ """
+ The DependencyTree shows all dependencies for a package and shows which useflags want which dependencies.
+
+ :IVariables:
+
+ deps : set(`Dependency`)
+ The list of dependencies which are not dependent on a useflag.
+
+ flags : dict(string -> `DependencyTree`)
+ Holds the additional dependency trees per useflag.
+ """
+
+ def __init__ (self):
+
+ self.deps = set()
+ self.flags = {}
+
+ def add (self, dep, *moredeps):
+ """
+ Adds one or more normal dependencies to the tree.
+
+ :Parameters:
+
+ dep : string
+ A dependency string.
+
+ moredeps
+ More parameters are allowed :)
+ """
+ self.deps.add(Dependency(dep))
+
+ for dep in moredeps:
+ self.deps.add(Dependency(dep))
+
+ def add_or (self, orlist):
+ """
+ Adds a list of dependencies, which are or'ed.
+
+ :param orlist: the dependency list
+ :type orlist: iter<string>
+ """
+ self.deps.add(OrDependency(orlist))
+
+ def add_flag (self, flag):
+ """
+ Adds a new useflag to this tree.
+ For convenience the newly created sub-tree is returned.
+
+ :param flag: the new flag
+ :rtype: `DependencyTree`
+ """
+ if not flag in self.flags:
+ self.flags[flag] = DependencyTree()
+
+ return self.get_flag_tree(flag)
+
+ def get_flag_tree (self, flag):
+ """
+ Returns the sub-tree of a specific tree.
+
+ :raises KeyError: if the flag is not (yet) in this tree
+ :rtype: `DependencyTree`
+ """
+ return self.flags[flag]