blob: ff09003209b78e1a0da16df2f2cc14b53e02ae4b [file] [log] [blame]
#!/bin/bash
# This script is a wrapper for programs that may have alternate versions
# (e.g. python2, python3). This wrapper allows the user to influence the
# selection of the program version by setting the <program name>_VERSION (e.g.
# PYTHON_VERSION, ROBOT_VERSION, etc.) environment variable.
# Users would be expected to create a link with the base name of the program
# that points to this file.
# Example:
# cd openbmc-test-automation/bin
# ln -s select_version python
# The PATH variable should contain the expanded path to
# openbmc-test-automation/bin.
# If <program name>_VERSION is blank or not set, then the program version
# will be whatever the system default program version is. If <program
# name>_VERSION is set to a value, then that value will be appended to the name
# of the program (e.g. if PYTHON_VERSION = "3", then python3 will be used.).
# If <program name>_VERSION is set to some value that does not correspond to a
# valid program version for the given system, this program will fail.
# Make sure program_name is set.
program_name="${0##*/}"
program_uppercase_name=${program_name^^}
function get_target_program_path {
local target_program_path_var="${1:-target_program_path}" ; shift
# Get the full path to the "real" program and assign it to the variable
# named in target_program_path_var.
# Description of argument(s):
# target_program_path_var The name of the variable to receive the
# result.
# Example result:
# /usr/bin/python3
local version_var_name
local alternate_program_name
local base_program_path
local base_program_name
local candidate
local candidates
local base_file_path
# The typical use of this program would be to create a link to it like this:
# ln -s select_version python
# That being the case, get the name of this actual program (rather than the
# name of the link to it).
base_program_path=$(readlink -f "${0}")
base_program_name=${base_program_path##*/}
if [ "${program_name}" == "${base_program_name}" ] ; then
{
echo -n "**ERROR** ${base_program_name} should never be called directly."
echo " Only links to ${base_program_name} should be called."
} >&2
exit 1
fi
# Compose the version_var_name value (e.g. PYTHON_VERSION).
version_var_name=${program_uppercase_name}_VERSION
# Compose the alternate_program_name (e.g. python3).
alternate_program_name=${program_name}${!version_var_name}
# Now use the "type" built-in to search the PATH variable for a list of
# target program candidates.
candidates=$(type -ap ${alternate_program_name})
# Example candidates:
# /home/robot/openbmc-test-automation/bin/python
# /usr/bin/python
# In this example, the first candidate is actually a link to
# /home/robot/openbmc-test-automation/bin/select_version. As such it will
# be rejected.
for candidate in ${candidates}
do
if [ -L "${candidate}" ] ; then
# The candidate is a link so we need to see if it's a link to this
# program file.
base_file_path=$(readlink "${candidate}")
[ "${base_file_path}" == "${base_program_name}" ] && continue
fi
# The candidate is NOT a link so it qualifies as the desired target
# program path.
eval ${target_program_path_var}=\"\${candidate}\"
return
done
}
# Main
get_target_program_path target_program_path
# Compose program path var name (e.g. PYTHON_PGM_PATH).
pgm_path_var_name=${program_uppercase_name}_PGM_PATH
# Set and export pgm_path_var_name (e.g. PYTHON_PGM_PATH=/usr/bin/python3).
# This value can be used by child programs for debug.
eval export ${pgm_path_var_name}=${target_program_path}
if [ "${1}" == "--print_only" ] ; then
echo "${target_program_path}"
else
# Use exec in order to replace this process with the target process.
exec ${target_program_path} "${@}"
fi