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

Update repo name handling for Bzlmod compatibility #1621

Merged
merged 8 commits into from
Oct 24, 2024
Merged
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
21 changes: 21 additions & 0 deletions scala/private/macros/bzlmod.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""Utilities for working with Bazel modules"""

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

Args:
repository_ctx: a repository_ctx object

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

# Based 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
6 changes: 3 additions & 3 deletions scala/private/phases/phase_dependency.bzl
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# Gathers information about dependency mode and analysis

load(
"@io_bazel_rules_scala//scala/private:dependency.bzl",
"//scala/private:dependency.bzl",
"get_compiler_deps_mode",
"get_strict_deps_mode",
"new_dependency_info",
)
load(
"@io_bazel_rules_scala//scala/private:paths.bzl",
"//scala/private:paths.bzl",
_get_files_with_extension = "get_files_with_extension",
_java_extension = "java_extension",
)
Expand Down Expand Up @@ -35,7 +35,7 @@ def _phase_dependency(
p,
unused_deps_always_off,
strict_deps_always_off):
toolchain = ctx.toolchains["@io_bazel_rules_scala//scala:toolchain_type"]
toolchain = ctx.toolchains[Label("//scala:toolchain_type")]

target_label = str(ctx.label)

Expand Down
7 changes: 7 additions & 0 deletions scala/private/resources.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ def _target_path_by_default_prefixes(resource):
if rel_path:
return rel_path

# Looking inside an external repository. Trim off both the "external/" and
# the repository name components. Especially important under Bzlmod, because
# the canonical repository name may change between versions.
(dir_1, dir_2, rel_path) = path.partition("external/")
if rel_path:
return rel_path[rel_path.index("/"):]

# Both short_path and path have quirks we wish to avoid, in short_path there are times where
# it is prefixed by `../` instead of `external/`. And in .path it will instead return the entire
# bazel-out/... path, which is also wanting to be avoided. So instead, we return the short-path if
Expand Down
10 changes: 6 additions & 4 deletions scala/scala_maven_import_external.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ the following macros are defined below that utilize jvm_import_external:
- java_import_external - to demonstrate that the original functionality of `java_import_external` stayed intact.
"""

load("//scala/private:macros/bzlmod.bzl", "apparent_repo_name")
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "read_netrc", "read_user_netrc", "use_netrc")

