crosstool-ng/scripts/version-check.sh
Alexey Neyman 74a53fdf3e Use enhanced framework for 'ct-ng update-samples'
Signed-off-by: Alexey Neyman <stilor@att.net>
2019-02-09 15:55:16 -08:00

215 lines
5.9 KiB
Bash

# This script checks the version of the configuration file and either
# alerts the user about the need to run the upgrade, or attempts to
# perform such an upgrade.
CFGFILE="${1}"
. "${CT_LIB_DIR}/scripts/functions"
. "${CFGFILE}"
# If an old config does not define a version, assume it is 0. This is used
# if we run this script on an old full .config file, not restored from a
# defconfig.
CT_CONFIG_VERSION="${CT_CONFIG_VERSION:-0}"
if [ "${CT_CONFIG_VERSION_CURRENT}" == "${CT_CONFIG_VERSION}" ]; then
# Nothing to do
exit 0
fi
if [ -z "${CT_UPGRADECONFIG}" ]; then
if [ "${CT_CONFIG_VERSION}" != "0" ]; then
oldversion="is version ${CT_CONFIG_VERSION}"
else
oldversion="has no version"
fi
cat 2>&1 <<EOF
Configuration file was generated by an older version of crosstool-NG;
configuration file ${oldversion}; crosstool-NG currently expects
version ${CT_CONFIG_VERSION_CURRENT}. If this configuration file was generated by a crosstool-NG
version 1.23.0 or later, you can run 'ct-ng upgradeconfig'.
Compatibility with previous releases is not guaranteed. In any case,
verify the resulting configuration.
EOF
if [ "${CT_VCHECK}" = "strict" ]; then
exit 1
else
exit 0
fi
fi
# From now on, we're running actual upgrade, not just a check. Preserve the CT_xxx
# variables that we need using a different prefix so that we can unset the stale
# values at each iteration.
MY_LIB_DIR="${CT_LIB_DIR}"
MY_CONFIG_VERSION_CURRENT="${CT_CONFIG_VERSION_CURRENT}"
is_set()
{
if [ "x${val+set}" = "xset" ]; then
return 0
else
return 1
fi
}
info()
{
# $opt comes from the caller
echo "INFO ${opt:+:: ${opt} }:: $1" >&2
}
warning()
{
# $opt comes from the caller
echo "WARN ${opt:+:: ${opt} }:: $1" >&2
}
error()
{
# $opt comes from the caller
echo " ERR ${opt:+:: ${opt} }:: $1" >&2
exit 1
}
warning_if_set()
{
if is_set; then
warning "$@"
fi
}
# When a symbol is replaced with a newer version. If it is a choice and
# the replacement existed in the old version as well, add a replacement_for
# handler for the other symbol to avoid kconfig warnings.
replace()
{
local newopt="${1}"
if is_set; then
info "No longer supported; replacing with '${newopt}'".
opt="${newopt}"
else
# Wasn't set; just drop it silently
unset opt
fi
}
# Avoid multiple definitions for a symbol when multiple old symbols are folded into one
# in a new version. If any of the variable names passed as arguments are set, skip
# emitting this variable (which, presumably, is "not set").
replacement_for()
{
while [ -n "${1}" ]; do
if [ -n "${!1}" ]; then
unset opt
return
fi
shift
done
}
# Helper: takes ${ln} in the caller's environment and sets ${opt} and ${val}
# accordingly. Returns 0 if this line was an option, 1 otherwise.
set_opt_and_val()
{
case "${ln}" in
CT_*=*)
opt=${ln%%=*}
val=${ln#*=}
case "${val}" in
\"*\")
val="${val%\"}"
val="${val#\"}"
q=\"
;;
esac
return 0
;;
"# CT_"*" is not set")
opt=${ln#* }
opt=${opt%% *}
return 0
;;
*)
;;
esac
return 1
}
# Main upgrade driver. One version at a time, read line by line, interpret
# the options and replace anything that needs replacing.
input="${CFGFILE}"
while :; do
# Purge any possibly stale values
unset "${!CT_@}"
# Reload the next input so that the upgrade function can rely on other CT_xxx variables,
# not just the currently processed variable.
. "${input}"
v=${CT_CONFIG_VERSION:-0}
if [ "${v}" -ge "${MY_CONFIG_VERSION_CURRENT}" ]; then
break
fi
vn=$[ v + 1 ]
info "Upgrading v${v} to v${vn}"
if [ ! -r "${MY_LIB_DIR}/scripts/upgrade/v${v}" ]; then
error "Missing upgrade script for v${v} of the config file"
fi
unset upgrade
. "${MY_LIB_DIR}/scripts/upgrade/v${v}"
# First pass: read in the whole file and mark the options mentioned;
# it may not be possible to upgrade a defconfig if some non-trivial
# option dependencies need to be resolved. We are not interested in
# values yet.
unset selected_opts
declare -A selected_opts
while read ln; do
if set_opt_and_val; then
selected_opts[${opt}]=1
fi
done < "${input}"
# Second pass: actually upgrade the options.
{
while read ln; do
unset opt
unset val
q=
if set_opt_and_val; then
case "${opt}" in
CT_CONFIG_VERSION_CURRENT|CT_CONFIG_VERSION)
continue
;;
esac
else
echo "${ln}"
fi
upgrade
# Emit the option(s)
if [ x${opt+set} = x ]; then
continue
elif [ x${val+set} = x ]; then
echo "# ${opt} is not set"
else
echo "${opt}=${q}${val}${q}"
fi
done
echo "CT_CONFIG_VERSION=\"${vn}\""
echo "CT_CONFIG_VERSION_CURRENT=\"${CT_CONFIG_VERSION_CURRENT}\""
} < "${input}" > "${CFGFILE}.${vn}"
unset opt
v=${vn}
rm -f "${input}"
input="${CFGFILE}.${vn}"
# Ideally, we'd do 'ct-ng olddefconfig' after each step with the appropriate
# Kconfig so that the next step would be able to use auto-set values from the
# previous step. However, that would require us to keep archived config/ trees
# from every config file version, which is not practical. So, I decided to defer
# this until it is actually needed. Even then, it is probably sufficient to only
# keep the versions where there is such a dependency.
done
mv "${CFGFILE}.${MY_CONFIG_VERSION_CURRENT}" "${CFGFILE}"