[bazel] Fix and simplify Webpack compatibility hack for elements-sk Sass styles.

Before this CL, said hack did not work from a fresh repository checkout because it copied files straight from the //infra-sk/node_modules directory, which does not exist until the user runs "npm ci".

This CL replaces said paths with paths within the @infra-sk_npm namespace created via the rules_nodejs toolchain, which automatically runs "npm ci" if the node_modules directory does not exist.

This CL also simplifies this hack by using an easier to read Skylark macro to copy the necessary files, rather than a contrived shell command.

Bug: skia:10614
Change-Id: Iae6a57934008cf0b0a22f01196e10fcdac2bf5dd
Reviewed-on: https://skia-review.googlesource.com/c/buildbot/+/371749
Reviewed-by: Joe Gregorio <jcgregorio@google.com>
Commit-Queue: Leandro Lovisolo <lovisolo@google.com>
diff --git a/BUILD.bazel b/BUILD.bazel
index 287e11f..5d757bd 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -3,6 +3,7 @@
 load("@com_github_bazelbuild_buildtools//buildifier:def.bzl", "buildifier")
 load("@io_bazel_rules_docker//container:container.bzl", "container_push")
 load("@io_bazel_rules_docker//docker/util:run.bzl", "container_run_and_commit")
+load("//:elements-sk-scss.bzl", "generate_tilde_prefixed_elements_sk_scss_files")
 
 # Disable generation of go_proto_library targets. Let Gazelle use checked-in .pb.go files instead.
 #
@@ -205,61 +206,10 @@
     ],
 )
 
