Windows,examples: //examples/shell now works

The targets in //examples/shell:* now use the Bash
runfiles library in
@bazel_tools//tools/bash/runfiles and work on
Windows.

Also undef the RUNFILES_* envvars in
bazel_example_test::test_shell (which builds the
shell example project) so that the runfiles
library discovers its own runfiles instead of
trying (and failing) to use the enclosing test's
runfiles (which it shouldn't use, because the test
executes "bazel run //examples/shell:bin" so that
target's runfiles are independent of the enclosing
test's runfiles).

Fixes https://github.com/bazelbuild/bazel/issues/3839

Closes #5480.

Change-Id: I44f9bf9b11f7fac0e1c0995a44c2336846dc2bc8
PiperOrigin-RevId: 202313105
diff --git a/examples/shell/BUILD b/examples/shell/BUILD
index 4b51df1..095cea4 100644
--- a/examples/shell/BUILD
+++ b/examples/shell/BUILD
@@ -3,7 +3,10 @@
 sh_binary(
     name = "bin",
     srcs = ["bin.sh"],
-    deps = [":lib"],
+    deps = [
+        ":lib",
+        "@bazel_tools//tools/bash/runfiles",
+    ],
 )
 
 sh_library(
@@ -12,6 +15,7 @@
         "data/file.txt",
         "lib.sh",
     ],
+    deps = ["@bazel_tools//tools/bash/runfiles"],
 )
 
 sh_test(
@@ -19,7 +23,10 @@
     size = "small",
     srcs = ["test.sh"],
     data = ["data/test_file.txt"],
-    deps = [":lib"],
+    deps = [
+        ":lib",
+        "@bazel_tools//tools/bash/runfiles",
+    ],
 )
 
 filegroup(
diff --git a/examples/shell/bin.sh b/examples/shell/bin.sh
index 5b51ccf..9131503 100755
--- a/examples/shell/bin.sh
+++ b/examples/shell/bin.sh
@@ -14,12 +14,28 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-set -eu
+set -euo pipefail
+# --- begin runfiles.bash initialization ---
+if [[ ! -d "${RUNFILES_DIR:-/dev/null}" && ! -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
+    if [[ -f "$0.runfiles_manifest" ]]; then
+      export RUNFILES_MANIFEST_FILE="$0.runfiles_manifest"
+    elif [[ -f "$0.runfiles/MANIFEST" ]]; then
+      export RUNFILES_MANIFEST_FILE="$0.runfiles/MANIFEST"
+    elif [[ -f "$0.runfiles/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
+      export RUNFILES_DIR="$0.runfiles"
+    fi
+fi
+if [[ -f "${RUNFILES_DIR:-/dev/null}/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
+  source "${RUNFILES_DIR}/bazel_tools/tools/bash/runfiles/runfiles.bash"
+elif [[ -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
+  source "$(grep -m1 "^bazel_tools/tools/bash/runfiles/runfiles.bash " \
+            "$RUNFILES_MANIFEST_FILE" | cut -d ' ' -f 2-)"
+else
+  echo >&2 "ERROR: cannot find @bazel_tools//tools/bash/runfiles:runfiles.bash"
+  exit 1
+fi
+# --- end runfiles.bash initialization ---
 
-# This allows the script to be both a binary and a library script. If our binary has defined
-# RUNFILES then we use it, otherwise we look for our own runfiles.
-RUNFILES=${RUNFILES:-$0.runfiles/io_bazel}
-
-source "${RUNFILES}/examples/shell/lib.sh"
+source "$(rlocation io_bazel/examples/shell/lib.sh)"
 
 showfile
diff --git a/examples/shell/lib.sh b/examples/shell/lib.sh
index 495ef3d..c70918a 100755
--- a/examples/shell/lib.sh
+++ b/examples/shell/lib.sh
@@ -14,12 +14,28 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-set -eu
-
-# This allows the script to be both a binary and a library script. If our binary has defined
-# RUNFILES then we use it, otherwise we look for our own runfiles.
-RUNFILES=${RUNFILES:-$0.runfiles/io_bazel}
+set -euo pipefail
+# --- begin runfiles.bash initialization ---
+if [[ ! -d "${RUNFILES_DIR:-/dev/null}" && ! -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
+    if [[ -f "$0.runfiles_manifest" ]]; then
+      export RUNFILES_MANIFEST_FILE="$0.runfiles_manifest"
+    elif [[ -f "$0.runfiles/MANIFEST" ]]; then
+      export RUNFILES_MANIFEST_FILE="$0.runfiles/MANIFEST"
+    elif [[ -f "$0.runfiles/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
+      export RUNFILES_DIR="$0.runfiles"
+    fi
+fi
+if [[ -f "${RUNFILES_DIR:-/dev/null}/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
+  source "${RUNFILES_DIR}/bazel_tools/tools/bash/runfiles/runfiles.bash"
+elif [[ -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
+  source "$(grep -m1 "^bazel_tools/tools/bash/runfiles/runfiles.bash " \
+            "$RUNFILES_MANIFEST_FILE" | cut -d ' ' -f 2-)"
+else
+  echo >&2 "ERROR: cannot find @bazel_tools//tools/bash/runfiles:runfiles.bash"
+  exit 1
+fi
+# --- end runfiles.bash initialization ---
 
 function showfile {
-  cat "${RUNFILES}/examples/shell/data/file.txt"
+  cat "$(rlocation io_bazel/examples/shell/data/file.txt)"
 }
diff --git a/examples/shell/test.sh b/examples/shell/test.sh
index 6b7ba90..b4c7bf8 100755
--- a/examples/shell/test.sh
+++ b/examples/shell/test.sh
@@ -14,17 +14,33 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-set -eu
+set -euo pipefail
+# --- begin runfiles.bash initialization ---
+if [[ ! -d "${RUNFILES_DIR:-/dev/null}" && ! -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
+    if [[ -f "$0.runfiles_manifest" ]]; then
+      export RUNFILES_MANIFEST_FILE="$0.runfiles_manifest"
+    elif [[ -f "$0.runfiles/MANIFEST" ]]; then
+      export RUNFILES_MANIFEST_FILE="$0.runfiles/MANIFEST"
+    elif [[ -f "$0.runfiles/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
+      export RUNFILES_DIR="$0.runfiles"
+    fi
+fi
+if [[ -f "${RUNFILES_DIR:-/dev/null}/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
+  source "${RUNFILES_DIR}/bazel_tools/tools/bash/runfiles/runfiles.bash"
+elif [[ -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
+  source "$(grep -m1 "^bazel_tools/tools/bash/runfiles/runfiles.bash " \
+            "$RUNFILES_MANIFEST_FILE" | cut -d ' ' -f 2-)"
+else
+  echo >&2 "ERROR: cannot find @bazel_tools//tools/bash/runfiles:runfiles.bash"
+  exit 1
+fi
+# --- end runfiles.bash initialization ---
 
-# This allows RUNFILES to be declared outside the script it you want.
-# RUNFILES for test is the directory of the script.
-RUNFILES=${RUNFILES:-$($(cd $(dirname ${BASH_SOURCE[0]})); pwd)}
-
-source "${RUNFILES}/examples/shell/lib.sh"
+source "$(rlocation io_bazel/examples/shell/lib.sh)"
 
 function test_output {
   OUTPUT=$(showfile)
-  EXPECTED_OUTPUT=$(cat "${RUNFILES}/examples/shell/data/test_file.txt")
+  EXPECTED_OUTPUT=$(cat "$(rlocation io_bazel/examples/shell/data/test_file.txt)")
 
   if [ "${OUTPUT}" != "${EXPECTED_OUTPUT}" ]; then
     # This would be a failure case.