http_archive: Support workspace_file and workspace_file_contents

...to be fully compatible with the native rules.

Change-Id: Ie340f73ec530ef0c8f50215a331f28f523398db8
PiperOrigin-RevId: 196801227
diff --git a/tools/build_defs/repo/git.bzl b/tools/build_defs/repo/git.bzl
index d9cf660..22026e8 100644
--- a/tools/build_defs/repo/git.bzl
+++ b/tools/build_defs/repo/git.bzl
@@ -113,6 +113,8 @@
     attrs = dict(_common_attrs.items() + {
         'build_file': attr.label(allow_single_file=True),
         'build_file_content': attr.string(),
+        'workspace_file': attr.label(),
+        'workspace_file_content': attr.string(),
     }.items())
 )
 """Clone an external git repository.
@@ -134,6 +136,14 @@
   build_file_content: The content for the BUILD file for this repository.
     Either build_file or build_file_content must be specified.
 
+  workspace_file: The file to use as the `WORKSPACE` file for this repository.
+
+    Either `workspace_file` or `workspace_file_content` can be specified, or
+    neither, but not both.
+  workspace_file_content: The content for the WORKSPACE file for this repository.
+
+    Either `workspace_file` or `workspace_file_content` can be specified, or
+    neither, but not both.
   tag: tag in the remote repository to checked out
 
   commit: specific commit to be checked out
diff --git a/tools/build_defs/repo/http.bzl b/tools/build_defs/repo/http.bzl
index 6659fcb..e478393 100644
--- a/tools/build_defs/repo/http.bzl
+++ b/tools/build_defs/repo/http.bzl
@@ -83,6 +83,8 @@
     "patches": attr.label_list(default=[]),
     "patch_tool": attr.string(default="patch"),
     "patch_cmds": attr.string_list(default=[]),
+    "workspace_file": attr.label(),
+    "workspace_file_content": attr.string(),
 }
 
 
@@ -148,6 +150,14 @@
   build_file_content: The content for the BUILD file for this repository.
 
     Either `build_file` or `build_file_content` can be specified.
+  workspace_file: The file to use as the `WORKSPACE` file for this repository.
+
+    Either `workspace_file` or `workspace_file_content` can be specified, or
+    neither, but not both.
+  workspace_file_content: The content for the WORKSPACE file for this repository.
+
+    Either `workspace_file` or `workspace_file_content` can be specified, or
+    neither, but not both.
   sha256: The expected SHA-256 of the file downloaded.
 
     This must match the SHA-256 of the file downloaded. _It is a security risk
diff --git a/tools/build_defs/repo/utils.bzl b/tools/build_defs/repo/utils.bzl
index b326a82..d46b90e 100644
--- a/tools/build_defs/repo/utils.bzl
+++ b/tools/build_defs/repo/utils.bzl
@@ -39,7 +39,19 @@
   if ctx.attr.build_file and ctx.attr.build_file_content:
     ctx.fail("Only one of build_file and build_file_content can be provided.")
 
-  ctx.file("WORKSPACE", "workspace(name = \"{name}\")\n".format(name=ctx.name))
+  if ctx.attr.workspace_file and ctx.attr.workspace_file_content:
+    ctx.fail("Only one of workspace_file and workspace_file_content can be provided.")
+
+  if ctx.attr.workspace_file:
+    bash_exe = ctx.os.environ["BAZEL_SH"] if "BAZEL_SH" in ctx.os.environ else "bash"
+    ctx.execute([bash_exe, "-c", "rm -f WORKSPACE"])
+    ctx.symlink(ctx.attr.workspace_file, "WORKSPACE")
+  elif ctx.attr.workspace_file_content:
+    bash_exe = ctx.os.environ["BAZEL_SH"] if "BAZEL_SH" in ctx.os.environ else "bash"
+    ctx.execute([bash_exe, "-c", "rm -f WORKSPACE"])
+    ctx.file("WORKSPACE", ctx.attr.build_file_content)
+  else:
+    ctx.file("WORKSPACE", "workspace(name = \"{name}\")\n".format(name=ctx.name))
 
   if ctx.attr.build_file:
     bash_exe = ctx.os.environ["BAZEL_SH"] if "BAZEL_SH" in ctx.os.environ else "bash"