Automated rollback of commit d550145730c330cf9412b0f48b5f423829d9ff85.

*** Reason for rollback ***

TAP breakage

*** Original change description ***

file_test: fix for Windows

Rewrite the file_test rule in
@bazel_tools//tools/build_rules:test_rules.bzl to
use ctx.actions.run_shell instead of running a
shell script.

This way Bazel (on Windows) knows how to run the
code.

See https://github.com/bazelbuild/bazel/issues/6122

Closes #6320.

PiperOrigin-RevId: 217375289
diff --git a/tools/BUILD b/tools/BUILD
index fcbc559..c9ffaf5 100644
--- a/tools/BUILD
+++ b/tools/BUILD
@@ -72,7 +72,6 @@
         "//tools/android:all_windows_tests",
         "//tools/bash:all_windows_tests",
         "//tools/build_defs:all_windows_tests",
-        "//tools/build_rules:all_windows_tests",
         "//tools/cpp/runfiles:all_windows_tests",
         "//tools/java:all_windows_tests",
         "//tools/jdk:all_windows_tests",
diff --git a/tools/build_rules/BUILD b/tools/build_rules/BUILD
index 8a99913..0b3f17a 100644
--- a/tools/build_rules/BUILD
+++ b/tools/build_rules/BUILD
@@ -21,20 +21,3 @@
     data = ["test_rules.bzl"],
     deps = ["//src/test/py/bazel:test_base"],
 )
-
-test_suite(
-    name = "windows_tests",
-    tags = [
-        "-no_windows",
-        "-slow",
-    ],
-    visibility = ["//visibility:private"],
-)
-
-test_suite(
-    name = "all_windows_tests",
-    tests = [
-        ":windows_tests",
-    ],
-    visibility = ["//tools:__pkg__"],
-)
diff --git a/tools/build_rules/test_rules.bzl b/tools/build_rules/test_rules.bzl
index 055c255..c365021 100644
--- a/tools/build_rules/test_rules.bzl
+++ b/tools/build_rules/test_rules.bzl
@@ -267,114 +267,49 @@
 
 def _file_test_impl(ctx):
     """check that a file has a given content."""
