summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbin/misc-functions.sh8
-rw-r--r--man/make.conf.56
-rw-r--r--pym/_emerge/AbstractEbuildProcess.py14
-rw-r--r--pym/_emerge/Binpkg.py20
-rw-r--r--pym/_emerge/BinpkgVerifier.py34
-rw-r--r--pym/_emerge/EbuildBuild.py15
-rw-r--r--pym/_emerge/EbuildFetcher.py11
-rw-r--r--pym/_emerge/EbuildPhase.py34
-rw-r--r--pym/_emerge/MetadataRegen.py6
-rw-r--r--pym/_emerge/PackageUninstall.py13
-rw-r--r--pym/_emerge/PollScheduler.py38
-rw-r--r--pym/_emerge/QueueScheduler.py6
-rw-r--r--pym/_emerge/Scheduler.py40
-rw-r--r--pym/_emerge/SpawnProcess.py16
-rw-r--r--pym/portage/const.py3
-rw-r--r--pym/portage/package/ebuild/doebuild.py10
-rw-r--r--pym/portage/package/ebuild/prepare_build_dirs.py29
17 files changed, 132 insertions, 171 deletions
diff --git a/bin/misc-functions.sh b/bin/misc-functions.sh
index 3a199bdf7..123edc0ec 100755
--- a/bin/misc-functions.sh
+++ b/bin/misc-functions.sh
@@ -474,10 +474,12 @@ install_qa_check() {
)
abort="no"
i=0
+ local grep_cmd=grep
+ [[ $PORTAGE_LOG_FILE = *.gz ]] && grep_cmd=zgrep
while [[ -n ${msgs[${i}]} ]] ; do
m=${msgs[$((i++))]}
# force C locale to work around slow unicode locales #160234
- f=$(LC_ALL=C grep "${m}" "${PORTAGE_LOG_FILE}")
+ f=$(LC_ALL=C $grep_cmd "${m}" "${PORTAGE_LOG_FILE}")
if [[ -n ${f} ]] ; then
vecho -ne '\a\n'
eqawarn "QA Notice: Package has poor programming practices which may compile"
@@ -487,8 +489,10 @@ install_qa_check() {
abort="yes"
fi
done
+ local cat_cmd=cat
+ [[ $PORTAGE_LOG_FILE = *.gz ]] && cat_cmd=zcat
[[ $reset_debug = 1 ]] && set -x
- f=$(cat "${PORTAGE_LOG_FILE}" | \
+ f=$($cat_cmd "${PORTAGE_LOG_FILE}" | \
"${PORTAGE_PYTHON:-/usr/bin/python}" "$PORTAGE_BIN_PATH"/check-implicit-pointer-usage.py || die "check-implicit-pointer-usage.py failed")
if [[ -n ${f} ]] ; then
diff --git a/man/make.conf.5 b/man/make.conf.5
index 0827db11a..74b24576b 100644
--- a/man/make.conf.5
+++ b/man/make.conf.5
@@ -231,6 +231,12 @@ A QA\-feature to ensure that a package doesn't overwrite files it doesn't own.
The \fICOLLISION_IGNORE\fR variable can be used to selectively disable this
feature. Also see the related \fIprotect\-owned\fR feature.
.TP
+.B compress\-build\-logs
+The causes all build logs to be compressed while they are being written.
+Log file names have an extension that is appropriate for the compression
+type. Currently, only \fBgzip\fR(1) compression is supported, so build
+logs will have a '.gz' extension when this feature is enabled.
+.TP
.B digest
Autogenerate digests for packages when running the \fBemerge\fR(1) command. If
the \fIassume\-digests\fR feature is also enabled then existing SRC_URI digests
diff --git a/pym/_emerge/AbstractEbuildProcess.py b/pym/_emerge/AbstractEbuildProcess.py
index aca254191..8c87812f5 100644
--- a/pym/_emerge/AbstractEbuildProcess.py
+++ b/pym/_emerge/AbstractEbuildProcess.py
@@ -183,21 +183,11 @@ class AbstractEbuildProcess(SpawnProcess):
phase = self.phase
for line in lines:
eerror(line, phase=phase, key=self.settings.mycpv, out=out)
- logfile = self.logfile
- if logfile is None:
- logfile = self.settings.get("PORTAGE_LOG_FILE")
msg = _unicode_decode(out.getvalue(),
encoding=_encodings['content'], errors='replace')
if msg:
- if not self.background:
- writemsg_stdout(msg, noiselevel=-1)
- if logfile is not None:
- log_file = codecs.open(_unicode_encode(logfile,
- encoding=_encodings['fs'], errors='strict'),
- mode='a', encoding=_encodings['content'],
- errors='backslashreplace')
- log_file.write(msg)
- log_file.close()
+ self.scheduler.output(msg,
+ log_path=self.settings.get("PORTAGE_LOG_FILE"))
def _set_returncode(self, wait_retval):
SpawnProcess._set_returncode(self, wait_retval)
diff --git a/pym/_emerge/Binpkg.py b/pym/_emerge/Binpkg.py
index 66b7bd424..2201decaf 100644
--- a/pym/_emerge/Binpkg.py
+++ b/pym/_emerge/Binpkg.py
@@ -27,20 +27,8 @@ class Binpkg(CompositeTask):
"_image_dir", "_infloc", "_pkg_path", "_tree", "_verify")
def _writemsg_level(self, msg, level=0, noiselevel=0):
-
- if not self.background:
- portage.util.writemsg_level(msg,
- level=level, noiselevel=noiselevel)
-
- log_path = self.settings.get("PORTAGE_LOG_FILE")
- if log_path is not None:
- f = codecs.open(_unicode_encode(log_path,
- encoding=_encodings['fs'], errors='strict'),
- mode='a', encoding=_encodings['content'], errors='replace')
- try:
- f.write(msg)
- finally:
- f.close()
+ self.scheduler.output(msg, level=level, noiselevel=noiselevel,
+ log_path=self.settings.get("PORTAGE_LOG_FILE"))
def _start(self):
@@ -146,9 +134,7 @@ class Binpkg(CompositeTask):
verifier = None
if self._verify:
- logfile = None
- if self.background:
- logfile = self.settings.get("PORTAGE_LOG_FILE")
+ logfile = self.settings.get("PORTAGE_LOG_FILE")
verifier = BinpkgVerifier(background=self.background,
logfile=logfile, pkg=self.pkg)
self._start_task(verifier, self._verifier_exit)
diff --git a/pym/_emerge/BinpkgVerifier.py b/pym/_emerge/BinpkgVerifier.py
index 83a02c76c..02a942c94 100644
--- a/pym/_emerge/BinpkgVerifier.py
+++ b/pym/_emerge/BinpkgVerifier.py
@@ -7,7 +7,9 @@ import sys
import portage
from portage import os
from portage import _encodings
+from portage import _unicode_decode
from portage import _unicode_encode
+from portage import StringIO
from portage.package.ebuild.fetch import _checksum_failure_temp_file
import codecs
@@ -27,27 +29,10 @@ class BinpkgVerifier(AsynchronousTask):
rval = os.EX_OK
stdout_orig = sys.stdout
stderr_orig = sys.stderr
- log_file = None
- if self.background and self.logfile is not None:
- if sys.hexversion >= 0x3000000:
- # Since we are replacing the sys.std* streams,
- # we need to use the normal open() function
- # so that we get the right class (otherwise our
- # code that expects the 'buffer' attribute
- # will break).
- log_file = open(_unicode_encode(self.logfile,
- encoding=_encodings['fs'], errors='strict'),
- mode='a', encoding=_encodings['content'],
- errors='backslashreplace')
- else:
- # For python2, sys.std* are expected to be binary streams.
- log_file = open(_unicode_encode(self.logfile,
- encoding=_encodings['fs'], errors='strict'),
- mode='ab')
+ out = portage.StringIO()
try:
- if log_file is not None:
- sys.stdout = log_file
- sys.stderr = log_file
+ sys.stdout = out
+ sys.stderr = out
try:
bintree.digestCheck(pkg)
except portage.exception.FileNotFound:
@@ -69,7 +54,7 @@ class BinpkgVerifier(AsynchronousTask):
if rval == os.EX_OK:
# If this was successful, discard the log here since otherwise
# we'll get multiple logs for the same package.
- if log_file is not None:
+ if self.logfile is not None:
try:
os.unlink(self.logfile)
except OSError:
@@ -83,8 +68,11 @@ class BinpkgVerifier(AsynchronousTask):
finally:
sys.stdout = stdout_orig
sys.stderr = stderr_orig
- if log_file is not None:
- log_file.close()
+
+ msg = _unicode_decode(out.getvalue(),
+ encoding=_encodings['content'], errors='replace')
+ if msg:
+ self.scheduler.output(msg, log_path=self.logfile)
self.returncode = rval
self.wait()
diff --git a/pym/_emerge/EbuildBuild.py b/pym/_emerge/EbuildBuild.py
index b8694df96..5c108fee4 100644
--- a/pym/_emerge/EbuildBuild.py
+++ b/pym/_emerge/EbuildBuild.py
@@ -218,19 +218,8 @@ class EbuildBuild(CompositeTask):
if self._issyspkg:
msg = ">>> This is a system package, " + \
"let's pack a rescue tarball.\n"
-
- log_path = self.settings.get("PORTAGE_LOG_FILE")
- if log_path is not None:
- log_file = codecs.open(_unicode_encode(log_path,
- encoding=_encodings['fs'], errors='strict'),
- mode='a', encoding=_encodings['content'], errors='replace')
- try:
- log_file.write(msg)
- finally:
- log_file.close()
-
- if not self.background:
- portage.writemsg_stdout(msg, noiselevel=-1)
+ self.scheduler.output(msg,
+ log_path=self.settings.get("PORTAGE_LOG_FILE"))
packager = EbuildBinpkg(background=self.background, pkg=self.pkg,
scheduler=self.scheduler, settings=self.settings)
diff --git a/pym/_emerge/EbuildFetcher.py b/pym/_emerge/EbuildFetcher.py
index 7f5bc6df4..63e423771 100644
--- a/pym/_emerge/EbuildFetcher.py
+++ b/pym/_emerge/EbuildFetcher.py
@@ -158,19 +158,10 @@ class EbuildFetcher(SpawnProcess):
out = portage.StringIO()
for line in lines:
eerror(line, phase="unpack", key=self.pkg.cpv, out=out)
- logfile = self.logfile
msg = _unicode_decode(out.getvalue(),
encoding=_encodings['content'], errors='replace')
if msg:
- if not self.background:
- writemsg_stdout(msg, noiselevel=-1)
- if logfile is not None:
- log_file = codecs.open(_unicode_encode(logfile,
- encoding=_encodings['fs'], errors='strict'),
- mode='a', encoding=_encodings['content'],
- errors='backslashreplace')
- log_file.write(msg)
- log_file.close()
+ self.scheduler.output(msg, log_path=self.logfile)
def _set_returncode(self, wait_retval):
SpawnProcess._set_returncode(self, wait_retval)
diff --git a/pym/_emerge/EbuildPhase.py b/pym/_emerge/EbuildPhase.py
index 7fbc66849..d2d4dce3a 100644
--- a/pym/_emerge/EbuildPhase.py
+++ b/pym/_emerge/EbuildPhase.py
@@ -75,24 +75,11 @@ class EbuildPhase(CompositeTask):
if self.phase == "install":
out = portage.StringIO()
- log_path = self.settings.get("PORTAGE_LOG_FILE")
- log_file = None
- if log_path is not None:
- log_file = codecs.open(_unicode_encode(log_path,
- encoding=_encodings['fs'], errors='strict'),
- mode='a', encoding=_encodings['content'], errors='replace')
- try:
- _check_build_log(self.settings, out=out)
- msg = _unicode_decode(out.getvalue(),
- encoding=_encodings['content'], errors='replace')
- if msg:
- if not self.background:
- writemsg_stdout(msg, noiselevel=-1)
- if log_file is not None:
- log_file.write(msg)
- finally:
- if log_file is not None:
- log_file.close()
+ _check_build_log(self.settings, out=out)
+ msg = _unicode_decode(out.getvalue(),
+ encoding=_encodings['content'], errors='replace')
+ self.scheduler.output(msg,
+ log_path=self.settings.get("PORTAGE_LOG_FILE"))
if fail:
self._die_hooks()
@@ -108,15 +95,8 @@ class EbuildPhase(CompositeTask):
msg = _unicode_decode(out.getvalue(),
encoding=_encodings['content'], errors='replace')
if msg:
- if not self.background:
- writemsg_stdout(msg, noiselevel=-1)
- log_path = self.settings.get("PORTAGE_LOG_FILE")
- if log_path is not None:
- log_file = codecs.open(_unicode_encode(log_path,
- encoding=_encodings['fs'], errors='strict'),
- mode='a', encoding=_encodings['content'], errors='replace')
- log_file.write(msg)
- log_file.close()
+ self.scheduler.output(msg,
+ log_path=self.settings.get("PORTAGE_LOG_FILE"))
post_phase_cmds = _post_phase_cmds.get(self.phase)
if post_phase_cmds is not None:
diff --git a/pym/_emerge/MetadataRegen.py b/pym/_emerge/MetadataRegen.py
index f819570d9..6c6dd6b90 100644
--- a/pym/_emerge/MetadataRegen.py
+++ b/pym/_emerge/MetadataRegen.py
@@ -1,4 +1,4 @@
-# Copyright 1999-2009 Gentoo Foundation
+# Copyright 1999-2010 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
import portage
@@ -26,10 +26,6 @@ class MetadataRegen(PollScheduler):
self._max_jobs = max_jobs
self._max_load = max_load
- self._sched_iface = self._sched_iface_class(
- register=self._register,
- schedule=self._schedule_wait,
- unregister=self._unregister)
self._valid_pkgs = set()
self._cp_set = set()
diff --git a/pym/_emerge/PackageUninstall.py b/pym/_emerge/PackageUninstall.py
index 6f528663a..e806bc154 100644
--- a/pym/_emerge/PackageUninstall.py
+++ b/pym/_emerge/PackageUninstall.py
@@ -42,15 +42,4 @@ class PackageUninstall(AsynchronousTask):
portage.util.writemsg_level(msg,
level=level, noiselevel=noiselevel)
else:
- if not background:
- portage.util.writemsg_level(msg,
- level=level, noiselevel=noiselevel)
-
- f = codecs.open(_unicode_encode(log_path,
- encoding=_encodings['fs'], errors='strict'),
- mode='a', encoding=_encodings['content'], errors='replace')
- try:
- f.write(msg)
- finally:
- f.close()
-
+ self.scheduler.output(msg, level=level, noiselevel=noiselevel)
diff --git a/pym/_emerge/PollScheduler.py b/pym/_emerge/PollScheduler.py
index 2a77f869e..2c9eb2a8c 100644
--- a/pym/_emerge/PollScheduler.py
+++ b/pym/_emerge/PollScheduler.py
@@ -1,10 +1,13 @@
-# Copyright 1999-2009 Gentoo Foundation
+# Copyright 1999-2010 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+import gzip
import logging
import select
import time
+from portage import _encodings
+from portage import _unicode_encode
from portage import os
from portage.util import writemsg_level
@@ -16,7 +19,7 @@ from _emerge.PollSelectAdapter import PollSelectAdapter
class PollScheduler(object):
class _sched_iface_class(SlotObject):
- __slots__ = ("register", "schedule", "unregister")
+ __slots__ = ("output", "register", "schedule", "unregister")
def __init__(self):
self._max_jobs = 1
@@ -29,6 +32,12 @@ class PollScheduler(object):
self._event_handler_id = 0
self._poll_obj = create_poll_instance()
self._scheduling = False
+ self._background = False
+ self.sched_iface = self._sched_iface_class(
+ output=self._task_output,
+ register=self._register,
+ schedule=self._schedule_wait,
+ unregister=self._unregister)
def _schedule(self):
"""
@@ -228,6 +237,31 @@ class PollScheduler(object):
return event_handled
+ def _task_output(self, msg, log_path=None, level=0, noiselevel=-1):
+ """
+ Output msg to stdout if not self._background. If log_path
+ is not None then append msg to the log (appends with
+ compression if the filename extension of log_path
+ corresponds to a supported compression type).
+ """
+
+ if not self._background:
+ writemsg_level(msg, level=level, noiselevel=noiselevel)
+
+ if log_path is not None:
+ f = open(_unicode_encode(log_path,
+ encoding=_encodings['fs'], errors='strict'),
+ mode='ab')
+
+ if log_path.endswith('.gz'):
+ # NOTE: The empty filename argument prevents us from triggering
+ # a bug in python3 which causes GzipFile to raise AttributeError
+ # if fileobj.name is bytes instead of unicode.
+ f = gzip.GzipFile(filename='', mode='ab', fileobj=f)
+
+ f.write(_unicode_encode(msg))
+ f.close()
+
_can_poll_device = None
def can_poll_device():
diff --git a/pym/_emerge/QueueScheduler.py b/pym/_emerge/QueueScheduler.py
index 8e1837c03..0e39d6ad3 100644
--- a/pym/_emerge/QueueScheduler.py
+++ b/pym/_emerge/QueueScheduler.py
@@ -1,4 +1,4 @@
-# Copyright 1999-2009 Gentoo Foundation
+# Copyright 1999-2010 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
from _emerge.PollScheduler import PollScheduler
@@ -18,10 +18,6 @@ class QueueScheduler(PollScheduler):
self._max_jobs = max_jobs
self._max_load = max_load
- self.sched_iface = self._sched_iface_class(
- register=self._register,
- schedule=self._schedule_wait,
- unregister=self._unregister)
self._queues = []
self._schedule_listeners = []
diff --git a/pym/_emerge/Scheduler.py b/pym/_emerge/Scheduler.py
index 1c732c309..aa0a40290 100644
--- a/pym/_emerge/Scheduler.py
+++ b/pym/_emerge/Scheduler.py
@@ -4,6 +4,7 @@
from __future__ import print_function
import codecs
+import gzip
import logging
import shutil
import sys
@@ -78,7 +79,8 @@ class Scheduler(PollScheduler):
class _iface_class(SlotObject):
__slots__ = ("dblinkEbuildPhase", "dblinkDisplayMerge",
- "dblinkElog", "dblinkEmergeLog", "fetch", "register", "schedule",
+ "dblinkElog", "dblinkEmergeLog", "fetch",
+ "output", "register", "schedule",
"scheduleSetup", "scheduleUnpack", "scheduleYield",
"unregister")
@@ -209,7 +211,8 @@ class Scheduler(PollScheduler):
dblinkDisplayMerge=self._dblink_display_merge,
dblinkElog=self._dblink_elog,
dblinkEmergeLog=self._dblink_emerge_log,
- fetch=fetch_iface, register=self._register,
+ fetch=fetch_iface, output=self._task_output,
+ register=self._register,
schedule=self._schedule_wait,
scheduleSetup=self._schedule_setup,
scheduleUnpack=self._schedule_unpack,
@@ -562,22 +565,9 @@ class Scheduler(PollScheduler):
installed = type_name == "installed"
return self._pkg(cpv, type_name, root_config, installed=installed)
- def _append_to_log_path(self, log_path, msg):
-
- f = codecs.open(_unicode_encode(log_path,
- encoding=_encodings['fs'], errors='strict'),
- mode='a', encoding=_encodings['content'],
- errors='backslashreplace')
- try:
- f.write(_unicode_decode(msg,
- encoding=_encodings['content'], errors='replace'))
- finally:
- f.close()
-
def _dblink_elog(self, pkg_dblink, phase, func, msgs):
log_path = pkg_dblink.settings.get("PORTAGE_LOG_FILE")
- background = self._background
out = StringIO()
for msg in msgs:
@@ -585,11 +575,7 @@ class Scheduler(PollScheduler):
out_str = out.getvalue()
- if not background:
- portage.util.writemsg_stdout(out_str, noiselevel=-1)
-
- if log_path is not None:
- self._append_to_log_path(log_path, out_str)
+ self._task_output(out_str, log_path=log_path)
def _dblink_emerge_log(self, msg):
self._logger.log(msg)
@@ -603,10 +589,7 @@ class Scheduler(PollScheduler):
portage.util.writemsg_level(msg,
level=level, noiselevel=noiselevel)
else:
- if not background:
- portage.util.writemsg_level(msg,
- level=level, noiselevel=noiselevel)
- self._append_to_log_path(log_path, msg)
+ self._task_output(msg, log_path=log_path)
def _dblink_ebuild_phase(self,
pkg_dblink, pkg_dbapi, ebuild_path, phase):
@@ -1100,11 +1083,14 @@ class Scheduler(PollScheduler):
log_path = self._locate_failure_log(failed_pkg)
if log_path is not None:
try:
- log_file = codecs.open(_unicode_encode(log_path,
- encoding=_encodings['fs'], errors='strict'),
- mode='r', encoding=_encodings['content'], errors='replace')
+ log_file = open(_unicode_encode(log_path,
+ encoding=_encodings['fs'], errors='strict'), mode='rb')
except IOError:
pass
+ else:
+ if log_path.endswith('.gz'):
+ log_file = gzip.GzipFile(filename='',
+ mode='rb', fileobj=log_file)
if log_file is not None:
try:
diff --git a/pym/_emerge/SpawnProcess.py b/pym/_emerge/SpawnProcess.py
index 6e0586815..aeb206a06 100644
--- a/pym/_emerge/SpawnProcess.py
+++ b/pym/_emerge/SpawnProcess.py
@@ -6,10 +6,13 @@ from _emerge.PollConstants import PollConstants
import sys
from portage.cache.mappings import slot_dict_class
import portage
+from portage import _encodings
+from portage import _unicode_encode
from portage import os
import fcntl
import errno
import array
+import gzip
class SpawnProcess(SubProcess):
@@ -77,7 +80,12 @@ class SpawnProcess(SubProcess):
fd_pipes[1] = slave_fd
fd_pipes[2] = slave_fd
- files.log = open(logfile, mode='ab')
+ files.log = open(_unicode_encode(logfile,
+ encoding=_encodings['fs'], errors='strict'), mode='ab')
+ if logfile.endswith('.gz'):
+ files.log = gzip.GzipFile(filename='', mode='ab',
+ fileobj=files.log)
+
portage.util.apply_secpass_permissions(logfile,
uid=portage.portage_uid, gid=portage.portage_gid,
mode=0o660)
@@ -188,7 +196,11 @@ class SpawnProcess(SubProcess):
fcntl.fcntl(files.stdout.fileno(),
fcntl.F_GETFL) ^ os.O_NONBLOCK)
- buf.tofile(files.log)
+ try:
+ buf.tofile(files.log)
+ except TypeError:
+ # array.tofile() doesn't work with GzipFile
+ files.log.write(buf.tostring())
files.log.flush()
else:
self._unregister()
diff --git a/pym/portage/const.py b/pym/portage/const.py
index 62d3ceaf2..bd2c5be8d 100644
--- a/pym/portage/const.py
+++ b/pym/portage/const.py
@@ -85,7 +85,8 @@ EBUILD_PHASES = ("pretend", "setup", "unpack", "prepare", "configure"
"nofetch", "config", "info", "other")
SUPPORTED_FEATURES = frozenset([
"assume-digests", "buildpkg", "buildsyspkg", "ccache",
- "collision-protect", "digest", "distcc", "distlocks",
+ "collision-protect", "compress-build-logs",
+ "digest", "distcc", "distlocks",
"fakeroot", "fail-clean", "fixpackages", "getbinpkg",
"installsources", "keeptemp", "keepwork", "fixlafiles", "lmirror",
"metadata-transfer", "mirror", "multilib-strict", "news",
diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py
index 21f716beb..b340e2759 100644
--- a/pym/portage/package/ebuild/doebuild.py
+++ b/pym/portage/package/ebuild/doebuild.py
@@ -5,6 +5,7 @@ __all__ = ['doebuild', 'doebuild_environment', 'spawn', 'spawnebuild']
import codecs
import errno
+import gzip
from itertools import chain
import logging
import os as _os
@@ -1179,12 +1180,14 @@ def _check_build_log(mysettings, out=None):
if logfile is None:
return
try:
- f = codecs.open(_unicode_encode(logfile,
- encoding=_encodings['fs'], errors='strict'),
- mode='r', encoding=_encodings['content'], errors='replace')
+ f = open(_unicode_encode(logfile, encoding=_encodings['fs'],
+ errors='strict'), mode='rb')
except EnvironmentError:
return
+ if logfile.endswith('.gz'):
+ f = gzip.GzipFile(filename='', mode='rb', fileobj=f)
+
am_maintainer_mode = []
bash_command_not_found = []
bash_command_not_found_re = re.compile(
@@ -1212,6 +1215,7 @@ def _check_build_log(mysettings, out=None):
try:
for line in f:
+ line = _unicode_decode(line)
if am_maintainer_mode_re.search(line) is not None and \
am_maintainer_mode_exclude_re.search(line) is None:
am_maintainer_mode.append(line.rstrip("\n"))
diff --git a/pym/portage/package/ebuild/prepare_build_dirs.py b/pym/portage/package/ebuild/prepare_build_dirs.py
index 0ae60342f..25e5beb6e 100644
--- a/pym/portage/package/ebuild/prepare_build_dirs.py
+++ b/pym/portage/package/ebuild/prepare_build_dirs.py
@@ -3,8 +3,8 @@
__all__ = ['prepare_build_dirs']
-import codecs
import errno
+import gzip
import shutil
import stat
import time
@@ -117,15 +117,17 @@ def _adjust_perms_msg(settings, msg):
if background and log_path is not None:
try:
- log_file = codecs.open(_unicode_encode(log_path,
- encoding=_encodings['fs'], errors='strict'),
- mode='a', encoding=_encodings['content'], errors='replace')
+ log_file = open(_unicode_encode(log_path,
+ encoding=_encodings['fs'], errors='strict'), mode='ab')
except IOError:
def write(msg):
pass
else:
+ if log_path.endswith('.gz'):
+ log_file = gzip.GzipFile(filename='',
+ mode='ab', fileobj=log_file)
def write(msg):
- log_file.write(_unicode_decode(msg))
+ log_file.write(_unicode_encode(msg))
log_file.flush()
try:
@@ -281,6 +283,11 @@ def _prepare_workdir(mysettings):
writemsg(_("!!! Disabling logging.\n"), noiselevel=-1)
while "PORT_LOGDIR" in mysettings:
del mysettings["PORT_LOGDIR"]
+
+ compress_log_ext = ''
+ if 'compress-build-logs' in mysettings.features:
+ compress_log_ext = '.gz'
+
if "PORT_LOGDIR" in mysettings and \
os.access(mysettings["PORT_LOGDIR"], os.W_OK):
logid_path = os.path.join(mysettings["PORTAGE_BUILDDIR"], ".logid")
@@ -292,12 +299,14 @@ def _prepare_workdir(mysettings):
if "split-log" in mysettings.features:
mysettings["PORTAGE_LOG_FILE"] = os.path.join(
- mysettings["PORT_LOGDIR"], "build", "%s/%s:%s.log" % \
- (mysettings["CATEGORY"], mysettings["PF"], logid_time))
+ mysettings["PORT_LOGDIR"], "build", "%s/%s:%s.log%s" % \
+ (mysettings["CATEGORY"], mysettings["PF"], logid_time,
+ compress_log_ext))
else:
mysettings["PORTAGE_LOG_FILE"] = os.path.join(
- mysettings["PORT_LOGDIR"], "%s:%s:%s.log" % \
- (mysettings["CATEGORY"], mysettings["PF"], logid_time))
+ mysettings["PORT_LOGDIR"], "%s:%s:%s.log%s" % \
+ (mysettings["CATEGORY"], mysettings["PF"], logid_time,
+ compress_log_ext))
ensure_dirs(os.path.dirname(mysettings["PORTAGE_LOG_FILE"]))
@@ -307,4 +316,4 @@ def _prepare_workdir(mysettings):
# current policy will allow it to work when a pty is available, but
# not through a normal pipe. See bug #162404.
mysettings["PORTAGE_LOG_FILE"] = os.path.join(
- mysettings["T"], "build.log")
+ mysettings["T"], "build.log%s" % compress_log_ext)