| #!/bin/sh |
| |
| # Don't set -e because we don't have robust trapping and printing of errors. |
| set -u |
| |
| # We use /bin/sh rather than /bin/bash for portability. See discussion here: |
| # https://groups.google.com/forum/?nomobile=true#!topic/bazel-dev/4Ql_7eDcLC0 |
| # We do lose the ability to set -o pipefail. |
| |
| STRICT="%STRICT%" |
| |
| if [ "$STRICT" = "1" ]; then |
| FAILURE_HEADER="\ |
| Error occurred while attempting to use the default Python toolchain \ |
| (@rules_python//python:autodetecting_toolchain)." |
| else |
| FAILURE_HEADER="\ |
| Error occurred while attempting to use the non-strict autodetecting Python \ |
| toolchain (@rules_python//python:autodetecting_toolchain_nonstrict)." |
| fi |
| |
| die() { |
| echo "$FAILURE_HEADER" 1>&2 |
| echo "$1" 1>&2 |
| exit 1 |
| } |
| |
| # We use `which` to locate the Python interpreter command on PATH. `command -v` |
| # is another option, but it doesn't check whether the file it finds has the |
| # executable bit. |
| # |
| # A tricky situation happens when this wrapper is invoked as part of running a |
| # tool, e.g. passing a py_binary target to `ctx.actions.run()`. Bazel will unset |
| # the PATH variable. Then the shell will see there's no PATH and initialize its |
| # own, sometimes without exporting it. This causes `which` to fail and this |
| # script to think there's no Python interpreter installed. To avoid this we |
| # explicitly pass PATH to each `which` invocation. We can't just export PATH |
| # because that would modify the environment seen by the final user Python |
| # program. |
| # |
| # See also: |
| # |
| # https://github.com/bazelbuild/continuous-integration/issues/578 |
| # https://github.com/bazelbuild/bazel/issues/8414 |
| # https://github.com/bazelbuild/bazel/issues/8415 |
| |
| # Try the "python%VERSION%" command name first, then fall back on "python". |
| PYTHON_BIN="$(PATH="$PATH" which python%VERSION% 2> /dev/null)" |
| USED_FALLBACK="0" |
| if [ -z "${PYTHON_BIN:-}" ]; then |
| PYTHON_BIN="$(PATH="$PATH" which python 2>/dev/null)" |
| USED_FALLBACK="1" |
| fi |
| if [ -z "${PYTHON_BIN:-}" ]; then |
| die "Neither 'python%VERSION%' nor 'python' were found on the target \ |
| platform's PATH, which is: |
| |
| $PATH |
| |
| Please ensure an interpreter is available on this platform (and marked \ |
| executable), or else register an appropriate Python toolchain as per the \ |
| documentation for py_runtime_pair \ |
| (https://github.com/bazelbuild/rules_python/blob/master/docs/python.md#py_runtime_pair)." |
| fi |
| |
| if [ "$STRICT" = "1" ]; then |
| # Verify that we grabbed an interpreter with the right version. |
| VERSION_STR="$("$PYTHON_BIN" -V 2>&1)" \ |
| || die "Could not get interpreter version via '$PYTHON_BIN -V'" |
| if ! echo "$VERSION_STR" | grep -q " %VERSION%\." ; then |
| die "According to '$PYTHON_BIN -V', version is '$VERSION_STR', but we \ |
| need version %VERSION%. PATH is: |
| |
| $PATH |
| |
| Please ensure an interpreter with version %VERSION% is available on this \ |
| platform as 'python%VERSION%' or 'python', or else register an appropriate \ |
| Python toolchain as per the documentation for py_runtime_pair \ |
| (https://github.com/bazelbuild/rules_python/blob/master/docs/python.md#py_runtime_pair). |
| |
| Note that prior to Bazel 0.27, there was no check to ensure that the \ |
| interpreter's version matched the version declared by the target (#4815). If \ |
| your build worked prior to Bazel 0.27, and you're sure your targets do not \ |
| require Python %VERSION%, you can opt out of this version check by using the \ |
| non-strict autodetecting toolchain instead of the standard autodetecting \ |
| toolchain. This can be done by passing the flag \ |
| \`--extra_toolchains=@rules_python//python:autodetecting_toolchain_nonstrict\` \ |
| on the command line or adding it to your bazelrc." |
| fi |
| fi |
| |
| exec "$PYTHON_BIN" "$@" |