aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Sachau <tommy@gentoo.org>2016-02-28 13:24:26 +0100
committerThomas Sachau <tommy@gentoo.org>2016-02-28 13:24:26 +0100
commit3a63f58d0993f66975cd324eb85f4a2340d4f7c3 (patch)
treebb48a71faf4016196f9f8bc42ba2173bccf57e9f
parentConvert forced flags from new multilib eclass to the matching ones from multi... (diff)
parentUpdates for a release (diff)
downloadportage-3a63f58d.tar.gz
portage-3a63f58d.tar.bz2
portage-3a63f58d.zip
Merge tag 'v2.2.23' into multilib
New release
-rw-r--r--.travis.yml1
-rw-r--r--README10
-rw-r--r--RELEASE-NOTES14
-rwxr-xr-xbin/cgroup-release-agent2
-rwxr-xr-xbin/chmod-lite10
-rwxr-xr-xbin/chmod-lite.py30
-rwxr-xr-xbin/dohtml.py47
-rw-r--r--bin/phase-helpers.sh4
-rw-r--r--man/make.conf.53
-rw-r--r--pym/_emerge/AbstractEbuildProcess.py14
-rw-r--r--pym/_emerge/Scheduler.py30
-rw-r--r--pym/portage/checksum.py4
-rw-r--r--pym/portage/const.py1
-rw-r--r--pym/portage/data.py2
-rw-r--r--pym/portage/dbapi/__init__.py23
-rw-r--r--pym/portage/dbapi/porttree.py18
-rw-r--r--pym/portage/package/ebuild/doebuild.py14
-rw-r--r--pym/portage/sync/controller.py39
-rw-r--r--pym/portage/util/__init__.py97
-rw-r--r--pym/repoman/_subprocess.py1
-rw-r--r--pym/repoman/_xml.py1
-rw-r--r--pym/repoman/actions.py3
-rw-r--r--pym/repoman/argparser.py4
-rw-r--r--pym/repoman/check_missingslot.py1
-rw-r--r--pym/repoman/checks/directories/files.py1
-rw-r--r--pym/repoman/checks/ebuilds/checks.py1
-rw-r--r--pym/repoman/checks/ebuilds/errors.py1
-rw-r--r--pym/repoman/checks/ebuilds/fetches.py1
-rw-r--r--pym/repoman/checks/ebuilds/isebuild.py1
-rw-r--r--pym/repoman/checks/ebuilds/keywords.py1
-rw-r--r--pym/repoman/checks/ebuilds/manifests.py1
-rw-r--r--pym/repoman/checks/ebuilds/misc.py1
-rw-r--r--pym/repoman/checks/ebuilds/pkgmetadata.py1
-rw-r--r--pym/repoman/checks/ebuilds/thirdpartymirrors.py1
-rw-r--r--pym/repoman/checks/ebuilds/use_flags.py1
-rw-r--r--pym/repoman/checks/herds/metadata.py1
-rw-r--r--pym/repoman/copyrights.py1
-rw-r--r--pym/repoman/ebuild.py1
-rw-r--r--pym/repoman/errors.py1
-rw-r--r--pym/repoman/gpg.py1
-rwxr-xr-xpym/repoman/main.py1
-rw-r--r--pym/repoman/metadata.py1
-rw-r--r--pym/repoman/modules/commit/repochecks.py1
-rw-r--r--pym/repoman/profile.py1
-rw-r--r--pym/repoman/qa_data.py1
-rw-r--r--pym/repoman/repos.py3
-rw-r--r--pym/repoman/scan.py4
-rw-r--r--pym/repoman/scanner.py29
-rw-r--r--pym/repoman/utilities.py1
-rw-r--r--pym/repoman/vcs/vcs.py1
-rw-r--r--pym/repoman/vcs/vcsstatus.py1
-rwxr-xr-xsetup.py2
52 files changed, 310 insertions, 125 deletions
diff --git a/.travis.yml b/.travis.yml
index 8a86aa69f..237963f14 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,6 +3,7 @@ python:
- 2.7
- 3.3
- 3.4
+ - 3.5
- pypy
script:
- ./setup.py test
diff --git a/README b/README
index 415a9625e..5e78842c9 100644
--- a/README
+++ b/README
@@ -2,8 +2,8 @@ About Portage
=============
Portage is a package management system based on ports collections. The
-Package Manager Specification Project (PMS) standardises and documents
-the behaviour of Portage so that the Portage tree can be used by other
+Package Manager Specification Project (PMS) standardises and documents
+the behaviour of Portage so that the Portage tree can be used by other
package managers.
@@ -28,7 +28,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Portage; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
@@ -44,6 +44,6 @@ More information
Links
=====
-Gentoo project page: <http://www.gentoo.org/proj/en/portage/>
+Gentoo project page: <https://wiki.gentoo.org/wiki/Project:Portage>
PMS: <https://dev.gentoo.org/~ulm/pms/head/pms.html>
-PMS git repo: <http://git.overlays.gentoo.org/gitweb/?p=proj/pms.git>
+PMS git repo: <https://gitweb.gentoo.org/proj/pms.git/>
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index b26ba208e..11b18a9c2 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -1,6 +1,20 @@
Release Notes; upgrade information mainly.
Features/major bugfixes are listed in NEWS
+portage-2.2.23
+==================================
+* Bug Fixes:
+ - Bug 561474 Add check that we need commit signing
+ - Bug 561596 Fix typo in function call
+ - Bug 561264 AbstractEbuildProcess: remove cgroup with release_agent
+ SyncRepos.async: group sync and callback as composite task
+ - Bug 554084 unpack: use chmod-lite helper
+ - Bug 562108 repoman/argparser.py: _unicode_decode the commitmsg
+ - Bug 561846 dohtml: handle unicode
+ - Bug 534022 scanner.py: Fix options.output_style for column output
+* Add icecream feature support
+
+
portage-2.2.22
==================================
* Bug Fixes:
diff --git a/bin/cgroup-release-agent b/bin/cgroup-release-agent
new file mode 100755
index 000000000..7aa6d56b4
--- /dev/null
+++ b/bin/cgroup-release-agent
@@ -0,0 +1,2 @@
+#!/bin/bash
+exec rmdir "/sys/fs/cgroup/portage/${1}"
diff --git a/bin/chmod-lite b/bin/chmod-lite
new file mode 100755
index 000000000..ffa8d4d23
--- /dev/null
+++ b/bin/chmod-lite
@@ -0,0 +1,10 @@
+#!/bin/bash
+# Copyright 2015 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+export __PORTAGE_HELPER_CWD=${PWD}
+
+# Use safe cwd, avoiding unsafe import for bug #469338.
+cd "${PORTAGE_PYM_PATH}" || exit 1
+PYTHONPATH=${PORTAGE_PYTHONPATH:-${PORTAGE_PYM_PATH}} \
+ exec "${PORTAGE_PYTHON:-/usr/bin/python}" "$PORTAGE_BIN_PATH/chmod-lite.py" "$@"
diff --git a/bin/chmod-lite.py b/bin/chmod-lite.py
new file mode 100755
index 000000000..177be7eab
--- /dev/null
+++ b/bin/chmod-lite.py
@@ -0,0 +1,30 @@
+#!/usr/bin/python -b
+# Copyright 2015 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+import os
+import sys
+
+from portage.util import apply_recursive_permissions
+
+# Change back to original cwd _after_ all imports (bug #469338).
+os.chdir(os.environ["__PORTAGE_HELPER_CWD"])
+
+def main(files):
+
+ if sys.hexversion >= 0x3000000:
+ # We can't trust that the filesystem encoding (locale dependent)
+ # correctly matches the arguments, so use surrogateescape to
+ # pass through the original argv bytes for Python 3.
+ fs_encoding = sys.getfilesystemencoding()
+ files = [x.encode(fs_encoding, 'surrogateescape') for x in files]
+
+ for filename in files:
+ # Emulate 'chmod -fR a+rX,u+w,g-w,o-w' with minimal chmod calls.
+ apply_recursive_permissions(filename, filemode=0o644,
+ filemask=0o022, dirmode=0o755, dirmask=0o022)
+
+ return os.EX_OK
+
+if __name__ == "__main__":
+ sys.exit(main(sys.argv[1:]))
diff --git a/bin/dohtml.py b/bin/dohtml.py
index 5359f5e89..dfcaa6026 100755
--- a/bin/dohtml.py
+++ b/bin/dohtml.py
@@ -28,13 +28,13 @@
# - will do as 'dohtml -r', but ignore directories named CVS, SCCS, RCS
#
-from __future__ import print_function
+from __future__ import print_function, unicode_literals
-import os
-import shutil
+import os as _os
import sys
-from portage.util import normalize_path
+from portage import _unicode_encode, _unicode_decode, os, shutil
+from portage.util import normalize_path, writemsg
# Change back to original cwd _after_ all imports (bug #469338).
os.chdir(os.environ["__PORTAGE_HELPER_CWD"])
@@ -92,7 +92,13 @@ def install(basename, dirname, options, prefix=""):
skipped_files.append(fullpath)
elif options.recurse and os.path.isdir(fullpath) and \
basename not in options.disallowed_dirs:
- for i in os.listdir(fullpath):
+ for i in _os.listdir(_unicode_encode(fullpath)):
+ try:
+ i = _unicode_decode(i, errors='strict')
+ except UnicodeDecodeError:
+ writemsg('dohtml: argument is not encoded as UTF-8: %s\n' %
+ _unicode_decode(i), noiselevel=-1)
+ sys.exit(1)
pfx = basename
if prefix:
pfx = os.path.join(prefix, pfx)
@@ -155,12 +161,29 @@ def print_help():
print()
def parse_args():
+ argv = sys.argv[:]
+
+ if sys.hexversion >= 0x3000000:
+ # We can't trust that the filesystem encoding (locale dependent)
+ # correctly matches the arguments, so use surrogateescape to
+ # pass through the original argv bytes for Python 3.
+ fs_encoding = sys.getfilesystemencoding()
+ argv = [x.encode(fs_encoding, 'surrogateescape') for x in argv]
+
+ for x, arg in enumerate(argv):
+ try:
+ argv[x] = _unicode_decode(arg, errors='strict')
+ except UnicodeDecodeError:
+ writemsg('dohtml: argument is not encoded as UTF-8: %s\n' %
+ _unicode_decode(arg), noiselevel=-1)
+ sys.exit(1)
+
options = OptionsClass()
args = []
x = 1
- while x < len(sys.argv):
- arg = sys.argv[x]
+ while x < len(argv):
+ arg = argv[x]
if arg in ["-h","-r","-V"]:
if arg == "-h":
print_help()
@@ -169,17 +192,17 @@ def parse_args():
options.recurse = True
elif arg == "-V":
options.verbose = True
- elif sys.argv[x] in ["-A","-a","-f","-x","-p"]:
+ elif argv[x] in ["-A","-a","-f","-x","-p"]:
x += 1
- if x == len(sys.argv):
+ if x == len(argv):
print_help()
sys.exit(0)
elif arg == "-p":
- options.doc_prefix = sys.argv[x]
+ options.doc_prefix = argv[x]
if options.doc_prefix:
options.doc_prefix = normalize_path(options.doc_prefix)
else:
- values = sys.argv[x].split(",")
+ values = argv[x].split(",")
if arg == "-A":
options.allowed_exts.extend(values)
elif arg == "-a":
@@ -189,7 +212,7 @@ def parse_args():
elif arg == "-x":
options.disallowed_dirs = values
else:
- args.append(sys.argv[x])
+ args.append(argv[x])
x += 1
return (options, args)
diff --git a/bin/phase-helpers.sh b/bin/phase-helpers.sh
index 28aa0ecea..4245ec382 100644
--- a/bin/phase-helpers.sh
+++ b/bin/phase-helpers.sh
@@ -532,8 +532,8 @@ unpack() {
done
# Do not chmod '.' since it's probably ${WORKDIR} and PORTAGE_WORKDIR_MODE
# should be preserved.
- find . -mindepth 1 '!' -type l '!' -perm /a+rX,u+w,g-w,o-w \
- -exec chmod -f a+rX,u+w,g-w,o-w '{}' +
+ find . -mindepth 1 -maxdepth 1 ! -type l -print0 | \
+ ${XARGS} -0 "${PORTAGE_BIN_PATH}/chmod-lite"
}
econf() {
diff --git a/man/make.conf.5 b/man/make.conf.5
index 13b80428d..1d1cfebd4 100644
--- a/man/make.conf.5
+++ b/man/make.conf.5
@@ -411,6 +411,9 @@ for all EAPIs (for obvious reasons).
Force emerges to always try to fetch files from the \fIPORTAGE_BINHOST\fR. See
\fBmake.conf\fR(5) for more information.
.TP
+.B icecream
+Enable portage support for the icecream package.
+.TP
.B installsources
Install source code into /usr/src/debug/${CATEGORY}/${PF} (also see
\fBsplitdebug\fR). This feature works only if debugedit is installed and CFLAGS
diff --git a/pym/_emerge/AbstractEbuildProcess.py b/pym/_emerge/AbstractEbuildProcess.py
index 68d96e406..2b5d9c78d 100644
--- a/pym/_emerge/AbstractEbuildProcess.py
+++ b/pym/_emerge/AbstractEbuildProcess.py
@@ -89,6 +89,13 @@ class AbstractEbuildProcess(SpawnProcess):
subprocess.check_call(['mount', '-t', 'cgroup',
'-o', 'rw,nosuid,nodev,noexec,none,name=portage',
'tmpfs', cgroup_portage])
+ with open(os.path.join(
+ cgroup_portage, 'release_agent'), 'w') as f:
+ f.write(os.path.join(self.settings['PORTAGE_BIN_PATH'],
+ 'cgroup-release-agent'))
+ with open(os.path.join(
+ cgroup_portage, 'notify_on_release'), 'w') as f:
+ f.write('1')
cgroup_path = tempfile.mkdtemp(dir=cgroup_portage,
prefix='%s:%s.' % (self.settings["CATEGORY"],
@@ -313,13 +320,6 @@ class AbstractEbuildProcess(SpawnProcess):
def _set_returncode(self, wait_retval):
SpawnProcess._set_returncode(self, wait_retval)
- if self.cgroup is not None:
- try:
- shutil.rmtree(self.cgroup)
- except EnvironmentError as e:
- if e.errno != errno.ENOENT:
- raise
-
if self._exit_timeout_id is not None:
self.scheduler.source_remove(self._exit_timeout_id)
self._exit_timeout_id = None
diff --git a/pym/_emerge/Scheduler.py b/pym/_emerge/Scheduler.py
index 8eeef06fe..20a4e854d 100644
--- a/pym/_emerge/Scheduler.py
+++ b/pym/_emerge/Scheduler.py
@@ -65,6 +65,10 @@ from _emerge.SequentialTaskQueue import SequentialTaskQueue
if sys.hexversion >= 0x3000000:
basestring = str
+# enums
+FAILURE = 1
+
+
class Scheduler(PollScheduler):
# max time between loadavg checks (milliseconds)
@@ -284,11 +288,11 @@ class Scheduler(PollScheduler):
self._parallel_fetch = True
if self._parallel_fetch:
- # clear out existing fetch log if it exists
- try:
- open(self._fetch_log, 'w').close()
- except EnvironmentError:
- pass
+ # clear out existing fetch log if it exists
+ try:
+ open(self._fetch_log, 'w').close()
+ except EnvironmentError:
+ pass
self._running_portage = None
portage_match = self._running_root.trees["vartree"].dbapi.match(
@@ -353,7 +357,7 @@ class Scheduler(PollScheduler):
Use this to free memory at the beginning of _calc_resume_list().
After _calc_resume_list(), the _init_graph() method
must to be called in order to re-generate the structures that
- this method destroys.
+ this method destroys.
"""
self._blocker_db = None
self._set_graph_config(None)
@@ -641,7 +645,7 @@ class Scheduler(PollScheduler):
writemsg_level(
"!!! Unable to generate manifest for '%s'.\n" \
% x.cpv, level=logging.ERROR, noiselevel=-1)
- return 1
+ return FAILURE
return os.EX_OK
@@ -673,7 +677,7 @@ class Scheduler(PollScheduler):
out = portage.output.EOutput()
for line in textwrap.wrap(msg, 70):
out.eerror(line)
- return 1
+ return FAILURE
return os.EX_OK
@@ -719,7 +723,7 @@ class Scheduler(PollScheduler):
failures |= 1
if failures:
- return 1
+ return FAILURE
return os.EX_OK
def _add_prefetchers(self):
@@ -934,7 +938,7 @@ class Scheduler(PollScheduler):
build_dir.unlock()
if failures:
- return 1
+ return FAILURE
return os.EX_OK
def merge(self):
@@ -949,7 +953,7 @@ class Scheduler(PollScheduler):
try:
self._background = self._background_mode()
except self._unknown_internal_error:
- return 1
+ return FAILURE
rval = self._handle_self_update()
if rval != os.EX_OK:
@@ -971,7 +975,7 @@ class Scheduler(PollScheduler):
out = portage.output.EOutput()
for l in msg:
out.eerror(l)
- return 1
+ return FAILURE
if self._background:
root_config.settings.unlock()
@@ -1180,7 +1184,7 @@ class Scheduler(PollScheduler):
printer.eerror("")
if self._failed_pkgs_all:
- return 1
+ return FAILURE
return os.EX_OK
def _elog_listener(self, mysettings, key, logentries, fulltext):
diff --git a/pym/portage/checksum.py b/pym/portage/checksum.py
index 642602ea1..cdf467003 100644
--- a/pym/portage/checksum.py
+++ b/pym/portage/checksum.py
@@ -7,7 +7,7 @@ from portage.const import PRELINK_BINARY, HASHING_BLOCKSIZE
from portage.localization import _
from portage import os
from portage import _encodings
-from portage import _unicode_encode
+from portage import _unicode_decode, _unicode_encode
import errno
import stat
import subprocess
@@ -22,7 +22,7 @@ def _open_file(filename):
return open(_unicode_encode(filename,
encoding=_encodings['fs'], errors='strict'), 'rb')
except IOError as e:
- func_call = "open('%s')" % filename
+ func_call = "open('%s')" % _unicode_decode(filename)
if e.errno == errno.EPERM:
raise portage.exception.OperationNotPermitted(func_call)
elif e.errno == errno.EACCES:
diff --git a/pym/portage/const.py b/pym/portage/const.py
index 6b03017cb..20cf40e16 100644
--- a/pym/portage/const.py
+++ b/pym/portage/const.py
@@ -150,6 +150,7 @@ SUPPORTED_FEATURES = frozenset([
"force-multilib",
"force-prefix",
"getbinpkg",
+ "icecream",
"installsources",
"ipc-sandbox",
"keeptemp",
diff --git a/pym/portage/data.py b/pym/portage/data.py
index 2fd287ddb..2c99548cb 100644
--- a/pym/portage/data.py
+++ b/pym/portage/data.py
@@ -139,7 +139,7 @@ def _get_global(k):
v = 2
elif unprivileged:
v = 2
- elif portage_gid in os.getgroups():
+ elif _get_global('portage_gid') in os.getgroups():
v = 1
elif k in ('portage_gid', 'portage_uid'):
diff --git a/pym/portage/dbapi/__init__.py b/pym/portage/dbapi/__init__.py
index b6745fa15..95053840d 100644
--- a/pym/portage/dbapi/__init__.py
+++ b/pym/portage/dbapi/__init__.py
@@ -215,7 +215,7 @@ class dbapi(object):
yield cpv
- def _match_use(self, atom, pkg, metadata):
+ def _match_use(self, atom, pkg, metadata, ignore_profile=False):
eapi_attrs = _get_eapi_attrs(metadata["EAPI"])
if eapi_attrs.iuse_effective:
iuse_implicit_match = self.settings._iuse_effective_match
@@ -261,17 +261,18 @@ class dbapi(object):
return False
elif not self.settings.local_config:
- # Check masked and forced flags for repoman.
- usemask = self.settings._getUseMask(pkg,
- stable=self.settings._parent_stable)
- if any(x in usemask for x in atom.use.enabled):
- return False
+ if not ignore_profile:
+ # Check masked and forced flags for repoman.
+ usemask = self.settings._getUseMask(pkg,
+ stable=self.settings._parent_stable)
+ if any(x in usemask for x in atom.use.enabled):
+ return False
- useforce = self.settings._getUseForce(pkg,
- stable=self.settings._parent_stable)
- if any(x in useforce and x not in usemask
- for x in atom.use.disabled):
- return False
+ useforce = self.settings._getUseForce(pkg,
+ stable=self.settings._parent_stable)
+ if any(x in useforce and x not in usemask
+ for x in atom.use.disabled):
+ return False
# Check unsatisfied use-default deps
if atom.use.enabled:
diff --git a/pym/portage/dbapi/porttree.py b/pym/portage/dbapi/porttree.py
index d13fdee6d..a954de53b 100644
--- a/pym/portage/dbapi/porttree.py
+++ b/pym/portage/dbapi/porttree.py
@@ -809,9 +809,9 @@ class portdbapi(dbapi):
return mylist
def freeze(self):
- for x in "bestmatch-visible", "cp-list", "match-all", \
- "match-all-cpv-only", "match-visible", "minimum-all", \
- "minimum-visible":
+ for x in ("bestmatch-visible", "cp-list", "match-all",
+ "match-all-cpv-only", "match-visible", "minimum-all",
+ "minimum-all-ignore-profile", "minimum-visible"):
self.xcache[x]={}
self.frozen=1
@@ -870,8 +870,9 @@ class portdbapi(dbapi):
myval = match_from_list(mydep,
self.cp_list(mykey, mytree=mytree))
- elif level in ("bestmatch-visible", "match-all", "match-visible",
- "minimum-all", "minimum-visible"):
+ elif level in ("bestmatch-visible", "match-all",
+ "match-visible", "minimum-all", "minimum-all-ignore-profile",
+ "minimum-visible"):
# Find the minimum matching visible version. This is optimized to
# minimize the number of metadata accesses (improves performance
# especially in cases where metadata needs to be generated).
@@ -881,7 +882,9 @@ class portdbapi(dbapi):
mylist = match_from_list(mydep,
self.cp_list(mykey, mytree=mytree))
- visibility_filter = level not in ("match-all", "minimum-all")
+ ignore_profile = level in ("minimum-all-ignore-profile",)
+ visibility_filter = level not in ("match-all",
+ "minimum-all", "minimum-all-ignore-profile")
single_match = level not in ("match-all", "match-visible")
myval = []
aux_keys = list(self._aux_cache_keys)
@@ -922,7 +925,8 @@ class portdbapi(dbapi):
continue
if mydep.unevaluated_atom.use is not None and \
- not self._match_use(mydep, pkg_str, metadata):
+ not self._match_use(mydep, pkg_str, metadata,
+ ignore_profile=ignore_profile):
continue
myval.append(pkg_str)
diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py
index 3594ff06f..e581724d9 100644
--- a/pym/portage/package/ebuild/doebuild.py
+++ b/pym/portage/package/ebuild/doebuild.py
@@ -45,7 +45,7 @@ portage.proxy.lazyimport.lazyimport(globals(),
'portage.util.ExtractKernelVersion:ExtractKernelVersion'
)
-from portage import auxdbkeys, bsd_chflags, \
+from portage import bsd_chflags, \
eapi_is_supported, merge, os, selinux, shutil, \
unmerge, _encodings, _os_merge, \
_shell_quote, _unicode_decode, _unicode_encode
@@ -69,7 +69,7 @@ from portage.localization import _
from portage.output import colormap
from portage.package.ebuild.prepare_build_dirs import prepare_build_dirs
from portage.util import apply_recursive_permissions, \
- apply_secpass_permissions, noiselimit, normalize_path, \
+ apply_secpass_permissions, noiselimit, \
writemsg, writemsg_stdout, write_atomic
from portage.util.cpuinfo import get_cpu_count
from portage.util.lafilefixer import rewrite_lafile
@@ -251,8 +251,6 @@ def doebuild_environment(myebuild, mydo, myroot=None, settings=None,
EAPI metadata.
The myroot and use_cache parameters are unused.
"""
- myroot = None
- use_cache = None
if settings is None:
raise TypeError("settings argument is required")
@@ -465,7 +463,9 @@ def doebuild_environment(myebuild, mydo, myroot=None, settings=None,
ccache = "ccache" in mysettings.features
distcc = "distcc" in mysettings.features
- if ccache or distcc:
+ icecream = "icecream" in mysettings.features
+
+ if ccache or distcc or icecream:
# Use default ABI libdir in accordance with bug #355283.
libdir = None
default_abi = mysettings.get("DEFAULT_ABI")
@@ -478,6 +478,10 @@ def doebuild_environment(myebuild, mydo, myroot=None, settings=None,
mysettings["PATH"] = os.path.join(os.sep, eprefix_lstrip,
"usr", libdir, "distcc", "bin") + ":" + mysettings["PATH"]
+ if icecream:
+ mysettings["PATH"] = os.path.join(os.sep, eprefix_lstrip,
+ "usr", 'libexec', "icecc", "bin") + ":" + mysettings["PATH"]
+
if ccache:
mysettings["PATH"] = os.path.join(os.sep, eprefix_lstrip,
"usr", libdir, "ccache", "bin") + ":" + mysettings["PATH"]
diff --git a/pym/portage/sync/controller.py b/pym/portage/sync/controller.py
index 28dbc575a..159b9c094 100644
--- a/pym/portage/sync/controller.py
+++ b/pym/portage/sync/controller.py
@@ -25,6 +25,7 @@ from portage.util._async.AsyncFunction import AsyncFunction
from portage import OrderedDict
from portage import _unicode_decode
from portage import util
+from _emerge.CompositeTask import CompositeTask
class TaskHandler(object):
@@ -119,10 +120,9 @@ class SyncManager(object):
self.settings, self.trees, self.mtimedb = emerge_config
self.xterm_titles = "notitles" not in self.settings.features
self.portdb = self.trees[self.settings['EROOT']]['porttree'].dbapi
- proc = AsyncFunction(target=self.sync,
- kwargs=dict(emerge_config=emerge_config, repo=repo))
- proc.addExitListener(self._sync_callback)
- return proc
+ return SyncRepo(sync_task=AsyncFunction(target=self.sync,
+ kwargs=dict(emerge_config=emerge_config, repo=repo)),
+ sync_callback=self._sync_callback)
def sync(self, emerge_config=None, repo=None):
self.callback = None
@@ -343,3 +343,34 @@ class SyncManager(object):
action_metadata(self.settings, self.portdb, self.emerge_config.opts,
porttrees=[repo.location])
+
+class SyncRepo(CompositeTask):
+ """
+ Encapsulates a sync operation and the callback which executes afterwards,
+ so both can be considered as a single composite task. This is useful
+ since we don't want to consider a particular repo's sync operation as
+ complete until after the callback has executed (bug 562264).
+
+ The kwargs and result properties expose attributes that are accessed
+ by SyncScheduler.
+ """
+
+ __slots__ = ('sync_task', 'sync_callback')
+
+ @property
+ def kwargs(self):
+ return self.sync_task.kwargs
+
+ @property
+ def result(self):
+ return self.sync_task.result
+
+ def _start(self):
+ self._start_task(self.sync_task, self._sync_task_exit)
+
+ def _sync_task_exit(self, sync_task):
+ self._current_task = None
+ self.returncode = sync_task.returncode
+ self.sync_callback(self.sync_task)
+ self._async_wait()
+
diff --git a/pym/portage/util/__init__.py b/pym/portage/util/__init__.py
index c0b509ba6..b739257e8 100644
--- a/pym/portage/util/__init__.py
+++ b/pym/portage/util/__init__.py
@@ -17,9 +17,9 @@ from copy import deepcopy
import errno
import io
try:
- from itertools import filterfalse
+ from itertools import chain, filterfalse
except ImportError:
- from itertools import ifilterfalse as filterfalse
+ from itertools import chain, ifilterfalse as filterfalse
import logging
import re
import shlex
@@ -1041,6 +1041,23 @@ def unique_everseen(iterable, key=None):
seen_add(k)
yield element
+def _do_stat(filename, follow_links=True):
+ try:
+ if follow_links:
+ return os.stat(filename)
+ else:
+ return os.lstat(filename)
+ except OSError as oe:
+ func_call = "stat('%s')" % filename
+ if oe.errno == errno.EPERM:
+ raise OperationNotPermitted(func_call)
+ elif oe.errno == errno.EACCES:
+ raise PermissionDenied(func_call)
+ elif oe.errno == errno.ENOENT:
+ raise FileNotFound(filename)
+ else:
+ raise
+
def apply_permissions(filename, uid=-1, gid=-1, mode=-1, mask=-1,
stat_cached=None, follow_links=True):
"""Apply user, group, and mode bits to a file if the existing bits do not
@@ -1058,21 +1075,7 @@ def apply_permissions(filename, uid=-1, gid=-1, mode=-1, mask=-1,
gid = int(gid)
if stat_cached is None:
- try:
- if follow_links:
- stat_cached = os.stat(filename)
- else:
- stat_cached = os.lstat(filename)
- except OSError as oe:
- func_call = "stat('%s')" % filename
- if oe.errno == errno.EPERM:
- raise OperationNotPermitted(func_call)
- elif oe.errno == errno.EACCES:
- raise PermissionDenied(func_call)
- elif oe.errno == errno.ENOENT:
- raise FileNotFound(filename)
- else:
- raise
+ stat_cached = _do_stat(filename, follow_links=follow_links)
if (uid != -1 and uid != stat_cached.st_uid) or \
(gid != -1 and gid != stat_cached.st_gid):
@@ -1177,22 +1180,40 @@ def apply_recursive_permissions(top, uid=-1, gid=-1,
else:
raise
+ # For bug 554084, always apply permissions to a directory before
+ # that directory is traversed.
all_applied = True
- for dirpath, dirnames, filenames in os.walk(top):
- try:
- applied = apply_secpass_permissions(dirpath,
- uid=uid, gid=gid, mode=dirmode, mask=dirmask,
- follow_links=follow_links)
- if not applied:
- all_applied = False
- except PortageException as e:
+
+ try:
+ stat_cached = _do_stat(top, follow_links=follow_links)
+ except FileNotFound:
+ # backward compatibility
+ return True
+
+ if stat.S_ISDIR(stat_cached.st_mode):
+ mode = dirmode
+ mask = dirmask
+ else:
+ mode = filemode
+ mask = filemask
+
+ try:
+ applied = apply_secpass_permissions(top,
+ uid=uid, gid=gid, mode=mode, mask=mask,
+ stat_cached=stat_cached, follow_links=follow_links)
+ if not applied:
all_applied = False
- onerror(e)
+ except PortageException as e:
+ all_applied = False
+ onerror(e)
- for name in filenames:
+ for dirpath, dirnames, filenames in os.walk(top):
+ for name, mode, mask in chain(
+ ((x, filemode, filemask) for x in filenames),
+ ((x, dirmode, dirmask) for x in dirnames)):
try:
applied = apply_secpass_permissions(os.path.join(dirpath, name),
- uid=uid, gid=gid, mode=filemode, mask=filemask,
+ uid=uid, gid=gid, mode=mode, mask=mask,
follow_links=follow_links)
if not applied:
all_applied = False
@@ -1216,25 +1237,13 @@ def apply_secpass_permissions(filename, uid=-1, gid=-1, mode=-1, mask=-1,
unapplied."""
if stat_cached is None:
- try:
- if follow_links:
- stat_cached = os.stat(filename)
- else:
- stat_cached = os.lstat(filename)
- except OSError as oe:
- func_call = "stat('%s')" % filename
- if oe.errno == errno.EPERM:
- raise OperationNotPermitted(func_call)
- elif oe.errno == errno.EACCES:
- raise PermissionDenied(func_call)
- elif oe.errno == errno.ENOENT:
- raise FileNotFound(filename)
- else:
- raise
+ stat_cached = _do_stat(filename, follow_links=follow_links)
all_applied = True
- if portage.data.secpass < 2:
+ # Avoid accessing portage.data.secpass when possible, since
+ # it triggers config loading (undesirable for chmod-lite).
+ if (uid != -1 or gid != -1) and portage.data.secpass < 2:
if uid != -1 and \
uid != stat_cached.st_uid:
diff --git a/pym/repoman/_subprocess.py b/pym/repoman/_subprocess.py
index 5449e64ff..dcdc985fe 100644
--- a/pym/repoman/_subprocess.py
+++ b/pym/repoman/_subprocess.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
import codecs
diff --git a/pym/repoman/_xml.py b/pym/repoman/_xml.py
index 7bf6698c6..0acda28e6 100644
--- a/pym/repoman/_xml.py
+++ b/pym/repoman/_xml.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
import sys
import xml
diff --git a/pym/repoman/actions.py b/pym/repoman/actions.py
index 54622487a..f4617036e 100644
--- a/pym/repoman/actions.py
+++ b/pym/repoman/actions.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
from __future__ import print_function, unicode_literals
@@ -172,7 +173,7 @@ class Actions(object):
digestgen(mysettings=self.repoman_settings, myportdb=self.repo_settings.portdb)
if self.repo_settings.sign_manifests:
- self.sign_manifests(myupdates, myremoved, mymanifests)
+ self.sign_manifest(myupdates, myremoved, mymanifests)
if self.vcs_settings.vcs == 'git':
# It's not safe to use the git commit -a option since there might
diff --git a/pym/repoman/argparser.py b/pym/repoman/argparser.py
index 1c9bd4582..0f34ed01c 100644
--- a/pym/repoman/argparser.py
+++ b/pym/repoman/argparser.py
@@ -10,6 +10,7 @@ import sys
# import our initialized portage instance
from repoman._portage import portage
+from portage import _unicode_decode
from portage import util
from portage.util._argparse import ArgumentParser
@@ -210,6 +211,9 @@ def parse_args(argv, qahelp, repoman_default_opts):
logger = logging.getLogger()
logger.setLevel(logger.getEffectiveLevel() + 10)
+ if opts.mode == 'commit' and opts.commitmsg:
+ opts.commitmsg = _unicode_decode(opts.commitmsg)
+
if opts.mode == 'commit' and not (opts.force or opts.pretend):
if opts.ignore_masked:
opts.ignore_masked = False
diff --git a/pym/repoman/check_missingslot.py b/pym/repoman/check_missingslot.py
index 3f79435b6..4a3c57b2c 100644
--- a/pym/repoman/check_missingslot.py
+++ b/pym/repoman/check_missingslot.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
# repoman: missing slot check
# Copyright 2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
diff --git a/pym/repoman/checks/directories/files.py b/pym/repoman/checks/directories/files.py
index b1d77df49..9bb560c78 100644
--- a/pym/repoman/checks/directories/files.py
+++ b/pym/repoman/checks/directories/files.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
'''repoman/checks/diretories/files.py
diff --git a/pym/repoman/checks/ebuilds/checks.py b/pym/repoman/checks/ebuilds/checks.py
index 5ebc6c1aa..245ab2b01 100644
--- a/pym/repoman/checks/ebuilds/checks.py
+++ b/pym/repoman/checks/ebuilds/checks.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
# repoman: Checks
# Copyright 2007-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
diff --git a/pym/repoman/checks/ebuilds/errors.py b/pym/repoman/checks/ebuilds/errors.py
index d5c8d2e97..3090de0d1 100644
--- a/pym/repoman/checks/ebuilds/errors.py
+++ b/pym/repoman/checks/ebuilds/errors.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
# repoman: Error Messages
# Copyright 2007-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
diff --git a/pym/repoman/checks/ebuilds/fetches.py b/pym/repoman/checks/ebuilds/fetches.py
index 077340dd8..32da21ac2 100644
--- a/pym/repoman/checks/ebuilds/fetches.py
+++ b/pym/repoman/checks/ebuilds/fetches.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
'''fetches.py
Performs the src_uri fetchlist and files checks
diff --git a/pym/repoman/checks/ebuilds/isebuild.py b/pym/repoman/checks/ebuilds/isebuild.py
index f0c9a48cc..3992c9c10 100644
--- a/pym/repoman/checks/ebuilds/isebuild.py
+++ b/pym/repoman/checks/ebuilds/isebuild.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
import stat
diff --git a/pym/repoman/checks/ebuilds/keywords.py b/pym/repoman/checks/ebuilds/keywords.py
index 235c75154..9d2585e46 100644
--- a/pym/repoman/checks/ebuilds/keywords.py
+++ b/pym/repoman/checks/ebuilds/keywords.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
'''keywords.py
Perform KEYWORDS related checks
diff --git a/pym/repoman/checks/ebuilds/manifests.py b/pym/repoman/checks/ebuilds/manifests.py
index 3b8dec5ac..1ca4f94fd 100644
--- a/pym/repoman/checks/ebuilds/manifests.py
+++ b/pym/repoman/checks/ebuilds/manifests.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
import logging
import sys
diff --git a/pym/repoman/checks/ebuilds/misc.py b/pym/repoman/checks/ebuilds/misc.py
index d73554272..e2bef34de 100644
--- a/pym/repoman/checks/ebuilds/misc.py
+++ b/pym/repoman/checks/ebuilds/misc.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
'''repoman/checks/ebuilds/misc.py
Miscelaneous ebuild check functions'''
diff --git a/pym/repoman/checks/ebuilds/pkgmetadata.py b/pym/repoman/checks/ebuilds/pkgmetadata.py
index 8dc3f60d8..f22ef1958 100644
--- a/pym/repoman/checks/ebuilds/pkgmetadata.py
+++ b/pym/repoman/checks/ebuilds/pkgmetadata.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
'''Package Metadata Checks operations'''
diff --git a/pym/repoman/checks/ebuilds/thirdpartymirrors.py b/pym/repoman/checks/ebuilds/thirdpartymirrors.py
index 061e71f5d..848dfb9f0 100644
--- a/pym/repoman/checks/ebuilds/thirdpartymirrors.py
+++ b/pym/repoman/checks/ebuilds/thirdpartymirrors.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
# import our initialized portage instance
from repoman._portage import portage
diff --git a/pym/repoman/checks/ebuilds/use_flags.py b/pym/repoman/checks/ebuilds/use_flags.py
index 73680d078..ac21b47b6 100644
--- a/pym/repoman/checks/ebuilds/use_flags.py
+++ b/pym/repoman/checks/ebuilds/use_flags.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
'''use_flags.py
Performs USE flag related checks
diff --git a/pym/repoman/checks/herds/metadata.py b/pym/repoman/checks/herds/metadata.py
index 3c67fcf36..b4a433ed7 100644
--- a/pym/repoman/checks/herds/metadata.py
+++ b/pym/repoman/checks/herds/metadata.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
class UnknownHerdsError(ValueError):
diff --git a/pym/repoman/copyrights.py b/pym/repoman/copyrights.py
index 056cfda09..761309af6 100644
--- a/pym/repoman/copyrights.py
+++ b/pym/repoman/copyrights.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
import difflib
diff --git a/pym/repoman/ebuild.py b/pym/repoman/ebuild.py
index 1dddfb940..fdfb08383 100644
--- a/pym/repoman/ebuild.py
+++ b/pym/repoman/ebuild.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
from portage import os
diff --git a/pym/repoman/errors.py b/pym/repoman/errors.py
index 305eecef1..2ea46803b 100644
--- a/pym/repoman/errors.py
+++ b/pym/repoman/errors.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
import sys
diff --git a/pym/repoman/gpg.py b/pym/repoman/gpg.py
index 90fe74904..26e243201 100644
--- a/pym/repoman/gpg.py
+++ b/pym/repoman/gpg.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
from __future__ import print_function, unicode_literals
diff --git a/pym/repoman/main.py b/pym/repoman/main.py
index e2325584e..00d48e70d 100755
--- a/pym/repoman/main.py
+++ b/pym/repoman/main.py
@@ -1,4 +1,5 @@
#!/usr/bin/python -bO
+# -*- coding:utf-8 -*-
# Copyright 1999-2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
diff --git a/pym/repoman/metadata.py b/pym/repoman/metadata.py
index f2b63a77c..70c07a874 100644
--- a/pym/repoman/metadata.py
+++ b/pym/repoman/metadata.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
import errno
import logging
diff --git a/pym/repoman/modules/commit/repochecks.py b/pym/repoman/modules/commit/repochecks.py
index 8019e283d..163466d4a 100644
--- a/pym/repoman/modules/commit/repochecks.py
+++ b/pym/repoman/modules/commit/repochecks.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
from __future__ import print_function, unicode_literals
diff --git a/pym/repoman/profile.py b/pym/repoman/profile.py
index 3634fb936..50da91728 100644
--- a/pym/repoman/profile.py
+++ b/pym/repoman/profile.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
from __future__ import print_function, unicode_literals
diff --git a/pym/repoman/qa_data.py b/pym/repoman/qa_data.py
index b26559c24..dddfb98ba 100644
--- a/pym/repoman/qa_data.py
+++ b/pym/repoman/qa_data.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
import logging
diff --git a/pym/repoman/repos.py b/pym/repoman/repos.py
index f16bf7a37..9a62e0519 100644
--- a/pym/repoman/repos.py
+++ b/pym/repoman/repos.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
import io
@@ -60,7 +61,7 @@ class RepoSettings(object):
if self.repo_config.allow_provide_virtual:
qawarnings.add("virtual.oldstyle")
- if self.repo_config.sign_commit:
+ if self.repo_config.sign_commit and options.mode in ("commit", "fix", "manifest"):
if vcs_settings.vcs:
func = getattr(self, '_vcs_gpg_%s' % vcs_settings.vcs)
func()
diff --git a/pym/repoman/scan.py b/pym/repoman/scan.py
index fef6d8295..0b74efd82 100644
--- a/pym/repoman/scan.py
+++ b/pym/repoman/scan.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
import logging
import os
@@ -167,4 +168,5 @@ class Changes(object):
with repoman_popen("hg status --no-status --removed .") as f:
removed = f.readlines()
self.removed = ["./" + elem.rstrip() for elem in removed]
- del changed, new, removed
+ del removed
+ del changed, new
diff --git a/pym/repoman/scanner.py b/pym/repoman/scanner.py
index 1e1a38e39..df46144e2 100644
--- a/pym/repoman/scanner.py
+++ b/pym/repoman/scanner.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
from __future__ import print_function, unicode_literals
@@ -632,7 +633,7 @@ class Scanner(object):
continue
# we are testing deps for a masked package; give it some lee-way
suffix = "masked"
- matchmode = "minimum-all"
+ matchmode = "minimum-all-ignore-profile"
else:
suffix = ""
matchmode = "minimum-visible"
@@ -688,15 +689,27 @@ class Scanner(object):
# if we emptied out our list, continue:
if not atoms:
continue
+ if self.options.output_style in ['column']:
+ self.qatracker.add_error(mykey,
+ "%s: %s: %s(%s) %s"
+ % (ebuild.relative_path, mytype, keyword,
+ prof, repr(atoms)))
+ else:
+ self.qatracker.add_error(mykey,
+ "%s: %s: %s(%s)\n%s"
+ % (ebuild.relative_path, mytype, keyword,
+ prof, pformat(atoms, indent=6)))
+ else:
+ if self.options.output_style in ['column']:
+ self.qatracker.add_error(mykey,
+ "%s: %s: %s(%s) %s"
+ % (ebuild.relative_path, mytype, keyword,
+ prof, repr(atoms)))
+ else:
self.qatracker.add_error(mykey,
"%s: %s: %s(%s)\n%s"
- % (ebuild.relative_path, mytype, keyword, prof,
- pformat(atoms, indent=6)))
- else:
- self.qatracker.add_error(mykey,
- "%s: %s: %s(%s)\n%s"
- % (ebuild.relative_path, mytype, keyword, prof,
- pformat(atoms, indent=6)))
+ % (ebuild.relative_path, mytype, keyword,
+ prof, pformat(atoms, indent=6)))
if not baddepsyntax and unknown_pkgs:
type_map = {}
diff --git a/pym/repoman/utilities.py b/pym/repoman/utilities.py
index 2a1f4d909..47b5aabcb 100644
--- a/pym/repoman/utilities.py
+++ b/pym/repoman/utilities.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
# repoman: Utilities
# Copyright 2007-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
diff --git a/pym/repoman/vcs/vcs.py b/pym/repoman/vcs/vcs.py
index 9b77e8eb5..49d305891 100644
--- a/pym/repoman/vcs/vcs.py
+++ b/pym/repoman/vcs/vcs.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
from __future__ import print_function, unicode_literals
diff --git a/pym/repoman/vcs/vcsstatus.py b/pym/repoman/vcs/vcsstatus.py
index 30e00ad53..4dc633eb5 100644
--- a/pym/repoman/vcs/vcsstatus.py
+++ b/pym/repoman/vcs/vcsstatus.py
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
# import our initialized portage instance
diff --git a/setup.py b/setup.py
index ec43cfdb0..fda95dbe3 100755
--- a/setup.py
+++ b/setup.py
@@ -612,7 +612,7 @@ def get_manpages():
setup(
name = 'portage',
- version = '2.2.22',
+ version = '2.2.23',
url = 'https://wiki.gentoo.org/wiki/Project:Portage',
author = 'Gentoo Portage Development Team',
author_email = 'dev-portage@gentoo.org',