Skip to content

Commit

Permalink
1.27.0: Add javaLauncher and toolchainSpec to `DownloadJbrForPlat…
Browse files Browse the repository at this point in the history
…form` task
  • Loading branch information
sergej-koscejev committed Jun 28, 2024
1 parent fd660b4 commit 389ea32
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 17 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 1.27.0

### Added

- `DownloadJbrForPlatform#toolchainSpec`: a `Provider<JavaToolchainSpec>` that can be used with `JavaToolchainService`
to look up tools such as the Java launcher, compiler or Javadoc generator.
- `DownloadJbrForPlatform#javaLauncher`: a `Provider<JavaLauncher>` that can be used with `JavaExec` tasks.

## 1.26.0

### Changed
Expand Down
4 changes: 3 additions & 1 deletion api/mps-gradle-plugin.api
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,11 @@ public class de/itemis/mps/gradle/downloadJBR/DownloadJbrConfiguration {
}

public class de/itemis/mps/gradle/downloadJBR/DownloadJbrForPlatform : org/gradle/api/DefaultTask {
public fun <init> ()V
public fun <init> (Lorg/gradle/api/model/ObjectFactory;Lorg/gradle/jvm/toolchain/JavaToolchainService;)V
public final fun getJavaExecutable ()Ljava/io/File;
public final fun getJavaLauncher ()Lorg/gradle/api/provider/Provider;
public final fun getJbrDir ()Ljava/io/File;
public final fun getToolchainSpec ()Lorg/gradle/api/provider/Provider;
public final fun setJavaExecutable (Ljava/io/File;)V
public final fun setJbrDir (Ljava/io/File;)V
}
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ plugins {
id("org.jetbrains.kotlinx.binary-compatibility-validator") version "0.13.2"
}

val baseVersion = "1.26.0"
val baseVersion = "1.27.0"

group = "de.itemis.mps"

Expand Down
23 changes: 11 additions & 12 deletions docs/plugins/download-jbr.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
## Download JetBrains Runtime

When building MPS projects with the JetBrains Runtime, the JDK/JRE used by MPS and other intellij based IDEs, it's
required to download the correct version of the runtime. Since the runtime is platform dependent it's required to
download a platform dependent binary. While it's possible to add the logic to your own build script we provide a convenient
way of doing this with a Gradle plugin.
When building MPS projects with the JetBrains Runtime, the JDK/JRE used by MPS and other JetBrains IDEs, it's
required to download the correct version of the runtime. Since the runtime is platform-dependent it is required to
download a platform-dependent binary. While it's possible to add the logic to your own build script, we provide
a convenient way of doing this with a Gradle plugin.

