Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add apparent_repo_name utility to modules.bzl #548

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,6 @@ use_repo(as_extension_test_ext, "bar", "foo")

use_all_repos_test_ext = use_extension("//tests:modules_test.bzl", "use_all_repos_test_ext", dev_dependency = True)
use_repo(use_all_repos_test_ext, "baz", "qux")

apparent_repo_name_test_ext = use_extension("//tests:extensions/apparent_repo_name.bzl", "apparent_repo_name_test_ext", dev_dependency = True)
use_repo(apparent_repo_name_test_ext, "apparent-repo-name-test")
4 changes: 4 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,7 @@ load("//tests/directory:external_directory_tests.bzl", "external_directory_tests
external_directory_tests(name = "external_directory_tests")

register_unittest_toolchains()

load("//tests:extensions/apparent_repo_name.bzl", "apparent_repo_name_test_macro")

apparent_repo_name_test_macro()
42 changes: 42 additions & 0 deletions docs/modules_doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,48 @@

Skylib module containing utilities for Bazel modules and module extensions.

<a id="modules.apparent_repo_name"></a>

## modules.apparent_repo_name

<pre>
modules.apparent_repo_name(<a href="#modules.apparent_repo_name-repository_ctx">repository_ctx</a>)
</pre>

Generates a repository's apparent name from a repository_ctx object.

Useful when generating the default top level `BUILD` target for the
repository.

Example:
```starlark
_ALIAS_TARGET_TEMPLATE = """alias(
name = "{name}",
actual = "@{target_repo_name}",
visibility = ["//visibility:public"],
)
"""

def _alias_repository_impl(repository_ctx):
repository_ctx.file("BUILD", _ALIAS_TARGET_TEMPLATE.format(
name = apparent_repo_name(rctx),
target = rctx.attr.target_repo_name,
))
```


**PARAMETERS**


| Name | Description | Default Value |
| :------------- | :------------- | :------------- |
| <a id="modules.apparent_repo_name-repository_ctx"></a>repository_ctx | a repository_ctx object | none |

**RETURNS**

An apparent repo name derived from repository_ctx.name


<a id="modules.as_extension"></a>

## modules.as_extension
Expand Down
40 changes: 40 additions & 0 deletions lib/modules.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,47 @@ def _use_all_repos(module_ctx, reproducible = False):
**extension_metadata_kwargs
)

def _apparent_repo_name(repository_ctx):
"""Generates a repository's apparent name from a repository_ctx object.

Useful when generating the default top level `BUILD` target for the
repository.

Example:
```starlark
_ALIAS_TARGET_TEMPLATE = \"\"\"alias(
name = "{name}",
actual = "@{target_repo_name}",
visibility = ["//visibility:public"],
)
\"\"\"

def _alias_repository_impl(repository_ctx):
repository_ctx.file("BUILD", _ALIAS_TARGET_TEMPLATE.format(
name = apparent_repo_name(rctx),
target = rctx.attr.target_repo_name,
))
```

Args:
repository_ctx: a repository_ctx object

Returns:
An apparent repo name derived from repository_ctx.name
"""
repo_name = repository_ctx.name

# Bazed on this pattern from the Bazel source:
# com.google.devtools.build.lib.cmdline.RepositoryName.VALID_REPO_NAME
for i in range(len(repo_name) - 1, -1, -1):
c = repo_name[i]
if not (c.isalnum() or c in "_-."):
return repo_name[i + 1:]

return repo_name

modules = struct(
as_extension = _as_extension,
use_all_repos = _use_all_repos,
apparent_repo_name = _apparent_repo_name,
)
22 changes: 22 additions & 0 deletions tests/extensions/apparent_repo_name.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""Repo rule and module extension used to test modules.apparent_repo_name"""

load("//lib:modules.bzl", "modules")

def _apparent_repo_name_test_repo_impl(repository_ctx):
repo_name = modules.apparent_repo_name(repository_ctx)
test_file = "repo-name.bzl"
repository_ctx.file("WORKSPACE")
repository_ctx.file("BUILD", """exports_files(["%s"])""" % test_file)
repository_ctx.file(test_file, "REPO_NAME = \"%s\"" % repo_name)

apparent_repo_name_test_repo = repository_rule(
_apparent_repo_name_test_repo_impl,
)

def apparent_repo_name_test_macro():
apparent_repo_name_test_repo(name = "apparent-repo-name-test")

apparent_repo_name_test_ext = module_extension(
lambda _: apparent_repo_name_test_macro(),
doc = "Only used for testing modules.apparent_repo_name()",
)
30 changes: 28 additions & 2 deletions tests/modules_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@

"""Test usage of modules.bzl."""

load("@apparent-repo-name-test//:repo-name.bzl", "REPO_NAME")
load("//lib:modules.bzl", "modules")
load("//lib:unittest.bzl", "asserts", "unittest")
load("//rules:build_test.bzl", "build_test")

_is_bzlmod_enabled = str(Label("//tests:module_tests.bzl")).startswith("@@")

def _repo_rule_impl(repository_ctx):
repository_ctx.file("WORKSPACE")
repository_ctx.file("BUILD", """exports_files(["hello"])""")
Expand Down Expand Up @@ -45,12 +49,34 @@ use_all_repos_test_ext = module_extension(
doc = "Only used for testing modules.use_all_repos().",
)

def _apparent_repo_name_test(ctx):
"""Unit tests for modules.apparent_repo_name."""
env = unittest.begin(ctx)

asserts.equals(
env,
"apparent-repo-name-test",
REPO_NAME,
msg = " ".join([
"Returns the original name unchanged under WORKSPACE, and",
"the apparent repo name under Bzlmod.",
]),
)

return unittest.end(env)

apparent_repo_name_test = unittest.make(_apparent_repo_name_test)

# buildifier: disable=unnamed-macro
def modules_test_suite():
"""Creates the tests for modules.bzl if Bzlmod is enabled."""

is_bzlmod_enabled = str(Label("//tests:module_tests.bzl")).startswith("@@")
if not is_bzlmod_enabled:
unittest.suite(
"modules_tests",
apparent_repo_name_test,
)

if not _is_bzlmod_enabled:
return

build_test(
Expand Down