diff options
author | Thomas Sachau <tommy@gentoo.org> | 2016-02-28 13:35:46 +0100 |
---|---|---|
committer | Thomas Sachau <tommy@gentoo.org> | 2016-02-28 13:35:46 +0100 |
commit | 58fb9ace0cb1bf49df2ce68b13999d303fa25756 (patch) | |
tree | d3b6824e35abaab0aba527d4d6a56289e7033c99 | |
parent | merge v2.2.26 (diff) | |
parent | Updates for the release (diff) | |
download | portage-58fb9ace.tar.gz portage-58fb9ace.tar.bz2 portage-58fb9ace.zip |
merge v2.2.27
55 files changed, 445 insertions, 269 deletions
@@ -1,5 +1,11 @@ News (mainly features/major bug fixes) + +portage-2.2.26 +-------------- +* EAPI 6 stable portage release + + portage-2.2.25 -------------- * EAPI 6 final fully implemented. diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 6a81495df..6e3e5910d 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,6 +1,30 @@ Release Notes; upgrade information mainly. Features/major bugfixes are listed in NEWS +portage-2.2.27 +================================== +* Bug Fixes: + - Bug 532224 Fixes commit 28828655da86 @profile pkg set support + - Bug 566024 Fix logic when deep is True + - Bug 567932 SyncManager.sync: always return 4-tuple + - Bug 561686 _dep_check_composite_db._visible: verify that highest_visible + matches + - Bug 567920 Manifest._apply_max_mtime: account for removals and renames + - Bug 567746 repoman: use metadata.dtd from rsync tree if available + - Bug 568354 depgraph._resolve: consider unresolved @system atoms fatal + - Bug 567360 doebuild: Support finding lib* for ccache/distcc/icecc + masquerade dir + - Bug 568054 repoman: Do not check for PATCHES array in EAPI 6 and later. + - Bug 568934 flat_hash: enable md5 validation for /var/cache/edb/dep + - Bug 569942 elog/mod_save: fix CATEGORY KeyError + - Bug 486362 repoman: add clutter to inherit.deprecated + - Bug 562652 emaint/.../merges: Rename --purge-tracker option + - Bug 570530 INSTALL_MASK: enable matching of broken symlinks + - Bug 570672 emerge: Add --autounmask-only parameter + - Bug 570798 support bsddb3 module + + + portage-2.2.26 ================================== * Bug Fixes: @@ -13,6 +37,7 @@ portage-2.2.26 - Bug 566704 depgraph: autounmask for conditional USE deps * other EAPI 6 code changes: eapply_user, several corrections + portage-2.2.25 ================================== * Bug Fixes: diff --git a/bin/ebuild b/bin/ebuild index 59fced08c..1f99177d8 100755 --- a/bin/ebuild +++ b/bin/ebuild @@ -1,5 +1,5 @@ #!/usr/bin/python -bO -# Copyright 1999-2014 Gentoo Foundation +# Copyright 1999-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 from __future__ import print_function @@ -8,6 +8,8 @@ import argparse import platform import signal import sys +import textwrap + # This block ensures that ^C interrupts are handled quietly. try: @@ -49,6 +51,9 @@ from portage import _shell_quote from portage import _unicode_decode from portage import _unicode_encode from portage.const import VDB_PATH +from portage.exception import PermissionDenied, PortageKeyError, \ + PortagePackageException, UnsupportedAPIException +import portage.util from _emerge.Package import Package from _emerge.RootConfig import RootConfig @@ -95,8 +100,6 @@ if not opts.ignore_default_opts: debug = opts.debug force = opts.force -import portage.util, portage.const - # do this _after_ 'import portage' to prevent unnecessary tracing if debug and "python-trace" in portage.features: import portage.debug @@ -273,7 +276,7 @@ try: metadata = dict(zip(Package.metadata_keys, portage.db[portage.settings['EROOT']][mytree].dbapi.aux_get( cpv, Package.metadata_keys, myrepo=myrepo))) -except KeyError: +except PortageKeyError: # aux_get failure, message should have been shown on stderr. sys.exit(1) @@ -304,8 +307,7 @@ def stale_env_warning(): msg = ("Existing ${T}/environment for '%s' will be sourced. " + \ "Run 'clean' to start with a fresh environment.") % \ (tmpsettings["PF"], ) - from textwrap import wrap - msg = wrap(msg, 70) + msg = textwrap.wrap(msg, 70) for x in msg: portage.writemsg(">>> %s\n" % x) @@ -313,9 +315,6 @@ def stale_env_warning(): open(os.path.join(tmpsettings['PORTAGE_BUILDDIR'], '.ebuild_changed'), 'w').close() -from portage.exception import PermissionDenied, \ - PortagePackageException, UnsupportedAPIException - if 'digest' in tmpsettings.features: if pargs and pargs[0] not in ("digest", "manifest"): pargs = ['digest'] + pargs @@ -344,8 +343,7 @@ for arg in pargs: # aux_get error a = 1 except UnsupportedAPIException as e: - from textwrap import wrap - msg = wrap(str(e), 70) + msg = textwrap.wrap(str(e), 70) del e for x in msg: portage.writemsg("!!! %s\n" % x, noiselevel=-1) diff --git a/bin/ebuild.sh b/bin/ebuild.sh index 0dd971bf4..65fad17f4 100755 --- a/bin/ebuild.sh +++ b/bin/ebuild.sh @@ -708,31 +708,6 @@ if ! has "$EBUILD_PHASE" clean cleanrm ; then [[ -n $CCACHE_SIZE ]] && ccache -M $CCACHE_SIZE &> /dev/null fi - - if [[ -n $QA_PREBUILT ]] ; then - - # these ones support fnmatch patterns - QA_EXECSTACK+=" $QA_PREBUILT" - QA_TEXTRELS+=" $QA_PREBUILT" - QA_WX_LOAD+=" $QA_PREBUILT" - - # these ones support regular expressions, so translate - # fnmatch patterns to regular expressions - for x in QA_DT_NEEDED QA_FLAGS_IGNORED QA_PRESTRIPPED QA_SONAME ; do - if [[ $(declare -p $x 2>/dev/null) = declare\ -a* ]] ; then - eval "$x=(\"\${$x[@]}\" ${QA_PREBUILT//\*/.*})" - else - eval "$x+=\" ${QA_PREBUILT//\*/.*}\"" - fi - done - - unset x - fi - - # This needs to be exported since prepstrip is a separate shell script. - [[ -n $QA_PRESTRIPPED ]] && export QA_PRESTRIPPED - eval "[[ -n \$QA_PRESTRIPPED_${ARCH/-/_} ]] && \ - export QA_PRESTRIPPED_${ARCH/-/_}" fi fi fi diff --git a/bin/egencache b/bin/egencache index ab36bbea7..7e3387ed9 100755 --- a/bin/egencache +++ b/bin/egencache @@ -1,5 +1,5 @@ #!/usr/bin/python -b -# Copyright 2009-2014 Gentoo Foundation +# Copyright 2009-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # unicode_literals for compat with TextIOWrapper in Python 2 @@ -113,12 +113,6 @@ def parse_args(args): common.add_argument("--gpg-key", help="override the PORTAGE_GPG_KEY variable", dest="gpg_key") - common.add_argument("--portdir", - help="override the PORTDIR variable (deprecated in favor of --repositories-configuration)", - dest="portdir") - common.add_argument("--portdir-overlay", - help="override the PORTDIR_OVERLAY variable (deprecated in favor of --repositories-configuration)", - dest="portdir_overlay") common.add_argument("--repositories-configuration", help="override configuration of repositories (in format of repos.conf)", dest="repositories_configuration") @@ -226,13 +220,6 @@ def parse_args(args): parser.error("Write access denied: --cache-dir='%s'" % \ (options.cache_dir,)) - if options.portdir is not None: - writemsg_level("egencache: warning: --portdir option is deprecated in favor of --repositories-configuration option\n", - level=logging.WARNING, noiselevel=-1) - if options.portdir_overlay is not None: - writemsg_level("egencache: warning: --portdir-overlay option is deprecated in favor of --repositories-configuration option\n", - level=logging.WARNING, noiselevel=-1) - for atom in args: try: atom = portage.dep.Atom(atom) @@ -949,15 +936,10 @@ def egencache_main(args): if options.repositories_configuration is not None: env['PORTAGE_REPOSITORIES'] = options.repositories_configuration - elif options.portdir_overlay is not None: - env['PORTDIR_OVERLAY'] = options.portdir_overlay if options.cache_dir is not None: env['PORTAGE_DEPCACHEDIR'] = options.cache_dir - if options.portdir is not None: - env['PORTDIR'] = options.portdir - settings = portage.config(config_root=config_root, local_config=False, env=env) diff --git a/bin/misc-functions.sh b/bin/misc-functions.sh index 84f01c1c8..46115a4ff 100755 --- a/bin/misc-functions.sh +++ b/bin/misc-functions.sh @@ -278,7 +278,8 @@ install_mask() { # The standard case where $no_inst is something that # the shell could expand on its own. - if [[ -e "${root}"/${no_inst} || "${root}"/${no_inst} != $(echo "${root}"/${no_inst}) ]] ; then + if [[ -e "${root}"/${no_inst} || -L "${root}"/${no_inst} || + "${root}"/${no_inst} != $(echo "${root}"/${no_inst}) ]] ; then __quiet_mode || einfo "Removing ${no_inst}" rm -Rf "${root}"/${no_inst} >&/dev/null fi diff --git a/bin/phase-functions.sh b/bin/phase-functions.sh index 96ed3391e..858f713cf 100644 --- a/bin/phase-functions.sh +++ b/bin/phase-functions.sh @@ -599,6 +599,33 @@ __dyn_install() { trap "__abort_install" SIGINT SIGQUIT __start_distcc + # Handle setting QA_* based on QA_PREBUILT + # Those variables shouldn't be needed before src_install() + # (QA_PRESTRIPPED is used in prepstrip, others in install-qa-checks) + # and delay in setting them allows us to set them in pkg_setup() + if [[ -n $QA_PREBUILT ]] ; then + # these ones support fnmatch patterns + QA_EXECSTACK+=" $QA_PREBUILT" + QA_TEXTRELS+=" $QA_PREBUILT" + QA_WX_LOAD+=" $QA_PREBUILT" + + # these ones support regular expressions, so translate + # fnmatch patterns to regular expressions + for x in QA_DT_NEEDED QA_FLAGS_IGNORED QA_PRESTRIPPED QA_SONAME ; do + if [[ $(declare -p $x 2>/dev/null) = declare\ -a* ]] ; then + eval "$x=(\"\${$x[@]}\" ${QA_PREBUILT//\*/.*})" + else + eval "$x+=\" ${QA_PREBUILT//\*/.*}\"" + fi + done + + unset x + fi + # This needs to be exported since prepstrip is a separate shell script. + [[ -n $QA_PRESTRIPPED ]] && export QA_PRESTRIPPED + eval "[[ -n \$QA_PRESTRIPPED_${ARCH/-/_} ]] && \ + export QA_PRESTRIPPED_${ARCH/-/_}" + __ebuild_phase pre_src_install if ___eapi_has_prefix_variables; then @@ -659,6 +686,15 @@ __dyn_install() { __vecho __ebuild_phase post_src_install + # record build & installed size in build log + if type -P du &>/dev/null; then + local sz=( $(du -ks "${WORKDIR}") ) + einfo "Final size of build directory: ${sz[0]} KiB" + sz=( $(du -ks "${D}") ) + einfo "Final size of installed tree: ${sz[0]} KiB" + __vecho + fi + cd "${PORTAGE_BUILDDIR}"/build-info set -f local f x diff --git a/bin/portageq b/bin/portageq index 548d090e0..925640b2e 100755 --- a/bin/portageq +++ b/bin/portageq @@ -1,5 +1,5 @@ #!/usr/bin/python -bO -# Copyright 1999-2014 Gentoo Foundation +# Copyright 1999-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 from __future__ import print_function, unicode_literals @@ -800,15 +800,25 @@ def envvar(argv): print("ERROR: insufficient parameters!") return 2 + exit_status = 0 + for arg in argv: if arg in ("PORTDIR", "PORTDIR_OVERLAY", "SYNC"): print("WARNING: 'portageq envvar %s' is deprecated. Use any of " "'get_repos, get_repo_path, repos_config' instead." % arg, file=sys.stderr) + + value = portage.settings.get(arg) + if value is None: + value = "" + exit_status = 1 + if verbose: - print(arg + "=" + portage._shell_quote(portage.settings[arg])) + print(arg + "=" + portage._shell_quote(value)) else: - print(portage.settings[arg]) + print(value) + + return exit_status docstrings['envvar'] = """<variable>+ Returns a specific environment variable as exists prior to ebuild.sh. diff --git a/bin/socks5-server.py b/bin/socks5-server.py index 71e6b01b9..cfe3ece26 100644 --- a/bin/socks5-server.py +++ b/bin/socks5-server.py @@ -10,6 +10,13 @@ import socket import struct import sys +if hasattr(asyncio, 'ensure_future'): + # Python >=3.4.4. + asyncio_ensure_future = asyncio.ensure_future +else: + # getattr() necessary because async is a keyword in Python >=3.7. + asyncio_ensure_future = getattr(asyncio, 'async') + class Socks5Server(object): """ @@ -141,7 +148,7 @@ class Socks5Server(object): # otherwise, start two loops: # remote -> local... - t = asyncio.async(self.handle_proxied_conn( + t = asyncio_ensure_future(self.handle_proxied_conn( proxied_reader, writer, asyncio.Task.current_task())) # and local -> remote... diff --git a/cnf/make.globals b/cnf/make.globals index 82d8cc170..836bb5c5b 100644 --- a/cnf/make.globals +++ b/cnf/make.globals @@ -92,7 +92,7 @@ PORTAGE_RSYNC_RETRIES="-1" # Number of seconds rsync will wait before timing out. #RSYNC_TIMEOUT="180" -PORTAGE_RSYNC_OPTS="--recursive --links --safe-links --perms --times --omit-dir-times --compress --force --whole-file --delete --stats --human-readable --timeout=180 --exclude=/distfiles --exclude=/local --exclude=/packages" +PORTAGE_RSYNC_OPTS="--recursive --links --safe-links --perms --times --omit-dir-times --compress --force --whole-file --delete --stats --human-readable --timeout=180 --exclude=/distfiles --exclude=/local --exclude=/packages --exclude=/.git" # The number of days after the last `emerge --sync` that a warning # message should be produced. diff --git a/man/ebuild.5 b/man/ebuild.5 index e60eee125..c9b5f4bd8 100644 --- a/man/ebuild.5 +++ b/man/ebuild.5 @@ -1449,9 +1449,9 @@ depending on local\-file's ending. Creates all necessary dirs. .PD 0 .TP -.B fowners\fR \fI<permissions> <file> [files] +.B fowners\fR \fI[-h|-H|-L|-P|-R] [user][:group] <file> [files] .TP -.B fperms\fR \fI<permissions> <file> [files] +.B fperms\fR \fI[-R] <permissions> <file> [files] .PD 1 Performs chown (\fBfowners\fR) or chmod (\fBfperms\fR), applying \fIpermissions\fR to \fIfiles\fR. diff --git a/man/egencache.1 b/man/egencache.1 index 2465ddf04..7fd17c21a 100644 --- a/man/egencache.1 +++ b/man/egencache.1 @@ -1,4 +1,4 @@ -.TH "EGENCACHE" "1" "Mar 2015" "Portage VERSION" "Portage" +.TH "EGENCACHE" "1" "Dec 2015" "Portage VERSION" "Portage" .SH "NAME" egencache \- generate metadata cache for ebuild repositories .SH "SYNOPSIS" @@ -71,14 +71,6 @@ Also see the related \fB\-\-load\-average\fR option. .BR \-\-load\-average=LOAD Specifies that maximum load allowed when spawning multiple jobs. .TP -.BR "\-\-portdir=PORTDIR" -Override the PORTDIR variable. This option is deprecated in favor of -\-\-repositories\-configuration option. -.TP -.BR "\-\-portdir\-overlay=PORTDIR_OVERLAY" -Override the PORTDIR_OVERLAY variable. This option is deprecated in favor of -\-\-repositories\-configuration option. -.TP .BR "\-\-preserve\-comments" Preserve the comments found in the output use.local.desc file. This requires the output file to exist before egencache is called. diff --git a/man/emerge.1 b/man/emerge.1 index c03f04471..05b2a0105 100644 --- a/man/emerge.1 +++ b/man/emerge.1 @@ -361,6 +361,12 @@ the specified configuration file(s), or enable the \fBEMERGE_DEFAULT_OPTS\fR variable may be used to disable this option by default in \fBmake.conf\fR(5). .TP +.BR "\-\-autounmask\-only [ y | n ]" +Instead of doing any package building, just unmask +packages and generate package.use settings as necessary +to satisfy dependencies. This option is disabled by +default. +.TP .BR "\-\-autounmask\-unrestricted\-atoms [ y | n ]" If \-\-autounmask is enabled, keyword and mask changes using the \'=\' operator will be written. With this diff --git a/man/emirrordist.1 b/man/emirrordist.1 index 2c9383018..6e6c50833 100644 --- a/man/emirrordist.1 +++ b/man/emirrordist.1 @@ -1,4 +1,4 @@ -.TH "EMIRRORDIST" "1" "Jul 2013" "Portage VERSION" "Portage" +.TH "EMIRRORDIST" "1" "Dec 2015" "Portage VERSION" "Portage" .SH "NAME" emirrordist \- a fetch tool for mirroring of package distfiles .SH SYNOPSIS @@ -47,14 +47,6 @@ Name of repo to operate on. \fB\-\-config\-root\fR=\fIDIR\fR Location of portage config files. .TP -\fB\-\-portdir\fR=\fIDIR\fR -Override the PORTDIR variable. This option is deprecated in favor of -\-\-repositories\-configuration option. -.TP -\fB\-\-portdir\-overlay\fR=\fIPORTDIR_OVERLAY\fR -Override the PORTDIR_OVERLAY variable. This option is deprecated in favor of -\-\-repositories\-configuration option. -.TP \fB\-\-repositories\-configuration\fR=\fIREPOSITORIES_CONFIGURATION\fR Override configuration of repositories. The argument of this option has the same format as repos.conf (see \fBportage\fR(5)). diff --git a/pym/_emerge/actions.py b/pym/_emerge/actions.py index 9f2ef2921..e0c8afd0d 100644 --- a/pym/_emerge/actions.py +++ b/pym/_emerge/actions.py @@ -1,4 +1,4 @@ -# Copyright 1999-2014 Gentoo Foundation +# Copyright 1999-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 from __future__ import division, print_function, unicode_literals @@ -327,6 +327,10 @@ def action_build(settings, trees, mtimedb, display_missing_pkg_set(root_config, e.value) return 1 + if "--autounmask-only" in myopts: + mydepgraph.display_problems() + return 0 + if not success: mydepgraph.display_problems() return 1 @@ -1580,7 +1584,7 @@ def action_info(settings, trees, myopts, myfiles): chost = settings.get("CHOST") append(getportageversion(settings["PORTDIR"], None, - settings.profile_path, settings["CHOST"], + settings.profile_path, chost, trees[settings['EROOT']]["vartree"].dbapi)) header_width = 65 @@ -2393,7 +2397,7 @@ def load_emerge_config(emerge_config=None, **kargs): return emerge_config -def getgccversion(chost): +def getgccversion(chost=None): """ rtype: C{str} return: the current in-use gcc version @@ -2408,30 +2412,31 @@ def getgccversion(chost): "!!! other terminals also.\n" ) - try: - proc = subprocess.Popen(["gcc-config", "-c"], - stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - except OSError: - myoutput = None - mystatus = 1 - else: - myoutput = _unicode_decode(proc.communicate()[0]).rstrip("\n") - mystatus = proc.wait() - if mystatus == os.EX_OK and myoutput.startswith(chost + "-"): - return myoutput.replace(chost + "-", gcc_ver_prefix, 1) + if chost: + try: + proc = subprocess.Popen(["gcc-config", "-c"], + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + except OSError: + myoutput = None + mystatus = 1 + else: + myoutput = _unicode_decode(proc.communicate()[0]).rstrip("\n") + mystatus = proc.wait() + if mystatus == os.EX_OK and myoutput.startswith(chost + "-"): + return myoutput.replace(chost + "-", gcc_ver_prefix, 1) - try: - proc = subprocess.Popen( - [chost + "-" + gcc_ver_command[0]] + gcc_ver_command[1:], - stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - except OSError: - myoutput = None - mystatus = 1 - else: - myoutput = _unicode_decode(proc.communicate()[0]).rstrip("\n") - mystatus = proc.wait() - if mystatus == os.EX_OK: - return gcc_ver_prefix + myoutput + try: + proc = subprocess.Popen( + [chost + "-" + gcc_ver_command[0]] + gcc_ver_command[1:], + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + except OSError: + myoutput = None + mystatus = 1 + else: + myoutput = _unicode_decode(proc.communicate()[0]).rstrip("\n") + mystatus = proc.wait() + if mystatus == os.EX_OK: + return gcc_ver_prefix + myoutput try: proc = subprocess.Popen(gcc_ver_command, @@ -2817,7 +2822,7 @@ def run_action(emerge_config): writemsg_level(bad("!!! has some basic instructions for the setup\n"),level=logging.ERROR, noiselevel=-1) return 1 - for fmt in emerge_config.target_config.settings["PORTAGE_BINPKG_FORMAT"].split(): + for fmt in emerge_config.target_config.settings.get("PORTAGE_BINPKG_FORMAT", "").split(): if not fmt in portage.const.SUPPORTED_BINPKG_FORMATS: if "--pkg-format" in emerge_config.opts: problematic="--pkg-format" @@ -2834,7 +2839,7 @@ def run_action(emerge_config): emerge_config.target_config.settings["PORTDIR"], None, emerge_config.target_config.settings.profile_path, - emerge_config.target_config.settings["CHOST"], + emerge_config.target_config.settings.get("CHOST"), emerge_config.target_config.trees['vartree'].dbapi) + '\n', noiselevel=-1) return 0 diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index f659b0a16..d97174936 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -3667,7 +3667,7 @@ class depgraph(object): if ebuild_path: if ebuild_path != os.path.join(os.path.realpath(tree_root), cp, os.path.basename(ebuild_path)): - writemsg(colorize("BAD", "\n*** You need to adjust PORTDIR or PORTDIR_OVERLAY to emerge this package.\n\n"), noiselevel=-1) + writemsg(colorize("BAD", "\n*** You need to adjust repos.conf to emerge this package.\n\n"), noiselevel=-1) self._dynamic_config._skip_restart = True return 0, myfavorites if mykey not in portdb.xmatch( @@ -4015,7 +4015,7 @@ class depgraph(object): continue if not (isinstance(arg, SetArg) and \ - arg.name in ("selected", "system", "world")): + arg.name in ("selected", "world")): self._dynamic_config._unsatisfied_deps_for_display.append( ((myroot, atom), {"myparent" : arg})) return 0, myfavorites @@ -5407,8 +5407,14 @@ class depgraph(object): @return: True if the package is deeper than the max allowed depth """ deep = self._dynamic_config.myparams.get("deep", 0) - return depth is self._UNREACHABLE_DEPTH or ( - isinstance(deep, int) and isinstance(depth, int) and depth > deep) + if depth is self._UNREACHABLE_DEPTH: + return True + elif deep is True: + return False + else: + # All non-integer cases are handled above, + # so both values must be int type. + return depth > deep def _depth_increment(self, depth, n=1): """ @@ -9058,7 +9064,9 @@ class _dep_check_composite_db(dbapi): # Note: highest_visible is not necessarily the real highest # visible, especially when --update is not enabled, so use # < operator instead of !=. - if highest_visible is not None and pkg < highest_visible: + if (highest_visible is not None and pkg < highest_visible + and atom_set.findAtomForPackage(highest_visible, + modified_use=self._depgraph._pkg_use_enabled(highest_visible))): return False elif in_graph != pkg: # Mask choices for packages that would trigger a slot diff --git a/pym/_emerge/main.py b/pym/_emerge/main.py index 5a8b93cd3..5dbafee77 100644 --- a/pym/_emerge/main.py +++ b/pym/_emerge/main.py @@ -127,6 +127,7 @@ def insert_optional_args(args): '--alert' : y_or_n, '--ask' : y_or_n, '--autounmask' : y_or_n, + '--autounmask-only' : y_or_n, '--autounmask-keep-masks': y_or_n, '--autounmask-unrestricted-atoms' : y_or_n, '--autounmask-write' : y_or_n, @@ -323,6 +324,11 @@ def parse_opts(tmpcmdline, silent=False): "choices" : true_y_or_n }, + "--autounmask-only": { + "help" : "only perform --autounmask", + "choices" : true_y_or_n + }, + "--autounmask-unrestricted-atoms": { "help" : "write autounmask changes with >= atoms if possible", "choices" : true_y_or_n @@ -745,6 +751,11 @@ def parse_opts(tmpcmdline, silent=False): if myoptions.autounmask in true_y: myoptions.autounmask = True + if myoptions.autounmask_only in true_y: + myoptions.autounmask_only = True + else: + myoptions.autounmask_only = None + if myoptions.autounmask_unrestricted_atoms in true_y: myoptions.autounmask_unrestricted_atoms = True diff --git a/pym/portage/_emirrordist/Config.py b/pym/portage/_emirrordist/Config.py index f884a49d2..574a83559 100644 --- a/pym/portage/_emirrordist/Config.py +++ b/pym/portage/_emirrordist/Config.py @@ -109,7 +109,15 @@ class Config(object): if self.options.dry_run and not os.path.exists(db_file): db = {} else: - db = shelve.open(db_file, flag=open_flag) + try: + db = shelve.open(db_file, flag=open_flag) + except ImportError as e: + # ImportError has different attributes for python2 vs. python3 + if (getattr(e, 'name', None) == 'bsddb' or + getattr(e, 'message', None) == 'No module named bsddb'): + from bsddb3 import dbshelve + db = dbshelve.open(db_file, flags=open_flag) + if sys.hexversion < 0x3000000: db = ShelveUnicodeWrapper(db) diff --git a/pym/portage/_emirrordist/main.py b/pym/portage/_emirrordist/main.py index 7378ac7b3..b63837b2a 100644 --- a/pym/portage/_emirrordist/main.py +++ b/pym/portage/_emirrordist/main.py @@ -1,4 +1,4 @@ -# Copyright 2013-2014 Gentoo Foundation +# Copyright 2013-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 import argparse @@ -74,15 +74,6 @@ common_options = ( "metavar" : "DIR" }, { - "longopt" : "--portdir", - "help" : "override the PORTDIR variable (deprecated in favor of --repositories-configuration)", - "metavar" : "DIR" - }, - { - "longopt" : "--portdir-overlay", - "help" : "override the PORTDIR_OVERLAY variable (deprecated in favor of --repositories-configuration)" - }, - { "longopt" : "--repositories-configuration", "help" : "override configuration of repositories (in format of repos.conf)" }, @@ -245,20 +236,8 @@ def emirrordist_main(args): config_root = options.config_root - if options.portdir is not None: - writemsg_level("emirrordist: warning: --portdir option is deprecated in favor of --repositories-configuration option\n", - level=logging.WARNING, noiselevel=-1) - if options.portdir_overlay is not None: - writemsg_level("emirrordist: warning: --portdir-overlay option is deprecated in favor of --repositories-configuration option\n", - level=logging.WARNING, noiselevel=-1) - if options.repositories_configuration is not None: env['PORTAGE_REPOSITORIES'] = options.repositories_configuration - elif options.portdir_overlay is not None: - env['PORTDIR_OVERLAY'] = options.portdir_overlay - - if options.portdir is not None: - env['PORTDIR'] = options.portdir settings = portage.config(config_root=config_root, local_config=False, env=env) diff --git a/pym/portage/_sets/__init__.py b/pym/portage/_sets/__init__.py index 47be418a3..91f9dd1ca 100644 --- a/pym/portage/_sets/__init__.py +++ b/pym/portage/_sets/__init__.py @@ -118,6 +118,10 @@ class SetConfig(object): parser.set("world", "class", "portage.sets.base.DummyPackageSet") parser.set("world", "packages", "@profile @selected @system") + parser.remove_section("profile") + parser.add_section("profile") + parser.set("profile", "class", "portage.sets.ProfilePackageSet.ProfilePackageSet") + parser.remove_section("selected") parser.add_section("selected") parser.set("selected", "class", "portage.sets.files.WorldSelectedSet") diff --git a/pym/portage/cache/anydbm.py b/pym/portage/cache/anydbm.py index 1d56b1458..80d24e55d 100644 --- a/pym/portage/cache/anydbm.py +++ b/pym/portage/cache/anydbm.py @@ -36,6 +36,9 @@ from portage.cache import cache_errors class database(fs_template.FsBased): + validation_chf = 'mtime' + chf_types = ('mtime', 'md5') + autocommits = True cleanse_keys = True serialize_eclasses = False diff --git a/pym/portage/cache/flat_hash.py b/pym/portage/cache/flat_hash.py index 53042965e..cca0f10e3 100644 --- a/pym/portage/cache/flat_hash.py +++ b/pym/portage/cache/flat_hash.py @@ -160,3 +160,8 @@ class md5_database(database): validation_chf = 'md5' store_eclass_paths = False + + +class mtime_md5_database(database): + validation_chf = 'mtime' + chf_types = ('mtime', 'md5') diff --git a/pym/portage/cache/sqlite.py b/pym/portage/cache/sqlite.py index 310ac9460..32e407635 100644 --- a/pym/portage/cache/sqlite.py +++ b/pym/portage/cache/sqlite.py @@ -18,6 +18,9 @@ if sys.hexversion >= 0x3000000: class database(fs_template.FsBased): + validation_chf = 'mtime' + chf_types = ('mtime', 'md5') + autocommits = False synchronous = False # cache_bytes is used together with page_size (set at sqlite build time) @@ -28,10 +31,12 @@ class database(fs_template.FsBased): def __init__(self, *args, **config): super(database, self).__init__(*args, **config) self._import_sqlite() - self._allowed_keys = ["_mtime_", "_eclasses_"] + self._allowed_keys = ["_eclasses_"] self._allowed_keys.extend(self._known_keys) - self._allowed_keys.sort() + self._allowed_keys.extend('_%s_' % k for k in self.chf_types) self._allowed_keys_set = frozenset(self._allowed_keys) + self._allowed_keys = sorted(self._allowed_keys_set) + self.location = os.path.join(self.location, self.label.lstrip(os.path.sep).rstrip(os.path.sep)) diff --git a/pym/portage/cache/template.py b/pym/portage/cache/template.py index bc81b8642..a7c6de0f6 100644 --- a/pym/portage/cache/template.py +++ b/pym/portage/cache/template.py @@ -46,9 +46,23 @@ class database(object): self.commit() self.updates = 0 d=self._getitem(cpv) + + try: + chf_types = self.chf_types + except AttributeError: + chf_types = (self.validation_chf,) + if self.serialize_eclasses and "_eclasses_" in d: - d["_eclasses_"] = reconstruct_eclasses(cpv, d["_eclasses_"], - self.validation_chf, paths=self.store_eclass_paths) + for chf_type in chf_types: + try: + d["_eclasses_"] = reconstruct_eclasses(cpv, d["_eclasses_"], + chf_type, paths=self.store_eclass_paths) + except cache_errors.CacheCorruption: + if chf_type is chf_types[-1]: + raise + else: + break + elif "_eclasses_" not in d: d["_eclasses_"] = {} # Never return INHERITED, since portdbapi.aux_get() will @@ -56,16 +70,23 @@ class database(object): # to omit it in comparisons between cache entries like # those that egencache uses to avoid redundant writes. d.pop("INHERITED", None) + + mtime_required = not any(d.get('_%s_' % x) + for x in chf_types if x != 'mtime') + mtime = d.get('_mtime_') - if mtime is None: - raise cache_errors.CacheCorruption(cpv, - '_mtime_ field is missing') - try: - mtime = long(mtime) - except ValueError: - raise cache_errors.CacheCorruption(cpv, - '_mtime_ conversion to long failed: %s' % (mtime,)) - d['_mtime_'] = mtime + if not mtime: + if mtime_required: + raise cache_errors.CacheCorruption(cpv, + '_mtime_ field is missing') + d.pop('_mtime_', None) + else: + try: + mtime = long(mtime) + except ValueError: + raise cache_errors.CacheCorruption(cpv, + '_mtime_ conversion to long failed: %s' % (mtime,)) + d['_mtime_'] = mtime return d def _getitem(self, cpv): @@ -204,15 +225,27 @@ class database(object): return x def validate_entry(self, entry, ebuild_hash, eclass_db): - hash_key = '_%s_' % self.validation_chf + try: + chf_types = self.chf_types + except AttributeError: + chf_types = (self.validation_chf,) + + for chf_type in chf_types: + if self._validate_entry(chf_type, entry, ebuild_hash, eclass_db): + return True + + return False + + def _validate_entry(self, chf_type, entry, ebuild_hash, eclass_db): + hash_key = '_%s_' % chf_type try: entry_hash = entry[hash_key] except KeyError: return False else: - if entry_hash != getattr(ebuild_hash, self.validation_chf): + if entry_hash != getattr(ebuild_hash, chf_type): return False - update = eclass_db.validate_and_rewrite_cache(entry['_eclasses_'], self.validation_chf, + update = eclass_db.validate_and_rewrite_cache(entry['_eclasses_'], chf_type, self.store_eclass_paths) if update is None: return False diff --git a/pym/portage/dbapi/porttree.py b/pym/portage/dbapi/porttree.py index a954de53b..23f3169b7 100644 --- a/pym/portage/dbapi/porttree.py +++ b/pym/portage/dbapi/porttree.py @@ -1,4 +1,4 @@ -# Copyright 1998-2014 Gentoo Foundation +# Copyright 1998-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 from __future__ import unicode_literals @@ -23,7 +23,7 @@ from portage.cache import volatile from portage.cache.cache_errors import CacheError from portage.cache.mappings import Mapping from portage.dbapi import dbapi -from portage.exception import PortageException, \ +from portage.exception import PortageException, PortageKeyError, \ FileNotFound, InvalidAtom, InvalidData, \ InvalidDependString, InvalidPackageName from portage.localization import _ @@ -435,7 +435,7 @@ class portdbapi(dbapi): writemsg(_("!!! aux_get(): ebuild for " \ "'%s' does not exist at:\n") % (cpv,), noiselevel=-1) writemsg("!!! %s\n" % ebuild_path, noiselevel=-1) - raise KeyError(cpv) + raise PortageKeyError(cpv) # Pull pre-generated metadata from the metadata/cache/ # directory if it exists and is valid, otherwise fall @@ -481,12 +481,12 @@ class portdbapi(dbapi): def aux_get(self, mycpv, mylist, mytree=None, myrepo=None): "stub code for returning auxilliary db information, such as SLOT, DEPEND, etc." 'input: "sys-apps/foo-1.0",["SLOT","DEPEND","HOMEPAGE"]' - 'return: ["0",">=sys-libs/bar-1.0","http://www.foo.com"] or raise KeyError if error' + 'return: ["0",">=sys-libs/bar-1.0","http://www.foo.com"] or raise PortageKeyError if error' cache_me = False if myrepo is not None: mytree = self.treemap.get(myrepo) if mytree is None: - raise KeyError(myrepo) + raise PortageKeyError(myrepo) if mytree is not None and len(self.porttrees) == 1 \ and mytree == self.porttrees[0]: @@ -507,22 +507,22 @@ class portdbapi(dbapi): try: cat, pkg = mycpv.split("/", 1) except ValueError: - # Missing slash. Can't find ebuild so raise KeyError. - raise KeyError(mycpv) + # Missing slash. Can't find ebuild so raise PortageKeyError. + raise PortageKeyError(mycpv) myebuild, mylocation = self.findname2(mycpv, mytree) if not myebuild: writemsg("!!! aux_get(): %s\n" % \ _("ebuild not found for '%s'") % mycpv, noiselevel=1) - raise KeyError(mycpv) + raise PortageKeyError(mycpv) mydata, ebuild_hash = self._pull_valid_cache(mycpv, myebuild, mylocation) doregen = mydata is None if doregen: if myebuild in self._broken_ebuilds: - raise KeyError(mycpv) + raise PortageKeyError(mycpv) proc = EbuildMetadataPhase(cpv=mycpv, ebuild_hash=ebuild_hash, portdb=self, @@ -534,7 +534,7 @@ class portdbapi(dbapi): if proc.returncode != os.EX_OK: self._broken_ebuilds.add(myebuild) - raise KeyError(mycpv) + raise PortageKeyError(mycpv) mydata = proc.metadata diff --git a/pym/portage/dep/dep_check.py b/pym/portage/dep/dep_check.py index 4e97ffa7f..e1704365b 100644 --- a/pym/portage/dep/dep_check.py +++ b/pym/portage/dep/dep_check.py @@ -675,10 +675,12 @@ def dep_check(depstring, mydbapi, mysettings, use="yes", mode=None, myuse=None, # matchall behavior to account for profile use.mask/force. The # ARCH/archlist code here may be redundant, since the profile # really should be handling ARCH masking/forcing itself. + arch = mysettings.get("ARCH") mymasks.update(mysettings.usemask) mymasks.update(mysettings.archlist()) - mymasks.discard(mysettings["ARCH"]) - useforce.add(mysettings["ARCH"]) + if arch: + mymasks.discard(arch) + useforce.add(arch) useforce.update(mysettings.useforce) useforce.difference_update(mymasks) diff --git a/pym/portage/elog/mod_save.py b/pym/portage/elog/mod_save.py index 7b1cd46a8..829ec6c5e 100644 --- a/pym/portage/elog/mod_save.py +++ b/pym/portage/elog/mod_save.py @@ -33,8 +33,7 @@ def process(mysettings, key, logentries, fulltext): uid = portage_uid ensure_dirs(logdir, uid=uid, gid=portage_gid, mode=0o2770) - cat = mysettings['CATEGORY'] - pf = mysettings['PF'] + cat, pf = portage.catsplit(key) elogfilename = pf + ":" + _unicode_decode( time.strftime("%Y%m%d-%H%M%S", time.gmtime(time.time())), diff --git a/pym/portage/emaint/modules/merges/__init__.py b/pym/portage/emaint/modules/merges/__init__.py index bcb2ac8ee..211b7eba3 100644 --- a/pym/portage/emaint/modules/merges/__init__.py +++ b/pym/portage/emaint/modules/merges/__init__.py @@ -16,7 +16,7 @@ module_spec = { 'functions': ['check', 'fix', 'purge'], 'func_desc': { 'purge': { - 'short': '-P', 'long': '--purge-tracker', + 'short': '-P', 'long': '--purge', 'help': 'Removes the list of previously failed merges.' + ' WARNING: Only use this option if you plan on' + ' manually fixing them or do not want them' diff --git a/pym/portage/exception.py b/pym/portage/exception.py index 857a727d5..263cdf087 100644 --- a/pym/portage/exception.py +++ b/pym/portage/exception.py @@ -1,4 +1,4 @@ -# Copyright 1998-2014 Gentoo Foundation +# Copyright 1998-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 import signal @@ -42,6 +42,9 @@ class PortageException(Exception): else: return repr(self.value) +class PortageKeyError(KeyError, PortageException): + __doc__ = KeyError.__doc__ + class CorruptionError(PortageException): """Corruption indication""" diff --git a/pym/portage/manifest.py b/pym/portage/manifest.py index f5cf0f5e0..f696f846e 100644 --- a/pym/portage/manifest.py +++ b/pym/portage/manifest.py @@ -282,7 +282,8 @@ class Manifest(object): try: myentries = list(self._createManifestEntries()) update_manifest = True - existing_st = None + preserved_stats = {} + preserved_stats[self.pkgdir.rstrip(os.sep)] = os.stat(self.pkgdir) if myentries and not force: try: f = io.open(_unicode_encode(self.getFullname(), @@ -290,7 +291,7 @@ class Manifest(object): mode='r', encoding=_encodings['repo.content'], errors='replace') oldentries = list(self._parseManifestLines(f)) - existing_st = os.fstat(f.fileno()) + preserved_stats[self.getFullname()] = os.fstat(f.fileno()) f.close() if len(oldentries) == len(myentries): update_manifest = False @@ -312,7 +313,7 @@ class Manifest(object): # non-empty for all currently known use cases. write_atomic(self.getFullname(), "".join("%s\n" % _unicode(myentry) for myentry in myentries)) - self._apply_max_mtime(existing_st, myentries) + self._apply_max_mtime(preserved_stats, myentries) rval = True else: # With thin manifest, there's no need to have @@ -332,17 +333,19 @@ class Manifest(object): raise return rval - def _apply_max_mtime(self, existing_st, entries): + def _apply_max_mtime(self, preserved_stats, entries): """ Set the Manifest mtime to the max mtime of all relevant files - (the existing Manifest mtime is included in order to account for - eclass modifications that change DIST entries). This results in a + and directories. Directory mtimes account for file renames and + removals. The existing Manifest mtime accounts for eclass + modifications that change DIST entries. This results in a stable/predictable mtime, which is useful when converting thin manifests to thick manifests for distribution via rsync. For portability, the mtime is set with 1 second resolution. - @param existing_st: stat result for existing Manifest - @type existing_st: posix.stat_result + @param preserved_stats: maps paths to preserved stat results + that should be used instead of os.stat() calls + @type preserved_stats: dict @param entries: list of current Manifest2Entry instances @type entries: list """ @@ -350,18 +353,41 @@ class Manifest(object): # it always rounds down. Note that stat_result.st_mtime will round # up from 0.999999999 to 1.0 when precision is lost during conversion # from nanosecond resolution to float. - max_mtime = None if existing_st is None else existing_st[stat.ST_MTIME] + max_mtime = None + _update_max = (lambda st: max_mtime if max_mtime is not None + and max_mtime > st[stat.ST_MTIME] else st[stat.ST_MTIME]) + _stat = (lambda path: preserved_stats[path] if path in preserved_stats + else os.stat(path)) + + for stat_result in preserved_stats.values(): + max_mtime = _update_max(stat_result) + for entry in entries: if entry.type == 'DIST': continue abs_path = (os.path.join(self.pkgdir, 'files', entry.name) if entry.type == 'AUX' else os.path.join(self.pkgdir, entry.name)) - mtime = os.stat(abs_path)[stat.ST_MTIME] - if max_mtime is None or mtime > max_mtime: - max_mtime = mtime + max_mtime = _update_max(_stat(abs_path)) + + if not self.thin: + # Account for changes to all relevant nested directories. + # This is not necessary for thin manifests because + # self.pkgdir is already included via preserved_stats. + for parent_dir, dirs, files in os.walk(self.pkgdir.rstrip(os.sep)): + try: + parent_dir = _unicode_decode(parent_dir, + encoding=_encodings['fs'], errors='strict') + except UnicodeDecodeError: + # If an absolute path cannot be decoded, then it is + # always excluded from the manifest (repoman will + # report such problems). + pass + else: + max_mtime = _update_max(_stat(parent_dir)) if max_mtime is not None: - os.utime(self.getFullname(), (max_mtime, max_mtime)) + for path in preserved_stats: + os.utime(path, (max_mtime, max_mtime)) def sign(self): """ Sign the Manifest """ diff --git a/pym/portage/package/ebuild/_config/LicenseManager.py b/pym/portage/package/ebuild/_config/LicenseManager.py index f76e7e2fe..1d4e08207 100644 --- a/pym/portage/package/ebuild/_config/LicenseManager.py +++ b/pym/portage/package/ebuild/_config/LicenseManager.py @@ -1,4 +1,4 @@ -# Copyright 201-2012 Gentoo Foundation +# Copyright 2010-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 __all__ = ( @@ -119,7 +119,7 @@ class LicenseManager(object): cp = cpv_getkey(cpv) cpdict = self._plicensedict.get(cp) if cpdict: - if not hasattr(cpv, slot): + if not hasattr(cpv, "slot"): cpv = _pkg_str(cpv, slot=slot, repo=repo) plicence_list = ordered_by_atom_specificity(cpdict, cpv) if plicence_list: diff --git a/pym/portage/package/ebuild/_config/special_env_vars.py b/pym/portage/package/ebuild/_config/special_env_vars.py index 905d5e7b3..f7810e007 100644 --- a/pym/portage/package/ebuild/_config/special_env_vars.py +++ b/pym/portage/package/ebuild/_config/special_env_vars.py @@ -74,7 +74,7 @@ environ_whitelist += [ "PORTAGE_SIGPIPE_STATUS", "PORTAGE_SOCKS5_PROXY", "PORTAGE_TMPDIR", "PORTAGE_UPDATE_ENV", "PORTAGE_USERNAME", "PORTAGE_VERBOSE", "PORTAGE_WORKDIR_MODE", "PORTAGE_XATTR_EXCLUDE", - "PORTDIR", "PORTDIR_OVERLAY", "PREROOTPATH", + "PORTDIR", "PORTDIR_OVERLAY", "PREROOTPATH", "PYTHONDONTWRITEBYTECODE", "REPLACING_VERSIONS", "REPLACED_BY_VERSION", "ROOT", "ROOTPATH", "T", "TMP", "TMPDIR", "USE_EXPAND", "USE_ORDER", "WORKDIR", diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py index d47b4f3aa..aa5d0694a 100644 --- a/pym/portage/package/ebuild/config.py +++ b/pym/portage/package/ebuild/config.py @@ -1,4 +1,4 @@ -# Copyright 2010-2014 Gentoo Foundation +# Copyright 2010-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 from __future__ import unicode_literals @@ -15,6 +15,7 @@ import platform import pwd import re import sys +import traceback import warnings from _emerge.Package import Package @@ -159,8 +160,8 @@ class config(object): 'repository', 'RESTRICT', 'LICENSE',) _module_aliases = { - "cache.metadata_overlay.database" : "portage.cache.flat_hash.database", - "portage.cache.metadata_overlay.database" : "portage.cache.flat_hash.database", + "cache.metadata_overlay.database" : "portage.cache.flat_hash.mtime_md5_database", + "portage.cache.metadata_overlay.database" : "portage.cache.flat_hash.mtime_md5_database", } _case_insensitive_vars = special_env_vars.case_insensitive_vars @@ -443,7 +444,7 @@ class config(object): (user_auxdbmodule, modules_file)) self.modules["default"] = { - "portdbapi.auxdbmodule": "portage.cache.flat_hash.database", + "portdbapi.auxdbmodule": "portage.cache.flat_hash.mtime_md5_database", } self.configlist=[] @@ -537,13 +538,13 @@ class config(object): #filling PORTDIR and PORTDIR_OVERLAY variable for compatibility main_repo = self.repositories.mainRepo() if main_repo is not None: - self["PORTDIR"] = main_repo.user_location + self["PORTDIR"] = main_repo.location self.backup_changes("PORTDIR") expand_map["PORTDIR"] = self["PORTDIR"] # repoman controls PORTDIR_OVERLAY via the environment, so no # special cases are needed here. - portdir_overlay = list(self.repositories.repoUserLocationList()) + portdir_overlay = list(self.repositories.repoLocationList()) if portdir_overlay and portdir_overlay[0] == self["PORTDIR"]: portdir_overlay = portdir_overlay[1:] @@ -836,7 +837,8 @@ class config(object): # reasonable defaults; this is important as without USE_ORDER, # USE will always be "" (nothing set)! if "USE_ORDER" not in self: - self.backupenv["USE_ORDER"] = "env:pkg:conf:defaults:pkginternal:repo:env.d" + self["USE_ORDER"] = "env:pkg:conf:defaults:pkginternal:repo:env.d" + self.backup_changes("USE_ORDER") if "CBUILD" not in self and "CHOST" in self: self["CBUILD"] = self["CHOST"] @@ -1264,13 +1266,13 @@ class config(object): use = frozenset(settings['PORTAGE_USE'].split()) values['ACCEPT_LICENSE'] = settings._license_manager.get_prunned_accept_license( \ - settings.mycpv, use, settings['LICENSE'], settings['SLOT'], settings.get('PORTAGE_REPO_NAME')) + settings.mycpv, use, settings.get('LICENSE', ''), settings.get('SLOT'), settings.get('PORTAGE_REPO_NAME')) values['PORTAGE_RESTRICT'] = self._restrict(use, settings) return values def _restrict(self, use, settings): try: - restrict = set(use_reduce(settings['RESTRICT'], uselist=use, flat=True)) + restrict = set(use_reduce(settings.get('RESTRICT', ''), uselist=use, flat=True)) except InvalidDependString: restrict = set() return ' '.join(sorted(restrict)) @@ -2580,7 +2582,23 @@ class config(object): try: return self._getitem(key) except KeyError: - return '' # for backward compat, don't raise KeyError + if portage._internal_caller: + stack = traceback.format_stack()[:-1] + traceback.format_exception(*sys.exc_info())[1:] + try: + # Ensure that output is written to terminal. + with open("/dev/tty", "w") as f: + f.write("=" * 96 + "\n") + f.write("=" * 8 + " Traceback for invalid call to portage.package.ebuild.config.config.__getitem__ " + "=" * 8 + "\n") + f.writelines(stack) + f.write("=" * 96 + "\n") + except Exception: + pass + raise + else: + warnings.warn(_("Passing nonexistent key %r to %s is deprecated. Use %s instead.") % + (key, "portage.package.ebuild.config.config.__getitem__", + "portage.package.ebuild.config.config.get"), DeprecationWarning, stacklevel=2) + return "" def _getitem(self, mykey): @@ -2707,10 +2725,9 @@ class config(object): filter_calling_env = True environ_whitelist = self._environ_whitelist - for x in self: + for x, myvalue in self.iteritems(): if x in environ_filter: continue - myvalue = self[x] if not isinstance(myvalue, basestring): writemsg(_("!!! Non-string value in config: %s=%s\n") % \ (x, myvalue), noiselevel=-1) diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py index e581724d9..1f1773091 100644 --- a/pym/portage/package/ebuild/doebuild.py +++ b/pym/portage/package/ebuild/doebuild.py @@ -466,7 +466,6 @@ def doebuild_environment(myebuild, mydo, myroot=None, settings=None, 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") if default_abi: @@ -474,17 +473,27 @@ def doebuild_environment(myebuild, mydo, myroot=None, settings=None, if not libdir: libdir = "lib" + # The installation locations use to vary between versions... + # Safer to look them up rather than assuming + possible_libexecdirs = (libdir, "lib", "libexec") + masquerades = [] if distcc: - mysettings["PATH"] = os.path.join(os.sep, eprefix_lstrip, - "usr", libdir, "distcc", "bin") + ":" + mysettings["PATH"] - + masquerades.append("distcc") if icecream: - mysettings["PATH"] = os.path.join(os.sep, eprefix_lstrip, - "usr", 'libexec', "icecc", "bin") + ":" + mysettings["PATH"] - + masquerades.append("icecc") if ccache: - mysettings["PATH"] = os.path.join(os.sep, eprefix_lstrip, - "usr", libdir, "ccache", "bin") + ":" + mysettings["PATH"] + masquerades.append("ccache") + + for m in masquerades: + for l in possible_libexecdirs: + p = os.path.join(os.sep, eprefix_lstrip, + "usr", l, m, "bin") + if os.path.isdir(p): + mysettings["PATH"] = p + ":" + mysettings["PATH"] + break + else: + writemsg(("Warning: %s requested but no masquerade dir" + + "can be found in /usr/lib*/%s/bin\n") % (m, m)) if 'MAKEOPTS' not in mysettings: nproc = get_cpu_count() diff --git a/pym/portage/package/ebuild/fetch.py b/pym/portage/package/ebuild/fetch.py index 7e4e6fe45..1be2800a2 100644 --- a/pym/portage/package/ebuild/fetch.py +++ b/pym/portage/package/ebuild/fetch.py @@ -1,4 +1,4 @@ -# Copyright 2010-2014 Gentoo Foundation +# Copyright 2010-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 from __future__ import print_function @@ -987,10 +987,9 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, } for k in ("DISTDIR", "PORTAGE_SSH_OPTS"): - try: - variables[k] = mysettings[k] - except KeyError: - pass + v = mysettings.get(k) + if v is not None: + variables[k] = v myfetch = shlex_split(locfetch) myfetch = [varexpand(x, mydict=variables) for x in myfetch] diff --git a/pym/portage/repository/config.py b/pym/portage/repository/config.py index a21c8910c..00319fe89 100644 --- a/pym/portage/repository/config.py +++ b/pym/portage/repository/config.py @@ -89,8 +89,8 @@ class RepoConfig(object): 'profile_formats', 'sign_commit', 'sign_manifest', 'sync_depth', 'sync_hooks_only_on_change', 'sync_type', 'sync_umask', 'sync_uri', 'sync_user', 'thin_manifest', - 'update_changelog', 'user_location', '_eapis_banned', - '_eapis_deprecated', '_masters_orig', 'module_specific_options', + 'update_changelog', '_eapis_banned', '_eapis_deprecated', + '_masters_orig', 'module_specific_options', ) def __init__(self, name, repo_opts, local_config=True): @@ -187,7 +187,6 @@ class RepoConfig(object): self.format = format location = repo_opts.get('location') - self.user_location = location if location is not None and location.strip(): if os.path.isdir(location) or portage._sync_mode: location = os.path.realpath(location) @@ -408,8 +407,8 @@ class RepoConfig(object): repo_msg.append(self.name) if self.format: repo_msg.append(indent + "format: " + self.format) - if self.user_location: - repo_msg.append(indent + "location: " + self.user_location) + if self.location: + repo_msg.append(indent + "location: " + self.location) if self.sync_type: repo_msg.append(indent + "sync-type: " + self.sync_type) if self.sync_umask: @@ -525,7 +524,7 @@ class RepoConfigLoader(object): old_location == default_portdir): ignored_map.setdefault(repo.name, []).append(old_location) if old_location == portdir: - portdir = repo.user_location + portdir = repo.location if repo.priority is None: if base_priority == 0 and ov == portdir_orig: @@ -805,7 +804,7 @@ class RepoConfigLoader(object): master_repos = [] for master_name in repo.masters: if master_name not in prepos: - layout_filename = os.path.join(repo.user_location, + layout_filename = os.path.join(repo.location, "metadata", "layout.conf") writemsg_level(_("Unavailable repository '%s' " \ "referenced by masters entry in '%s'\n") % \ @@ -886,14 +885,6 @@ class RepoConfigLoader(object): self._prepos_changed = False return self._repo_location_list - def repoUserLocationList(self): - """Get a list of repositories location. Replaces PORTDIR_OVERLAY""" - user_location_list = [] - for repo in self.prepos_order: - if self.prepos[repo].location is not None: - user_location_list.append(self.prepos[repo].user_location) - return tuple(user_location_list) - def mainRepoLocation(self): """Returns the location of main repo""" main_repo = self.prepos['DEFAULT'].main_repo diff --git a/pym/portage/sync/controller.py b/pym/portage/sync/controller.py index e71ba67a5..92be3cbf5 100644 --- a/pym/portage/sync/controller.py +++ b/pym/portage/sync/controller.py @@ -129,16 +129,17 @@ class SyncManager(object): self.repo = repo self.exitcode = 1 self.updatecache_flg = False + hooks_enabled = master_hooks or not repo.sync_hooks_only_on_change if repo.sync_type in self.module_names: tasks = [self.module_controller.get_class(repo.sync_type)] else: msg = "\n%s: Sync module '%s' is not an installed/known type'\n" \ % (bad("ERROR"), repo.sync_type) - return self.exitcode, msg + return self.exitcode, msg, self.updatecache_flg, hooks_enabled rval = self.pre_sync(repo) if rval != os.EX_OK: - return rval, None + return rval, None, self.updatecache_flg, hooks_enabled # need to pass the kwargs dict to the modules # so they are available if needed. @@ -157,7 +158,6 @@ class SyncManager(object): taskmaster = TaskHandler(callback=self.do_callback) taskmaster.run_tasks(tasks, func, status, options=task_opts) - hooks_enabled = False if (master_hooks or self.updatecache_flg or not repo.sync_hooks_only_on_change): hooks_enabled = True diff --git a/pym/portage/tests/dbapi/test_portdb_cache.py b/pym/portage/tests/dbapi/test_portdb_cache.py index 5ac9b0394..bd934460a 100644 --- a/pym/portage/tests/dbapi/test_portdb_cache.py +++ b/pym/portage/tests/dbapi/test_portdb_cache.py @@ -1,4 +1,4 @@ -# Copyright 2012-2014 Gentoo Foundation +# Copyright 2012-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 import subprocess @@ -134,6 +134,7 @@ class PortdbCacheTestCase(TestCase): "PORTAGE_OVERRIDE_EPREFIX" : eprefix, "PORTAGE_PYTHON" : portage_python, "PORTAGE_REPOSITORIES" : settings.repositories.config_string(), + "PYTHONDONTWRITEBYTECODE" : os.environ.get("PYTHONDONTWRITEBYTECODE", ""), "PYTHONPATH" : pythonpath, } diff --git a/pym/portage/tests/ebuild/test_config.py b/pym/portage/tests/ebuild/test_config.py index 20aac519a..1dd828538 100644 --- a/pym/portage/tests/ebuild/test_config.py +++ b/pym/portage/tests/ebuild/test_config.py @@ -1,4 +1,4 @@ -# Copyright 2010-2014 Gentoo Foundation +# Copyright 2010-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 from __future__ import unicode_literals @@ -252,7 +252,7 @@ class ConfigTestCase(TestCase): new_repo_config = settings.repositories["new_repo"] old_repo_config = settings.repositories["old_repo"] self.assertTrue(len(new_repo_config.masters) > 0, "new_repo has no default master") - self.assertEqual(new_repo_config.masters[0].user_location, playground.settings.repositories["test_repo"].location, + self.assertEqual(new_repo_config.masters[0].location, playground.settings.repositories["test_repo"].location, "new_repo default master is not test_repo") self.assertEqual(new_repo_config.thin_manifest, True, "new_repo_config.thin_manifest != True") diff --git a/pym/portage/tests/ebuild/test_doebuild_fd_pipes.py b/pym/portage/tests/ebuild/test_doebuild_fd_pipes.py index 61392dd54..b89421822 100644 --- a/pym/portage/tests/ebuild/test_doebuild_fd_pipes.py +++ b/pym/portage/tests/ebuild/test_doebuild_fd_pipes.py @@ -1,8 +1,6 @@ -# Copyright 2013 Gentoo Foundation +# Copyright 2013-2016 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -import textwrap - import portage from portage import os from portage.tests import TestCase @@ -10,7 +8,6 @@ from portage.tests.resolver.ResolverPlayground import ResolverPlayground from portage.package.ebuild._ipc.QueryCommand import QueryCommand from portage.util._async.ForkProcess import ForkProcess from portage.util._async.TaskScheduler import TaskScheduler -from portage.util._eventloop.global_event_loop import global_event_loop from _emerge.Package import Package from _emerge.PipeReader import PipeReader @@ -31,19 +28,16 @@ class DoebuildFdPipesTestCase(TestCase): supported for API consumers (see bug #475812). """ - ebuild_body = textwrap.dedent(""" - S=${WORKDIR} - pkg_info() { echo info ; } - pkg_nofetch() { echo nofetch ; } - pkg_pretend() { echo pretend ; } - pkg_setup() { echo setup ; } - src_unpack() { echo unpack ; } - src_prepare() { echo prepare ; } - src_configure() { echo configure ; } - src_compile() { echo compile ; } - src_test() { echo test ; } - src_install() { echo install ; } - """) + output_fd = 200 + ebuild_body = ['S=${WORKDIR}'] + for phase_func in ('pkg_info', 'pkg_nofetch', 'pkg_pretend', + 'pkg_setup', 'src_unpack', 'src_prepare', 'src_configure', + 'src_compile', 'src_test', 'src_install'): + ebuild_body.append(('%s() { echo ${EBUILD_PHASE}' + ' 1>&%s; }') % (phase_func, output_fd)) + + ebuild_body.append('') + ebuild_body = '\n'.join(ebuild_body) ebuilds = { 'app-misct/foo-1': { @@ -60,6 +54,7 @@ class DoebuildFdPipesTestCase(TestCase): self.assertEqual(true_binary is None, False, "true command not found") + dev_null = open(os.devnull, 'wb') playground = ResolverPlayground(ebuilds=ebuilds) try: QueryCommand._db = playground.trees @@ -75,6 +70,7 @@ class DoebuildFdPipesTestCase(TestCase): settings.features.add("test") settings['PORTAGE_PYTHON'] = portage._python_interpreter settings['PORTAGE_QUIET'] = "1" + settings['PYTHONDONTWRITEBYTECODE'] = os.environ.get("PYTHONDONTWRITEBYTECODE", "") fake_bin = os.path.join(settings["EPREFIX"], "bin") portage.util.ensure_dirs(fake_bin) @@ -105,7 +101,11 @@ class DoebuildFdPipesTestCase(TestCase): doebuild_kwargs={"settings" : settings, "mydbapi": portdb, "tree": "porttree", "vartree": root_config.trees["vartree"], - "fd_pipes": {1: pw, 2: pw}, + "fd_pipes": { + 1: dev_null.fileno(), + 2: dev_null.fileno(), + output_fd: pw, + }, "prev_mtimes": {}}) consumer = PipeReader( @@ -133,5 +133,6 @@ class DoebuildFdPipesTestCase(TestCase): self.assertEqual(phase, output) finally: + dev_null.close() playground.cleanup() QueryCommand._db = None diff --git a/pym/portage/tests/ebuild/test_doebuild_spawn.py b/pym/portage/tests/ebuild/test_doebuild_spawn.py index ae9a5c504..6b344658f 100644 --- a/pym/portage/tests/ebuild/test_doebuild_spawn.py +++ b/pym/portage/tests/ebuild/test_doebuild_spawn.py @@ -1,4 +1,4 @@ -# Copyright 2010-2012 Gentoo Foundation +# Copyright 2010-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 import textwrap @@ -65,6 +65,7 @@ class DoebuildSpawnTestCase(TestCase): settings['PORTAGE_PYTHON'] = _python_interpreter settings['PORTAGE_BUILDDIR'] = os.path.join( settings['PORTAGE_TMPDIR'], cpv) + settings['PYTHONDONTWRITEBYTECODE'] = os.environ.get('PYTHONDONTWRITEBYTECODE', '') settings['T'] = os.path.join( settings['PORTAGE_BUILDDIR'], 'temp') for x in ('PORTAGE_BUILDDIR', 'T'): diff --git a/pym/portage/tests/ebuild/test_ipc_daemon.py b/pym/portage/tests/ebuild/test_ipc_daemon.py index a87107625..835f51f80 100644 --- a/pym/portage/tests/ebuild/test_ipc_daemon.py +++ b/pym/portage/tests/ebuild/test_ipc_daemon.py @@ -1,4 +1,4 @@ -# Copyright 2010-2012 Gentoo Foundation +# Copyright 2010-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 import tempfile @@ -51,6 +51,7 @@ class IpcDaemonTestCase(TestCase): env['PORTAGE_BIN_PATH'] = PORTAGE_BIN_PATH env['PORTAGE_PYM_PATH'] = PORTAGE_PYM_PATH env['PORTAGE_BUILDDIR'] = os.path.join(tmpdir, 'cat', 'pkg-1') + env['PYTHONDONTWRITEBYTECODE'] = os.environ.get('PYTHONDONTWRITEBYTECODE', '') if "__PORTAGE_TEST_HARDLINK_LOCKS" in os.environ: env["__PORTAGE_TEST_HARDLINK_LOCKS"] = \ diff --git a/pym/portage/tests/emerge/test_config_protect.py b/pym/portage/tests/emerge/test_config_protect.py index 5d7d8e993..06ab059ee 100644 --- a/pym/portage/tests/emerge/test_config_protect.py +++ b/pym/portage/tests/emerge/test_config_protect.py @@ -1,4 +1,4 @@ -# Copyright 2014 Gentoo Foundation +# Copyright 2014-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 from __future__ import unicode_literals @@ -222,6 +222,7 @@ src_install() { "PORTAGE_PYTHON" : portage_python, "PORTAGE_REPOSITORIES" : settings.repositories.config_string(), "PORTAGE_TMPDIR" : portage_tmpdir, + "PYTHONDONTWRITEBYTECODE" : os.environ.get("PYTHONDONTWRITEBYTECODE", ""), "PYTHONPATH" : pythonpath, "__PORTAGE_TEST_PATH_OVERRIDE" : fake_bin, } diff --git a/pym/portage/tests/emerge/test_emerge_slot_abi.py b/pym/portage/tests/emerge/test_emerge_slot_abi.py index d1f2d9241..200699396 100644 --- a/pym/portage/tests/emerge/test_emerge_slot_abi.py +++ b/pym/portage/tests/emerge/test_emerge_slot_abi.py @@ -1,4 +1,4 @@ -# Copyright 2012-2014 Gentoo Foundation +# Copyright 2012-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 import subprocess @@ -119,6 +119,7 @@ class SlotAbiEmergeTestCase(TestCase): "PATH" : path, "PORTAGE_PYTHON" : portage_python, "PORTAGE_REPOSITORIES" : settings.repositories.config_string(), + "PYTHONDONTWRITEBYTECODE" : os.environ.get("PYTHONDONTWRITEBYTECODE", ""), "PYTHONPATH" : pythonpath, } diff --git a/pym/portage/tests/emerge/test_simple.py b/pym/portage/tests/emerge/test_simple.py index 010136299..394ed430b 100644 --- a/pym/portage/tests/emerge/test_simple.py +++ b/pym/portage/tests/emerge/test_simple.py @@ -1,4 +1,4 @@ -# Copyright 2011-2014 Gentoo Foundation +# Copyright 2011-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 import subprocess @@ -369,6 +369,7 @@ pkg_preinst() { "PORTAGE_PYTHON" : portage_python, "PORTAGE_REPOSITORIES" : settings.repositories.config_string(), "PORTAGE_TMPDIR" : portage_tmpdir, + "PYTHONDONTWRITEBYTECODE" : os.environ.get("PYTHONDONTWRITEBYTECODE", ""), "PYTHONPATH" : pythonpath, "__PORTAGE_TEST_PATH_OVERRIDE" : fake_bin, } diff --git a/pym/portage/tests/repoman/test_simple.py b/pym/portage/tests/repoman/test_simple.py index f41f05754..af6f95d0c 100644 --- a/pym/portage/tests/repoman/test_simple.py +++ b/pym/portage/tests/repoman/test_simple.py @@ -1,4 +1,4 @@ -# Copyright 2011-2014 Gentoo Foundation +# Copyright 2011-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 import subprocess @@ -229,6 +229,7 @@ class SimpleRepomanTestCase(TestCase): "PORTAGE_GRPNAME" : os.environ["PORTAGE_GRPNAME"], "PORTAGE_USERNAME" : os.environ["PORTAGE_USERNAME"], "PORTAGE_REPOSITORIES" : settings.repositories.config_string(), + "PYTHONDONTWRITEBYTECODE" : os.environ.get("PYTHONDONTWRITEBYTECODE", ""), "PYTHONPATH" : pythonpath, } diff --git a/pym/portage/tests/sync/test_sync_local.py b/pym/portage/tests/sync/test_sync_local.py index 7753a261c..b57bdbae7 100644 --- a/pym/portage/tests/sync/test_sync_local.py +++ b/pym/portage/tests/sync/test_sync_local.py @@ -1,4 +1,4 @@ -# Copyright 2014 Gentoo Foundation +# Copyright 2014-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 import subprocess @@ -194,6 +194,7 @@ class SyncLocalTestCase(TestCase): "PATH" : os.environ["PATH"], "PORTAGE_GRPNAME" : os.environ["PORTAGE_GRPNAME"], "PORTAGE_USERNAME" : os.environ["PORTAGE_USERNAME"], + "PYTHONDONTWRITEBYTECODE" : os.environ.get("PYTHONDONTWRITEBYTECODE", ""), "PYTHONPATH" : pythonpath, } repos_set_conf("rsync") diff --git a/pym/portage/xml/metadata.py b/pym/portage/xml/metadata.py index fcd9dc0e3..33b977915 100644 --- a/pym/portage/xml/metadata.py +++ b/pym/portage/xml/metadata.py @@ -80,6 +80,8 @@ class _Maintainer(object): @ivar name: Maintainer's name. Used for both Gentoo and upstream. @type description: str or None @ivar description: Description of what a maintainer does. Gentoo only. + @type maint_type: str or None + @ivar maint_type: GLEP67 maintainer type (project or person). Gentoo only. @type restrict: str or None @ivar restrict: e.g. >=portage-2.2 means only maintains versions of Portage greater than 2.2. Should be DEPEND string with < and > @@ -92,6 +94,7 @@ class _Maintainer(object): self.email = None self.name = None self.description = None + self.maint_type = node.get('type') self.restrict = node.get('restrict') self.status = node.get('status') for attr in node: diff --git a/pym/repoman/_xml.py b/pym/repoman/_xml.py index 0acda28e6..43fc9307c 100644 --- a/pym/repoman/_xml.py +++ b/pym/repoman/_xml.py @@ -51,11 +51,12 @@ class _MetadataTreeBuilder(xml.etree.ElementTree.TreeBuilder): class XmlLint(object): - def __init__(self, options, repoman_settings): - self.metadata_dtd = os.path.join(repoman_settings["DISTDIR"], 'metadata.dtd') + def __init__(self, options, repoman_settings, metadata_dtd=None): + self.metadata_dtd = (metadata_dtd or + os.path.join(repoman_settings["DISTDIR"], 'metadata.dtd')) self.options = options self.repoman_settings = repoman_settings - self._is_capable = False + self._is_capable = metadata_dtd is not None self.binary = None self._check_capable() @@ -65,7 +66,8 @@ class XmlLint(object): self.binary = find_binary('xmllint') if not self.binary: print(red("!!! xmllint not found. Can't check metadata.xml.\n")) - else: + self._is_capable = False + elif not self._is_capable: if not fetch_metadata_dtd(self.metadata_dtd, self.repoman_settings): sys.exit(1) # this can be problematic if xmllint changes their output diff --git a/pym/repoman/checks/ebuilds/checks.py b/pym/repoman/checks/ebuilds/checks.py index e23fcfea2..7bab8e472 100644 --- a/pym/repoman/checks/ebuilds/checks.py +++ b/pym/repoman/checks/ebuilds/checks.py @@ -337,6 +337,10 @@ class EbuildPatches(LineCheck): re = re.compile(r'^\s*PATCHES=[^\(]') error = errors.PATCHES_ERROR + def check_eapi(self, eapi): + return eapi in ("0", "1", "2", "3", "4", "4-python", + "4-slot-abi", "5", "5-hdepend", "5-progress") + class EbuildQuotedA(LineCheck): """Ensure ebuilds have no quoting around ${A}""" @@ -418,6 +422,12 @@ class InheritDeprecated(LineCheck): "python": "python-r1 / python-single-r1 / python-any-r1", "ruby": "ruby-ng", "x-modular": "xorg-2", + "gst-plugins-bad": "gstreamer", + "gst-plugins-base": "gstreamer", + "gst-plugins-good": "gstreamer", + "gst-plugins-ugly": "gstreamer", + "gst-plugins10": "gstreamer", + "clutter": "gnome2", } _inherit_re = re.compile(r'^\s*inherit\s(.*)$') diff --git a/pym/repoman/checks/ebuilds/pkgmetadata.py b/pym/repoman/checks/ebuilds/pkgmetadata.py index f22ef1958..74fec6994 100644 --- a/pym/repoman/checks/ebuilds/pkgmetadata.py +++ b/pym/repoman/checks/ebuilds/pkgmetadata.py @@ -40,18 +40,20 @@ from repoman._xml import _XMLParser, _MetadataTreeBuilder, XmlLint class PkgMetadata(object): '''Package metadata.xml checks''' - def __init__(self, options, qatracker, repoman_settings): + def __init__(self, options, qatracker, repoman_settings, metadata_dtd=None): '''PkgMetadata init function @param options: ArgumentParser.parse_known_args(argv[1:]) options @param qatracker: QATracker instance @param repoman_settings: settings instance + @param metadata_dtd: path of metadata.dtd ''' self.options = options self.qatracker = qatracker self.repoman_settings = repoman_settings self.musedict = {} - self.xmllint = XmlLint(self.options, self.repoman_settings) + self.xmllint = XmlLint(self.options, self.repoman_settings, + metadata_dtd=metadata_dtd) def check(self, xpkg, checkdir, checkdirlist, repolevel): '''Performs the checks on the metadata.xml for the package diff --git a/pym/repoman/qa_data.py b/pym/repoman/qa_data.py index df9b8362b..b9475e801 100644 --- a/pym/repoman/qa_data.py +++ b/pym/repoman/qa_data.py @@ -343,6 +343,7 @@ suspect_virtual = { ruby_deprecated = frozenset([ "ruby_targets_ree18", "ruby_targets_ruby18", + "ruby_targets_ruby19", ]) diff --git a/pym/repoman/scanner.py b/pym/repoman/scanner.py index 9e5a313cd..d1c10d7b1 100644 --- a/pym/repoman/scanner.py +++ b/pym/repoman/scanner.py @@ -82,13 +82,24 @@ class Scanner(object): portage.util.stack_lists([self.categories], incremental=1)) self.categories = self.repo_settings.repoman_settings.categories + metadata_dtd = None + for path in reversed(self.repo_settings.repo_config.eclass_db.porttrees): + path = os.path.join(path, 'metadata/dtd/metadata.dtd') + if os.path.exists(path): + metadata_dtd = path + break + self.portdb = repo_settings.portdb self.portdb.settings = self.repo_settings.repoman_settings # We really only need to cache the metadata that's necessary for visibility # filtering. Anything else can be discarded to reduce memory consumption. - self.portdb._aux_cache_keys.clear() - self.portdb._aux_cache_keys.update( - ["EAPI", "IUSE", "KEYWORDS", "repository", "SLOT"]) + if self.options.mode != "manifest" and self.options.digest != "y": + # Don't do this when generating manifests, since that uses + # additional keys if spawn_nofetch is called (RESTRICT and + # DEFINED_PHASES). + self.portdb._aux_cache_keys.clear() + self.portdb._aux_cache_keys.update( + ["EAPI", "IUSE", "KEYWORDS", "repository", "SLOT"]) self.reposplit = myreporoot.split(os.path.sep) self.repolevel = len(self.reposplit) @@ -201,7 +212,8 @@ class Scanner(object): self.status_check = VCSStatus(self.vcs_settings, self.qatracker) self.fetchcheck = FetchChecks( self.qatracker, self.repo_settings, self.portdb, self.vcs_settings) - self.pkgmeta = PkgMetadata(self.options, self.qatracker, self.repo_settings.repoman_settings) + self.pkgmeta = PkgMetadata(self.options, self.qatracker, + self.repo_settings.repoman_settings, metadata_dtd=metadata_dtd) self.thirdparty = ThirdPartyMirrors(self.repo_settings.repoman_settings, self.qatracker) self.use_flag_checks = USEFlagChecks(self.qatracker, uselist) self.keywordcheck = KeywordChecks(self.qatracker, self.options) diff --git a/pym/repoman/vcs/vcsstatus.py b/pym/repoman/vcs/vcsstatus.py index 4dc633eb5..53b8ffeb5 100644 --- a/pym/repoman/vcs/vcsstatus.py +++ b/pym/repoman/vcs/vcsstatus.py @@ -67,7 +67,7 @@ class VCSStatus(object): try: myf = repoman_popen( "svn status --depth=files --verbose " + - portage._shell_quote(self.checkdir)) + portage._shell_quote(checkdir)) myl = myf.readlines() myf.close() except IOError: @@ -615,7 +615,7 @@ def get_manpages(): setup( name = 'portage', - version = '2.2.26', + version = '2.2.27', url = 'https://wiki.gentoo.org/wiki/Project:Portage', author = 'Gentoo Portage Development Team', author_email = 'dev-portage@gentoo.org', |