-    script1 = ctx.actions.declare_file(ctx.label.name + "-gen.bash")
-
-    # Since file_test is used from the @bazel_tools repo but also tested in the main Bazel repo, we
-    # cannot create a sh_binary for the script below and use it from file_test, because depending on
-    # the sh_binary would require knowing which depot the file_test is instantiated from.
-    #
-    # In other words, if there were a @bazel_tools//tools/build_rules:file_test_helper rule (the
-    # sh_binary), then file_test could reference it as:
-    #   - @bazel_tools//tools/build_rules:file_test_helper, which would work when using a Bazel
-    #     version that already contains this target, but not with Bazel 0.17.2 (latest release as of
-    #     the writing of this comment), or
-    #   - @io_bazel//tools/build_rules:file_test_helper, which would only work if the @io_bazel repo
-    #     is defined (either in Bazel's own source tree, or if the current project imports Bazel's
-    #     tree)
-    #   - //tools/build_rules:file_test_helper, which would only work if the current source tree
-    #     contains this target, which is unlikely.
-    # Considering that all 3 options are wrong, we resort to writing a script file on-the-fly.
-    ctx.actions.write(script1, is_executable = True, content = """#!/bin/bash
-set -euo pipefail
-declare -r OUT="$1"
-declare -r INPUT="$2"
-declare -r IS_WINDOWS="$3"
-declare -r CONTENT="$4"
-declare -r REGEXP="$5"
-declare -r MATCHES="$6"
-
-if [[ ( -n "${CONTENT:-}" && -n "${REGEXP:-}" ) || ( -z "${CONTENT:-}" && -z "${REGEXP:-}" ) ]]; then
-  echo >&2 "ERROR: expected either 'content' or 'regexp'"
-  exit 1
-elif [[ -n "${CONTENT:-}" && ( -n "${MATCHES:-}" && "$MATCHES" != "-1" ) ]]; then
-  echo >&2 "ERROR: cannot specify 'matches' together with 'content'"
-  exit 1
-elif [[ ! ( -z "${MATCHES:-}" || "$MATCHES" = 0 || "$MATCHES" =~ ^-?[1-9][0-9]*$ ) ]]; then
-  echo >&2 "ERROR: 'matches' must be an integer"
-  exit 1
-elif [[ ! -e "${INPUT:-/dev/null/does-not-exist}" ]]; then
-  echo >&2 "ERROR: input file must exist"
-  exit 1
-else
-  if [[ -n "${CONTENT:-}" ]]; then
-    declare -r GOLDEN_FILE="$(mktemp)"
-    declare -r ACTUAL_FILE="$(mktemp)"
-    # Normalize line endings in both files.
-    echo -e -n "$CONTENT" | sed 's,\\r\\n,\\n,g' > "$GOLDEN_FILE"
-    sed 's,\\r\\n,\\n,g' "$INPUT" > "$ACTUAL_FILE"
-    if ! diff -u "$GOLDEN_FILE" "$ACTUAL_FILE" ; then
-      echo >&2 "ERROR: file did not have expected content"
-      exit 1
-    fi
-  else
-    if [[ -n "${MATCHES:-}" && $MATCHES -gt -1 ]]; then
-      if [[ "$MATCHES" != $(grep -c "$REGEXP" "$INPUT") ]]; then
-        echo >&2 "ERROR: file did not contain expected regexp $MATCHES times"
-        exit 1
-      fi
-    else
-      if ! grep "$REGEXP" "$INPUT"; then
-        echo >&2 "ERROR: file did not contain expected regexp"
-        exit 1
-      fi
-    fi
-  fi
-
-  # Write a platform-specific script that is the actual test.
-  # The test script is a dummy, always-passing test. However if this script got to this point, then
-  # the actual assertions succeeded.
-  # The test script has an embedded timestamp, for the purpose of correct cache hit reporting. If it
-  # didn't, Bazel would always report file_test to be cached, because its only input (the test
-  # script) would never change. However, Bazel would still rebuild the action that generates the
-  # test script, i.e. it would perform the actual assertions, but it would look like it didn't.
-  if [[ "${IS_WINDOWS:-}" = "yes" ]]; then
-    echo -e "@rem $(date +"%s.%N")\\n@echo PASSED" > "$OUT"
-  else
-    echo -e "#!/bin/sh\\n# $(date +"%s.%N")\\necho PASSED" > "$OUT"
-  fi
-  chmod +x "$OUT"
-fi
-""")
-
-    is_windows = bool(ctx.attr.is_windows)
-    script2 = ctx.actions.declare_file(ctx.label.name + (".bat" if is_windows else ".bash"))
-
-    # TODO(laszlocsomor): once https://github.com/bazelbuild/bazel/issues/6391 is fixed, change the
-    # "command" to only contain script1's path, and pass arguments with the "arguments" attribute.
-    ctx.actions.run_shell(
-        inputs = [ctx.file.src],
-        outputs = [script2],
-        tools = [script1],
-        command = " ".join([
-            script1.path,
-            script2.path,
-            ctx.file.src.path,
-            "yes" if is_windows else "no",
-            repr(ctx.attr.content),
-            repr(ctx.attr.regexp),
-            ctx.attr.matches if ctx.attr.matches > -1 else repr(""),
-        ]),
+    exe = ctx.outputs.executable
+    file_ = ctx.file.file
+    content = ctx.attr.content
+    regexp = ctx.attr.regexp
+    matches = ctx.attr.matches
+    if bool(content) == bool(regexp):
+        fail("Must specify one and only one of content or regexp")
+    if content and matches != -1:
+        fail("matches only makes sense with regexp")
+    if content:
+        dat = ctx.new_file(ctx.genfiles_dir, exe, ".dat")
+        ctx.file_action(
+            output = dat,
+            content = content,
+        )
+        ctx.file_action(
+            output = exe,
+            content = "diff -u %s %s" % (dat.short_path, file_.short_path),
+            executable = True,
+        )
+        return struct(runfiles = ctx.runfiles([exe, dat, file_]))
+    if matches != -1:
+        script = "[ %s == $(grep -c %s %s) ]" % (
+            matches,
+            repr(regexp),
+            file_.short_path,
+        )
+    else:
+        script = "grep %s %s" % (repr(regexp), file_.short_path)
+    ctx.file_action(
+        output = exe,
+        content = script,
+        executable = True,
     )
+    return struct(runfiles = ctx.runfiles([exe, file_]))
 
-    return [DefaultInfo(executable = script2)]
-
-_file_test = rule(
+file_test = rule(
     attrs = {
-        "src": attr.label(
+        "file": attr.label(
             mandatory = True,
-            allow_single_file = True,
+            allow_files = True,
+            single_file = True,
         ),
-        "is_windows": attr.bool(mandatory = True),
         "content": attr.string(default = ""),
         "regexp": attr.string(default = ""),
         "matches": attr.int(default = -1),
@@ -383,17 +318,3 @@
     test = True,
     implementation = _file_test_impl,
 )
-
-def file_test(name, file, content = None, regexp = None, matches = None, **kwargs):
-    _file_test(
-        name = name,
-        src = file,
-        content = content,
-        regexp = regexp,
-        matches = matches or -1,
-        is_windows = select({
-            "@bazel_tools//src/conditions:windows": True,
-            "//conditions:default": False,
-        }),
-        **kwargs
-    )