diff --git a/README.md b/README.md
index 074c5ed89..7fe3f238d 100644
--- a/README.md
+++ b/README.md
@@ -36,9 +36,13 @@ http_archive(
load("@io_bazel_rules_scala//scala:scala.bzl", "scala_repositories")
scala_repositories()
```
-To use a particular tag, use the tagged number in `tag = ` and omit the `commit` attribute.
-Note that these plugins are still evolving quickly, as is bazel, so you may need to select
-the version most appropriate for you.
+In addition, you **must** register `scala_toolchain` - To register default empty toolcahin simply add those lines to `WORKSPACE` file:
+```python
+
+load("@io_bazel_rules_scala/scala:toolchains.bzl", "scala_register_toolchains")
+scala_register_toolchains()
+```
+[read more here](#scala_toolchain)
Then in your BUILD file just add the following so the rules will be available:
```python
@@ -543,9 +547,50 @@ generated by the [ScalaPB compiler](https://github.com/scalapb/ScalaPB).
+## scala_toolchain
+Scala toolchain allows you to define global configuration to all scala targets.
+Currently the only option that can be set is `scalacopts` but the plan is to expand it to other options as well.
+
+**some scala_toolchain must be registered!**
+### Several options to configure scala_toolchain:
+#### A) Use default scala_toolchain:
+In your workspace file add the following lines:
+ ```python
+ # WORKSPACE
+ # register default scala toolchain
+ load("@io_bazel_rules_scala/scala:toolchains.bzl", "scala_register_toolchains")
+ scala_register_toolchains()
+ ```
+#### B) Defining your own scala_toolchain requires 2 steps:
+1. Add your own definition to scala_toolchain to a `BUILD` file:
+ ```python
+ # //toolchains/BUILD
+ load("//scala:scala_toolchain.bzl", "scala_toolchain")
+
+ scala_toolchain(
+ name = "my_toolchain_impl",
+ scalacopts = ["-Ywarn-unused"],
+ visibility = ["//visibility:public"]
+ )
+
+ toolchain(
+ name = "my_scala_toolchain",
+ toolchain_type = "@io_bazel_rules_scala//scala:toolchain_type",
+ toolchain = "my_toolchain_impl",
+ visibility = ["//visibility:public"]
+ )
+ ```
+2. register your custom toolchain from `WORKSPACE`:
+ ```python
+ # WORKSPACE
+ # ...
+ register_toolchains("//toolchains:my_scala_toolchain")
+ ```
+
+
## [Experimental] Using strict-deps
-Bazel pushes towards explicit and minimial dependencies to keep BUILD file higene and allow for targets to refactor their dependencies without fear of downstream breaking.
-Currently rules_scala does this at the cost of having cryptic `scalac` errors when one mistakenly depends on a transitive dependency or, as more often the case for some, a transitive dependency is needed to [please scalac](https://github.com/scalacenter/advisoryboard/blob/master/proposals/009-improve-direct-dependency-experience.md) itself.
+Bazel pushes towards explicit and minimial dependencies to keep BUILD file higene and allow for targets to refactor their dependencies without fear of downstream breaking.
+Currently rules_scala does this at the cost of having cryptic `scalac` errors when one mistakenly depends on a transitive dependency or, as more often the case for some, a transitive dependency is needed to [please scalac](https://github.com/scalacenter/advisoryboard/blob/master/proposals/009-improve-direct-dependency-experience.md) itself.
To learn more about the motivation of strict-deps itself you can visit this Bazel blog [post](https://blog.bazel.build/2017/06/28/sjd-unused_deps.html) on the subject.
To use it just add `--strict_java_deps=WARN|ERROR` to your `bazel` invocation.
@@ -556,7 +601,7 @@ Target '//some_package:transitive_dependency' is used but isn't explicitly decla
You can use the following buildozer command:
buildozer 'add deps //some_package:transitive_dependency' //some_other_package:transitive_dependency_user
```
-Note that if you have `buildozer` installed you can just run the last line and have it automatically apply the fix for you.
+Note that if you have `buildozer` installed you can just run the last line and have it automatically apply the fix for you.
**Caveats:**
@@ -564,7 +609,7 @@ Note that if you have `buildozer` installed you can just run the last line and h
- Label propagation- since label of targets are needed for the clear message and since it's not currently supported by JavaInfo from bazel we manually propagate it. This means that the error messages have a significantly lower grade if you don't use one of the scala rules or scala_import (since they don't propagate these labels)
- javac outputs incorrect targets due to a problem we're tracing down. Practically we've noticed it's pretty trivial to understand the correct target (i.e. it's almost a formatting problem)
-
+
Note: Currently strict-deps is protected by a feature toggle but we're strongly considering making it the default behavior as `java_*` rules do.
## Building from source
diff --git a/WORKSPACE b/WORKSPACE
index 0b06eb76b..e66f37740 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -80,3 +80,6 @@ filegroup(
)
"""
)
+
+load("@io_bazel_rules_scala//scala:toolchains.bzl","scala_register_toolchains")
+scala_register_toolchains()
diff --git a/scala/BUILD b/scala/BUILD
index e69de29bb..f10a1f8a4 100644
--- a/scala/BUILD
+++ b/scala/BUILD
@@ -0,0 +1,21 @@
+load("//scala:scala_toolchain.bzl", "scala_toolchain")
+
+toolchain_type(
+ name = "toolchain_type",
+ visibility = ["//visibility:public"]
+)
+
+
+scala_toolchain(
+ name = 'default_toolchain_impl',
+ scalacopts = [],
+ visibility = ["//visibility:public"]
+)
+
+
+toolchain(
+ name = 'default_toolchain',
+ toolchain_type = '@io_bazel_rules_scala//scala:toolchain_type',
+ toolchain = ':default_toolchain_impl',
+ visibility = ["//visibility:public"]
+)
diff --git a/scala/scala.bzl b/scala/scala.bzl
index ed8c63c62..1dfa485ce 100644
--- a/scala/scala.bzl
+++ b/scala/scala.bzl
@@ -16,6 +16,8 @@
load("//specs2:specs2_junit.bzl", "specs2_junit_dependencies")
load(":scala_cross_version.bzl", "scala_version", "scala_mvn_artifact")
+load("@io_bazel_rules_scala//scala:scala_toolchain.bzl", "scala_toolchain")
+
_jar_filetype = FileType([".jar"])
_java_filetype = FileType([".java"])
_scala_filetype = FileType([".scala"])
@@ -183,6 +185,9 @@ CurrentTarget: {current_target}
compiler_classpath = ":".join([j.path for j in compiler_classpath_jars])
+ toolchain = ctx.toolchains['@io_bazel_rules_scala//scala:toolchain_type']
+ scalacopts = toolchain.scalacopts + ctx.attr.scalacopts
+
scalac_args = """
Classpath: {cp}
EnableIjar: {enableijar}
@@ -205,7 +210,7 @@ DependencyAnalyzerMode: {dependency_analyzer_mode}
""".format(
out=ctx.outputs.jar.path,
manifest=ctx.outputs.manifest.path,
- scala_opts=",".join(ctx.attr.scalacopts),
+ scala_opts=",".join(scalacopts),
print_compile_time=ctx.attr.print_compile_time,
plugin_arg=plugin_arg,
cp=compiler_classpath,
@@ -963,7 +968,8 @@ scala_library = rule(
implementation=_scala_library_impl,
attrs=_scala_library_attrs,
outputs=library_outputs,
- fragments = ["java"]
+ fragments = ["java"],
+ toolchains = ['@io_bazel_rules_scala//scala:toolchain_type'],
)
# the scala compiler plugin used for dependency analysis is compiled using `scala_library`.
@@ -978,7 +984,8 @@ scala_library_for_plugin_bootstrapping = rule(
implementation=_scala_library_impl,
attrs= _scala_library_for_plugin_bootstrapping_attrs,
outputs=library_outputs,
- fragments = ["java"]
+ fragments = ["java"],
+ toolchains = ['@io_bazel_rules_scala//scala:toolchain_type'],
)
_scala_macro_library_attrs = {
@@ -993,7 +1000,8 @@ scala_macro_library = rule(
implementation=_scala_macro_library_impl,
attrs= _scala_macro_library_attrs,
outputs= common_outputs,
- fragments = ["java"]
+ fragments = ["java"],
+ toolchains = ['@io_bazel_rules_scala//scala:toolchain_type'],
)
_scala_binary_attrs = {
@@ -1008,7 +1016,8 @@ scala_binary = rule(
attrs= _scala_binary_attrs,
outputs= common_outputs,
executable=True,
- fragments = ["java"]
+ fragments = ["java"],
+ toolchains = ['@io_bazel_rules_scala//scala:toolchain_type'],
)
_scala_test_attrs = {
@@ -1030,7 +1039,8 @@ scala_test = rule(
outputs= common_outputs,
executable=True,
test=True,
- fragments = ["java"]
+ fragments = ["java"],
+ toolchains = ['@io_bazel_rules_scala//scala:toolchain_type'],
)
_scala_repl_attrs = {}
@@ -1043,7 +1053,8 @@ scala_repl = rule(
attrs= _scala_repl_attrs,
outputs= common_outputs,
executable=True,
- fragments = ["java"]
+ fragments = ["java"],
+ toolchains = ['@io_bazel_rules_scala//scala:toolchain_type'],
)
SCALA_BUILD_FILE = """
@@ -1210,7 +1221,8 @@ scala_junit_test = rule(
attrs= _scala_junit_test_attrs,
outputs= common_outputs,
test=True,
- fragments = ["java"]
+ fragments = ["java"],
+ toolchains = ['@io_bazel_rules_scala//scala:toolchain_type']
)
def scala_specs2_junit_test(name, **kwargs):
@@ -1220,3 +1232,4 @@ def scala_specs2_junit_test(name, **kwargs):
suite_label = Label("//src/java/io/bazel/rulesscala/specs2:specs2_test_discovery"),
suite_class = "io.bazel.rulesscala.specs2.Specs2DiscoveredTestSuite",
**kwargs)
+
diff --git a/scala/scala_toolchain.bzl b/scala/scala_toolchain.bzl
new file mode 100644
index 000000000..fa3ff689c
--- /dev/null
+++ b/scala/scala_toolchain.bzl
@@ -0,0 +1,12 @@
+def _scala_toolchain_impl(ctx):
+ toolchain = platform_common.ToolchainInfo(
+ scalacopts = ctx.attr.scalacopts,
+ )
+ return [toolchain]
+
+scala_toolchain = rule(
+ _scala_toolchain_impl,
+ attrs = {
+ 'scalacopts': attr.string_list(),
+ }
+)
\ No newline at end of file
diff --git a/scala/toolchains.bzl b/scala/toolchains.bzl
new file mode 100644
index 000000000..5e5f78b81
--- /dev/null
+++ b/scala/toolchains.bzl
@@ -0,0 +1,3 @@
+
+def scala_register_toolchains():
+ native.register_toolchains("@io_bazel_rules_scala//scala:default_toolchain")
\ No newline at end of file
diff --git a/test_expect_failure/scalacopts_from_toolchain/BUILD b/test_expect_failure/scalacopts_from_toolchain/BUILD
new file mode 100644
index 000000000..4bdc92487
--- /dev/null
+++ b/test_expect_failure/scalacopts_from_toolchain/BUILD
@@ -0,0 +1,21 @@
+load("//scala:scala_toolchain.bzl", "scala_toolchain")
+load("//scala:scala.bzl", "scala_library")
+
+scala_toolchain(
+ name = "failing_toolchain_impl",
+ scalacopts = ["-Ywarn-unused"],
+ visibility = ["//visibility:public"]
+)
+
+toolchain(
+ name = "failing_scala_toolchain",
+ toolchain_type = "@io_bazel_rules_scala//scala:toolchain_type",
+ toolchain = "failing_toolchain_impl",
+ visibility = ["//visibility:public"]
+)
+
+scala_library(
+ name = "failing_build",
+ srcs = ["ClassWithUnused.scala"],
+ scalacopts = ["-Xfatal-warnings"]
+)
\ No newline at end of file
diff --git a/test_expect_failure/scalacopts_from_toolchain/ClassWithUnused.scala b/test_expect_failure/scalacopts_from_toolchain/ClassWithUnused.scala
new file mode 100644
index 000000000..52a0d01ac
--- /dev/null
+++ b/test_expect_failure/scalacopts_from_toolchain/ClassWithUnused.scala
@@ -0,0 +1,8 @@
+package test_expect_failure.scalacopts_from_toolchain
+
+class ClassWithUnused(name:String){
+ def talk():String = {
+ val unusedValue = "I am not used :-("
+ s"hello $name"
+ }
+}
\ No newline at end of file
diff --git a/test_intellij_aspect.sh b/test_intellij_aspect.sh
index fde665593..bb93c8d87 100755
--- a/test_intellij_aspect.sh
+++ b/test_intellij_aspect.sh
@@ -20,7 +20,7 @@ test_intellij_aspect() {
cd intellij && git fetch && git pull
fi
git checkout "${intellij_git_tag}"
- bazel test --test_output=errors --override_repository io_bazel_rules_scala="${rules_scala_dir}" //aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/...
+ bazel test --test_output=errors --override_repository io_bazel_rules_scala="${rules_scala_dir}" --extra_toolchains=@io_bazel_rules_scala//scala:default_toolchain //aspect/testing/tests/src/com/google/idea/blaze/aspect/scala/...
}
dir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
diff --git a/test_rules_scala.sh b/test_rules_scala.sh
index ae80baa7f..8ebd87a38 100755
--- a/test_rules_scala.sh
+++ b/test_rules_scala.sh
@@ -667,6 +667,10 @@ test_scala_import_expect_failure_on_missing_direct_deps_warn_mode() {
test_expect_failure_or_warning_on_missing_direct_deps_with_expected_message "${expected_message1}" ${test_target} "--strict_java_deps=warn" "ne" "${expected_message2}"
}
+test_scalaopts_from_scala_toolchain() {
+ action_should_fail build --extra_toolchains="//test_expect_failure/scalacopts_from_toolchain:failing_scala_toolchain" //test_expect_failure/scalacopts_from_toolchain:failing_build
+}
+
dir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
# shellcheck source=./test_runner.sh
. "${dir}"/test_runner.sh
@@ -735,3 +739,4 @@ $runner test_scala_library_expect_failure_on_missing_direct_deps_warn_mode_java
$runner test_scala_library_expect_better_failure_message_on_missing_transitive_dependency_labels_from_other_jvm_rules
$runner test_scala_import_expect_failure_on_missing_direct_deps_warn_mode
$runner bazel build "test_expect_failure/missing_direct_deps/internal_deps/... --strict_java_deps=warn"
+$runner test_scalaopts_from_scala_toolchain