aboutsummaryrefslogtreecommitdiff
blob: f6943beb445159b0b133565542444635645fdf82 (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
#!/usr/bin/python
# Copyright 2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
#
# Licensed under the GNU General Public License, v2

"""Routines to load profile information for ekeyword/eshowkw"""

__all__ = ("load_profile_data",)


import os.path
import portage
import sys

from portage import _encodings, _unicode_encode


def warning(msg):
    """Write |msg| as a warning to stderr"""
    print("warning: %s" % msg, file=sys.stderr)


def load_profile_data(portdir=None, repo="gentoo"):
    """Load the list of known arches from the tree

    Args:
      portdir: The repository to load all data from (and ignore |repo|)
      repo: Look up this repository by name to locate profile data

    Returns:
      A dict mapping the keyword to its preferred state:
      {'x86': ('stable', 'arch'), 'mips': ('dev', '~arch'), ...}
    """
    if portdir is None:
        portdir = (
            portage.db[portage.root]["vartree"].settings.repositories[repo].location
        )

    arch_status = {}

    try:
        arch_list = os.path.join(portdir, "profiles", "arch.list")
        with open(
            _unicode_encode(arch_list, encoding=_encodings["fs"]),
            encoding=_encodings["content"],
        ) as f:
            for line in f:
                line = line.split("#", 1)[0].strip()
                if line:
                    arch_status[line] = None
    except IOError:
        pass

    try:
        profile_status = {
            "stable": 0,
            "dev": 1,
            "exp": 2,
            None: 3,
        }
        profiles_list = os.path.join(portdir, "profiles", "profiles.desc")
        with open(
            _unicode_encode(profiles_list, encoding=_encodings["fs"]),
            encoding=_encodings["content"],
        ) as f:
            for line in f:
                line = line.split("#", 1)[0].split()
                if line:
                    arch, _profile, status = line
                    arch_status.setdefault(arch, status)
                    curr_status = profile_status[arch_status[arch]]
                    new_status = profile_status[status]
                    if new_status < curr_status:
                        arch_status[arch] = status
    except IOError:
        pass

    if arch_status:
        arch_status["all"] = None
    else:
        warning("could not read profile files: %s" % arch_list)
        warning("will not be able to verify args are correct")

    arches_desc = {}
    try:
        arches_list = os.path.join(portdir, "profiles", "arches.desc")
        with open(
            _unicode_encode(arches_list, encoding=_encodings["fs"]),
            encoding=_encodings["content"],
        ) as f:
            for line in f:
                line = line.split("#", 1)[0].split()
                if line:
                    arch, status = line
                    arches_desc[arch] = status
    except IOError:
        # backwards compatibility
        arches_desc = {
            "alpha": "testing",
            "ia64": "testing",
            "m68k": "testing",
            "mips": "testing",
            "riscv": "testing",
        }
        for k in arch_status:
            if "-" in k:
                arches_desc[k] = "testing"

    for k, v in arch_status.items():
        if arches_desc.get(k) == "testing":
            arch_status[k] = (v, "~arch")
        else:
            # TODO: explicit distinction of transitional, bad values?
            arch_status[k] = (v, "arch")

    return arch_status