summaryrefslogtreecommitdiff
path: root/portato/backend/portage/sets.py
blob: 0e9bf2fd68391f2f8e9c2873f41da48ee6569d0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# -*- coding: utf-8 -*-
#
# File: portato/backend/portage/sets.py
# This file is part of the Portato-Project, a graphical portage-frontend.
#
# Copyright (C) 2006-2010 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_builtins import map, filter, zip

import re
import itertools as itt

import portage

from .. import system
from ...helper import debug

class Set(object):

    def get_pkgs(self, key, is_regexp, masked, with_version, only_cpv):
        raise NotImplementedError

    def find (self, key, masked = False, with_version = True, only_cpv = False):
        if key is None: key = ""
        
        is_regexp = key == "" or ("*" in key[1:] and key[0] not in ("=","<",">","~","!"))

        try:
            t = self.get_pkgs(key, is_regexp, masked, with_version, only_cpv)
        # catch the "ambigous package" Exception
        except ValueError as e:
            if isinstance(e[0], list):
                t = set()
                for cp in e[0]:
                    t.update(self.get_pkgs(cp, is_regexp, masked, with_version, only_cpv))
            else:
                raise

        return t

class InstalledSet (Set):
    """For the moment do not use the portage-2.2 @installed set.
    It only contains the current slot-cps - and to get the cpvs
    via the PortageSet results in an infinite recursion :(."""

    def _get_regexp (self, key, with_version):
        if with_version:
            t = system.settings.vartree.dbapi.cpv_all()
        else:
            t = system.settings.vartree.dbapi.cp_all()

        if key:
            t = [x for x in t if re.search(key, x, re.I)]

        return t

    def _get_by_key (self, key, with_version):
        t = system.settings.vartree.dbapi.match(key)
        if not with_version:
            t = itt.imap(portage.cpv_getkey, t)

        return t

    def get_pkgs (self, key, is_regexp, masked, with_version, only_cpv):
        if is_regexp:
            return set(self._get_regexp(key, with_version))
        else:
            return set(self._get_by_key(key, with_version))

class TreeSet (Set):

    def get_pkgs (self, key, is_regexp, masked, with_version, only_cpv):
        if is_regexp:
            if with_version:
                t = system.settings.porttree.dbapi.cpv_all()
            else:
                t = system.settings.porttree.dbapi.cp_all()

            if key:
                t = [x for x in t if re.search(key, x, re.I)]

            return set(t)

        elif masked:
            t = system.settings.porttree.dbapi.xmatch("match-all", key)
        else:
            t = system.settings.porttree.dbapi.match(key)

        if not with_version:
            t = itt.imap(portage.dep.dep_getkey, t)

        return set(t)

class AllSet (Set):
    
    def __init__ (self):
        Set.__init__(self)
        self.tree = TreeSet()
        self.installed = InstalledSet()

    def find (self, *args, **kwargs):
        return self.tree.find(*args, **kwargs) | self.installed.find(*args, **kwargs)

class UninstalledSet (Set):

    def __init__ (self):
        Set.__init__(self)
        self.all = AllSet()
        self.installed = InstalledSet()

    def find (self, *args, **kwargs):
        return self.all.find(*args, **kwargs) - self.installed.find(*args, **kwargs)

class FilterSet (InstalledSet):

    def get_list(self):
        raise NotImplementedError
    
    def get_pkgs (self, key, is_regexp, masked, with_version, only_cpv):
        t = set()
        for pkg in self.get_list():
            if is_regexp and key:
                if not re.search(key, pkg, re.I): continue

            if not with_version:
                t.add(portage.dep.dep_getkey(pkg))
            else:
                t.update(self._get_by_key(pkg, with_version))

        return t

class PortageSet (FilterSet):
    def __init__ (self, name):
        debug("Loading portage set '%s'", name)
        self.name = name

    def get_list(self):
        return itt.imap(str, system.settings.setsconfig.getSetAtoms(self.name))

class SystemSet (FilterSet):

    def get_list(self):
        for cp in system.settings.global_settings.packages:
            if cp[0] == "*": yield cp[1:]

class WorldSet (FilterSet):

    def get_list(self):
        with open(portage.WORLD_FILE) as f:
            for cp in f:
                cp = cp.strip()
                if cp and cp[0] != "#":
                    yield cp