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

Draft: Add bzlmod minimal support #1541

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
Draft
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: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ hash2
.metals
.vscode
unformatted-*.backup.scala
.scala-build
.scala-build
MODULE.bazel.lock
32 changes: 32 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
module(name = "io_bazel_rules_scala")

bazel_dep(name = "bazel_skylib", version = "1.4.1")
bazel_dep(name = "rules_cc", version = "0.0.6")
bazel_dep(name = "rules_java", version = "5.5.0")
bazel_dep(name = "rules_proto", version = "5.3.0-21.7")

use_repo(
use_extension("//:extensions/scala_config_ext.bzl", "scala_config_dep"),
"io_bazel_rules_scala_config"
)

non_module_deps = use_extension("//:extensions/non_module_deps.bzl", "non_module_deps")
use_repo(non_module_deps, "scala_compiler_source")
use_repo(non_module_deps, "io_bazel_rules_scala_scala_library")
use_repo(non_module_deps, "io_bazel_rules_scala_scala_compiler")
use_repo(non_module_deps, "io_bazel_rules_scala_scala_xml")
use_repo(non_module_deps, "io_bazel_rules_scala_scala_parser_combinators")
use_repo(non_module_deps, "io_bazel_rules_scala_scala_interfaces")
use_repo(non_module_deps, "io_bazel_rules_scala_scala_reflect")
use_repo(non_module_deps, "org_scalameta_semanticdb_scalac")
use_repo(non_module_deps, "io_bazel_rules_scala_scala_tasty_core")
use_repo(non_module_deps, "io_bazel_rules_scala_scala_asm")
use_repo(non_module_deps, "io_bazel_rules_scala_scala_library_2")
use_repo(non_module_deps, "io_bazel_rules_scala_org_openjdk_jmh_jmh_core")
use_repo(non_module_deps, "io_bazel_rules_scala_org_openjdk_jmh_jmh_generator_asm")
use_repo(non_module_deps, "io_bazel_rules_scala_org_openjdk_jmh_jmh_generator_reflection")
use_repo(non_module_deps, "io_bazel_rules_scala_org_ows2_asm_asm")
use_repo(non_module_deps, "io_bazel_rules_scala_net_sf_jopt_simple_jopt_simple")
use_repo(non_module_deps, "io_bazel_rules_scala_org_apache_commons_commons_math3")

register_toolchains("@io_bazel_rules_scala//jmh:jmh_toolchain")
178 changes: 178 additions & 0 deletions WORKSPACE.bzlmod
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
workspace(name = "io_bazel_rules_scala")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

_build_tools_release = "5.1.0"

http_archive(
name = "com_github_bazelbuild_buildtools",
sha256 = "e3bb0dc8b0274ea1aca75f1f8c0c835adbe589708ea89bf698069d0790701ea3",
strip_prefix = "buildtools-%s" % _build_tools_release,
url = "https://github.com/bazelbuild/buildtools/archive/%s.tar.gz" % _build_tools_release,
)

load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")

# Declares @com_google_protobuf//:protoc pointing to released binary
# This should stop building protoc during bazel build
# See https://github.com/bazelbuild/rules_proto/pull/36
rules_proto_dependencies()

rules_proto_toolchains()

load("//scala:scala_cross_version.bzl", "default_maven_server_urls")
load("//twitter_scrooge:twitter_scrooge.bzl", "twitter_scrooge")

twitter_scrooge()

load("//scala_proto:scala_proto.bzl", "scala_proto_repositories")

scala_proto_repositories()

load("//scalatest:scalatest.bzl", "scalatest_repositories")

scalatest_repositories()

load("//specs2:specs2_junit.bzl", "specs2_junit_repositories")

specs2_junit_repositories()

register_toolchains("//testing:testing_toolchain")

load("//scala/scalafmt:scalafmt_repositories.bzl", "scalafmt_default_config", "scalafmt_repositories")

scalafmt_default_config()

scalafmt_repositories()

MAVEN_SERVER_URLS = default_maven_server_urls()

# needed for the cross repo proto test
load("//test/proto_cross_repo_boundary:repo.bzl", "proto_cross_repo_boundary_repository")

proto_cross_repo_boundary_repository()

new_local_repository(
name = "test_new_local_repo",
build_file_content =
"""
filegroup(
name = "data",
srcs = glob(["**/*.txt"]),
visibility = ["//visibility:public"],
)
""",
path = "third_party/test/new_local_repo",
)

local_repository(
name = "example_external_workspace",
path = "third_party/test/example_external_workspace",
)

load("@io_bazel_rules_scala//scala:toolchains.bzl", "scala_register_unused_deps_toolchains")

scala_register_unused_deps_toolchains()

register_toolchains("@io_bazel_rules_scala//test/proto:scalapb_toolchain")

load("//scala:scala_maven_import_external.bzl", "java_import_external")

