Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into bzlmod_support_part1
Browse files Browse the repository at this point in the history
# Conflicts:
#	.gitignore
#	third_party/repositories/repositories.bzl
  • Loading branch information
agluszak committed Aug 7, 2024
2 parents 706b5f1 + 6c6ba4e commit 579edc1
Show file tree
Hide file tree
Showing 177 changed files with 2,548 additions and 1,003 deletions.
23 changes: 23 additions & 0 deletions .bazelci/presubmit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ tasks:
platform: macos
shell_commands:
- "./test_rules_scala.sh"
test_rules_scala_win:
name: "./test_rules_scala"
platform: windows
shell_commands:
- "bash test_rules_scala.sh"
test_coverage_linux_6_3_0:
name: "./test_coverage"
platform: ubuntu2004
Expand Down Expand Up @@ -80,8 +85,26 @@ tasks:
bazel: 6.3.0
shell_commands:
- "./test_examples.sh"
cross_build_linux:
name: "./test_cross_build"
platform: ubuntu2004
bazel: 6.3.0
shell_commands:
- "./test_cross_build.sh"
lint_linux:
name: "bazel //tools:lint_check"
platform: ubuntu2004
run_targets:
- "//tools:lint_check"
test_rules_scala_jdk21:
name: "./test_rules_scala with jdk21"
platform: ubuntu2004
shell_commands:
- sudo apt update && sudo apt install -y libxml2-utils
- mv tools/bazel.rc.buildkite tools/bazel.rc
- echo "import %workspace%/tools/bazel.rc" > .bazelrc
- echo "build --java_language_version=21" >> .bazelrc
- echo "build --java_runtime_version=21" >> .bazelrc
- echo "build --tool_java_language_version=21" >> .bazelrc
- echo "build --tool_java_runtime_version=21" >> .bazelrc
- "./test_rules_scala.sh"
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ hash2
.vscode
unformatted-*.backup.scala
.scala-build
test/semanticdb/tempsrc
MODULE.bazel.lock
4 changes: 2 additions & 2 deletions .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
align.openParenCallSite = false
align.openParenDefnSite = false
continuationIndent.defnSite = 2
danglingParentheses = true
docstrings = JavaDoc
danglingParentheses.preset = true
docstrings.style = Asterisk
importSelectors = singleLine
maxColumn = 120
verticalMultiline.newlineBeforeImplicitKW = true
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,12 @@ scala_register_toolchains()
Note: Toolchains are a more flexible way to configure dependencies, so you should prefer that way.
Please also note, that the `overriden_artifacts` parameter is likely to be removed in the future.

### Multiple versions (cross-compilation)

Rules scala supports configuring multiple Scala versions and offers target-level control of which one to use.

Please check [cross-compilation.md](docs/cross-compilation.md) for more details on cross-compilation support.

## Bazel compatible versions

