bazelbuild / rules_scala

Scala rules for Bazel
Apache License 2.0
363 stars 278 forks source link

Use custom repo rule to generate @scalafmt_default #1626

Closed mbland closed 1 month ago

mbland commented 1 month ago

Description

Replaces native.new_local_repository in scalafmt_default_config with the new scalafmt_config repo rule. Also updates the native.register_toolchains call with a stringified Label to remove the hardcoding of @io_bazel_rules_scala.

Resolves an incompatibility between Bazel 6.5.0 and 7.3.2, while creating a much smaller @scalafmt_default repo. The problem is that under Bazel 7.3.2, calling scalafmt_default_config from a module extension produces this error:

$ bazel test //test/scalafmt/...

ERROR: Traceback (most recent call last):
  File ".../scala/extensions/deps.bzl",
    line 218, column 32, in _scala_deps_impl
    scalafmt_default_config()
  File ".../scala/scalafmt/scalafmt_repositories.bzl",
    line 18, column 32, in scalafmt_default_config
    native.new_local_repository(

Error in new_local_repository: The native module can be accessed only
  from a BUILD thread. Wrap the function in a macro and call it from a
  BUILD file

Ostensibly the solution is to replace native.new_local_repository with:

load(
  "@bazel_tools//tools/build_defs/repo:local.bzl",
  "new_local_repository",
)

However, local.bzl isn't available in Bazel 6.5.0:

$ bazel test //test/scalafmt/...

ERROR: Error computing the main repository mapping:
  at .../scala/scalafmt/scalafmt_repositories.bzl:8:6:
cannot load '@bazel_tools//tools/build_defs/repo:local.bzl':
  no such file

The new scalafmt_config repository rule works under both Bazel 6.5.0 and 7.3.2, WORKSPACE and Bzlmod. Also, it symlinks only the single Scalafmt config file, instead of every top level file and directory in the project, as new_local_repository did.

Motivation

Part of the Bzlmodification effort from #1482, to make scalafmt_default_config compatible with both WORKSPACE and MODULE.bazel under both Bazel 6 and 7.

Also, removing instances of @io_bazel_rules_scala with Labels reduces the project's dependency on this name. Bzlmod consumers will then be able to call bazel_dep(name = "rules_scala", ...) without having to set repo_name = "io_bazel_rules_scala".

mbland commented 1 month ago

Rebased and passing after #1627, including latest Bazel 7.3.2.