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
|
# Copyright 2010 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
__all__ = (
'LocationsManager',
)
import codecs
from portage import os, eapi_is_supported, _encodings, _unicode_encode
from portage.const import CUSTOM_PROFILE_PATH, GLOBAL_CONFIG_PATH, PROFILE_PATH, USER_CONFIG_PATH
from portage.dep import Atom
from portage.exception import DirectoryNotFound, InvalidAtom, ParseError
from portage.localization import _
from portage.util import ensure_dirs, grabdict, grabfile, normalize_path, shlex_split, stack_dictlist, writemsg
from portage.versions import cpv_getkey
class LocationsManager(object):
def __init__(self, config_root=None, eprefix=None, config_profile_path=None, local_config=True, \
target_root=None):
self.user_profile_dir = None
self._local_repo_conf_path = None
self.eprefix = eprefix
self.config_root = config_root
self.target_root = target_root
if self.eprefix is None:
self.eprefix = ""
if self.config_root is None:
self.config_root = self.eprefix + os.sep
self.config_root = normalize_path(os.path.abspath(
self.config_root)).rstrip(os.path.sep) + os.path.sep
self._check_var_directory("PORTAGE_CONFIGROOT", self.config_root)
self.abs_user_config = os.path.join(self.config_root, USER_CONFIG_PATH)
if not config_profile_path:
config_profile_path = \
os.path.join(self.config_root, PROFILE_PATH)
if os.path.isdir(config_profile_path):
self.profile_path = config_profile_path
else:
config_profile_path = \
os.path.join(self.abs_user_config, 'make.profile')
if os.path.isdir(config_profile_path):
self.profile_path = config_profile_path
else:
self.profile_path = None
else:
self.profile_path = config_profile_path
# The symlink might not exist or might not be a symlink.
self.profiles = []
if self.profile_path is not None:
try:
self._addProfile(os.path.realpath(self.profile_path))
except ParseError as e:
writemsg(_("!!! Unable to parse profile: '%s'\n") % \
self.profile_path, noiselevel=-1)
writemsg("!!! ParseError: %s\n" % str(e), noiselevel=-1)
self.profiles = []
if local_config and self.profiles:
custom_prof = os.path.join(
self.config_root, CUSTOM_PROFILE_PATH)
if os.path.exists(custom_prof):
self.user_profile_dir = custom_prof
self.profiles.append(custom_prof)
del custom_prof
self.profiles = tuple(self.profiles)
def _check_var_directory(self, varname, var):
if not os.path.isdir(var):
writemsg(_("!!! Error: %s='%s' is not a directory. "
"Please correct this.\n") % (varname, var),
noiselevel=-1)
raise DirectoryNotFound(var)
def _addProfile(self, currentPath):
parentsFile = os.path.join(currentPath, "parent")
eapi_file = os.path.join(currentPath, "eapi")
try:
eapi = codecs.open(_unicode_encode(eapi_file,
encoding=_encodings['fs'], errors='strict'),
mode='r', encoding=_encodings['content'], errors='replace'
).readline().strip()
except IOError:
pass
else:
if not eapi_is_supported(eapi):
raise ParseError(_(
"Profile contains unsupported "
"EAPI '%s': '%s'") % \
(eapi, os.path.realpath(eapi_file),))
if os.path.exists(parentsFile):
parents = grabfile(parentsFile)
if not parents:
raise ParseError(
_("Empty parent file: '%s'") % parentsFile)
for parentPath in parents:
parentPath = normalize_path(os.path.join(
currentPath, parentPath))
if os.path.exists(parentPath):
self._addProfile(parentPath)
else:
raise ParseError(
_("Parent '%s' not found: '%s'") % \
(parentPath, parentsFile))
self.profiles.append(currentPath)
def set_root_override(self, root_overwrite=None):
# Allow ROOT setting to come from make.conf if it's not overridden
# by the constructor argument (from the calling environment).
if self.target_root is None and root_overwrite is not None:
self.target_root = root_overwrite
if not self.target_root.strip():
self.target_root = None
if self.target_root is None:
self.target_root = "/"
self.target_root = normalize_path(os.path.abspath(
self.target_root)).rstrip(os.path.sep) + os.path.sep
ensure_dirs(self.target_root)
self._check_var_directory("ROOT", self.target_root)
self.eroot = self.target_root.rstrip(os.sep) + self.eprefix + os.sep
# make.globals should not be relative to config_root
# because it only contains constants. However, if EPREFIX
# is set then there are two possible scenarios:
# 1) If $ROOT == "/" then make.globals should be
# relative to EPREFIX.
# 2) If $ROOT != "/" then the correct location of
# make.globals needs to be specified in the constructor
# parameters, since it's a property of the host system
# (and the current config represents the target system).
self.global_config_path = GLOBAL_CONFIG_PATH
if self.eprefix:
if self.target_root == "/":
# case (1) above
self.global_config_path = os.path.join(self.eprefix,
GLOBAL_CONFIG_PATH.lstrip(os.sep))
else:
# case (2) above
# For now, just assume make.globals is relative
# to EPREFIX.
# TODO: Pass in more info to the constructor,
# so we know the host system configuration.
self.global_config_path = os.path.join(self.eprefix,
GLOBAL_CONFIG_PATH.lstrip(os.sep))
def set_port_dirs(self, portdir, portdir_overlay):
self.portdir = portdir
self.portdir_overlay = portdir_overlay
if self.portdir_overlay is None:
self.portdir_overlay = ""
self.overlay_profiles = []
for ov in shlex_split(self.portdir_overlay):
ov = normalize_path(ov)
profiles_dir = os.path.join(ov, "profiles")
if os.path.isdir(profiles_dir):
self.overlay_profiles.append(profiles_dir)
self.profile_locations = [os.path.join(portdir, "profiles")] + self.overlay_profiles
self.profile_locations = tuple(self.profile_locations)
self.pmask_locations = [os.path.join(portdir, "profiles")]
self.pmask_locations.extend(self.profiles)
self.pmask_locations.extend(self.overlay_profiles)
self.pmask_locations = tuple(self.pmask_locations)
|