blob: 745a5ac73f011a3183456f60f0fcb74a0a2831fb [file] [log] [blame]
"""Repository rules for downloading archives from GitHub and GitLab"""
def workspace_and_buildfile(ctx):
"""Utility function for writing WORKSPACE and, if requested, a BUILD file.
This rule is intended to be used in the implementation function of a
repository rule.
It assumes the parameters `name`, `build_file`, `build_file_content`,
`workspace_file`, and `workspace_file_content` to be
present in `ctx.attr`; the latter four possibly with value None.
Args:
ctx: The repository context of the repository rule calling this utility
function.
"""
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.")
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:
ctx.file("WORKSPACE", ctx.read(ctx.attr.workspace_file))
elif ctx.attr.workspace_file_content:
ctx.file("WORKSPACE", ctx.attr.workspace_file_content)
else:
ctx.file("WORKSPACE", "workspace(name = \"{name}\")\n".format(name = ctx.name))
if ctx.attr.build_file:
ctx.file("BUILD.bazel", ctx.read(ctx.attr.build_file))
elif ctx.attr.build_file_content:
ctx.file("BUILD.bazel", ctx.attr.build_file_content)
def _github_archive_impl(repository_ctx):
"""A rule to be called in the WORKSPACE that adds an external from github using a workspace rule.
The required name= is the rule name and so is used for @name//... labels when referring to this archive from BUILD files.
The required commit= is the git hash to download.
When the git project is also a git submodule in CMake, this should be kept in sync with the git submodule commit used there.
This can also be a tag.
The required sha256= is the checksum of the downloaded archive.
When unsure, you can omit this argument (or comment it out) and then the checksum-mismatch error message message will offer a suggestion.
The optional build_file= is the BUILD file label to use for building this external.
When omitted, the BUILD file(s) within the archive will be used.
The optional local_repository_override= can be used for temporary local testing;
instead of retrieving the code from github, the code is retrieved from the local filesystem path given in the argument.
Args:
repository_ctx: The context object for the repository rule.
"""
if repository_ctx.attr.build_file and repository_ctx.attr.build_file_content:
fail("Only one of build_file and build_file_content can be provided.")
if repository_ctx.attr.workspace_file and repository_ctx.attr.workspace_file_content:
fail("Only one of workspace_file and workspace_file_content can be provided.")
repository = repository_ctx.attr.repository
commit = repository_ctx.attr.commit
urls = ["https://github.com/%s/archive/%s.tar.gz" % (repository, commit)]
repository_split = repository.split("/")
if len(repository_split) != 2:
fail("The repository must be formatted as 'organization/project'. Got: %s" % repository)
_, project = repository_split
# Github archives omit the "v" in version tags, for some reason.
strip_commit = commit.removeprefix("v")
strip_prefix = project + "-" + strip_commit
repository_ctx.download_and_extract(
urls,
sha256 = repository_ctx.attr.sha256,
stripPrefix = strip_prefix,
)
workspace_and_buildfile(repository_ctx)
github_archive = repository_rule(
implementation = _github_archive_impl,
local = True,
attrs = {
"repository": attr.string(mandatory = True, doc = "The github repository to download from."),
"commit": attr.string(mandatory = True, doc = "The git commit hash to download."),
"sha256": attr.string(default = "0" * 64, doc = "The sha256 checksum of the downloaded archive."),
"build_file": attr.label(doc = "The BUILD file label to use for building this external."),
"build_file_content": attr.string(doc = "The content for the BUILD file for this repository."),
"workspace_file": attr.label(doc = "The file to use as the `WORKSPACE` file for this repository."),
"workspace_file_content": attr.string(doc = "The content for the WORKSPACE file for this repository."),
},
)