From fff85038d0b008964f01fa2af2f6c35552704244 Mon Sep 17 00:00:00 2001 From: Fabian Groffen Date: Sat, 15 Nov 2008 16:29:35 +0000 Subject: [PATCH] Merged from trunk -r11913:11935 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit | 11916 | Fix new* and do* ebuild helpers to generate consistent error | | zmedico | messages for missing files and generate an appropriate QA | | | Notice when such an error is detected in the build log. | | | Thanks to Diego 'Flameeyes' Pettenò for the | | | suggestion. | | 11918 | Bug #216190 - Make dblink.treewalk() bail out rather than | | zmedico | install a package with file paths containing newlines. | | 11920 | Bug #243022 - Inside dblink.mergeme(), when merging a | | zmedico | directory and a symlink is in the way, verify that if points | | | to a directory before accepting it, otherwise move it out of | | | the way. | | 11922 | Bug #236683 - Fix PermissionDenied handling to report the | | zmedico | exception type. | | 11924 | Make digestgen() handle PermissionDenied internally by | | zmedico | returning failure, so callers like repoman don't need | | | exception handling. | | 11926 | Bug #236714 - Handle PortagePackageException raised from | | zmedico | Manifest.create(). | | 11928 | Bug #173284 - Do not traverse hidden directories such as | | zmedico | .svn or .git when search for protected files. | | 11929 | Bug #173284 - Do not traverse hidden directories such as | | zmedico | .svn or .git when search for protected files. | | 11931 | Remove stray print statement from previous commit. | | zmedico | | | 11933 | Bug #173284 - Update config update counting code in | | zmedico | chk_updated_cfg_files() so hidden directories are ignored. | | 11935 | Bug #236207 - Replace some hardcoded colors with color | | zmedico | codes, and use portage.output.EOutput() where appropriate. | svn path=/main/branches/prefix/; revision=11946 --- bin/dispatch-conf | 4 +-- bin/dobin | 2 +- bin/dodoc | 2 +- bin/doexe | 3 +- bin/doinfo | 9 +++++- bin/doins | 1 + bin/doman | 2 +- bin/domo | 2 +- bin/ebuild | 9 +++++- bin/etc-update | 8 +++-- bin/newbin | 5 +++ bin/newconfd | 5 +++ bin/newdoc | 5 +++ bin/newenvd | 5 +++ bin/newexe | 5 +++ bin/newinitd | 5 +++ bin/newins | 5 +++ bin/newlib.a | 5 +++ bin/newlib.so | 5 +++ bin/newman | 5 +++ bin/newsbin | 5 +++ pym/_emerge/__init__.py | 62 +++++++++++++++++++++--------------- pym/portage/__init__.py | 23 +++++++++++-- pym/portage/dbapi/vartree.py | 28 ++++++++++++++-- 24 files changed, 167 insertions(+), 43 deletions(-) diff --git a/bin/dispatch-conf b/bin/dispatch-conf index 557a50734..cf42a1ce5 100755 --- a/bin/dispatch-conf +++ b/bin/dispatch-conf @@ -31,7 +31,7 @@ import portage from portage import dispatch_conf, const from portage.process import find_binary -FIND_EXTANT_CONFIGS = "find '%s' %s -iname '._cfg????_%s' ! -iname '.*~' ! -iname '.*.bak'" +FIND_EXTANT_CONFIGS = "find '%s' %s -name '._cfg????_%s' ! -name '.*~' ! -iname '.*.bak' -print" DIFF_CONTENTS = "diff -Nu '%s' '%s'" DIFF_CVS_INTERP = "diff -Nu '%s' '%s' | grep '^[+-][^+-]' | grep -v '# .Header:.*'" DIFF_WSCOMMENTS = "diff -Nu '%s' '%s' | grep '^[+-][^+-]' | grep -v '^[-+]#' | grep -v '^[-+][:space:]*$'" @@ -96,7 +96,7 @@ class dispatch: except OSError: continue basename = "*" - find_opts = "" + find_opts = "-name '.*' -type d -prune -o" if not stat.S_ISDIR(mymode): path, basename = os.path.split(path) find_opts = "-maxdepth 1" diff --git a/bin/dobin b/bin/dobin index 57a07a809..274d4f409 100755 --- a/bin/dobin +++ b/bin/dobin @@ -20,7 +20,7 @@ for x in "$@" ; do if [[ -e ${x} ]] ; then install -m 0755 -o ${PORTAGE_INST_UID:-0} -g ${PORTAGE_INST_GID:-0} "${x}" "${ED}${DESTTREE}/bin" else - vecho "!!! ${0##*/}: ${x} does not exist" 1>&2 + echo "!!! ${0##*/}: $x does not exist" 1>&2 false fi ((ret+=$?)) diff --git a/bin/dodoc b/bin/dodoc index 343ee91f3..bdfbe7aef 100755 --- a/bin/dodoc +++ b/bin/dodoc @@ -20,7 +20,7 @@ for x in "$@" ; do install -m0644 "${x}" "${dir}" ecompress --queue "${dir}/${x##*/}" elif [ ! -e "${x}" ] ; then - echo "dodoc: ${x} does not exist" 1>&2 + echo "!!! ${0##*/}: $x does not exist" 1>&2 ((++ret)) fi done diff --git a/bin/doexe b/bin/doexe index cfb6a72e2..bd278e52e 100755 --- a/bin/doexe +++ b/bin/doexe @@ -24,5 +24,6 @@ for x in "$@" ; do else mysrc="${x}" fi - install ${EXEOPTIONS} "${mysrc}" "${ED}${_E_EXEDESTTREE_}" + install $EXEOPTIONS "$mysrc" "$ED$_E_EXEDESTTREE_" || \ + echo "!!! ${0##*/}: $mysrc does not exist" 1>&2 done diff --git a/bin/doinfo b/bin/doinfo index c263a093a..a00885c0c 100755 --- a/bin/doinfo +++ b/bin/doinfo @@ -12,4 +12,11 @@ if [[ ! -d ${ED}usr/share/info ]] ; then install -d "${ED}usr/share/info" || exit 1 fi -exec install -m0644 "$@" "${ED}usr/share/info" +install -m0644 "$@" "${ED}usr/share/info" +rval=$? +if [ $rval -ne 0 ] ; then + for x in "$@" ; do + [ -e "$x" ] || echo "!!! ${0##*/}: $x does not exist" 1>&2 + done +fi +exit $rval diff --git a/bin/doins b/bin/doins index e823da782..a1141ccfe 100755 --- a/bin/doins +++ b/bin/doins @@ -51,6 +51,7 @@ _doins() { install ${INSOPTIONS} "${mysrc}" "${ED}${INSDESTTREE}/${mydir}" rval=$? [[ -n ${cleanup} ]] && rm -f "${cleanup}" + [ $rval -ne 0 ] && echo "!!! ${0##*/}: $mysrc does not exist" 1>&2 return $rval } diff --git a/bin/doman b/bin/doman index 0ee656bef..88e87be87 100755 --- a/bin/doman +++ b/bin/doman @@ -49,7 +49,7 @@ for x in "$@" ; do install -m0644 "${x}" "${ED}/usr/share/man/${mandir}/${name}" ((ret+=$?)) elif [[ ! -e ${x} ]] ; then - vecho "doman: ${x} does not exist" 1>&2 + echo "!!! ${0##*/}: $x does not exist" 1>&2 ((++ret)) fi else diff --git a/bin/domo b/bin/domo index 9f41c360d..2f1295e9c 100755 --- a/bin/domo +++ b/bin/domo @@ -21,6 +21,6 @@ for x in "$@" ; do fi install -m0644 "${x}" "${mydir}/${MOPREFIX}.mo" else - echo "${0}: ${x} does not exist" + echo "!!! ${0##*/}: $x does not exist" 1>&2 fi done diff --git a/bin/ebuild b/bin/ebuild index 03fbe08a2..80c4d744e 100755 --- a/bin/ebuild +++ b/bin/ebuild @@ -205,7 +205,8 @@ def stale_env_warning(): for x in msg: portage.writemsg(">>> %s\n" % x) -from portage.exception import UnsupportedAPIException +from portage.exception import PermissionDenied, \ + PortagePackageException, UnsupportedAPIException checked_for_stale_env = False for arg in pargs: @@ -233,6 +234,12 @@ for arg in pargs: for x in msg: portage.writemsg("!!! %s\n" % x, noiselevel=-1) a = 1 + except PortagePackageException, e: + portage.writemsg("!!! %s\n" % (e,), noiselevel=-1) + a = 1 + except PermissionDenied, e: + portage.writemsg("!!! Permission Denied: %s\n" % (e,), noiselevel=-1) + a = 1 if a == None: print "Could not run the required binary?" a = 127 diff --git a/bin/etc-update b/bin/etc-update index ad0419be6..a9b056831 100755 --- a/bin/etc-update +++ b/bin/etc-update @@ -50,17 +50,19 @@ scan() { for path in ${CONFIG_PROTECT} ; do path="${EROOT}${path}" - find_opts="-iname ._cfg????_*" + # Do not traverse hidden directories such as .svn or .git. + find_opts="-name .* -type d -prune -o -name ._cfg????_*" if [ ! -d "${path}" ]; then [ ! -f "${path}" ] && continue my_basename="${path##*/}" path="${path%/*}" - find_opts="-maxdepth 1 -iname ._cfg????_${my_basename}" + find_opts="-maxdepth 1 -name ._cfg????_${my_basename}" fi ofile="" # The below set -f turns off file name globbing in the ${find_opts} expansion. - for file in $(set -f; find ${path}/ ${find_opts} ! -iname '.*~' ! -iname '.*.bak' | + for file in $(set -f ; find ${path}/ ${find_opts} \ + ! -name '.*~' ! -iname '.*.bak' -print | sed -e "s:\(^.*/\)\(\._cfg[0-9]*_\)\(.*$\):\1\2\3\%\2\%\3:" | sort -t'%' -k3 -k2 | LANG=POSIX LC_ALL=POSIX cut -f1 -d'%'); do diff --git a/bin/newbin b/bin/newbin index b45dd8497..925229329 100755 --- a/bin/newbin +++ b/bin/newbin @@ -8,6 +8,11 @@ if [[ -z ${T} ]] || [[ -z ${2} ]] ; then exit 1 fi +if [ ! -e "$1" ] ; then + echo "!!! ${0##*/}: $1 does not exist" 1>&2 + exit 1 +fi + rm -rf "${T}/${2}" && \ cp -f "${1}" "${T}/${2}" && \ exec dobin "${T}/${2}" diff --git a/bin/newconfd b/bin/newconfd index 9ce6d4069..877ddfdc1 100755 --- a/bin/newconfd +++ b/bin/newconfd @@ -8,6 +8,11 @@ if [[ -z ${T} ]] || [[ -z ${2} ]] ; then exit 1 fi +if [ ! -e "$1" ] ; then + echo "!!! ${0##*/}: $1 does not exist" 1>&2 + exit 1 +fi + rm -rf "${T}/${2}" && \ cp -f "${1}" "${T}/${2}" && \ exec doconfd "${T}/${2}" diff --git a/bin/newdoc b/bin/newdoc index 8b41093f4..82e8c5ca8 100755 --- a/bin/newdoc +++ b/bin/newdoc @@ -8,6 +8,11 @@ if [[ -z ${T} ]] || [[ -z ${2} ]] ; then exit 1 fi +if [ ! -e "$1" ] ; then + echo "!!! ${0##*/}: $1 does not exist" 1>&2 + exit 1 +fi + rm -rf "${T}/${2}" && \ cp -f "${1}" "${T}/${2}" && \ exec dodoc "${T}/${2}" diff --git a/bin/newenvd b/bin/newenvd index ece766bf3..5628cc7d2 100755 --- a/bin/newenvd +++ b/bin/newenvd @@ -8,6 +8,11 @@ if [[ -z ${T} ]] || [[ -z ${2} ]] ; then exit 1 fi +if [ ! -e "$1" ] ; then + echo "!!! ${0##*/}: $1 does not exist" 1>&2 + exit 1 +fi + rm -rf "${T}/${2}" && \ cp -f "${1}" "${T}/${2}" && \ exec doenvd "${T}/${2}" diff --git a/bin/newexe b/bin/newexe index 6bd52418c..007bcdaa8 100755 --- a/bin/newexe +++ b/bin/newexe @@ -8,6 +8,11 @@ if [[ -z ${T} ]] || [[ -z ${2} ]] ; then exit 1 fi +if [ ! -e "$1" ] ; then + echo "!!! ${0##*/}: $1 does not exist" 1>&2 + exit 1 +fi + rm -rf "${T}/${2}" && \ cp -f "${1}" "${T}/${2}" && \ exec doexe "${T}/${2}" diff --git a/bin/newinitd b/bin/newinitd index 5ab06d3af..9f5ed7296 100755 --- a/bin/newinitd +++ b/bin/newinitd @@ -8,6 +8,11 @@ if [[ -z ${T} ]] || [[ -z ${2} ]] ; then exit 1 fi +if [ ! -e "$1" ] ; then + echo "!!! ${0##*/}: $1 does not exist" 1>&2 + exit 1 +fi + rm -rf "${T}/${2}" && \ cp -f "${1}" "${T}/${2}" && \ exec doinitd "${T}/${2}" diff --git a/bin/newins b/bin/newins index a0e58bed8..f3ce74cbc 100755 --- a/bin/newins +++ b/bin/newins @@ -8,6 +8,11 @@ if [[ -z ${T} ]] || [[ -z ${2} ]] ; then exit 1 fi +if [ ! -e "$1" ] ; then + echo "!!! ${0##*/}: $1 does not exist" 1>&2 + exit 1 +fi + rm -rf "${T}/${2}" || exit $? cp -f "${1}" "${T}/${2}" || exit $? doins "${T}/${2}" diff --git a/bin/newlib.a b/bin/newlib.a index f26abfbcb..b84dc1295 100755 --- a/bin/newlib.a +++ b/bin/newlib.a @@ -8,6 +8,11 @@ if [[ -z ${T} ]] || [[ -z ${2} ]] ; then exit 1 fi +if [ ! -e "$1" ] ; then + echo "!!! ${0##*/}: $1 does not exist" 1>&2 + exit 1 +fi + rm -rf "${T}/${2}" && \ cp -f "${1}" "${T}/${2}" && \ exec dolib.a "${T}/${2}" diff --git a/bin/newlib.so b/bin/newlib.so index 558bc2fc0..649f18895 100755 --- a/bin/newlib.so +++ b/bin/newlib.so @@ -8,6 +8,11 @@ if [[ -z ${T} ]] || [[ -z ${2} ]] ; then exit 1 fi +if [ ! -e "$1" ] ; then + echo "!!! ${0##*/}: $1 does not exist" 1>&2 + exit 1 +fi + rm -rf "${T}/${2}" && \ cp -f "${1}" "${T}/${2}" && \ exec dolib.so "${T}/${2}" diff --git a/bin/newman b/bin/newman index 5273fc64c..32e4486b4 100755 --- a/bin/newman +++ b/bin/newman @@ -8,6 +8,11 @@ if [[ -z ${T} ]] || [[ -z ${2} ]] ; then exit 1 fi +if [ ! -e "$1" ] ; then + echo "!!! ${0##*/}: $1 does not exist" 1>&2 + exit 1 +fi + rm -rf "${T}/${2}" && \ cp -f "${1}" "${T}/${2}" && \ exec doman "${T}/${2}" diff --git a/bin/newsbin b/bin/newsbin index 74acaf170..8240edf8a 100755 --- a/bin/newsbin +++ b/bin/newsbin @@ -8,6 +8,11 @@ if [[ -z ${T} ]] || [[ -z ${2} ]] ; then exit 1 fi +if [ ! -e "$1" ] ; then + echo "!!! ${0##*/}: $1 does not exist" 1>&2 + exit 1 +fi + rm -rf "${T}/${2}" && \ cp -f "${1}" "${T}/${2}" && \ exec dosbin "${T}/${2}" diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index d2c9470f5..4a1e55b78 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -5377,7 +5377,10 @@ class depgraph(object): print "- "+pkg.cpv+" ("+", ".join(mreasons)+")" elif masked_packages: - print "\n!!! "+red("All ebuilds that could satisfy ")+green(xinfo)+red(" have been masked.") + print "\n!!! " + \ + colorize("BAD", "All ebuilds that could satisfy ") + \ + colorize("INFORM", xinfo) + \ + colorize("BAD", " have been masked.") print "!!! One of the following masked packages is required to complete your request:" have_eapi_mask = show_masked_packages(masked_packages) if have_eapi_mask: @@ -11022,6 +11025,7 @@ def unmerge(root_config, myopts, unmerge_action, def chk_updated_info_files(root, infodirs, prev_mtimes, retval): if os.path.exists(EPREFIX+"/usr/bin/install-info"): + out = portage.output.EOutput() regen_infodirs=[] for z in infodirs: if z=='': @@ -11034,13 +11038,16 @@ def chk_updated_info_files(root, infodirs, prev_mtimes, retval): regen_infodirs.append(inforoot) if not regen_infodirs: - portage.writemsg_stdout("\n "+green("*")+" GNU info directory index is up-to-date.\n") + portage.writemsg_stdout("\n") + out.einfo("GNU info directory index is up-to-date.") else: - portage.writemsg_stdout("\n "+green("*")+" Regenerating GNU info directory index...\n") + portage.writemsg_stdout("\n") + out.einfo("Regenerating GNU info directory index...") dir_extensions = ("", ".gz", ".bz2") icount=0 badcount=0 + errmsg = "" for inforoot in regen_infodirs: if inforoot=='': continue @@ -11048,7 +11055,7 @@ def chk_updated_info_files(root, infodirs, prev_mtimes, retval): if not os.path.isdir(inforoot) or \ not os.access(inforoot, os.W_OK): continue - errmsg = "" + file_list = os.listdir(inforoot) file_list.sort() dir_file = os.path.join(inforoot, "dir") @@ -11118,11 +11125,12 @@ def chk_updated_info_files(root, infodirs, prev_mtimes, retval): prev_mtimes[inforoot] = long(os.stat(inforoot).st_mtime) if badcount: - print " "+yellow("*")+" Processed",icount,"info files;",badcount,"errors." - print errmsg + out.eerror("Processed %d info files; %d errors." % \ + (icount, badcount)) + writemsg_level(errmsg, level=logging.ERROR, noiselevel=-1) else: if icount > 0: - print " "+green("*")+" Processed",icount,"info files." + out.einfo("Processed %d info files." % (icount,)) def display_news_notification(root_config, myopts): @@ -11333,11 +11341,11 @@ def chk_updated_cfg_files(target_root, config_protect): except OSError: pass if stat.S_ISDIR(mymode): - mycommand = "find '%s' -iname '._cfg????_*'" % x + mycommand = "find '%s' -name '.*' -type d -prune -o -name '._cfg????_*'" % x else: - mycommand = "find '%s' -maxdepth 1 -iname '._cfg????_%s'" % \ + mycommand = "find '%s' -maxdepth 1 -name '._cfg????_%s'" % \ os.path.split(x.rstrip(os.path.sep)) - mycommand += " ! -iname '.*~' ! -iname '.*.bak' -print0" + mycommand += " ! -name '.*~' ! -iname '.*.bak' -print0" a = commands.getstatusoutput(mycommand) if a[0] != 0: sys.stderr.write(" %s error scanning '%s': " % (bad("*"), x)) @@ -11420,6 +11428,7 @@ def action_sync(settings, trees, mtimedb, myopts, myaction): xterm_titles = "notitles" not in settings.features emergelog(xterm_titles, " === sync") myportdir = settings.get("PORTDIR", None) + out = portage.output.EOutput() if not myportdir: sys.stderr.write("!!! PORTDIR is undefined. Is /etc/make.globals missing?\n") sys.exit(1) @@ -11749,26 +11758,27 @@ def action_sync(settings, trees, mtimedb, myopts, myaction): ">>> Exceeded PORTAGE_RSYNC_RETRIES: %s\n" % maxretries) sys.exit(1) elif (exitcode>0): - print + msg = [] if exitcode==1: - print darkred("!!!")+green(" Rsync has reported that there is a syntax error. Please ensure") - print darkred("!!!")+green(" that your SYNC statement is proper.") - print darkred("!!!")+green(" SYNC="+settings["SYNC"]) + msg.append("Rsync has reported that there is a syntax error. Please ensure") + msg.append("that your SYNC statement is proper.") + msg.append("SYNC=" + settings["SYNC"]) elif exitcode==11: - print darkred("!!!")+green(" Rsync has reported that there is a File IO error. Normally") - print darkred("!!!")+green(" this means your disk is full, but can be caused by corruption") - print darkred("!!!")+green(" on the filesystem that contains PORTDIR. Please investigate") - print darkred("!!!")+green(" and try again after the problem has been fixed.") - print darkred("!!!")+green(" PORTDIR="+settings["PORTDIR"]) + msg.append("Rsync has reported that there is a File IO error. Normally") + msg.append("this means your disk is full, but can be caused by corruption") + msg.append("on the filesystem that contains PORTDIR. Please investigate") + msg.append("and try again after the problem has been fixed.") + msg.append("PORTDIR=" + settings["PORTDIR"]) elif exitcode==20: - print darkred("!!!")+green(" Rsync was killed before it finished.") + msg.append("Rsync was killed before it finished.") else: - print darkred("!!!")+green(" Rsync has not successfully finished. It is recommended that you keep") - print darkred("!!!")+green(" trying or that you use the 'emerge-webrsync' option if you are unable") - print darkred("!!!")+green(" to use rsync due to firewall or other restrictions. This should be a") - print darkred("!!!")+green(" temporary problem unless complications exist with your network") - print darkred("!!!")+green(" (and possibly your system's filesystem) configuration.") - print + msg.append("Rsync has not successfully finished. It is recommended that you keep") + msg.append("trying or that you use the 'emerge-webrsync' option if you are unable") + msg.append("to use rsync due to firewall or other restrictions. This should be a") + msg.append("temporary problem unless complications exist with your network") + msg.append("(and possibly your system's filesystem) configuration.") + for line in msg: + out.eerror(line) sys.exit(exitcode) elif syncuri[:6]=="cvs://": if not os.path.exists(EPREFIX+"/usr/bin/cvs"): diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index b09acaf70..7e75f18f8 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -4280,7 +4280,14 @@ def digestgen(myarchives, mysettings, overwrite=1, manifestonly=0, myportdb=None writemsg(("!!! File %s doesn't exist, can't update " + \ "Manifest\n") % e, noiselevel=-1) return 0 - mf.write(sign=False) + except portage.exception.PortagePackageException, e: + writemsg(("!!! %s\n") % (e,), noiselevel=-1) + return 0 + try: + mf.write(sign=False) + except portage.exception.PermissionDenied, e: + writemsg("!!! Permission Denied: %s\n" % (e,), noiselevel=-1) + return 0 if "assume-digests" not in mysettings.features: distlist = mf.fhashdict.get("DIST", {}).keys() distlist.sort() @@ -4522,6 +4529,9 @@ def _check_build_log(mysettings, out=None): bash_command_not_found = [] bash_command_not_found_re = re.compile( r'(.*): line (\d*): (.*): command not found$') + helper_missing_file = [] + helper_missing_file_re = re.compile( + r'^!!! (do|new).*: .* does not exist$') configure_opts_warn = [] configure_opts_warn_re = re.compile( @@ -4538,6 +4548,9 @@ def _check_build_log(mysettings, out=None): if bash_command_not_found_re.match(line) is not None: bash_command_not_found.append(line.rstrip("\n")) + if helper_missing_file_re.match(line) is not None: + helper_missing_file.append(line.rstrip("\n")) + if configure_opts_warn_re.match(line) is not None: configure_opts_warn.append(line.rstrip("\n")) finally: @@ -4574,6 +4587,12 @@ def _check_build_log(mysettings, out=None): msg.extend("\t" + line for line in bash_command_not_found) _eqawarn(msg) + if helper_missing_file: + msg = ["QA Notice: file does not exist:"] + msg.append("") + msg.extend("\t" + line[4:] for line in helper_missing_file) + _eqawarn(msg) + if configure_opts_warn: msg = ["QA Notice: Unrecognized configure options:"] msg.append("") @@ -5732,7 +5751,7 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, elif "digest" in mysettings.features: digestgen(aalist, mysettings, overwrite=0, myportdb=mydbapi) except portage.exception.PermissionDenied, e: - writemsg("!!! %s\n" % str(e), noiselevel=-1) + writemsg("!!! Permission Denied: %s\n" % (e,), noiselevel=-1) if mydo in ("digest", "manifest"): return 1 diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py index 3ed3c55b6..1d060b3b7 100644 --- a/pym/portage/dbapi/vartree.py +++ b/pym/portage/dbapi/vartree.py @@ -3609,19 +3609,40 @@ class dblink(object): myfilelist = [] mylinklist = [] + paths_with_newlines = [] + srcroot_len = len(srcroot) def onerror(e): raise for parent, dirs, files in os.walk(srcroot, onerror=onerror): for f in files: file_path = os.path.join(parent, f) + relative_path = file_path[srcroot_len:] + + if "\n" in relative_path: + paths_with_newlines.append(relative_path) + file_mode = os.lstat(file_path).st_mode if stat.S_ISREG(file_mode): - myfilelist.append(file_path[len(srcroot):]) + myfilelist.append(relative_path) elif stat.S_ISLNK(file_mode): # Note: os.walk puts symlinks to directories in the "dirs" # list and it does not traverse them since that could lead # to an infinite recursion loop. - mylinklist.append(file_path[len(srcroot):]) + mylinklist.append(relative_path) + + if paths_with_newlines: + msg = [] + msg.append("This package installs one or more files containing") + msg.append("a newline (\\n) character:") + msg.append("") + paths_with_newlines.sort() + for f in paths_with_newlines: + msg.append("\t/%s" % (f.replace("\n", "\\n"))) + msg.append("") + msg.append("package %s NOT merged" % self.mycpv) + msg.append("") + eerror(msg) + return 1 # If there are no files to merge, and an installed package in the same # slot has files, it probably means that something went wrong. @@ -4181,7 +4202,8 @@ class dblink(object): writemsg("!!! And finish by running this: env-update\n\n") return 1 - if stat.S_ISLNK(mydmode) or stat.S_ISDIR(mydmode): + if stat.S_ISDIR(mydmode) or \ + (stat.S_ISLNK(mydmode) and os.path.isdir(mydest)): # a symlink to an existing directory will work for us; keep it: showMessage("--- %s/\n" % mydest) if bsd_chflags: -- 2.26.2