aboutsummaryrefslogtreecommitdiff
blob: f2bed6fa85e91736d150f367decb4e313d493431 (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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#!/usr/bin/python
#
# Copyright(c) 2010, Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
#


"""Provides support functions for USE flag settings and analysis"""


__all__ = (
    "get_iuse",
    "get_installed_use",
    "reduce_flag",
    "reduce_flags",
    "defaulted_flags",
    "filter_flags",
    "get_all_cpv_use",
    "get_flags",
)


import portage


def get_iuse(cpv):
    """Gets the current IUSE flags from the tree

    To be used when a gentoolkit package object is not needed
    @type: cpv: string
    @param cpv: cat/pkg-ver
    @rtype list
    @returns [] or the list of IUSE flags
    """
    try:
        # aux_get might return dupes, so run them through set() to remove them
        iuse = set(
            portage.db[portage.root]["porttree"].dbapi.aux_get(cpv, ["IUSE"])[0].split()
        )
        # there could still be dupes due to IUSE defaults
        iuse = [x for x in iuse if "+" + x not in iuse and "-" + x not in iuse]
        return list(iuse)
    except:
        return []


def get_installed_use(cpv, use="USE"):
    """Gets the installed USE flags from the VARDB

    To be used when a gentoolkit package object is not needed
    @type: cpv: string
    @param cpv: cat/pkg-ver
    @type use: string
    @param use: 1 of ["USE", "PKGUSE"]
    @rtype list
    @returns [] or the list of IUSE flags
    """
    return portage.db[portage.root]["vartree"].dbapi.aux_get(cpv, [use])[0].split()


def reduce_flag(flag):
    """Absolute value function for a USE flag

    @type flag: string
    @param flag: the use flag to absolute.
    @rtype: string
    @return absolute USE flag
    """
    if flag[0] in ["+", "-"]:
        return flag[1:]
    else:
        return flag


def reduce_flags(the_list):
    """Absolute value function for a USE flag list

    @type the_list: list
    @param the_list: the use flags to absolute.
    @rtype: list
    @return absolute USE flags
    """
    r = []
    for member in the_list:
        r.append(reduce_flag(member))
    return r


def defaulted_flags(the_list):
    """Absolute value function for a USE flag list

    @type the_list: list
    @param the_list: the use flags to get defaulted ones from.
    @rtype: dict of lists
    @return defaulted USE flags {'+': [...], '-': [...]}
    """
    r = {"+": [], "-": []}
    for member in the_list:
        if member[0] in ["+", "-"]:
            r[member[0]].append(member[1:])
    return r


def filter_flags(use, use_expand_hidden, usemasked, useforced):
    """Filter function to remove hidden or otherwise not normally
    visible USE flags from a list.

    @type use: list
    @param use: the USE flag list to be filtered.
    @type use_expand_hidden: list
    @param  use_expand_hidden: list of flags hidden.
    @type usemasked: list
    @param usemasked: list of masked USE flags.
    @type useforced: list
    @param useforced: the forced USE flags.
    @rtype: list
    @return the filtered USE flags.
    """
    # clean out some environment flags, since they will most probably
    # be confusing for the user
    use = {reduce_flag(flag): flag for flag in use}
    for f in use_expand_hidden:
        f = f.lower() + "_"
        for x in list(use):
            if x.startswith(f):
                del use[x]
    # clean out any arch's
    archlist = portage.settings["PORTAGE_ARCHLIST"].split()
    for a in archlist:
        use.pop(a, None)
    # dbl check if any from usemasked  or useforced are still there
    masked = usemasked + useforced
    for a in masked:
        use.pop(a, None)
    return list(use.values())


def get_all_cpv_use(cpv):
    """Uses portage to determine final USE flags and settings for an emerge

    @type cpv: string
    @param cpv: eg cat/pkg-ver
    @rtype: lists
    @return  use, use_expand_hidden, usemask, useforce
    """
    use = None
    portage.db[portage.root]["porttree"].dbapi.settings.unlock()
    try:
        portage.db[portage.root]["porttree"].dbapi.settings.setcpv(
            cpv, mydb=portage.portdb
        )
        use = portage.settings["PORTAGE_USE"].split()
        use_expand_hidden = portage.settings["USE_EXPAND_HIDDEN"].split()
        usemask = list(portage.db[portage.root]["porttree"].dbapi.settings.usemask)
        useforce = list(portage.db[portage.root]["porttree"].dbapi.settings.useforce)
    except KeyError:
        portage.db[portage.root]["porttree"].dbapi.settings.reset()
        portage.db[portage.root]["porttree"].dbapi.settings.lock()
        return [], [], [], []
    # reset cpv filter
    portage.db[portage.root]["porttree"].dbapi.settings.reset()
    portage.db[portage.root]["porttree"].dbapi.settings.lock()
    return use, use_expand_hidden, usemask, useforce


def get_flags(cpv, final_setting=False, include_forced_masked=False):
    """Retrieves all information needed to filter out hidded, masked, etc.
    USE flags for a given package.

    @type cpv: string
    @param cpv: eg. cat/pkg-ver
    @type final_setting: boolean
    @param final_setting: used to also determine the final
            enviroment USE flag settings and return them as well.
    @type include_forced_masked: boolean
    @param include_forced_masked: used to toggle the inclusion of forced and
            masked USE flags in the returned result.
    @rtype: list
            or list, list
            or list, list, list
            or list, list, list, list
    @return IUSE
            or IUSE, final_flags
            or IUSE, useforced, usemasked
            or IUSE, final_flags, useforced, usemasked
    """
    final_use, use_expand_hidden, usemasked, useforced = get_all_cpv_use(cpv)
    if include_forced_masked:
        iuse_flags = filter_flags(get_iuse(cpv), use_expand_hidden, [], [])
        if final_setting:
            final_flags = filter_flags(final_use, use_expand_hidden, [], [])
            return iuse_flags, final_flags, useforced, usemasked
        return iuse_flags, useforced, usemasked
    else:
        iuse_flags = filter_flags(
            get_iuse(cpv), use_expand_hidden, usemasked, useforced
        )
        if final_setting:
            final_flags = filter_flags(
                final_use, use_expand_hidden, usemasked, useforced
            )
            return iuse_flags, final_flags
        return iuse_flags