From f52aa8f84d11191a14837b831ec6dcbffd0cdfa0 Mon Sep 17 00:00:00 2001 From: Fabian Groffen Date: Sun, 25 Nov 2007 16:27:00 +0000 Subject: [PATCH] Merged from trunk 8642:8659 | 8643 | Use `md5` if `md5sum` is not available (useful for FreeBSD | | zmedico | users). | | 8645 | Bug #140180 - Never trigger a LICENSE.missing violation for | | zmedico | old style virtuals since they don't directly install | | | anything. | | 8647 | Bug #200238 - Make ebuild.sh properly bail out when the | | zmedico | pkg_info() function doesn't exist. | | 8649 | Implement loading of environment.bz2 for the pkg_info() | | zmedico | phase. Since a temporary directory is required for | | | processing of ${T}/environment, and we want a user who's not | | | in the portage group to be able to run the pkg_info() phase, | | | PORTAGE_TMPDIR is temporarily overridden with a directory | | | created by mkdtemp. To make this work, doebuild() creates | | | the tempdir and cleans it up in a finally block. | | 8651 | * Load environment.bz2 for the pkg_config() phase. * Run the | | zmedico | "clean" phase if pkg_config() succeeds. | | 8653 | The qa_call() function and anything before it are portage | | zmedico | internals that the user will not be interested in. | | | Therefore, the stack trace should only show calls that come | | | after qa_call(). | | 8654 | Test if ebuild functions are defined before calling them. | | zmedico | This will be useful if an environment.bz2 has been loaded | | | and it has missing functions for some reason. For example, | | | there are a lot of default functions that are empty and | | | could simply be omitted from the environment. | | 8655 | Remove the empty default pkg_setup, src_install, | | zmedico | pkg_preinst, pkg_postinst, pkg_prerm, pkg_postrm, and | | | pkg_config functions since they do nothing more than clutter | | | the environment. | | 8659 | Allow the pkg_info and pkg_config pre/post hooks to run even | | zmedico | when the ebuild function is not defined. | svn path=/main/branches/prefix/; revision=8661 --- bin/ebuild.sh | 76 +++++++++++++-------------------------- bin/isolated-functions.sh | 12 ++++++- bin/misc-functions.sh | 12 +++++-- bin/repoman | 6 ++-- pym/_emerge/__init__.py | 8 ++++- pym/portage/__init__.py | 29 +++++++++++++-- 6 files changed, 83 insertions(+), 60 deletions(-) diff --git a/bin/ebuild.sh b/bin/ebuild.sh index cd68edc57..f8b33f698 100755 --- a/bin/ebuild.sh +++ b/bin/ebuild.sh @@ -549,10 +549,6 @@ einstall() { fi } -pkg_setup() { - return -} - pkg_nofetch() { [ -z "${SRC_URI}" ] && return @@ -603,26 +599,6 @@ src_install() { return } -pkg_preinst() { - return -} - -pkg_postinst() { - return -} - -pkg_prerm() { - return -} - -pkg_postrm() { - return -} - -pkg_config() { - eerror "This ebuild does not have a config function." -} - # Used to generate the /lib/cpp and /usr/bin/cc wrappers gen_wrapper() { cat > "$1" <<-EOF @@ -632,10 +608,19 @@ gen_wrapper() { chmod 0755 "$1" } +ebuild_phase() { + [ "$(type -t ${1})" == "function" ] && qa_call ${1} +} + +ebuild_phase_with_hooks() { + local x phase_name=${1} + for x in {pre_,,post_}${phase_name} ; do + ebuild_phase ${x} + done +} + dyn_setup() { - [ "$(type -t pre_pkg_setup)" == "function" ] && qa_call pre_pkg_setup - qa_call pkg_setup - [ "$(type -t post_pkg_setup)" == "function" ] && qa_call post_pkg_setup + ebuild_phase_with_hooks pkg_setup } dyn_unpack() { @@ -683,7 +668,7 @@ dyn_unpack() { fi cd "${WORKDIR}" || die "Directory change failed: \`cd '${WORKDIR}'\`" vecho ">>> Unpacking source..." - qa_call src_unpack + ebuild_phase src_unpack touch "${PORTAGE_BUILDDIR}/.unpacked" || die "IO Failure -- Failed 'touch .unpacked' in ${PORTAGE_BUILDDIR}" vecho ">>> Source unpacked." cd "${PORTAGE_BUILDDIR}" @@ -905,7 +890,7 @@ dyn_compile() { #our libtool to create problematic .la files export PWORKDIR="$WORKDIR" vecho ">>> Compiling source in ${srcdir} ..." - qa_call src_compile + ebuild_phase src_compile vecho ">>> Source compiled." #|| abort_compile "fail" cd "${PORTAGE_BUILDDIR}" @@ -944,7 +929,7 @@ dyn_test() { vecho ">>> Test phase [explicitly disabled]: ${CATEGORY}/${PF}" else addpredict / - qa_call src_test + ebuild_phase src_test SANDBOX_PREDICT="${SANDBOX_PREDICT%:/}" fi @@ -980,7 +965,7 @@ dyn_install() { #some packages uses an alternative to $S to build in, cause #our libtool to create problematic .la files export PWORKDIR="$WORKDIR" - qa_call src_install + ebuild_phase src_install touch "${PORTAGE_BUILDDIR}/.installed" vecho ">>> Completed installing ${PF} into ${ED}" vecho @@ -1029,12 +1014,7 @@ dyn_preinst() { eerror "${FUNCNAME}: D is unset" return 1 fi - - [ "$(type -t pre_pkg_preinst)" == "function" ] && qa_call pre_pkg_preinst - - pkg_preinst - - [ "$(type -t post_pkg_preinst)" == "function" ] && qa_call post_pkg_preinst + ebuild_phase_with_hooks pkg_preinst } dyn_help() { @@ -1477,7 +1457,7 @@ save_ebuild_env() { debug-print-section inherit EXPORT_FUNCTIONS newdepend newrdepend \ newpdepend do_newdepend remove_path_entry killparent \ save_ebuild_env filter_readonly_variables preprocess_ebuild_env \ - source_all_bashrcs + source_all_bashrcs ebuild_phase ebuild_phase_with_hooks # portage config variables and variables set directly by portage unset ACCEPT_KEYWORDS AUTOCLEAN BAD BRACKET BUILD_PREFIX CLEAN_DELAY \ @@ -1629,7 +1609,8 @@ if hasq "depend" "${EBUILD_SH_ARGS}"; then unset BIN_PATH BIN BODY FUNC_SRC fi -if hasq ${EBUILD_PHASE} setup prerm && [ ! -f "${T}/environment" ]; then +if hasq ${EBUILD_PHASE} config info prerm setup \ + && [ ! -f "${T}/environment" ] ; then bzip2 -dc "${EBUILD%/*}"/environment.bz2 > \ "${T}/environment" 2> /dev/null if [ -s "${T}/environment" ] ; then @@ -1754,29 +1735,20 @@ fi if [ -n "${EBUILD_SH_ARGS}" ] ; then case ${EBUILD_SH_ARGS} in nofetch) - qa_call pkg_nofetch + ebuild_phase_with_hooks pkg_nofetch exit 1 ;; prerm|postrm|postinst|config|info) - if [ "${EBUILD_SH_ARGS}" == "info" ] && \ + if hasq ${EBUILD_SH_ARGS} config info && \ [ "$(type -t pkg_${EBUILD_SH_ARGS})" != "function" ]; then ewarn "pkg_${EBUILD_SH_ARGS}() is not defined: '${EBUILD##*/}'" - continue fi export SANDBOX_ON="0" if [ "${PORTAGE_DEBUG}" != "1" ] || [ "${-/x/}" != "$-" ]; then - [ "$(type -t pre_pkg_${EBUILD_SH_ARGS})" == "function" ] && \ - qa_call pre_pkg_${EBUILD_SH_ARGS} - qa_call pkg_${EBUILD_SH_ARGS} - [ "$(type -t post_pkg_${EBUILD_SH_ARGS})" == "function" ] && \ - qa_call post_pkg_${EBUILD_SH_ARGS} + ebuild_phase_with_hooks pkg_${EBUILD_SH_ARGS} else set -x - [ "$(type -t pre_pkg_${EBUILD_SH_ARGS})" == "function" ] && \ - qa_call pre_pkg_${EBUILD_SH_ARGS} - qa_call pkg_${EBUILD_SH_ARGS} - [ "$(type -t post_pkg_${EBUILD_SH_ARGS})" == "function" ] && \ - qa_call post_pkg_${EBUILD_SH_ARGS} + ebuild_phase_with_hooks pkg_${EBUILD_SH_ARGS} set +x fi ;; diff --git a/bin/isolated-functions.sh b/bin/isolated-functions.sh index 743a1187f..3d54a01d7 100755 --- a/bin/isolated-functions.sh +++ b/bin/isolated-functions.sh @@ -20,8 +20,18 @@ dump_trace() { declare -i strip=${1:-1} local filespacing=$2 linespacing=$3 + # The qa_call() function and anything before it are portage internals + # that the user will not be interested in. Therefore, the stack trace + # should only show calls that come after qa_call(). + (( n = ${#FUNCNAME[@]} - 1 )) + while (( n > 0 )) ; do + [ "${FUNCNAME[${n}]}" == "qa_call" ] && break + (( n-- )) + done + (( n == 0 )) && (( n = ${#FUNCNAME[@]} - 1 )) + eerror "Call stack:" - for (( n = ${#FUNCNAME[@]} - 1, p = ${#BASH_ARGV[@]} ; n > ${strip} ; n-- )) ; do + for (( p = ${#BASH_ARGV[@]} ; n > ${strip} ; n-- )) ; do funcname=${FUNCNAME[${n} - 1]} sourcefile=$(basename ${BASH_SOURCE[${n}]}) lineno=${BASH_LINENO[${n} - 1]} diff --git a/bin/misc-functions.sh b/bin/misc-functions.sh index 0c1eb7c66..f97470c01 100644 --- a/bin/misc-functions.sh +++ b/bin/misc-functions.sh @@ -613,8 +613,16 @@ dyn_package() { rm -f "${PORTAGE_BINPKG_TMPFILE}" die "Failed to append metadata to the tbz2 file" fi - local md5sum_output=$(md5sum "${PORTAGE_BINPKG_TMPFILE}") - echo ${md5sum_output%% *} > "${PORTAGE_BUILDDIR}"/build-info/BINPKGMD5 + local md5_hash="" + if type md5sum &>/dev/null ; then + md5_hash=$(md5sum "${PORTAGE_BINPKG_TMPFILE}") + md5_hash=${md5_hash%% *} + elif type md5 &>/dev/null ; then + md5_hash=$(md5 "${PORTAGE_BINPKG_TMPFILE}") + md5_hash=${md5_hash##* } + fi + [ -n "${md5_hash}" ] && \ + echo ${md5_hash} > "${PORTAGE_BUILDDIR}"/build-info/BINPKGMD5 vecho ">>> Done." cd "${PORTAGE_BUILDDIR}" touch .packaged || die "Failed to 'touch .packaged' in ${PORTAGE_BUILDDIR}" diff --git a/bin/repoman b/bin/repoman index 6fd5e9b32..4705dfd2c 100755 --- a/bin/repoman +++ b/bin/repoman @@ -1208,8 +1208,10 @@ for x in scanlist: stats["virtual.exists"]+=1 fails["virtual.exists"].append(x+"/"+y+".ebuild: "+prov_cp) - for pos in range(0,len(missingvars)): - if not myaux[missingvars[pos]]: + for pos, missing_var in enumerate(missingvars): + if not myaux.get(missing_var): + if missing_var == "LICENSE" and catdir == "virtual": + continue myqakey=missingvars[pos]+".missing" stats[myqakey]=stats[myqakey]+1 fails[myqakey].append(x+"/"+y+".ebuild") diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index 0d089dea4..66f81cca0 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -5832,9 +5832,15 @@ def action_config(settings, trees, myopts, myfiles): print ebuildpath = trees[settings["ROOT"]]["vartree"].dbapi.findname(pkg) mysettings = portage.config(clone=settings) - portage.doebuild(ebuildpath, "config", settings["ROOT"], mysettings, + vardb = trees[mysettings["ROOT"]]["vartree"].dbapi + debug = mysettings.get("PORTAGE_DEBUG") == "1" + retval = portage.doebuild(ebuildpath, "config", mysettings["ROOT"], + mysettings, debug=(settings.get("PORTAGE_DEBUG", "") == 1), cleanup=True, mydbapi=trees[settings["ROOT"]]["vartree"].dbapi, tree="vartree") + if retval == os.EX_OK: + portage.doebuild(ebuildpath, "clean", mysettings["ROOT"], + mysettings, debug=debug, mydbapi=vardb, tree="vartree") print def action_info(settings, trees, myopts, myfiles): diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 1a56afab2..eb3877323 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -3633,6 +3633,10 @@ def doebuild_environment(myebuild, mydo, myroot, mysettings, debug, use_cache, m raise portage.exception.IncorrectParameter( "Invalid ebuild path: '%s'" % myebuild) + # Make a backup of PORTAGE_TMPDIR prior to calling config.reset() + # so that the caller can override it. + tmpdir = mysettings["PORTAGE_TMPDIR"] + if mydo != "depend": """For performance reasons, setcpv only triggers reset when it detects a package-specific change in config. For the ebuild @@ -3642,6 +3646,10 @@ def doebuild_environment(myebuild, mydo, myroot, mysettings, debug, use_cache, m mysettings.reset(use_cache=use_cache) mysettings.setcpv(mycpv, use_cache=use_cache, mydb=mydbapi) + # config.reset() might have reverted a change made by the caller, + # so restore it to it's original value. + mysettings["PORTAGE_TMPDIR"] = tmpdir + mysettings["EBUILD_PHASE"] = mydo mysettings["PORTAGE_MASTER_PID"] = str(os.getpid()) @@ -4090,12 +4098,24 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, logfile=None builddir_lock = None + tmpdir = None + tmpdir_orig = None try: if mydo in ("digest", "manifest", "help"): # Temporarily exempt the depend phase from manifest checks, in case # aux_get calls trigger cache generation. _doebuild_manifest_exempt_depend += 1 + # If we don't need much space and we don't need a constant location, + # we can temporarily override PORTAGE_TMPDIR with a random temp dir + # so that there's no need for locking and it can be used even if the + # user isn't in the portage group. + if mydo in ("info",): + from tempfile import mkdtemp + tmpdir = mkdtemp() + tmpdir_orig = mysettings["PORTAGE_TMPDIR"] + mysettings["PORTAGE_TMPDIR"] = tmpdir + doebuild_environment(myebuild, mydo, myroot, mysettings, debug, use_cache, mydbapi) @@ -4187,13 +4207,15 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, # Build directory creation isn't required for any of these. have_build_dirs = False - if mydo not in ("digest", "fetch", "help", "info", "manifest"): + if mydo not in ("digest", "fetch", "help", "manifest"): mystatus = prepare_build_dirs(myroot, mysettings, cleanup) if mystatus: return mystatus have_build_dirs = True # PORTAGE_LOG_FILE is set above by the prepare_build_dirs() call. - logfile = mysettings.get("PORTAGE_LOG_FILE", None) + logfile = mysettings.get("PORTAGE_LOG_FILE") + if logfile and not os.access(os.path.dirname(logfile), os.W_OK): + logfile = None if mydo == "unmerge": return unmerge(mysettings["CATEGORY"], mysettings["PF"], myroot, mysettings, vartree=vartree) @@ -4453,6 +4475,9 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, return retval finally: + if tmpdir: + mysettings["PORTAGE_TMPDIR"] = tmpdir_orig + shutil.rmtree(tmpdir) if builddir_lock: portage.locks.unlockdir(builddir_lock) -- 2.26.2