| minimal bazel version | rules_scala gitsha |
Expand Down Expand Up @@ -280,6 +286,7 @@ Here's a (non-exhaustive) list of companies that use `rules_scala` in production
* [Stripe](https://stripe.com/)
* [Tally](https://www.meettally.com/)
* [Twitter](https://twitter.com/)
* [VirtusLab](https://virtuslab.com/)
* [VSCO](https://vsco.co)
* [Wix](https://www.wix.com/)

6 changes: 6 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,9 @@ repositories(
],
maven_servers = MAVEN_SERVER_URLS,
)

load("//test/toolchains:jdk.bzl", "remote_jdk21_repositories", "remote_jdk21_toolchains")

remote_jdk21_repositories()

remote_jdk21_toolchains()
213 changes: 213 additions & 0 deletions docs/cross-compilation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
# Cross compilation support

Read *Quick start* for an information on how to use cross compilation.
The remaining sections contain more detailed information, useful especially for toolchain & rule developers.

## Quick start
`scala_config` repository rule accepts two parameters related to Scala version:
* `scala_version` – a single, default version;
* `scala_versions` – a list of versions to make available for use.

The first one, `scala_version`, will be used as a default, but it can be overridden for specific targets for any version from the `scala_versions`.

Multiple rules, such as:
- [scala_library](/scala/private/rules/scala_library.bzl)
- [scala_binary](/scala/private/rules/scala_binary.bzl)
- [scala_repl](/scala/private/rules/scala_repl.bzl)
- [scala_test](/scala/private/rules/scala_test.bzl)

support such override via the `scala_version` attribute, e.g.:
```starlark
scala_library(
name = ...
...
scala_version = "2.12.18",
...
)
```

For this library and all its dependencies 2.12.18 compiler will be used, unless explicitly overridden again in another target.

## Version configuration

`scala_config` creates the repository `@io_bazel_rules_scala_config`.
File created there, `config.bzl`, consists of many variables. In particular:
* `SCALA_VERSION` – representing the default Scala version, e.g. `"3.3.1"`;
* `SCALA_VERSIONS` – representing all configured Scala versions, e.g. `["2.12.18", "3.3.1"]`.


## Build settings
Configured `SCALA_VERSIONS` correspond to allowed values of [build setting](https://bazel.build/extending/config#user-defined-build-setting).

### `scala_version`
`@io_bazel_rules_scala_config` in its root package defines the following build setting:
```starlark
string_setting(
name = "scala_version",
build_setting_default = "3.3.1",
values = ["3.3.1"],
visibility = ["//visibility:public"],
)
...
```
This build setting can be subject of change by [transitions](https://bazel.build/extending/config#user-defined-transitions) (within allowed `values`).

### Config settings
Then for each Scala version we have a [config setting](https://bazel.build/extending/config#build-settings-and-select):
```starlark
config_setting(
name = "scala_version_3_3_1",
flag_values = {":scala_version": "3.3.1"},
)
...
```
The `name` of `config_setting` corresponds to `"scala_version" + version_suffix(scala_version)`.
One may use this config setting in `select()` e.g. to provide dependencies relevant to a currently used Scala version.


## Version-dependent behavior
Don't rely on `SCALA_VERSION` as it represents the default Scala version, not necessarily the one that is currently requested.

If you need to customize the behavior for specific Scala version, there are two scenarios.

### From toolchain
If you have an access to the Scala toolchain (`@io_bazel_rules_scala//scala:toolchain_type`), there is `scala_version` field provided in there:
```starlark
def _rule_impl(ctx):
...
ctx.toolchains["@io_bazel_rules_scala//scala:toolchain_type"].scala_version
...
```

### From config setting
In BUILD files, you need to use the config settings with `select()`.
Majority of use cases is covered by the `select_for_scala_version` utility macro.
If more flexibility is needed, you can always write the select manually.

#### With select macro
See example usage of the `select_for_scala_version`:

```starlark
load("@io_bazel_rules_scala//:scala_cross_version_select.bzl", "select_for_scala_version")

scala_library(
...
srcs = select_for_scala_version(
before_3_1 = [
# for Scala version < 3.1
],
between_3_1_and_3_2 = [
# for 3.1 ≤ Scala version < 3.2
],
between_3_2_and_3_3_1 = [
# for 3.2 ≤ Scala version < 3.3.1
],
since_3_3_1 = [
# for 3.3.1 ≤ Scala version
],
)
...
)
```

See complete documentation in the [scala_cross_version_select.bzl](/scala/scala_cross_version_select.bzl) file

#### Manually
An example usage of `select()` to provide custom dependency for specific Scala version:
```starlark
deps = select({
"@io_bazel_rules_scala_config//:scala_version_3_3_1": [...],
...
})
```

For more complex logic, you can extract it to a `.bzl` file:
```starlark
def srcs(scala_version):
if scala_version.startswith("2"):
...
...
```
and then in the `BUILD` file:
```starlark
load("@io_bazel_rules_scala//:scala_cross_version.bzl", "version_suffix")
load("@io_bazel_rules_scala_config//:config.bzl", "SCALA_VERSIONS")
load("....bzl", "srcs")

scala_library(
...
srcs = select({
"@io_bazel_rules_scala_config//:scala_version" + version_suffix(v): srcs(v)
for v in SCALA_VERSIONS
}),
...
)
```


## Requesting specific version
To use other than default version of Scala, you need to change the current `@io_bazel_rules_scala_config//:scala_version` build setting.

Simple transition, setting the Scala version to one found in `scala_version` attribute:
```starlark
def _scala_version_transition_impl(settings, attr):
if attr.scala_version:
return {"@io_bazel_rules_scala_config//:scala_version": attr.scala_version}
else:
return {}

scala_version_transition = transition(
implementation = _scala_version_transition_impl,
inputs = [],
outputs = ["@io_bazel_rules_scala_config//:scala_version"],
)
```

To use it in a rule, use the `scala_version_transition` as `cfg` and use `toolchain_transition_attr` in `attrs`:
```starlark
load("@io_bazel_rules_scala//scala:scala_cross_version.bzl", "scala_version_transition", "toolchain_transition_attr")

_scala_library_attrs.update(toolchain_transition_attr)

def make_scala_library(*extras):
return rule(
attrs = _dicts.add(
...
toolchain_transition_attr,
...
),
...
cfg = scala_version_transition,
incompatible_use_toolchain_transition = True,
...
)
```


## Toolchains
Standard [toolchain resolution](https://bazel.build/extending/toolchains#toolchain-resolution) procedure determines which toolchain to use for Scala targets.

Toolchain should declare its compatibility with Scala version by using `target_settings` attribute of the `toolchain` rule:

```starlark
toolchain(
...
target_settings = ["@io_bazel_rules_scala_config//:scala_version_3_3_1"],
...
)
```

### Cross-build support tiers
`rules_scala` consists of many toolchains implementing various toolchain types.
Their support level for cross-build setup varies.

We can distinguish following tiers:

* No `target_settings` set – not migrated, will work on the default `SCALA_VERSION`; undefined behavior on other versions.
* (all toolchains not mentioned elsewhere)
* `target_settings` set to the `SCALA_VERSION` – not fully migrated; will work only on the default `SCALA_VERSION` and will fail the toolchain resolution on other versions.
* (no development in progress)
* Multiple toolchain instances with `target_settings` corresponding to each of `SCALA_VERSIONS` – fully migrated; will work in cross-build setup.
* [the main Scala toolchain](/scala/BUILD)
* [Scalafmt](/scala/scalafmt/BUILD)
* [Scalatest](/testing/testing.bzl)
2 changes: 2 additions & 0 deletions docs/phase_scalafmt.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ The extension provides default configuration, but there are 2 ways to use custom
- Put `.scalafmt.conf` at root of your workspace
- Pass `.scalafmt.conf` in via `config` attribute

If using scala 3 you must append `runner.dialect = scala3` to .scalafmt.conf

## IntelliJ plugin support

If you use IntelliJ Bazel plugin, then you should check the [Customizable Phase](/docs/customizable_phase.md#cooperation-with-intellij-plugin) page.
Expand Down
25 changes: 25 additions & 0 deletions examples/crossbuild/1_single/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
load("@io_bazel_rules_scala//scala:scala.bzl", "scala_binary", "scala_library", "scala_test")

# Here we demonstrate the simplest case,
# single binary, test or library for which we set a specific version or use the default one:

# This one will be compiled by 2.11 compiler:
scala_library(
name = "lib211",
srcs = ["lib.scala"],
scala_version = "2.11.12",
)

# This one will be compiled by 2.13 compiler:
scala_test(
name = "test213",
srcs = ["test.scala"],
scala_version = "2.13.12",
)

# This one will be compiled by 3.3 compiler (the default one):
scala_binary(
name = "bin33",
srcs = ["bin.scala"],
main_class = "X",
)
3 changes: 3 additions & 0 deletions examples/crossbuild/1_single/bin.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
object C extends App {
println("Hello")
}
1 change: 1 addition & 0 deletions examples/crossbuild/1_single/lib.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
class A
7 changes: 7 additions & 0 deletions examples/crossbuild/1_single/test.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import org.scalatest.flatspec.AnyFlatSpec

class Zero extends AnyFlatSpec {
"Equality" should "be tested" in {
assert (0 == -0)
}
}
37 changes: 37 additions & 0 deletions examples/crossbuild/2_deps/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
load("@io_bazel_rules_scala//scala:scala.bzl", "scala_binary", "scala_library")

# Here we demonstrate how scala_version is propagated through deps.

# This one will always be compiled by 2.11 compiler:
scala_library(
name = "lib211",
srcs = ["lib.scala"],
scala_version = "2.11.12",
)

# This one will be compiled by 3.3 compiler (unless requested otherwise)
scala_library(
name = "lib",
srcs = ["lib_default.scala"],
)

scala_binary(
name = "bin213",
srcs = ["bin.scala"], # compiled with 2.13 (as per `scala_version`)
main_class = "C",
scala_version = "2.13.12",
deps = [
":lib", # compiled 2.13 (as per `scala_version`)
":lib211", # compiled with 2.11 (that target overrides version)
],
)

scala_binary(
name = "bin33",
srcs = ["bin.scala"], # compiled with 3.3 (the default)
main_class = "C",
deps = [
":lib", # compiled with 3.3 (default)
":lib211", # compiled with 2.11 (that target overrides version)
],
)
3 changes: 3 additions & 0 deletions examples/crossbuild/2_deps/bin.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
object C extends App {
println("Hello, world")
}
1 change: 1 addition & 0 deletions examples/crossbuild/2_deps/lib.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
class A
1 change: 1 addition & 0 deletions examples/crossbuild/2_deps/lib_default.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
class B
Loading

0 comments on commit 579edc1

Please sign in to comment.