To try and provide better stability across bash versions, set the language compat level based on the current EAPI. This does not ban newer features, it tells bash to use the older bash behavior when the behavior changes across versions. --- bin/eapi.sh | 8 ++++++++ bin/ebuild.sh | 42 ++++++++++++++++++++++++++++++++++++++++++ bin/save-ebuild-env.sh | 2 +- 3 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/bin/eapi.sh b/bin/eapi.sh index 528e6f2..cd3e1a4 100644 --- a/bin/eapi.sh +++ b/bin/eapi.sh @@ -191,3 +191,11 @@ ___eapi_enables_failglob_in_global_scope() { ___eapi_enables_globstar() { [[ ${1-${EAPI-0}} =~ ^(4-python|5-progress)$ ]] } + +___eapi_bash_3_2() { + [[ ${1-${EAPI-0}} =~ ^(0|1|2|3|4|4-python|4-slot-abi|5|5-hdepend|5-progress)$ ]] +} + +___eapi_bash_4_2() { + [[ ${1-${EAPI-0}} =~ ^(6)$ ]] +} diff --git a/bin/ebuild.sh b/bin/ebuild.sh index 75a9d24..78a93f0 100755 --- a/bin/ebuild.sh +++ b/bin/ebuild.sh @@ -6,8 +6,50 @@ # Make sure it's before everything so we don't mess aliases that follow. unalias -a +# Make sure this isn't exported to scripts we execute. +unset BASH_COMPAT + source "${PORTAGE_BIN_PATH}/isolated-functions.sh" || exit 1 +# Set up the bash version compatibility level. This does not disable +# features when running with a newer version, but makes it so that when +# bash changes behavior in an incompatible way, the older behavior is +# used instead. +__check_bash_version() { + # Figure out which min version of bash we require. + local maj min + if ___eapi_bash_3_2 ; then + maj=3 min=2 + elif ___eapi_bash_4_2 ; then + maj=4 min=2 + else + return + fi + + # Make sure the active bash is sane. + if [[ ${BASH_VERSINFO[0]} -lt ${maj} ]] || + [[ ${BASH_VERSINFO[0]} -eq ${maj} && ${BASH_VERSINFO[1]} -lt ${min} ]] ; then + die ">=bash-${maj}.${min} is required" + fi + + # Set the compat level in case things change with newer ones. We must not + # export this into the env otherwise we might break other shell scripts we + # execute (e.g. ones in /usr/bin). + BASH_COMPAT="${maj}.${min}" + + # The variable above is new to bash-4.3. For older versions, we have to use + # a compat knob. Further, the compat knob only exists with older versions + # (e.g. bash-4.3 has compat42 but not compat43). This means we only need to + # turn the knob with older EAPIs, and only when running newer bash versions: + # there is no bash-3.3 (it went 3.2 to 4.0), and when requiring bash-4.2, the + # var works with bash-4.3+, and you don't need to set compat to 4.2 when you + # are already running 4.2. + if ___eapi_bash_3_2 && [[ ${BASH_VERSINFO[0]} -gt 3 ]] ; then + shopt -s compat32 + fi +} +__check_bash_version + if [[ $EBUILD_PHASE != depend ]] ; then source "${PORTAGE_BIN_PATH}/phase-functions.sh" || die source "${PORTAGE_BIN_PATH}/save-ebuild-env.sh" || die diff --git a/bin/save-ebuild-env.sh b/bin/save-ebuild-env.sh index 477ed28..1120297 100644 --- a/bin/save-ebuild-env.sh +++ b/bin/save-ebuild-env.sh @@ -75,7 +75,7 @@ __save_ebuild_env() { __ebuild_main __ebuild_phase __ebuild_phase_with_hooks \ __ebuild_arg_to_phase __ebuild_phase_funcs default \ __unpack_tar __unset_colors \ - __source_env_files __try_source \ + __source_env_files __try_source __check_bash_version \ __eqaquote __eqatag \ ${QA_INTERCEPTORS} -- 2.6.2