Rename `stripPrefix=` to `strip_prefix=`

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

Closes #24019.

RELNOTES: The stripPrefix parameter of repository_ctx.download_and_extract()
and repository_ctx.extract() has been renamed to strip_prefix; the deprecated
stripPrefix name remains usable for compatibility.
PiperOrigin-RevId: 687224164
Change-Id: Iffaba2e65c049a2ff8bb98d1fba52e0bba9e5a02
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/starlark/StarlarkBaseExternalContext.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/starlark/StarlarkBaseExternalContext.java
index 25b155e..8902fe2 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/starlark/StarlarkBaseExternalContext.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/starlark/StarlarkBaseExternalContext.java
@@ -904,16 +904,18 @@
                 ".tzst", "tar.bz2", ".tbz", ".ar", or ".deb" here.
                 """),
         @Param(
-            name = "stripPrefix",
+            name = "strip_prefix",
             defaultValue = "''",
             named = true,
             doc =
                 """
-                A directory prefix to strip from the extracted files.
-                Many archives contain a top-level directory that contains all files in the \
-                archive. Instead of needing to specify this prefix over and over in the \
-                <code>build_file</code>, this field can be used to strip it from extracted \
-                files.
+                A directory prefix to strip from the extracted files. Many archives contain a
+                top-level directory that contains all files in the archive. Instead of needing to
+                specify this prefix over and over in the <code>build_file</code>, this field can
+                be used to strip it from extracted files.
+
+                <p>For compatibility, this parameter may also be used under the deprecated name
+                <code>stripPrefix</code>.
                 """),
         @Param(
             name = "allow_fail",
@@ -973,6 +975,12 @@
 contain non-Unicode filenames, or which have files that would extract to \
 the same path on case-insensitive filesystems.
 """),
+        @Param(
+            name = "stripPrefix",
+            documented = false,
+            positional = false,
+            named = true,
+            defaultValue = "''"),
       })
   public StructImpl downloadAndExtract(
       Object url,
@@ -986,8 +994,10 @@
       Dict<?, ?> headersUnchecked, // <String, List<String> | String> expected
       String integrity,
       Dict<?, ?> renameFiles, // <String, String> expected
+      String oldStripPrefix,
       StarlarkThread thread)
       throws RepositoryFunctionException, InterruptedException, EvalException {
+    stripPrefix = renamedStripPrefix("download_and_extract", stripPrefix, oldStripPrefix);
     ImmutableMap<URI, Map<String, List<String>>> authHeaders =
         getAuthHeaders(getAuthContents(authUnchecked, "auth"));
 
@@ -996,8 +1006,9 @@
     ImmutableList<URL> urls =
         getUrls(
             url,
-            /*ensureNonEmpty=*/ !allowFail,
-            /*checksumGiven=*/ !Strings.isNullOrEmpty(sha256) || !Strings.isNullOrEmpty(integrity));
+            /* ensureNonEmpty= */ !allowFail,
+            /* checksumGiven= */ !Strings.isNullOrEmpty(sha256)
+                || !Strings.isNullOrEmpty(integrity));
     Optional<Checksum> checksum;
     RepositoryFunctionException checksumValidation = null;
     try {
@@ -1141,15 +1152,19 @@
                 "path to the directory where the archive will be unpacked,"
                     + " relative to the repository directory."),
         @Param(
-            name = "stripPrefix",
+            name = "strip_prefix",
             defaultValue = "''",
             named = true,
             doc =
-                "a directory prefix to strip from the extracted files."
-                    + "\nMany archives contain a top-level directory that contains all files in the"
-                    + " archive. Instead of needing to specify this prefix over and over in the"
-                    + " <code>build_file</code>, this field can be used to strip it from extracted"
-                    + " files."),
+                """
+                a directory prefix to strip from the extracted files. Many archives contain a
+                top-level directory that contains all files in the archive. Instead of needing to
+                specify this prefix over and over in the <code>build_file</code>, this field can be
+                used to strip it from extracted files.
+
+                <p>For compatibility, this parameter may also be used under the deprecated name
+                <code>stripPrefix</code>.
+                """),
         @Param(
             name = "rename_files",
             defaultValue = "{}",
@@ -1173,6 +1188,12 @@
                     + "not attempt to watch the file; passing 'auto' will only attempt to watch "
                     + "the file when it is legal to do so (see <code>watch()</code> docs for more "
                     + "information."),
+        @Param(
+            name = "stripPrefix",
+            documented = false,
+            positional = false,
+            named = true,
+            defaultValue = "''"),
       })
   public void extract(
       Object archive,
@@ -1180,8 +1201,10 @@
       String stripPrefix,
       Dict<?, ?> renameFiles, // <String, String> expected
       String watchArchive,
+      String oldStripPrefix,
       StarlarkThread thread)
       throws RepositoryFunctionException, InterruptedException, EvalException {
+    stripPrefix = renamedStripPrefix("extract", stripPrefix, oldStripPrefix);
     StarlarkPath archivePath = getPath(archive);
 
     if (!archivePath.exists()) {
@@ -1258,6 +1281,20 @@
     }
   }
 
+  private static String renamedStripPrefix(String method, String stripPrefix, String oldStripPrefix)
+      throws EvalException {
+    if (oldStripPrefix.isEmpty()) {
+      return stripPrefix;
+    }
+    if (stripPrefix.isEmpty()) {
+      return oldStripPrefix;
+    }
+    throw Starlark.errorf(
+        "%s() got multiple values for parameter 'strip_prefix' (via compatibility alias"
+            + " 'stripPrefix')",
+        method);
+  }
+
   @StarlarkMethod(
       name = "file",
       doc = "Generates a file in the repository directory with the provided content.",
diff --git a/src/test/shell/bazel/external_integration_test.sh b/src/test/shell/bazel/external_integration_test.sh
index 54c0215..527b613 100755
--- a/src/test/shell/bazel/external_integration_test.sh
+++ b/src/test/shell/bazel/external_integration_test.sh
@@ -1922,7 +1922,7 @@
   result = ctx.download_and_extract(
     url = [],
     type = "zip",
-    stripPrefix="ext",
+    strip_prefix="ext",
     sha256 = ctx.attr.sha256,
     allow_fail = True,
   )