+ echo "${FUNCNAME[0]}(): Adding $venv/bin to PATH"
+ PATH=$venv/bin:$PATH
+
+} # ENd lf-venv-activate()
+
+################################################################################
+#
+# NAME
+# lf-venv-create python [package]...
+#
+# SYNOPSIS
+# # shellcheck disable=SC1090
+# source ~/lf-env.sh
+#
+# lf-venv-create python3 tox tox-pyenv virtualenv
+# lf-venv-create python3.6
+#
+# DESCRIPTION
+# This function will create/update a Python Virtual Environment (venv) based
+# on the python specified. The 'python' argument must be in the PATH. The venv
+# will be located in ~/.venv## where ## comes from the 'python' argument.
+# I.E. python3 -> ~/.venv3. The resulting venv will be left 'read-only' to
+# discourage the installation of any other packages (except by
+# lf-venv-create()). By default, only versioned packages will be installed, so
+# any required packages need to be specified. By default the 'pip install
+# --upgrade' will be run multiple times. Sometimes pip needs that to get the
+# versioning correct.
+#
+# RETURN VALUES
+# None
+#
+################################################################################
+
+function lf-venv-create()
+{
+ if (( $# < 1 )); then
+ lf-echo-stderr "${FUNCNAME[0]}(): ERROR: Missing Required Arguments"
+ return 1
+ fi
+ python=$1
+ shift
+ if ! type $python > /dev/null; then
+ lf-echo-stderr "${FUNCNAME[0]}(): ERROR: Unknown Python: $python"
+ return 1
+ fi
+ local pkg_list="$* "
+ local venv=~/.venv${python#python}
+ local suffix=$python-$$
+ local pip_log=/tmp/pip_log.$suffix
+ if [[ -f $venv/$_lf_done_file ]]; then
+ echo "Venv Already Exists: '$venv'"
+ return
+ fi
+ # Make sure noting is left over
+ if [[ -d $venv ]]; then
+ chmod -R +w $venv
+ rm -rf $venv
+ fi
+
+ echo "Creating '$python' venv ($venv)"
+
+ case $python in
+ python2*)
+ # For Python2, just create venv and install pip
+ virtualenv -p $python $venv > $pip_log || return 1
+ $venv/bin/pip install --upgrade pip > $pip_log || return 1
+ $venv/bin/pip install --upgrade $pkg_list > $pip_log || return 1
+ ;;
+ python3*)
+ # Include any packages that are tied to a specific version
+ pkg_list+="jenkins-job-builder==2.8.0 "
+ $python -m venv $venv > $pip_log
+ $venv/bin/pip install --upgrade pip > $pip_log || return 1
+ # Redirect errors for now
+ $venv/bin/pip install --upgrade $pkg_list >> $pip_log 2> /dev/null || return 1
+ # Generate list of packages
+ pkg_list=$($venv/bin/pip freeze | awk -F '=' '{print $1}') || return 1
+ # Update all packages, may need to run twice to get all versions
+ # synced up. Ignore exit status on first try
+ $venv/bin/pip install --upgrade $pkg_list >> $pip_log || true
+ echo "Running 'pip --upgrade' to validate..."
+ $venv/bin/pip install --upgrade $pkg_list >> $pip_log || return 1
+ ;;
+ *)
+ lf-echo-stderr "${FUNCNAME[0]}(): ERROR: No support for: $python"
+ return 1
+ ;;
+ esac
+
+ touch $venv/$_lf_done_file
+ # Once this venv is created, make it read-only
+ chmod -R -w $venv
+ # Archive output of 'pip freeze'
+ mkdir -p $WORKSPACE/archives
+ $venv/bin/pip freeze > $WORKSPACE/archives/freeze-log-$python || return 1
+ rm -rf $pip_log
+
+} # End lf-venv-create()
+
+################################################################################
+#
+# NAME
+# lf-venv-add()
+#
+# SYNOPSIS
+# # shellcheck disable=SC1090
+# source ~/lf-env.sh
+#
+# lf-venv-add python3 pkg
+# or
+# lf-venv-add python2 pkg1 pkg2 pkg3
+#
+# DESCRIPTION
+# This function will add one or more python packages to an existing venv.
+# Attempts to add packages directly (pip) will result in errors because
+# the venv does not have 'write' permission.
+#
+# RETURN VALUES
+# None
+#
+################################################################################
+
+function lf-venv-add()
+{
+ if (( $# < 2 )); then
+ lf-echo-stderr "${FUNCNAME[0]}(): ERROR: Missing Package argument"
+ return 1
+ fi
+ python=$1
+ if ! type $python > /dev/null ; then
+ lf-echo-stderr "${FUNCNAME[0]}(): ERROR: Unknown Python: $python"
+ return 1
+ fi
+ shift
+ local venv=~/.venv${python#python}
+ if [[ ! -f $venv/$_lf_done_file ]]; then
+ lf-echo-stderr "${FUNCNAME[0]}(): ERROR: '$venv' is not a valid venv"
+ return 1
+ fi
+ local pkg_list=$*
+ local pip_log=/tmp/pip_log-$$
+
+ echo "Installing '$pkg_list' into $venv"
+ chmod -R +w $venv
+ rm $venv/$_lf_done_file
+ $venv/bin/pip install --upgrade $pkg_list > $pip_log || return 1
+ pkg_list=$($venv/bin/pip freeze | awk -F '=' '{print $1}') || return 1
+ $venv/bin/pip install --upgrade $pkg_list > $pip_log || return 1
+ touch $venv/$_lf_done_file
+ chmod -R -w $venv
+ # Archive output of 'pip freeze'
+ $venv/bin/pip freeze > $WORKSPACE/archives/freeze-log-$python || return 1
+
+} # End lf-venv-add()