# https://github.com/bazelbuild/bazel/issues/13709#issuecomment-1336699672
Expand Down Expand Up @@ -64,19 +65,20 @@ def _jvm_import_external(repository_ctx):
if (repository_ctx.attr.generated_linkable_rule_name and
not repository_ctx.attr.neverlink):
fail("Only use generated_linkable_rule_name if neverlink is set")
name = repository_ctx.attr.generated_rule_name or repository_ctx.name
repo_name = apparent_repo_name(repository_ctx)
name = repository_ctx.attr.generated_rule_name or repo_name
urls = repository_ctx.attr.jar_urls
if repository_ctx.attr.jar_sha256:
print("'jar_sha256' is deprecated. Please use 'artifact_sha256'")
sha = repository_ctx.attr.jar_sha256 or repository_ctx.attr.artifact_sha256
path = repository_ctx.name + ".jar"
path = repo_name + ".jar"
for url in urls:
if url.endswith(".jar"):
path = url[url.rindex("/") + 1:]
break
srcurls = repository_ctx.attr.srcjar_urls
srcsha = repository_ctx.attr.srcjar_sha256
srcpath = repository_ctx.name + "-src.jar" if srcurls else ""
srcpath = repo_name + "-src.jar" if srcurls else ""
coordinates = repository_ctx.attr.coordinates
for url in srcurls:
if url.endswith(".jar"):
Expand Down Expand Up @@ -136,7 +138,7 @@ def _jvm_import_external(repository_ctx):
"",
"alias(",
" name = \"jar\",",
" actual = \"@%s\"," % repository_ctx.name,
" actual = \"//:%s\"," % repo_name,
")",
"",
]))
Expand Down
51 changes: 38 additions & 13 deletions scala/scala_toolchain.bzl
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
load(
"@io_bazel_rules_scala//scala:providers.bzl",
_DepsInfo = "DepsInfo",
)
load("//scala:providers.bzl", _DepsInfo = "DepsInfo")
load(
"@io_bazel_rules_scala_config//:config.bzl",
"ENABLE_COMPILER_DEPENDENCY_TRACKING",
Expand Down Expand Up @@ -108,17 +105,17 @@ def _scala_toolchain_impl(ctx):

def _default_dep_providers():
dep_providers = [
"@io_bazel_rules_scala//scala:scala_xml_provider",
"@io_bazel_rules_scala//scala:parser_combinators_provider",
"@io_bazel_rules_scala//scala:scala_compile_classpath_provider",
"@io_bazel_rules_scala//scala:scala_library_classpath_provider",
"@io_bazel_rules_scala//scala:scala_macro_classpath_provider",
"scala_xml",
"parser_combinators",
"scala_compile_classpath",
"scala_library_classpath",
"scala_macro_classpath",
]
if SCALA_MAJOR_VERSION.startswith("2"):
dep_providers.append("@io_bazel_rules_scala//scala:semanticdb_provider")
return dep_providers
if SCALA_MAJOR_VERSION.startswith("2."):
dep_providers.append("semanticdb")
return [Label("//scala:%s_provider" % p) for p in dep_providers]

scala_toolchain = rule(
_scala_toolchain = rule(
_scala_toolchain_impl,
attrs = {
"scalacopts": attr.string_list(),
Expand Down Expand Up @@ -179,3 +176,31 @@ scala_toolchain = rule(
},
fragments = ["java"],
)

def _expand_patterns(patterns):
"""Expands string patterns to match actual Label values."""
result = []

for p in patterns:
exclude = p.startswith("-")
p = p.lstrip("-")
expanded = str(native.package_relative_label(p)) if p else ""

# If the original pattern doesn't contain ":", match any target
# beginning with the pattern prefix.
if expanded and ":" not in p:
expanded = expanded[:expanded.rindex(":")]

result.append(("-" if exclude else "") + expanded)

return result

def scala_toolchain(**kwargs):
"""Creates a Scala toolchain target."""
strict = kwargs.pop("dependency_tracking_strict_deps_patterns", [""])
unused = kwargs.pop("dependency_tracking_unused_deps_patterns", [""])
_scala_toolchain(
dependency_tracking_strict_deps_patterns = _expand_patterns(strict),
dependency_tracking_unused_deps_patterns = _expand_patterns(unused),
**kwargs
)
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class ScalaLibResourcesFromExternalDepTest extends SpecWithJUnit {
"allow to load resources" >> {

val expectedString = String.format("A resource%n"); //Using platform dependent newline (%n)
get("/external/test_new_local_repo/resource.txt") must beEqualTo(expectedString)
get("/resource.txt") must beEqualTo(expectedString)

}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class ScalaLibResourcesFromExternalScalaTest extends AnyFunSuite {

test("Scala library depending on resources from external resource-only jar should allow to load resources") {
val expectedString = String.format("A resource%n"); //Using platform dependent newline (%n)
assert(get("/external/test_new_local_repo/resource.txt") === expectedString)
assert(get("/resource.txt") === expectedString)
}

private def get(s: String): String =
Expand Down
19 changes: 15 additions & 4 deletions third_party/repositories/repositories.bzl
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
load("//scala/private:macros/bzlmod.bzl", "apparent_repo_name")
load(
"//third_party/repositories:scala_2_11.bzl",
_artifacts_2_11 = "artifacts",
Expand Down Expand Up @@ -102,14 +103,24 @@ def repositories(
default_artifacts = artifacts_by_major_scala_version[major_scala_version]
artifacts = dict(default_artifacts.items() + overriden_artifacts.items())
for id in for_artifact_ids:
if id not in artifacts:
fail("artifact %s not in third_party/repositories/scala_%s.bzl" % (
id,
major_scala_version.replace(".", "_"),
))

artifact_repo_name = id + suffix
_scala_maven_import_external(
name = id + suffix,
name = artifact_repo_name,
artifact = artifacts[id]["artifact"],
artifact_sha256 = artifacts[id]["sha256"],
licenses = ["notice"],
server_urls = maven_servers,
deps = [dep + suffix for dep in artifacts[id].get("deps", [])],
runtime_deps = artifacts[id].get("runtime_deps", []),
runtime_deps = [
dep + suffix
for dep in artifacts[id].get("runtime_deps", [])
],
testonly_ = artifacts[id].get("testonly", False),
fetch_sources = fetch_sources,
)
Expand All @@ -118,13 +129,13 @@ def repositories(
# See: https://github.com/bazelbuild/rules_scala/pull/1573
# Hopefully we can deprecate and remove it one day.
if suffix and scala_version == SCALA_VERSION:
_alias_repository(name = id, target = id + suffix)
_alias_repository(name = id, target = artifact_repo_name)

def _alias_repository_impl(rctx):
""" Builds a repository containing just two aliases to the Scala Maven artifacts in the `target` repository. """

format_kwargs = {
"name": rctx.name,
"name": apparent_repo_name(rctx),
"target": rctx.attr.target,
}
rctx.file("BUILD", """alias(
Expand Down