[bazel] Generate driver workarounds file

With GN, this can be done by setting the GN arg
    skia_generate_workarounds=true
and then running
    ninja -C out/Generate workaround_list

Now with Bazel, this can be done with:
    bazel run //tools:generate_workarounds

The reason we need to generate a Python script to run
our Python script is that we need Bazel to run the
script from the Skia root directory so it can modify
the //include/gpu/GrDriverBugWorkaroundsAutogen.h

By generating a script, users don't have to remember
to add on a special Bazel CLI argument [1]:
    --run_under='cd $SKIA_ROOT &&'

[1] https://bazel.build/docs/user-manual#run_under

Change-Id: I81d74392382b2791c7555a1e8e5105bd87776973
Bug: b/257466108
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/600436
Reviewed-by: Greg Daniel <egdaniel@google.com>
Reviewed-by: Ben Wagner <bungeman@google.com>
diff --git a/include/gpu/GrDriverBugWorkarounds.h b/include/gpu/GrDriverBugWorkarounds.h
index c57efc6..1aa995c 100644
--- a/include/gpu/GrDriverBugWorkarounds.h
+++ b/include/gpu/GrDriverBugWorkarounds.h
@@ -13,7 +13,8 @@
 #ifdef SK_GPU_WORKAROUNDS_HEADER
 #include SK_GPU_WORKAROUNDS_HEADER
 #else
-// To regenerate this file, set gn arg "skia_generate_workarounds = true".
+// To regenerate this file, set gn arg "skia_generate_workarounds = true"
+// or invoke `bazel run //tools:generate_workarounds`
 // This is not rebuilt by default to avoid embedders having to have extra
 // build steps.
 #include "include/gpu/GrDriverBugWorkaroundsAutogen.h"
diff --git a/tools/BUILD.bazel b/tools/BUILD.bazel
index de7df57..c604992 100644
--- a/tools/BUILD.bazel
+++ b/tools/BUILD.bazel
@@ -93,3 +93,53 @@
         "//tools/sksl-minify:__pkg__",
     ],
 )
+
+# Regenerate workarounds with `bazel run //tools:generate_workarounds`
+py_binary(
+    name = "generate_workarounds",
+    srcs = [":generate_workarounds.py"],
+    args = [
+        "--output-file",
+        "include/gpu/GrDriverBugWorkaroundsAutogen.h",
+        "src/gpu/gpu_workaround_list.txt",
+    ],
+    data = [
+        ":build_workaround_header",
+    ],
+    tags = ["no-remote"],
+)
+
+py_binary(
+    name = "build_workaround_header",
+    srcs = ["build_workaround_header.py"],
+)
+
+_GENERATE_WORKAROUNDS = """
+import os
+import subprocess
+import sys
+
+# https://bazel.build/docs/user-manual#running-executables
+# Note: Bazel eats single quotes, so we must use double quotes.
+os.chdir(os.environ["BUILD_WORKSPACE_DIRECTORY"])
+
+# execpath returns the path to the given label relative to the Skia root.
+# This will be something like:
+#   bazel-out/k8-opt-exec-81C6BA4F/bin/tools/build_workaround_header
+# https://bazel.build/reference/be/make-variables#predefined_label_variables
+generate_script = os.path.abspath("$(execpath :build_workaround_header)")
+
+result = subprocess.run(
+    [generate_script] + sys.argv[1:], capture_output=True, encoding="utf-8")
+if result.returncode != 0:
+    print(result.stdout)
+    print(result.stderr)
+    sys.exit(result.returncode)
+"""
+
+genrule(
+    name = "create_generate_workarounds_script",
+    outs = ["generate_workarounds.py"],
+    cmd = "echo '%s' > $@" % _GENERATE_WORKAROUNDS,
+    exec_tools = [":build_workaround_header"],
+)