New bin/select_version as python/robot wrapper

Created bin/python and bin/robot link to new bin/select_version.

This bash shell in the git repo bin directory will select the correct
version of python/robot to interpret a python/robot program based on
environment variable PYTHON_VERSION (or ROBOT_VERSION).

Change-Id: I372eda2a69bc73ffbeeb2a3051efb781331d423d
Signed-off-by: Michael Walsh <micwalsh@us.ibm.com>
diff --git a/bin/python b/bin/python
new file mode 120000
index 0000000..a7dfdfd
--- /dev/null
+++ b/bin/python
@@ -0,0 +1 @@
+select_version
\ No newline at end of file
diff --git a/bin/robot b/bin/robot
new file mode 120000
index 0000000..a7dfdfd
--- /dev/null
+++ b/bin/robot
@@ -0,0 +1 @@
+select_version
\ No newline at end of file
diff --git a/bin/select_version b/bin/select_version
new file mode 100755
index 0000000..320fc59
--- /dev/null
+++ b/bin/select_version
@@ -0,0 +1,111 @@
+#!/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 appened 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##*/}
+
+  # 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
+    ${target_program_path} "${@}"
+  fi
+