-####################################################################################################
-# Support for "~"-prefixed Sass imports of elements-sk styles, e.g.:                               #
-#                                                                                                  #
-#   @import '~elements-sk/themes/themes';                                                          #
-#                                                                                                  #
-# This hack is necessary to maintain compatibility with the Webpack build, which uses the          #
-# css-loader plugin to inline CSS imports. Said plugin adds all NPM packages to the Sass compiler  #
-# import path with the "~" prefix. See https://webpack.js.org/loaders/css-loader/#import for more. #
-####################################################################################################
-
-ELEMENTS_SK_SCSS = [
-    # To regenerate this list, please run the following Bash command:
-    #
-    #   $ find infra-sk/node_modules/elements-sk -name "*.scss" \
-    #       | sed -E "s/infra-sk\//\/\/infra-sk:/" | sort
-    "//infra-sk:node_modules/elements-sk/checkbox-sk/checkbox-sk.scss",
-    "//infra-sk:node_modules/elements-sk/collapse-sk/collapse-sk.scss",
-    "//infra-sk:node_modules/elements-sk/colors.scss",
-    "//infra-sk:node_modules/elements-sk/icon/icon-sk.scss",
-    "//infra-sk:node_modules/elements-sk/multi-select-sk/multi-select-sk.scss",
-    "//infra-sk:node_modules/elements-sk/nav-links-sk/nav-links-sk.scss",
-    "//infra-sk:node_modules/elements-sk/radio-sk/radio-sk.scss",
-    "//infra-sk:node_modules/elements-sk/select-sk/select-sk.scss",
-    "//infra-sk:node_modules/elements-sk/spinner-sk/spinner-sk.scss",
-    "//infra-sk:node_modules/elements-sk/styles/buttons/buttons.scss",
-    "//infra-sk:node_modules/elements-sk/styles/select/select.scss",
-    "//infra-sk:node_modules/elements-sk/styles/table/table.scss",
-    "//infra-sk:node_modules/elements-sk/tabs-panel-sk/tabs-panel-sk.scss",
-    "//infra-sk:node_modules/elements-sk/tabs-sk/tabs-sk.scss",
-    "//infra-sk:node_modules/elements-sk/themes/color-palette.scss",
-    "//infra-sk:node_modules/elements-sk/themes/themes.scss",
-    "//infra-sk:node_modules/elements-sk/toast-sk/toast-sk.scss",
-]
-
-TILDE_ELEMENTS_SK_SCSS = [f.replace("//infra-sk:node_modules/", "~") for f in ELEMENTS_SK_SCSS]
-
-# Recursively copies all *.scss files from //infra-sk/node_modules/elements-sk to //~elements-sk.
-genrule(
-    name = "~elements-sk_generator",
-    srcs = ELEMENTS_SK_SCSS,
-    outs = TILDE_ELEMENTS_SK_SCSS,
-    cmd =
-        "for FILENAME in $(SRCS); do " +
-        "  TILDE_FILENAME=`echo $$FILENAME | sed -E 's/infra-sk\\/node_modules\\/(.*)/~\\1/'`; " +
-        "  TILDE_DIR=$$(dirname $$TILDE_FILENAME); " +
-        "  mkdir -p $(RULEDIR)/$$TILDE_DIR; " +
-        "  cp $$FILENAME $(RULEDIR)/$$TILDE_FILENAME; " +
-        "done",
-)
-
-# Do not use directly. Use //infra-sk:elements-sk_scss instead, which includes these files as well.
-filegroup(
+# Generate a copy of the elements-sk SCSS stylesheets under //bazel-bin/~elements-sk for
+# compatibility with Webpack-style tilde-prefixed SCSS imports. See the macro docstring for details.
+generate_tilde_prefixed_elements_sk_scss_files(
     name = "~elements-sk",
-    srcs = TILDE_ELEMENTS_SK_SCSS,
-    visibility = ["//infra-sk:__pkg__"],
 )
 
 go_library(
diff --git a/elements-sk-scss.bzl b/elements-sk-scss.bzl
new file mode 100644
index 0000000..c65e588
--- /dev/null
+++ b/elements-sk-scss.bzl
@@ -0,0 +1,73 @@
+"""This module provides a macro to support Webpack-style SCSS imports for elements-sk styles.
+
+This module will be removed once the migration off Webpack is complete.
+"""
+
+def generate_tilde_prefixed_elements_sk_scss_files(name):
+    """Copies @infra-sk_npm//:node_modules/elements-sk/**/*.scss files into //bazel-bin/~elemnts-sk.
+
+    This macro adds support for tilde-prefixed Sass imports of elements-sk styles, e.g.:
+
+    ```
+    @import '~elements-sk/themes/themes';
+    ```
+
+    The output of this macro is a filegroup with the generated tilde-prefixed SCSS files. Do not use
+    directly; client code should use the //infra-sk:elements-sk_scss sass_library target instead.
+
+    This hack is necessary to maintain compatibility with the Webpack build, which uses the
+    css-loader plugin to inline CSS imports. Said plugin adds all NPM packages to the Sass compiler
+    import path, prefixed with "~". See https://webpack.js.org/loaders/css-loader/#import for more.
+
+    This macro will be removed once we're completely off Webpack, and all our SCSS imports have been
+    rewritten using the conventional (i.e. non-Webpack) syntax.
+
+    Args:
+        name: Name of the output filegroup which will contain the tilde-prefixed SCSS files.
+    """
+
+    scss_files = [
+        # To regenerate this list, please run the following Bash command:
+        #
+        #   $ find infra-sk/node_modules/elements-sk -name "*.scss" \
+        #       | sed -E "s/infra-sk\//@infra-sk_npm\/\/:/" \
+        #       | sort
+        "@infra-sk_npm//:node_modules/elements-sk/checkbox-sk/checkbox-sk.scss",
+        "@infra-sk_npm//:node_modules/elements-sk/collapse-sk/collapse-sk.scss",
+        "@infra-sk_npm//:node_modules/elements-sk/colors.scss",
+        "@infra-sk_npm//:node_modules/elements-sk/icon/icon-sk.scss",
+        "@infra-sk_npm//:node_modules/elements-sk/multi-select-sk/multi-select-sk.scss",
+        "@infra-sk_npm//:node_modules/elements-sk/nav-links-sk/nav-links-sk.scss",
+        "@infra-sk_npm//:node_modules/elements-sk/radio-sk/radio-sk.scss",
+        "@infra-sk_npm//:node_modules/elements-sk/select-sk/select-sk.scss",
+        "@infra-sk_npm//:node_modules/elements-sk/spinner-sk/spinner-sk.scss",
+        "@infra-sk_npm//:node_modules/elements-sk/styles/buttons/buttons.scss",
+        "@infra-sk_npm//:node_modules/elements-sk/styles/select/select.scss",
+        "@infra-sk_npm//:node_modules/elements-sk/styles/table/table.scss",
+        "@infra-sk_npm//:node_modules/elements-sk/tabs-panel-sk/tabs-panel-sk.scss",
+        "@infra-sk_npm//:node_modules/elements-sk/tabs-sk/tabs-sk.scss",
+        "@infra-sk_npm//:node_modules/elements-sk/themes/color-palette.scss",
+        "@infra-sk_npm//:node_modules/elements-sk/themes/themes.scss",
+        "@infra-sk_npm//:node_modules/elements-sk/toast-sk/toast-sk.scss",
+    ]
+
+    tilde_prefixed_scss_files = [
+        f.replace("@infra-sk_npm//:node_modules/elements-sk", "~elements-sk")
+        for f in scss_files
+    ]
+
+    # Copy each SCSS file into its tilde-prefixed location.
+    for scss_file, tilde_prefixed_scss_file in zip(scss_files, tilde_prefixed_scss_files):
+        native.genrule(
+            name = tilde_prefixed_scss_file.replace("/", "__"),  # No slashes on build target names.
+            srcs = [scss_file],
+            outs = [tilde_prefixed_scss_file],
+            cmd = "cp $< $@",
+        )
+
+    # Do not use directly. Use //infra-sk:elements-sk_scss instead, which includes these files.
+    native.filegroup(
+        name = name,
+        srcs = tilde_prefixed_scss_files,
+        visibility = ["//infra-sk:__pkg__"],
+    )