drop IMAGE -- people have had years to catch up (trunk r14694)
[portage.git] / bin / isolated-functions.sh
1 # Copyright 1999-2009 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3 # $Id$
4
5 # We need this next line for "die" and "assert". It expands
6 # It _must_ preceed all the calls to die and assert.
7 shopt -s expand_aliases
8 alias assert='_pipestatus="${PIPESTATUS[*]}"; [[ "${_pipestatus// /}" -eq 0 ]] || die'
9 alias save_IFS='[ "${IFS:-unset}" != "unset" ] && old_IFS="${IFS}"'
10 alias restore_IFS='if [ "${old_IFS:-unset}" != "unset" ]; then IFS="${old_IFS}"; unset old_IFS; else unset IFS; fi'
11
12 shopt -s extdebug
13
14 # dump_trace([number of funcs on stack to skip],
15 #            [whitespacing for filenames],
16 #            [whitespacing for line numbers])
17 dump_trace() {
18         local funcname="" sourcefile="" lineno="" s="yes" n p
19         declare -i strip=${1:-1}
20         local filespacing=$2 linespacing=$3
21
22         # The qa_call() function and anything before it are portage internals
23         # that the user will not be interested in. Therefore, the stack trace
24         # should only show calls that come after qa_call().
25         (( n = ${#FUNCNAME[@]} - 1 ))
26         (( p = ${#BASH_ARGV[@]} ))
27         while (( n > 0 )) ; do
28                 [ "${FUNCNAME[${n}]}" == "qa_call" ] && break
29                 (( p -= ${BASH_ARGC[${n}]} ))
30                 (( n-- ))
31         done
32         if (( n == 0 )) ; then
33                 (( n = ${#FUNCNAME[@]} - 1 ))
34                 (( p = ${#BASH_ARGV[@]} ))
35         fi
36
37         eerror "Call stack:"
38         while (( n > ${strip} )) ; do
39                 funcname=${FUNCNAME[${n} - 1]}
40                 sourcefile=$(basename ${BASH_SOURCE[${n}]})
41                 lineno=${BASH_LINENO[${n} - 1]}
42                 # Display function arguments
43                 args=
44                 if [[ -n "${BASH_ARGV[@]}" ]]; then
45                         for (( j = 1 ; j <= ${BASH_ARGC[${n} - 1]} ; ++j )); do
46                                 newarg=${BASH_ARGV[$(( p - j - 1 ))]}
47                                 args="${args:+${args} }'${newarg}'"
48                         done
49                         (( p -= ${BASH_ARGC[${n} - 1]} ))
50                 fi
51                 eerror "  $(printf "%${filespacing}s" "${sourcefile}"), line $(printf "%${linespacing}s" "${lineno}"):  Called ${funcname}${args:+ ${args}}"
52                 (( n-- ))
53         done
54 }
55
56 nonfatal() {
57         if has "${EAPI:-0}" 0 1 2; then
58                 die "$FUNCNAME() not supported in this EAPI"
59         fi
60         if [[ $# -lt 1 ]]; then
61                 die "$FUNCNAME(): Missing argument"
62         fi
63
64         PORTAGE_NONFATAL=1 "$@"
65 }
66
67 die() {
68         if [[ $PORTAGE_NONFATAL -eq 1 ]]; then
69                 echo -e " $WARN*$NORMAL ${FUNCNAME[1]}: WARNING: $@" >&2
70                 return 1
71         fi
72
73         set +e
74         if [ -n "${QA_INTERCEPTORS}" ] ; then
75                 # die was called from inside inherit. We need to clean up
76                 # QA_INTERCEPTORS since sed is called below.
77                 unset -f ${QA_INTERCEPTORS}
78                 unset QA_INTERCEPTORS
79         fi
80         local n filespacing=0 linespacing=0
81         # setup spacing to make output easier to read
82         (( n = ${#FUNCNAME[@]} - 1 ))
83         while (( n > 0 )) ; do
84                 [ "${FUNCNAME[${n}]}" == "qa_call" ] && break
85                 (( n-- ))
86         done
87         (( n == 0 )) && (( n = ${#FUNCNAME[@]} - 1 ))
88         while (( n > 0 )); do
89                 sourcefile=${BASH_SOURCE[${n}]} sourcefile=${sourcefile##*/}
90                 lineno=${BASH_LINENO[${n}]}
91                 ((filespacing < ${#sourcefile})) && filespacing=${#sourcefile}
92                 ((linespacing < ${#lineno}))     && linespacing=${#lineno}
93                 (( n-- ))
94         done
95
96         eerror "ERROR: $CATEGORY/$PF failed:"
97         eerror "  ${*:-(no error message)}"
98         eerror
99         dump_trace 2 ${filespacing} ${linespacing}
100         eerror "  $(printf "%${filespacing}s" "${BASH_SOURCE[1]##*/}"), line $(printf "%${linespacing}s" "${BASH_LINENO[0]}"):  Called die"
101         eerror "The specific snippet of code:"
102         # This scans the file that called die and prints out the logic that
103         # ended in the call to die.  This really only handles lines that end
104         # with '|| die' and any preceding lines with line continuations (\).
105         # This tends to be the most common usage though, so let's do it.
106         # Due to the usage of appending to the hold space (even when empty),
107         # we always end up with the first line being a blank (thus the 2nd sed).
108         sed -n \
109                 -e "# When we get to the line that failed, append it to the
110                     # hold space, move the hold space to the pattern space,
111                     # then print out the pattern space and quit immediately
112                     ${BASH_LINENO[0]}{H;g;p;q}" \
113                 -e '# If this line ends with a line continuation, append it
114                     # to the hold space
115                     /\\$/H' \
116                 -e '# If this line does not end with a line continuation,
117                     # erase the line and set the hold buffer to it (thus
118                     # erasing the hold buffer in the process)
119                     /[^\]$/{s:^.*$::;h}' \
120                 ${BASH_SOURCE[1]} \
121                 | sed -e '1d' -e 's:^:RETAIN-LEADING-SPACE:' \
122                 | while read -r n ; do eerror "  ${n#RETAIN-LEADING-SPACE}" ; done
123         eerror
124         eerror "If you need support, post the output of 'emerge --info =$CATEGORY/$PF',"
125         eerror "the complete build log and the output of 'emerge -pqv =$CATEGORY/$PF'."
126         if [[ -n ${EBUILD_OVERLAY_ECLASSES} ]] ; then
127                 eerror "This ebuild used the following eclasses from overlays:"
128                 local x
129                 for x in ${EBUILD_OVERLAY_ECLASSES} ; do
130                         eerror "  ${x}"
131                 done
132         fi
133         if [ "${EMERGE_FROM}" != "binary" ] && \
134                 ! hasq ${EBUILD_PHASE} prerm postrm && \
135                 [ "${EBUILD#${PORTDIR}/}" == "${EBUILD}" ] ; then
136                 local overlay=${EBUILD%/*}
137                 overlay=${overlay%/*}
138                 overlay=${overlay%/*}
139                 if [[ -n $PORTAGE_REPO_NAME ]] ; then
140                         eerror "This ebuild is from an overlay named" \
141                                 "'$PORTAGE_REPO_NAME': '${overlay}/'"
142                 else
143                         eerror "This ebuild is from an overlay: '${overlay}/'"
144                 fi
145         elif [[ -n $PORTAGE_REPO_NAME && -f "$PORTDIR"/profiles/repo_name ]] ; then
146                 local portdir_repo_name=$(<"$PORTDIR"/profiles/repo_name)
147                 if [[ -n $portdir_repo_name && \
148                         $portdir_repo_name != $PORTAGE_REPO_NAME ]] ; then
149                         eerror "This ebuild is from a repository" \
150                                 "named '$PORTAGE_REPO_NAME'"
151                 fi
152         fi
153
154         if [[ "${EBUILD_PHASE/depend}" == "${EBUILD_PHASE}" ]] ; then
155                 local x
156                 for x in $EBUILD_DEATH_HOOKS; do
157                         ${x} "$@" >&2 1>&2
158                 done
159         fi
160
161         [[ -n ${PORTAGE_LOG_FILE} ]] \
162                 && eerror "The complete build log is located at '${PORTAGE_LOG_FILE}'."
163         if [ -f "${T}/environment" ] ; then
164                 eerror "The ebuild environment file is located at '${T}/environment'."
165         elif [ -d "${T}" ] ; then
166                 {
167                         set
168                         export
169                 } > "${T}/die.env"
170                 eerror "The ebuild environment file is located at '${T}/die.env'."
171         fi
172         eerror "S: '${S}'"
173
174         [ -n "$EBUILD_EXIT_STATUS_FILE" ] && > "$EBUILD_EXIT_STATUS_FILE"
175
176         # subshell die support
177         [[ $BASHPID = $EBUILD_MASTER_PID ]] || kill -s SIGTERM $EBUILD_MASTER_PID
178         exit 1
179 }
180
181 # We need to implement diefunc() since environment.bz2 files contain
182 # calls to it (due to alias expansion).
183 diefunc() {
184         die "${@}"
185 }
186
187 quiet_mode() {
188         [[ ${PORTAGE_QUIET} -eq 1 ]]
189 }
190
191 vecho() {
192         quiet_mode || echo "$@"
193 }
194
195 # Internal logging function, don't use this in ebuilds
196 elog_base() {
197         local messagetype
198         [ -z "${1}" -o -z "${T}" -o ! -d "${T}/logging" ] && return 1
199         case "${1}" in
200                 INFO|WARN|ERROR|LOG|QA)
201                         messagetype="${1}"
202                         shift
203                         ;;
204                 *)
205                         vecho -e " ${BAD}*${NORMAL} Invalid use of internal function elog_base(), next message will not be logged"
206                         return 1
207                         ;;
208         esac
209         echo -e "$@" | while read -r ; do
210                 echo "$messagetype $REPLY" >> \
211                         "${T}/logging/${EBUILD_PHASE:-other}"
212         done
213         return 0
214 }
215
216 eqawarn() {
217         elog_base QA "$*"
218         [[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
219         echo -e "$@" | while read -r ; do
220                 vecho " $WARN*$NORMAL $REPLY" >&2
221         done
222         LAST_E_CMD="eqawarn"
223         return 0
224 }
225
226 elog() {
227         elog_base LOG "$*"
228         [[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
229         echo -e "$@" | while read -r ; do
230                 echo " $GOOD*$NORMAL $REPLY"
231         done
232         LAST_E_CMD="elog"
233         return 0
234 }
235
236 esyslog() {
237         local pri=
238         local tag=
239
240         if [ -x /usr/bin/logger ]
241         then
242                 pri="$1"
243                 tag="$2"
244
245                 shift 2
246                 [ -z "$*" ] && return 0
247
248                 /usr/bin/logger -p "${pri}" -t "${tag}" -- "$*"
249         fi
250
251         return 0
252 }
253
254 einfo() {
255         elog_base INFO "$*"
256         [[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
257         echo -e "$@" | while read -r ; do
258                 echo " $GOOD*$NORMAL $REPLY"
259         done
260         LAST_E_CMD="einfo"
261         return 0
262 }
263
264 einfon() {
265         elog_base INFO "$*"
266         [[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
267         echo -ne " ${GOOD}*${NORMAL} $*"
268         LAST_E_CMD="einfon"
269         return 0
270 }
271
272 ewarn() {
273         elog_base WARN "$*"
274         [[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
275         echo -e "$@" | while read -r ; do
276                 echo " $WARN*$NORMAL $RC_INDENTATION$REPLY" >&2
277         done
278         LAST_E_CMD="ewarn"
279         return 0
280 }
281
282 eerror() {
283         elog_base ERROR "$*"
284         [[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
285         echo -e "$@" | while read -r ; do
286                 echo " $BAD*$NORMAL $RC_INDENTATION$REPLY" >&2
287         done
288         LAST_E_CMD="eerror"
289         return 0
290 }
291
292 ebegin() {
293         local msg="$*" dots spaces=${RC_DOT_PATTERN//?/ }
294         if [[ -n ${RC_DOT_PATTERN} ]] ; then
295                 dots=$(printf "%$(( COLS - 3 - ${#RC_INDENTATION} - ${#msg} - 7 ))s" '')
296                 dots=${dots//${spaces}/${RC_DOT_PATTERN}}
297                 msg="${msg}${dots}"
298         else
299                 msg="${msg} ..."
300         fi
301         einfon "${msg}"
302         [[ ${RC_ENDCOL} == "yes" ]] && echo
303         LAST_E_LEN=$(( 3 + ${#RC_INDENTATION} + ${#msg} ))
304         LAST_E_CMD="ebegin"
305         return 0
306 }
307
308 _eend() {
309         local retval=${1:-0} efunc=${2:-eerror} msg
310         shift 2
311
312         if [[ ${retval} == "0" ]] ; then
313                 msg="${BRACKET}[ ${GOOD}ok${BRACKET} ]${NORMAL}"
314         else
315                 if [[ -n $* ]] ; then
316                         ${efunc} "$*"
317                 fi
318                 msg="${BRACKET}[ ${BAD}!!${BRACKET} ]${NORMAL}"
319         fi
320
321         if [[ ${RC_ENDCOL} == "yes" ]] ; then
322                 echo -e "${ENDCOL}  ${msg}"
323         else
324                 [[ ${LAST_E_CMD} == ebegin ]] || LAST_E_LEN=0
325                 printf "%$(( COLS - LAST_E_LEN - 6 ))s%b\n" '' "${msg}"
326         fi
327
328         return ${retval}
329 }
330
331 eend() {
332         local retval=${1:-0}
333         shift
334
335         _eend ${retval} eerror "$*"
336
337         LAST_E_CMD="eend"
338         return ${retval}
339 }
340
341 KV_major() {
342         [[ -z $1 ]] && return 1
343
344         local KV=$@
345         echo "${KV%%.*}"
346 }
347
348 KV_minor() {
349         [[ -z $1 ]] && return 1
350
351         local KV=$@
352         KV=${KV#*.}
353         echo "${KV%%.*}"
354 }
355
356 KV_micro() {
357         [[ -z $1 ]] && return 1
358
359         local KV=$@
360         KV=${KV#*.*.}
361         echo "${KV%%[^[:digit:]]*}"
362 }
363
364 KV_to_int() {
365         [[ -z $1 ]] && return 1
366
367         local KV_MAJOR=$(KV_major "$1")
368         local KV_MINOR=$(KV_minor "$1")
369         local KV_MICRO=$(KV_micro "$1")
370         local KV_int=$(( KV_MAJOR * 65536 + KV_MINOR * 256 + KV_MICRO ))
371
372         # We make version 2.2.0 the minimum version we will handle as
373         # a sanity check ... if its less, we fail ...
374         if [[ ${KV_int} -ge 131584 ]] ; then
375                 echo "${KV_int}"
376                 return 0
377         fi
378
379         return 1
380 }
381
382 _RC_GET_KV_CACHE=""
383 get_KV() {
384         [[ -z ${_RC_GET_KV_CACHE} ]] \
385                 && _RC_GET_KV_CACHE=$(uname -r)
386
387         echo $(KV_to_int "${_RC_GET_KV_CACHE}")
388
389         return $?
390 }
391
392 unset_colors() {
393         COLS="25 80"
394         ENDCOL=
395
396         GOOD=
397         WARN=
398         BAD=
399         NORMAL=
400         HILITE=
401         BRACKET=
402 }
403
404 set_colors() {
405         COLS=${COLUMNS:-0}      # bash's internal COLUMNS variable
406         (( COLS == 0 )) && COLS=$(set -- $(stty size 2>/dev/null) ; echo $2)
407         (( COLS > 0 )) || (( COLS = 80 ))
408         COLS=$((${COLS} - 8))   # width of [ ok ] == 7
409         # Adjust COLS so that eend works properly on a standard BSD console.
410         [[ $TERM = cons25 || $TERM = dumb ]] && ((COLS--))
411
412         # Now, ${ENDCOL} will move us to the end of the
413         # column;  irregardless of character width
414         ENDCOL=$'\e[A\e['${COLS}'C'
415         if [ -n "${PORTAGE_COLORMAP}" ] ; then
416                 eval ${PORTAGE_COLORMAP}
417         else
418                 GOOD=$'\e[32;01m'
419                 WARN=$'\e[33;01m'
420                 BAD=$'\e[31;01m'
421                 HILITE=$'\e[36;01m'
422                 BRACKET=$'\e[34;01m'
423         fi
424         NORMAL=$'\e[0m'
425 }
426
427 RC_ENDCOL="yes"
428 RC_INDENTATION=''
429 RC_DEFAULT_INDENT=2
430 RC_DOT_PATTERN=''
431
432 case "${NOCOLOR:-false}" in
433         yes|true)
434                 unset_colors
435                 ;;
436         no|false)
437                 set_colors
438                 ;;
439 esac
440
441 if [[ -z ${USERLAND} ]] ; then
442         case $(uname -s) in
443         *BSD|DragonFly)
444                 export USERLAND="BSD"
445                 ;;
446         *)
447                 export USERLAND="GNU"
448                 ;;
449         esac
450 fi
451
452 if [[ -z ${XARGS} ]] ; then
453         case ${USERLAND} in
454         BSD)
455                 export XARGS="xargs"
456                 ;;
457         *)
458                 export XARGS="xargs -r"
459                 ;;
460         esac
461 fi
462
463 has() {
464         hasq "$@"
465 }
466
467 hasv() {
468         if hasq "$@" ; then
469                 echo "$1"
470                 return 0
471         fi
472         return 1
473 }
474
475 hasq() {
476         [[ " ${*:2} " == *" $1 "* ]]
477 }
478
479 # @FUNCTION: save_ebuild_env
480 # @DESCRIPTION:
481 # echo the current environment to stdout, filtering out redundant info.
482 #
483 # --exclude-init-phases causes pkg_nofetch and src_* phase functions to
484 # be excluded from the output. These function are not needed for installation
485 # or removal of the packages, and can therefore be safely excluded.
486 #
487 save_ebuild_env() {
488         (
489
490                 if hasq --exclude-init-phases $* ; then
491                         unset S _E_DOCDESTTREE_ _E_EXEDESTTREE_
492                         unset -f pkg_nofetch src_unpack src_prepare src_configure \
493                         src_compile src_test src_install
494                         if [[ -n $PYTHONPATH ]] ; then
495                                 export PYTHONPATH=${PYTHONPATH/${PORTAGE_PYM_PATH}:}
496                                 [[ -z $PYTHONPATH ]] && unset PYTHONPATH
497                         fi
498                 fi
499
500                 # misc variables inherited from the calling environment
501                 unset COLORTERM DISPLAY EDITOR LESS LESSOPEN LOGNAME LS_COLORS PAGER \
502                         TERM TERMCAP USER
503
504                 # other variables inherited from the calling environment
505                 unset ECHANGELOG_USER GPG_AGENT_INFO \
506                 SSH_AGENT_PID SSH_AUTH_SOCK STY WINDOW XAUTHORITY
507
508                 # CCACHE and DISTCC config
509                 unset ${!CCACHE_*} ${!DISTCC_*}
510
511                 # There's no need to bloat environment.bz2 with internally defined
512                 # functions and variables, so filter them out if possible.
513
514                 for x in pkg_setup pkg_nofetch src_unpack src_prepare src_configure \
515                         src_compile src_test src_install pkg_preinst pkg_postinst \
516                         pkg_prerm pkg_postrm ; do
517                         unset -f default_$x _eapi{0,1,2}_$x
518                 done
519                 unset x
520
521                 unset -f dump_trace die diefunc quiet_mode vecho elog_base eqawarn elog \
522                         esyslog einfo einfon ewarn eerror ebegin _eend eend KV_major \
523                         KV_minor KV_micro KV_to_int get_KV unset_colors set_colors has \
524                         has_phase_defined_up_to \
525                         hasg hasgq hasv hasq qa_source qa_call \
526                         addread addwrite adddeny addpredict _sb_append_var \
527                         lchown lchgrp esyslog use usev useq has_version portageq \
528                         best_version use_with use_enable register_die_hook check_KV \
529                         keepdir unpack strip_duplicate_slashes econf einstall \
530                         dyn_setup dyn_unpack dyn_clean into insinto exeinto docinto \
531                         insopts diropts exeopts libopts \
532                         abort_handler abort_prepare abort_configure abort_compile \
533                         abort_test abort_install dyn_prepare dyn_configure \
534                         dyn_compile dyn_test dyn_install \
535                         dyn_preinst dyn_help debug-print debug-print-function \
536                         debug-print-section inherit EXPORT_FUNCTIONS newdepend newrdepend \
537                         newpdepend do_newdepend remove_path_entry \
538                         save_ebuild_env filter_readonly_variables preprocess_ebuild_env \
539                         source_all_bashrcs ebuild_main \
540                         ebuild_phase ebuild_phase_with_hooks \
541                         _ebuild_arg_to_phase _ebuild_phase_funcs default \
542                         _pipestatus \
543                         ${QA_INTERCEPTORS}
544
545                 # portage config variables and variables set directly by portage
546                 unset ACCEPT_LICENSE BAD BRACKET BUILD_PREFIX COLS \
547                         DISTCC_DIR DISTDIR DOC_SYMLINKS_DIR \
548                         EBUILD_EXIT_STATUS_FILE EBUILD_FORCE_TEST EBUILD_MASTER_PID \
549                         ECLASSDIR ECLASS_DEPTH ENDCOL FAKEROOTKEY \
550                         GOOD HILITE HOME \
551                         LAST_E_CMD LAST_E_LEN LD_PRELOAD MISC_FUNCTIONS_ARGS MOPREFIX \
552                         NOCOLOR NORMAL PKGDIR PKGUSE PKG_LOGDIR PKG_TMPDIR \
553                         PORTAGE_ACTUAL_DISTDIR PORTAGE_ARCHLIST \
554                         PORTAGE_BASHRC PORTAGE_BASHRCS_SOURCED \
555                         PORTAGE_BINPKG_TAR_OPTS PORTAGE_BINPKG_TMPFILE PORTAGE_BUILDDIR \
556                         PORTAGE_COLORMAP PORTAGE_CONFIGROOT PORTAGE_DEBUG \
557                         PORTAGE_DEPCACHEDIR PORTAGE_GID PORTAGE_INST_GID \
558                         PORTAGE_INST_UID PORTAGE_LOG_FILE PORTAGE_MASTER_PID \
559                         PORTAGE_NONFATAL PORTAGE_QUIET \
560                         PORTAGE_REPO_NAME PORTAGE_RESTRICT PORTAGE_UPDATE_ENV \
561                         PORTAGE_VERBOSE PORTAGE_WORKDIR_MODE PORTDIR \
562                         PORTDIR_OVERLAY ${!PORTAGE_SANDBOX_*} PREROOTPATH \
563                         PROFILE_PATHS PWORKDIR QA_INTERCEPTORS \
564                         RC_DEFAULT_INDENT RC_DOT_PATTERN RC_ENDCOL \
565                         RC_INDENTATION READONLY_EBUILD_METADATA READONLY_PORTAGE_VARS \
566                         ROOT ROOTPATH RPMDIR STARTDIR TMP TMPDIR USE_EXPAND \
567                         WARN XARGS _RC_GET_KV_CACHE
568
569                 # user config variables
570                 unset DOC_SYMLINKS_DIR INSTALL_MASK PKG_INSTALL_MASK
571
572                 declare -p
573                 declare -fp
574         )
575 }
576
577 true