The download-jbr plugin will add new dependencies and a task to your build. It will add a dependency to `com.jetbrains.jdk:jbr`
to your build, you need to make sure that it is available in your dependency repositories. The itemis Maven repository at
https://artifacts.itemis.cloud/repository/maven-mps provides this dependency, but you can create your own with
the scripts located in [mbeddr/build.publish.jdk](https://github.com/mbeddr/build.publish.jdk).
The `download-jbr` plugin will add new dependencies and a task to your build. It will add a dependency to
`com.jetbrains.jdk:jbr` to your build, you need to make sure that it is available in your dependency repositories. The
[itemis Maven repository](https://artifacts.itemis.cloud/repository/maven-mps) provides this dependency, but you can
create your own with the scripts located in [mbeddr/build.publish.jdk](https://github.com/mbeddr/build.publish.jdk).

For easy consumption and incremental build support the plugin creates a task `downloadJbr` which exposes the location of
the java executable via the `javaExecutable` property. See
the java executable via the `javaExecutable` and `javaLauncher` properties. See
[the tests](../../src/test/kotlin/test/others/JBRDownloadTest.kt) for an example of how to use it.

### Usage
Expand All @@ -25,9 +25,7 @@ plugins {
repositories {
mavenCentral()
maven {
url = URI("https://artifacts.itemis.cloud/repository/maven-mps")
}
maven("https://artifacts.itemis.cloud/repository/maven-mps")
}
downloadJbr {
Expand All @@ -51,6 +49,7 @@ downloadJbr {
```

### Parameters

* `jbrVersion` - version of the JBR to download. While this supports maven version selectors we highly recommend not
using wildcards like `*` or `+` in there for reproducible builds.
* `distributionType` - optional distribution type for the JBR to use. Will default to `jbr_jcef` if omitted.
Expand Down
30 changes: 27 additions & 3 deletions src/main/kotlin/de/itemis/mps/gradle/downloadJBR/Tasks.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,23 @@ package de.itemis.mps.gradle.downloadJBR
import org.gradle.api.DefaultTask
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.*
import org.gradle.jvm.toolchain.JavaLauncher
import org.gradle.jvm.toolchain.JavaToolchainService
import org.gradle.jvm.toolchain.JavaToolchainSpec
import org.gradle.jvm.toolchain.internal.SpecificInstallationToolchainSpec
import java.io.File
import javax.inject.Inject

open class DownloadJbrForPlatform : DefaultTask() {
open class DownloadJbrForPlatform @Inject constructor(
private val objects: ObjectFactory,
private val javaToolchainService: JavaToolchainService
) : DefaultTask() {

@get:Internal
internal val jbrDirProperty: DirectoryProperty = project.objects.directoryProperty()
internal val jbrDirProperty: DirectoryProperty = objects.directoryProperty()

@get:Internal
var jbrDir : File
Expand All @@ -19,12 +29,26 @@ open class DownloadJbrForPlatform : DefaultTask() {
}

@get:Internal
internal val javaExecutableProperty: RegularFileProperty = project.objects.fileProperty()
internal val javaExecutableProperty: RegularFileProperty = objects.fileProperty()

@get:Internal
var javaExecutable: File
get() = javaExecutableProperty.get().asFile
set(value) {
javaExecutableProperty.set(value)
}

/**
* A [JavaToolchainSpec] that can be passed to [JavaToolchainService] to obtain various tools (Java compiler,
* launcher, javadoc).
*/
@get:Internal
val toolchainSpec: Provider<JavaToolchainSpec> =
javaExecutableProperty.map { SpecificInstallationToolchainSpec.fromJavaExecutable(objects, it.asFile.path) }

/**
* A [JavaLauncher] for the downloaded JBR that can be used with [JavaExec] task.
*/
@get:Internal
val javaLauncher: Provider<JavaLauncher> = toolchainSpec.flatMap(javaToolchainService::launcherFor)
}
48 changes: 48 additions & 0 deletions src/test/kotlin/test/others/JBRDownloadTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package test.others

import org.gradle.testkit.runner.GradleRunner
import org.gradle.testkit.runner.TaskOutcome
import org.hamcrest.CoreMatchers.containsString
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Assert
import org.junit.Before
import org.junit.Rule
Expand Down Expand Up @@ -199,4 +201,50 @@ class JBRDownloadTest {
.build()
Assert.assertEquals(TaskOutcome.SUCCESS, result.task(":exec")?.outcome)
}

@Test
fun `executed downloaded java using JavaLauncher`() {
settingsFile.writeText("""
rootProject.name = "hello-world"
""".trimIndent())

buildFile.writeText("""
import java.net.URI
import de.itemis.mps.gradle.downloadJBR.DownloadJbrForPlatform
plugins {
id("download-jbr")
}
repositories {
mavenCentral()
maven {
url = URI("https://artifacts.itemis.cloud/repository/maven-mps")
}
}
downloadJbr {
jbrVersion = "$JBR_VERSION"
}
val downloadJbrTask = tasks.named("downloadJbr", DownloadJbrForPlatform::class)
tasks.register<JavaExec>("exec") {
dependsOn(downloadJbrTask)
javaLauncher.set(downloadJbrTask.flatMap { it.javaLauncher })
jvmArgs("--version")
// Main class will be ignored due to --version but has to be provided
mainClass.set("ignored")
}
""".trimIndent())

val result = GradleRunner.create()
.withProjectDir(testProjectDir.root)
.withArguments("exec")
.withPluginClasspath()
.build()
Assert.assertEquals(TaskOutcome.SUCCESS, result.task(":exec")?.outcome)
assertThat(result.output, containsString("OpenJDK Runtime Environment JBR"))
}
}

0 comments on commit 389ea32

Please sign in to comment.