repodir = startdir
for x in range(0, repolevel - 1):
repodir = os.path.dirname(repodir)
+repodir = os.path.realpath(repodir)
def caterror(mycat):
err(mycat+" is not an official category. Skipping QA checks in this directory.\nPlease ensure that you add "+catdir+" to "+repodir+"/profiles/categories\nif it is a new category.")
Specifies \fIsite\-specific\fR repository configuration information. Note that
configuration settings which are specified here do not apply to tools
such as \fBrepoman\fR(1) and \fBegencache\fR(1) since their operations
-are inherently \fBnot\fR \fIsite\-specific\fR. Beware that use of
-\fBeclass\-overrides\fR is generally not recommended and that it may trigger
+are inherently \fBnot\fR \fIsite\-specific\fR. \fBWARNING:\fR Use of
+\fBrepos.conf\fR is generally not recommended since resulting changes in
+eclass inheritance (especially due ot \fBeclass\-overrides\fR) may trigger
performance issues under some circumstances (see \fBbug #124041\fR).
.I Example:
# disable all eclass overrides for ebuilds from the gentoo repository
[gentoo]
eclass\-overrides =
+
+# override the metadata/layout.conf masters setting from the kde-testing repo
+[kde-testing]
+masters = gentoo kde
.fi
.RE
.TP
repositories which satisfy dependencies on eclasses and/or ebuilds. Each
repository name should correspond the value of a \fBrepo_name\fR entry
from one of the repositories that is configured via the \fBPORTDIR\fR or
-\fBPORTDIR_OVERLAY\fR variables (see \fBmake.conf\fR(5)).
+\fBPORTDIR_OVERLAY\fR variables (see \fBmake.conf\fR(5)). Site-specific
+overrides to \fBlayout.conf\fR settings may be specified in
+\fB/etc/portage/repos.conf\fR.
.I Example:
.nf
return bool(missing_repo_names)
+def repo_name_duplicate_check(trees):
+ ignored_repos = {}
+ for root, root_trees in trees.iteritems():
+ if 'porttree' in root_trees:
+ portdb = root_trees['porttree'].dbapi
+ if portdb.mysettings.get('PORTAGE_REPO_DUPLICATE_WARN') != '0':
+ for repo_name, paths in portdb._ignored_repos:
+ k = (root, repo_name, portdb.getRepositoryPath(repo_name))
+ ignored_repos.setdefault(k, []).extend(paths)
+
+ if ignored_repos:
+ msg = []
+ msg.append('WARNING: One or more repositories ' + \
+ 'have been ignored due to duplicate')
+ msg.append(' profiles/repo_name entries:')
+ msg.append('')
+ for k in sorted(ignored_repos):
+ msg.append(' %s overrides' % (k,))
+ for path in ignored_repos[k]:
+ msg.append(' %s' % (path,))
+ msg.append('')
+ msg.extend(' ' + x for x in textwrap.wrap(
+ "All profiles/repo_name entries must be unique in order " + \
+ "to avoid having duplicates ignored. " + \
+ "Set PORTAGE_REPO_DUPLICATE_WARN=\"0\" in " + \
+ "/etc/make.conf if you would like to disable this warning."))
+ writemsg_level(''.join('%s\n' % l for l in msg),
+ level=logging.WARNING, noiselevel=-1)
+
+ return bool(ignored_repos)
+
def config_protect_check(trees):
for root, root_trees in trees.iteritems():
if not root_trees["root_config"].settings.get("CONFIG_PROTECT"):
if "--quiet" not in myopts:
portage.deprecated_profile_check(settings=settings)
repo_name_check(trees)
+ repo_name_duplicate_check(trees)
config_protect_check(trees)
for mytrees in trees.itervalues():
return regex
class _local_repo_config(object):
- __slots__ = ('eclass_overrides', 'name',)
+ __slots__ = ('eclass_overrides', 'masters', 'name',)
def __init__(self, name, repo_opts):
self.name = name
- self.eclass_overrides = \
- tuple(repo_opts.get('eclass-overrides', '').split())
+
+ eclass_overrides = repo_opts.get('eclass-overrides')
+ if eclass_overrides is not None:
+ eclass_overrides = tuple(eclass_overrides.split())
+ self.eclass_overrides = eclass_overrides
+
+ masters = repo_opts.get('masters')
+ if masters is not None:
+ masters = tuple(masters.split())
+ self.masters = masters
class config(object):
"""
"PORTAGE_GPG_DIR",
"PORTAGE_GPG_KEY", "PORTAGE_IONICE_COMMAND",
"PORTAGE_PACKAGE_EMPTY_ABORT",
+ "PORTAGE_REPO_DUPLICATE_WARN",
"PORTAGE_RO_DISTDIRS",
"PORTAGE_RSYNC_EXTRA_OPTS", "PORTAGE_RSYNC_OPTS",
"PORTAGE_RSYNC_RETRIES", "PORTAGE_USE", "PORT_LOGDIR",
try:
mysize = os.stat(myfile_path).st_size
except OSError, e:
- if e.errno != errno.ENOENT:
+ if e.errno not in (errno.ENOENT, errno.ESTALE):
raise
del e
mysize = 0
try:
os.unlink(myfile_path)
except OSError, e:
- if e.errno != errno.ENOENT:
+ if e.errno not in (errno.ENOENT, errno.ESTALE):
raise
del e
os.symlink(readonly_file, myfile_path)
" %(file)s\n" % {"file":myfile}))
break
except (IOError, OSError), e:
- if e.errno != errno.ENOENT:
+ if e.errno not in (errno.ENOENT, errno.ESTALE):
raise
del e
try:
mystat = os.stat(myfile_path)
except OSError, e:
- if e.errno != errno.ENOENT:
+ if e.errno not in (errno.ENOENT, errno.ESTALE):
raise
del e
else:
try:
mysize = os.stat(myfile_path).st_size
except OSError, e:
- if e.errno != errno.ENOENT:
+ if e.errno not in (errno.ENOENT, errno.ESTALE):
raise
del e
mysize = 0
try:
mystat = os.stat(myfile_path)
except OSError, e:
- if e.errno != errno.ENOENT:
+ if e.errno not in (errno.ENOENT, errno.ESTALE):
raise
del e
fetched = 0
try:
os.unlink(myfile_path)
except OSError, e:
- if e.errno != errno.ENOENT:
+ if e.errno not in \
+ (errno.ENOENT, errno.ESTALE):
raise
del e
fetched = 0
try:
mystat = os.stat(myfile_path)
except OSError, e:
- if e.errno != errno.ENOENT:
+ if e.errno not in (errno.ENOENT, errno.ESTALE):
raise
del e
fetched = 0
repository_map = {}
self.treemap = treemap
self._repository_map = repository_map
- identically_named_paths = set()
+ identically_named_paths = {}
for path in porttrees:
if path in repository_map:
continue
if identically_named_path is not None:
# The earlier one is discarded.
del repository_map[identically_named_path]
- identically_named_paths.add(identically_named_path)
+ identically_named_paths[identically_named_path] = repo_name
if identically_named_path == porttrees[0]:
# Found another repo with the same name as
# $PORTDIR, so update porttrees[0] to match.
# Ensure that each repo_name is unique. Later paths override
# earlier ones that correspond to the same name.
porttrees = [x for x in porttrees if x not in identically_named_paths]
+ ignored_map = {}
+ for path, repo_name in identically_named_paths.iteritems():
+ ignored_map.setdefault(repo_name, []).append(path)
+ self._ignored_repos = tuple((repo_name, tuple(paths)) \
+ for repo_name, paths in ignored_map.iteritems())
self.porttrees = porttrees
porttree_root = porttrees[0]
continue
repo_name = self._repository_map.get(path)
+
+ loc_repo_conf = None
+ if local_repo_configs is not None:
+ if repo_name is not None:
+ loc_repo_conf = local_repo_configs.get(repo_name)
+ else:
+ loc_repo_conf = default_loc_repo_config
+
layout_filename = os.path.join(path, "metadata/layout.conf")
layout_file = KeyValuePairFileLoader(layout_filename, None, None)
layout_data, layout_errors = layout_file.load()
porttrees = []
- for master_name in layout_data.get('masters', '').split():
+
+ masters = None
+ if loc_repo_conf is not None and \
+ loc_repo_conf.masters is not None:
+ masters = loc_repo_conf.masters
+ else:
+ masters = layout_data.get('masters', '').split()
+
+ for master_name in masters:
master_path = self.treemap.get(master_name)
if master_path is None:
writemsg_level(("Unavailable repository '%s' " + \
porttrees.append(path)
- if local_repo_configs is not None:
- loc_repo_conf = None
- if repo_name is not None:
- loc_repo_conf = local_repo_configs.get(repo_name)
- if loc_repo_conf is None:
- loc_repo_conf = default_loc_repo_config
- if loc_repo_conf is not None:
+ if loc_repo_conf is not None and \
+ loc_repo_conf.eclass_overrides is not None:
for other_name in loc_repo_conf.eclass_overrides:
other_path = self.treemap.get(other_name)
if other_path is None:
if os.stat(lockfilename).st_gid != portage_gid:
os.chown(lockfilename, -1, portage_gid)
except OSError, e:
- if e.errno == errno.ENOENT: # No such file or directory
+ if e.errno in (errno.ENOENT, errno.ESTALE):
return lockfile(mypath,
wantnewlockfile=wantnewlockfile,
unlinkfile=unlinkfile, waiting_msg=waiting_msg,
try:
return os.fstat(fd).st_nlink
except EnvironmentError, e:
- if e.errno == errno.ENOENT:
+ if e.errno in (errno.ENOENT, errno.ESTALE):
# Some filesystems such as CIFS return
# ENOENT which means st_nlink == 0.
return 0