Skip to content

Commit

Permalink
Allow scala version to be explicitly declared (gradle#31118)
Browse files Browse the repository at this point in the history
  • Loading branch information
jvandort authored Jan 31, 2025
2 parents 76e81b8 + 520c233 commit 2761896
Show file tree
Hide file tree
Showing 40 changed files with 564 additions and 156 deletions.
41 changes: 41 additions & 0 deletions platforms/documentation/docs/src/docs/release/notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,47 @@ try (GroupTestEventReporter outer = root.reportTestGroup("OuterNestingSuite")) {

Nested events are reflected in the HTML test reports, providing clear traceability.

#### Scala version can be declared explicitly

Starting in this version of Gradle, when applying the [scala-base or scala](userguide/scala_plugin.html) plugins, you can now explicitly declare the Scala version on the `scala` extension.
This allows Gradle to automatically resolve the required Scala toolchain dependencies, eliminating the need for the user to declare them manually.
It also removes the need to infer the Scala version from the production runtime classpath, which was error-prone.

Previously, you had to declare a `scala-library` dependency, like this:

```kotlin
plugins {
id("scala")
}

repositories {
mavenCentral()
}

dependencies {
implementation("org.scala-lang:scala-library:2.13.12")
// OR
implementation("org.scala-lang:scala3-library_3:3.6.3")
}
```

Now, you can explicitly set the Scala version in the `scala` extension, and the `scala-library` dependency is no longer required:
```kotlin
plugins {
id("scala")
}

repositories {
mavenCentral()
}

scala {
scalaVersion = "2.13.12"
// OR
scalaVersion = "3.6.3"
}
```

#### Distribution base plugin introduced

Gradle now includes a `distribution-base` plugin, which mirrors the functionality of the [Distribution Plugin](userguide/distribution_plugin.html) but does not add a default distribution.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,25 +115,50 @@ include::sample[dir="snippets/scala/customizedLayout/kotlin",files="build.gradle
include::sample[dir="snippets/scala/customizedLayout/groovy",files="build.gradle[tags=custom-source-locations]"]
====

[[sec:scala_dependency_management]]
== Dependency management
== Scala version

Scala projects need to declare a `scala-library` dependency. This dependency will then be used on compile and runtime class paths. It will also be used to get hold of the Scala compiler and Scaladoc tool, respectively.footnote:[See <<#sec:configure_scala_classpath,Automatic configuration of Scala classpath>>.]
The Scala version can be declared directly on the `scala` extension.
Dependencies are automatically added to the `scalaToolchain` configuration based on the declared Scala version.
The `scalaToolchainRuntimeClasspath` configuration resolves the dependencies declared on the `scalaToolchain` configuration and contains files required to run the Scala compiler.

If Scala is used for production code, the `scala-library` dependency should be added to the `implementation` configuration:
NOTE: Direct dependencies on the Scala SDK do not need to be declared when the `scalaVersion` property is set.

.Declaring a Scala 2 version
====
include::sample[dir="snippets/scala/quickstart/kotlin",files="build.gradle.kts[tags=scala-version]"]
include::sample[dir="snippets/scala/quickstart/groovy",files="build.gradle[tags=scala-version]"]
====

Configuring Gradle to use Scala 3 is no different from Scala 2.

.Declaring a Scala 3 version
====
include::sample[dir="snippets/scala/scala3/kotlin",files="build.gradle.kts[tags=scala-version]"]
include::sample[dir="snippets/scala/scala3/groovy",files="build.gradle[tags=scala-version]"]
====

NOTE: The `scalaVersion` property is incubating.

=== Declaring Scala dependencies

When not using the `scalaVersion` property, the Scala SDK dependency must be declared manually on the `implementation` configuration.
This pattern is not preferred, as it relies on <<#sec:configure_scala_classpath,inferring the Scala classpath>> from the production runtime classpath.
Omitting the Scala version from the `scala` extension will be deprecated in a future Gradle version.

Scala 2 projects need to declare a `scala-library` dependency.

.Declaring a Scala dependency for production code
====
include::sample[dir="snippets/scala/quickstart/kotlin",files="build.gradle.kts[tags=scala-dependency]"]
include::sample[dir="snippets/scala/quickstart/groovy",files="build.gradle[tags=scala-dependency]"]
include::sample[dir="snippets/scala/quickstart/kotlin/inferred-version",files="build.gradle.kts[tags=scala-dependency]"]
include::sample[dir="snippets/scala/quickstart/groovy/inferred-version",files="build.gradle[tags=scala-dependency]"]
====

If you want to use Scala 3 instead of the `scala-library` dependency you should add the `scala3-library_3` dependency:
Scala 3 projects need to declare a `scala3-library_3` dependency instead:

.Declaring a Scala 3 dependency for production code
====
include::sample[dir="snippets/scala/scala3/kotlin",files="build.gradle.kts"]
include::sample[dir="snippets/scala/scala3/groovy",files="build.gradle"]
include::sample[dir="snippets/scala/scala3/kotlin/inferred-version",files="build.gradle.kts[tags=scala-dependency]"]
include::sample[dir="snippets/scala/scala3/groovy/inferred-version",files="build.gradle[tags=scala-dependency]"]
====

If Scala is only used for test code, the `scala-library` dependency should be added to the `testImplementation` configuration:
Expand All @@ -147,9 +172,11 @@ include::sample[dir="snippets/scala/scalaDependency/groovy",files="build.gradle[
[[sec:configure_scala_classpath]]
== Automatic configuration of scalaClasspath

The `ScalaCompile` and `ScalaDoc` tasks consume Scala code in two ways: on their `classpath`, and on their `scalaClasspath`. The former is used to locate classes referenced by the source code, and will typically contain `scala-library` along with other libraries. The latter is used to load and execute the Scala compiler and Scaladoc tool, respectively, and should only contain the `scala-compiler` library and its dependencies.
The `ScalaCompile` and `ScalaDoc` tasks consume Scala code in two ways: on their `classpath`, and on their `scalaClasspath`.
The former is used to locate classes referenced by the source code, and will typically contain `scala-library` along with other libraries.
The latter is used to load and execute the Scala compiler and Scaladoc tool, respectively, and should only contain the `scala-compiler` library and its dependencies.

Unless a task's `scalaClasspath` is configured explicitly, the Scala (base) plugin will try to infer it from the task's `classpath`. This is done as follows:
If the `scala` extension's `scalaVersion` property is not set and the task's `scalaClasspath` is not configured explicitly, the Scala (base) plugin will try to infer the classpath from the task's `classpath`. This is done as follows:

* If a `scala-library` jar is found on `classpath`, and the project has at least one repository declared, a corresponding `scala-compiler` repository dependency will be added to `scalaClasspath`.
* Otherwise, execution of the task will fail with a message saying that `scalaClasspath` could not be inferred.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
plugins {
id 'scala'
id("scala")
}

repositories {
mavenCentral()
}

scala {
scalaVersion = "2.13.12"
}

// tag::compiler-plugin[]
dependencies {
implementation "org.scala-lang:scala-library:2.13.12"
scalaCompilerPlugins "org.typelevel:kind-projector_2.13.12:0.13.2"
scalaCompilerPlugins("org.typelevel:kind-projector_2.13.12:0.13.2")
}
// end::compiler-plugin[]
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
plugins {
scala
id("scala")
}

repositories {
mavenCentral()
}

scala {
scalaVersion = "2.13.12"
}

// tag::compiler-plugin[]
dependencies {
implementation("org.scala-lang:scala-library:2.13.12")
scalaCompilerPlugins("org.typelevel:kind-projector_2.13.12:0.13.2")
}
// end::compiler-plugin[]
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
plugins {
id 'scala'
id("scala")
}

version = '1.0'
Expand All @@ -8,9 +8,12 @@ repositories {
mavenCentral()
}

scala {
scalaVersion = "2.13.12"
}

dependencies {
implementation 'org.scala-lang:scala-library:2.13.12'
testImplementation 'junit:junit:4.13'
testImplementation("junit:junit:4.13")
}

// tag::custom-source-locations[]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
plugins {
scala
id("scala")
}

version = "1.0"
Expand All @@ -8,8 +8,11 @@ repositories {
mavenCentral()
}

scala {
scalaVersion = "2.13.12"
}

dependencies {
implementation("org.scala-lang:scala-library:2.13.12")
testImplementation("junit:junit:4.13")
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
plugins {
id 'scala'
id("scala")
}

repositories {
mavenCentral()
}

dependencies {
implementation 'org.scala-lang:scala-library:2.13.12'
scala {
scalaVersion = "2.13.12"
}

dependencies {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
plugins {
scala
id("scala")
}

repositories {
mavenCentral()
}

dependencies {
implementation("org.scala-lang:scala-library:2.13.12")
scala {
scalaVersion = "2.13.12"
}

dependencies {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
id 'scala'
id 'idea'
id("scala")
id("idea")
}

// tag::scala-idea-target-version[]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
scala
idea
id("scala")
id("idea")
}

// tag::scala-idea-target-version[]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
plugins {
id 'scala'
id("scala")
}

version = 1.0
Expand All @@ -8,7 +8,10 @@ repositories {
mavenCentral()
}

scala {
scalaVersion = "2.13.12"
}

dependencies {
implementation 'org.scala-lang:scala-library:2.13.12'
testImplementation 'junit:junit:4.13'
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
// tag::use-plugin[]
plugins {
// end::use-plugin[]
id 'eclipse'
id("eclipse")
// tag::use-plugin[]
id 'scala'
id("scala")
}
// end::use-plugin[]

// tag::scala-dependency[]
// tag::scala-version[]
repositories {
mavenCentral()
}

dependencies {
implementation 'org.scala-lang:scala-library:2.13.12'
testImplementation 'junit:junit:4.13'
scala {
scalaVersion = "2.13.12"
}
// end::scala-dependency[]
// end::scala-version[]

dependencies {
implementation 'commons-collections:commons-collections:3.2.2'
testImplementation 'junit:junit:4.13'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
plugins {
id("scala")
}

// tag::scala-dependency[]
repositories {
mavenCentral()
}

dependencies {
implementation("org.scala-lang:scala-library:2.13.12")
}
// end::scala-dependency[]
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
rootProject.name = 'quickstart'

include("inferred-version")
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
// tag::use-plugin[]
plugins {
// end::use-plugin[]
eclipse
id("eclipse")
// tag::use-plugin[]
scala
id("scala")
}
// end::use-plugin[]

// tag::scala-dependency[]
// tag::scala-version[]
repositories {
mavenCentral()
}

dependencies {
implementation("org.scala-lang:scala-library:2.13.12")
testImplementation("junit:junit:4.13")
scala {
scalaVersion = "2.13.12"
}
// end::scala-dependency[]
// end::scala-version[]

dependencies {
implementation("commons-collections:commons-collections:3.2.2")
testImplementation("junit:junit:4.13")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
plugins {
id("scala")
}

// tag::scala-dependency[]
repositories {
mavenCentral()
}

dependencies {
implementation("org.scala-lang:scala-library:2.13.12")
}
// end::scala-dependency[]
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
rootProject.name = "quickstart"

include("inferred-version")
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@

plugins {
id 'scala'
id("scala")
}

// tag::scala-version[]
repositories {
mavenCentral()
}

scala {
scalaVersion = "3.6.3"
}
// end::scala-version[]

dependencies {
implementation 'org.scala-lang:scala3-library_3:3.0.1'
implementation 'commons-collections:commons-collections:3.2.2'
testImplementation 'org.scalatest:scalatest_3:3.2.9'
testImplementation 'junit:junit:4.13'
Expand Down
Loading

0 comments on commit 2761896

Please sign in to comment.