# bazel's java_import_external has been altered in rules_scala to be a macro based on jvm_import_external
# in order to allow for other jvm-language imports (e.g. scala_import)
# the 3rd-party dependency below is using the java_import_external macro
# in order to make sure no regression with the original java_import_external
java_import_external(
name = "org_apache_commons_commons_lang_3_5_without_file",
generated_linkable_rule_name = "linkable_org_apache_commons_commons_lang_3_5_without_file",
jar_sha256 = "8ac96fc686512d777fca85e144f196cd7cfe0c0aec23127229497d1a38ff651c",
jar_urls = ["https://repo.maven.apache.org/maven2/org/apache/commons/commons-lang3/3.5/commons-lang3-3.5.jar"],
licenses = ["notice"], # Apache 2.0
neverlink = True,
testonly_ = True,
)

## Linting

load("//private:format.bzl", "format_repositories")

format_repositories()

http_archive(
name = "io_bazel_rules_go",
sha256 = "dd926a88a564a9246713a9c00b35315f54cbd46b31a26d5d8fb264c07045f05d",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.38.1/rules_go-v0.38.1.zip",
"https://github.com/bazelbuild/rules_go/releases/download/v0.38.1/rules_go-v0.38.1.zip",
],
)

load(
"@io_bazel_rules_go//go:deps.bzl",
"go_register_toolchains",
"go_rules_dependencies",
)

go_rules_dependencies()

go_register_toolchains(version = "1.19.5")

# Explicitly pull in a different (newer) version of rules_java for remote jdks
rules_java_extra_version = "5.1.0"

rules_java_extra_sha = "d974a2d6e1a534856d1b60ad6a15e57f3970d8596fbb0bb17b9ee26ca209332a"

rules_java_extra_url = "https://github.com/bazelbuild/rules_java/releases/download/{}/rules_java-{}.tar.gz".format(rules_java_extra_version, rules_java_extra_version)

http_archive(
name = "rules_java_extra",
sha256 = rules_java_extra_sha,
url = rules_java_extra_url,
)

load("@rules_java//java:repositories.bzl", "remote_jdk8_repos")

# We need to select based on platform when we use these
# https://github.com/bazelbuild/bazel/issues/11655
remote_jdk8_repos()

http_archive(
name = "bazelci_rules",
sha256 = "eca21884e6f66a88c358e580fd67a6b148d30ab57b1680f62a96c00f9bc6a07e",
strip_prefix = "bazelci_rules-1.0.0",
url = "https://github.com/bazelbuild/continuous-integration/releases/download/rules-1.0.0/bazelci_rules-1.0.0.tar.gz",
)

load("@bazelci_rules//:rbe_repo.bzl", "rbe_preconfig")

rbe_preconfig(
name = "rbe_default",
toolchain = "ubuntu2004-bazel-java11",
)

load("//third_party/repositories:repositories.bzl", "repositories")

repositories(
fetch_sources = False,
for_artifact_ids = [
# test adding a scala jar:
"com_twitter__scalding_date",
# test of strict deps (scalac plugin UT + E2E)
"com_google_guava_guava_21_0_with_file",
"com_github_jnr_jffi_native",
"org_apache_commons_commons_lang_3_5",
"com_google_guava_guava_21_0",
# test of import external
# scala maven import external decodes maven artifacts to its parts
# (group id, artifact id, packaging, version and classifier). To make sure
# the decoding and then the download url composition are working the artifact example
# must contain all the different parts and sha256s so the downloaded content will be
# validated against it
"org_springframework_spring_core",
"org_springframework_spring_tx",
"org_typelevel_kind_projector",
# For testing that we don't include sources jars to the classpath
"org_typelevel__cats_core",
],
maven_servers = MAVEN_SERVER_URLS,
)
74 changes: 74 additions & 0 deletions extensions/non_module_deps.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
load("//third_party/repositories:repositories.bzl", "repository")
load(
"@io_bazel_rules_scala//scala/private:macros/scala_repositories.bzl",
_dt_patched_compiler_setup = "dt_patched_compiler_setup",
)

def _non_module_deps_impl(ctx):
_dt_patched_compiler_setup()
repository(
id = "io_bazel_rules_scala_scala_library",
validate_scala_version = True,
)
repository(
id = "io_bazel_rules_scala_scala_compiler",
validate_scala_version = True,
)
repository(
id = "io_bazel_rules_scala_scala_xml",
validate_scala_version = True,
)
repository(
id = "io_bazel_rules_scala_scala_parser_combinators",
validate_scala_version = True,
)
repository(
id = "io_bazel_rules_scala_scala_interfaces",
validate_scala_version = True,
)
repository(
id = "io_bazel_rules_scala_scala_reflect",
validate_scala_version = True,
)
repository(
id = "org_scalameta_semanticdb_scalac",
validate_scala_version = True,
)
repository(
id = "io_bazel_rules_scala_scala_tasty_core",
validate_scala_version = True,
)
repository(
id = "io_bazel_rules_scala_scala_asm",
validate_scala_version = True,
)
repository(
id = "io_bazel_rules_scala_scala_library_2",
validate_scala_version = True,
)
repository(
id = "io_bazel_rules_scala_org_openjdk_jmh_jmh_core",
fetch_sources = False,
)
repository(
id = "io_bazel_rules_scala_org_openjdk_jmh_jmh_generator_asm",
fetch_sources = False,
)
repository(
id = "io_bazel_rules_scala_org_openjdk_jmh_jmh_generator_reflection",
fetch_sources = False,
)
repository(
id = "io_bazel_rules_scala_org_ows2_asm_asm",
fetch_sources = False,
)
repository(
id = "io_bazel_rules_scala_net_sf_jopt_simple_jopt_simple",
fetch_sources = False,
)
repository(
id = "io_bazel_rules_scala_org_apache_commons_commons_math3",
fetch_sources = False,
)

non_module_deps = module_extension(implementation = _non_module_deps_impl)
8 changes: 8 additions & 0 deletions extensions/scala_config_ext.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
load("//:scala_config.bzl", "scala_config")

def _scala_config_dep_impl(ctx):
scala_config(enable_compiler_dependency_tracking = True)

scala_config_dep = module_extension(
implementation = _scala_config_dep_impl,
)
4 changes: 2 additions & 2 deletions scala/private/phases/phase_dependency.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,11 @@ def _get_unused_deps_mode(ctx):

def _is_target_included(target, includes, excludes):
for exclude in excludes:
if target.startswith(exclude):
if target.startswith(exclude) or target.startswith("@" + exclude):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://bazel.build/external/overview#canonical-repo-name
for blzmod labels can be like "@@..."

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I don't miss anything, you don't need to do anything here - it'll be easier for users to just specify correct prefix themselves. It's a sloppy implementation to support label prefixes, I think let's not add more logic to it.

return False

for include in includes:
if target.startswith(include):
if target.startswith(include) or target.startswith("@" + include):
return True

return False
5 changes: 3 additions & 2 deletions scala/scala_maven_import_external.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ 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
name = repository_ctx.attr.repo_name or repository_ctx.attr.generated_rule_name or repository_ctx.name
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

names of repositories issued by bzlmod module extensions will look like:
_main~non_module_deps~new_repo
this is why I added explicit parameter to achieve: @new_repo

urls = repository_ctx.attr.jar_urls
if repository_ctx.attr.jar_sha256:
print("'jar_sha256' is deprecated. Please use 'artifact_sha256'")
Expand Down Expand Up @@ -133,7 +133,7 @@ def _jvm_import_external(repository_ctx):
"",
"alias(",
" name = \"jar\",",
" actual = \"@%s\"," % repository_ctx.name,
" actual = \"@%s\"," % (repository_ctx.attr.repo_name or repository_ctx.name),
")",
"",
]))
Expand Down Expand Up @@ -219,6 +219,7 @@ jvm_import_external = repository_rule(
implementation = _jvm_import_external,
attrs = {
"rule_name": attr.string(mandatory = True),
"repo_name": attr.string(),
"licenses": attr.string_list(mandatory = True, allow_empty = False),
"jar_urls": attr.string_list(mandatory = True, allow_empty = False),
"jar_sha256": attr.string(doc = "'jar_sha256' is deprecated. Please use 'artifact_sha256'"),
Expand Down
2 changes: 1 addition & 1 deletion test/shell/test_scala_config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ test_classpath_contains_2_13() {

test_scala_config_content() {
bazel build --repo_env=SCALA_VERSION=0.0.0 @io_bazel_rules_scala_config//:all 2> /dev/null
grep "SCALA_MAJOR_VERSION='0.0'" $(bazel info output_base)/external/io_bazel_rules_scala_config/config.bzl
grep "SCALA_MAJOR_VERSION='0.0'" $(bazel info output_base)/external/*/config.bzl
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when built with bzlmod target will be in sth like:
/external/~main_non_module_deps~io_bazel_rules_scala_config/config.bzl

}

$runner test_classpath_contains_2_12
Expand Down
2 changes: 1 addition & 1 deletion test/shell/test_scala_library.sh
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ test_scala_library_expect_better_failure_with_target_label_from_stamped_jar_on_m

test_scala_library_expect_better_failure_message_on_missing_transitive_dependency_labels_from_other_jvm_rules() {
transitive_target='.*transitive_dependency_without_manifest.jar'
direct_target='@//test_expect_failure/missing_direct_deps/internal_deps:unstamped_direct_java_provider_dependency'
direct_target='@.*//test_expect_failure/missing_direct_deps/internal_deps:unstamped_direct_java_provider_dependency'
test_target='//test_expect_failure/missing_direct_deps/internal_deps:unstamped_jar_dependent_on_some_java_provider'

expected_message="Unknown label of file $transitive_target which came from $direct_target"
Expand Down
Loading