Skip to content

Commit

Permalink
1.26.0: Introduce MpsTask interface
Browse files Browse the repository at this point in the history
  • Loading branch information
sergej-koscejev committed Jun 21, 2024
1 parent f74c02c commit 67ec69e
Show file tree
Hide file tree
Showing 16 changed files with 115 additions and 156 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@
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.26.0

### Changed

- All MPS tasks now implement `MpsTask` interface which defines common properties. As a result, some tasks were
affected:
- `MpsCheck`: `pluginRoots` type was changed from `SetProperty<Directory>` to `ConfigurableFileCollection` because
the latter is easier to work with from Gradle. **This is a breaking change.**
- `MpsExecute`: `folderMacros` are now supported and will be passed to MPS.

### Deprecated

- `MpsCheck`, `MpsGenerate`, `MpsExecute`: `varMacros` (or `macros` in case of `MpsExecute`) are now deprecated and will
be removed in a later release. Only folder macros (pointing to an existing directory) are supported by MPS, any
non-folder macros would not have worked properly anyway.

## 1.25.2

### Fixed
Expand Down
36 changes: 12 additions & 24 deletions api/mps-gradle-plugin.api
Original file line number Diff line number Diff line change
Expand Up @@ -302,29 +302,25 @@ public final class de/itemis/mps/gradle/runmigrations/RunMigrationsMpsProjectPlu
public final fun getMIN_VERSION_FOR_HALT_ON_PRECHECK_FAILURE ()Lnet/swiftzer/semver/SemVer;
}

public abstract class de/itemis/mps/gradle/tasks/MpsCheck : org/gradle/api/tasks/JavaExec, org/gradle/api/tasks/VerificationTask {
public abstract class de/itemis/mps/gradle/tasks/MpsCheck : org/gradle/api/tasks/JavaExec, de/itemis/mps/gradle/tasks/MpsTask, org/gradle/api/tasks/VerificationTask {
public fun <init> ()V
public fun exec ()V
public final fun getAdditionalModelcheckBackendClasspath ()Lorg/gradle/api/file/ConfigurableFileCollection;
protected final fun getCompiledClasses ()Lorg/gradle/api/file/FileTree;
public final fun getExcludeModels ()Lorg/gradle/api/provider/ListProperty;
public final fun getExcludeModules ()Lorg/gradle/api/provider/ListProperty;
public final fun getFolderMacros ()Lorg/gradle/api/provider/MapProperty;
public final fun getJunitFile ()Lorg/gradle/api/file/RegularFileProperty;
public final fun getJunitFormat ()Lorg/gradle/api/provider/Property;
public final fun getModels ()Lorg/gradle/api/provider/ListProperty;
public final fun getModules ()Lorg/gradle/api/provider/ListProperty;
public final fun getMpsHome ()Lorg/gradle/api/file/DirectoryProperty;
public final fun getMpsVersion ()Lorg/gradle/api/provider/Property;
public final fun getParallel ()Lorg/gradle/api/provider/Property;
public final fun getPluginRoots ()Lorg/gradle/api/provider/SetProperty;
public final fun getProjectLocation ()Lorg/gradle/api/file/DirectoryProperty;
protected final fun getSources ()Lorg/gradle/api/file/FileTree;
public final fun getVarMacros ()Lorg/gradle/api/provider/MapProperty;
public final fun getWarningAsError ()Lorg/gradle/api/provider/Property;
}

public abstract class de/itemis/mps/gradle/tasks/MpsExecute : org/gradle/api/tasks/JavaExec {
public abstract class de/itemis/mps/gradle/tasks/MpsExecute : org/gradle/api/tasks/JavaExec, de/itemis/mps/gradle/tasks/MpsTask {
public fun <init> ()V
public fun exec ()V
public final fun getAdditionalExecuteBackendClasspath ()Lorg/gradle/api/file/ConfigurableFileCollection;
Expand All @@ -333,60 +329,52 @@ public abstract class de/itemis/mps/gradle/tasks/MpsExecute : org/gradle/api/tas
public abstract fun getMethod ()Lorg/gradle/api/provider/Property;
public abstract fun getMethodArguments ()Lorg/gradle/api/provider/ListProperty;
public abstract fun getModule ()Lorg/gradle/api/provider/Property;
public abstract fun getMpsHome ()Lorg/gradle/api/file/DirectoryProperty;
public abstract fun getMpsVersion ()Lorg/gradle/api/provider/Property;
public abstract fun getPluginRoots ()Lorg/gradle/api/provider/SetProperty;
public abstract fun getProjectLocation ()Lorg/gradle/api/file/DirectoryProperty;
}

public abstract class de/itemis/mps/gradle/tasks/MpsGenerate : org/gradle/api/tasks/JavaExec {
public abstract class de/itemis/mps/gradle/tasks/MpsGenerate : org/gradle/api/tasks/JavaExec, de/itemis/mps/gradle/tasks/MpsTask {
public fun <init> ()V
public fun exec ()V
public final fun getAdditionalGenerateBackendClasspath ()Lorg/gradle/api/file/ConfigurableFileCollection;
protected final fun getCompiledClasses ()Lorg/gradle/api/file/FileTree;
public final fun getEnvironmentKind ()Lorg/gradle/api/provider/Property;
public final fun getExcludeModels ()Lorg/gradle/api/provider/ListProperty;
public final fun getExcludeModules ()Lorg/gradle/api/provider/ListProperty;
public final fun getFolderMacros ()Lorg/gradle/api/provider/MapProperty;
public final fun getModels ()Lorg/gradle/api/provider/ListProperty;
public final fun getModules ()Lorg/gradle/api/provider/ListProperty;
public final fun getMpsHome ()Lorg/gradle/api/file/DirectoryProperty;
public final fun getMpsVersion ()Lorg/gradle/api/provider/Property;
public final fun getParallelGenerationThreads ()Lorg/gradle/api/provider/Property;
public final fun getPluginRoots ()Lorg/gradle/api/file/ConfigurableFileCollection;
public final fun getProjectLocation ()Lorg/gradle/api/file/DirectoryProperty;
protected final fun getSources ()Lorg/gradle/api/file/FileTree;
public final fun getStrictMode ()Lorg/gradle/api/provider/Property;
public final fun getVarMacros ()Lorg/gradle/api/provider/MapProperty;
}

public abstract class de/itemis/mps/gradle/tasks/MpsMigrate : org/gradle/api/DefaultTask {
public abstract class de/itemis/mps/gradle/tasks/MpsMigrate : org/gradle/api/DefaultTask, de/itemis/mps/gradle/tasks/MpsTask {
public fun <init> (Lorg/gradle/api/model/ObjectFactory;Lorg/gradle/api/provider/ProviderFactory;)V
public final fun execute ()V
protected final fun getAllProjectFiles ()Lorg/gradle/api/provider/Provider;
public final fun getAntJvmArgs ()Lorg/gradle/api/provider/ListProperty;
public final fun getFolderMacros ()Lorg/gradle/api/provider/MapProperty;
public final fun getHaltOnDependencyError ()Lorg/gradle/api/provider/Property;
public final fun getHaltOnPrecheckFailure ()Lorg/gradle/api/provider/Property;
public final fun getJavaExecutable ()Lorg/gradle/api/file/RegularFileProperty;
public final fun getJavaLauncher ()Lorg/gradle/api/provider/Property;
public final fun getJvmArgs ()Lorg/gradle/api/provider/ListProperty;
public final fun getMaxHeapSize ()Lorg/gradle/api/provider/Property;
public final fun getMpsHome ()Lorg/gradle/api/file/DirectoryProperty;
public final fun getMpsVersion ()Lorg/gradle/api/provider/Property;
public final fun getPluginRoots ()Lorg/gradle/api/file/ConfigurableFileCollection;
public final fun getProjectDirectories ()Lorg/gradle/api/file/ConfigurableFileCollection;
}

public class de/itemis/mps/gradle/tasks/Remigrate : org/gradle/api/tasks/JavaExec {
public abstract interface class de/itemis/mps/gradle/tasks/MpsTask : org/gradle/api/Task {
public abstract fun getFolderMacros ()Lorg/gradle/api/provider/MapProperty;
public abstract fun getMpsHome ()Lorg/gradle/api/file/DirectoryProperty;
public abstract fun getMpsVersion ()Lorg/gradle/api/provider/Property;
public abstract fun getPluginRoots ()Lorg/gradle/api/file/ConfigurableFileCollection;
}

public abstract class de/itemis/mps/gradle/tasks/Remigrate : org/gradle/api/tasks/JavaExec, de/itemis/mps/gradle/tasks/MpsTask {
public fun <init> (Lorg/gradle/api/model/ObjectFactory;Lorg/gradle/api/provider/ProviderFactory;)V
public fun exec ()V
public final fun getAdditionalClasspath ()Lorg/gradle/api/file/ConfigurableFileCollection;
protected final fun getAllProjectFiles ()Lorg/gradle/api/provider/Provider;
public final fun getFolderMacros ()Lorg/gradle/api/provider/MapProperty;
public final fun getMpsHome ()Lorg/gradle/api/file/DirectoryProperty;
public final fun getMpsVersion ()Lorg/gradle/api/provider/Property;
public final fun getPluginRoots ()Lorg/gradle/api/file/ConfigurableFileCollection;
public final fun getProjectDirectories ()Lorg/gradle/api/file/ConfigurableFileCollection;
}

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.25.2"
val baseVersion = "1.26.0"

group = "de.itemis.mps"

Expand Down
5 changes: 2 additions & 3 deletions docs/tasks/MpsCheck.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,13 @@ Parameters:
backend.
* `folderMacros` - path variables/macros that are necessary to open the project. Path macros are not considered part of
Gradle build cache key.
* `varMacros` - non-path variables/macros that are necessary to open the project. Variable macros *are* considered part
of Gradle build cache key.
* `varMacros` - Deprecated and will be removed (only folder macros are supported by MPS).
* `junitFile` - the JUnit XML file to produce. Defaults to `$buildDir/TEST-${task.name}.xml`
* `junitFormat` - the format of the JUnit XML file. Defaults to `module-and-model`.
* `parallel` (since 1.20) - runs model checker in parallel mode. Supported in MPS 2021.3.4. Default is `false`.
* `mpsHome` - the home directory of the MPS distribution (or RCP) to use for testing.
* `mpsVersion` - the MPS version, such as "2021.3". Autodetected by reading `$mpsHome/build.properties` by default.
* `pluginRoots` - directories containing additional plugins to load
* `pluginRoots` - directories that will be searched (recursively) for additional plugins to load.
* `warningAsError` - whether to treat warnings as errors.
* `ignoreFailures` (inherited from `VerificationTask`) - whether to fail the build if an error is found.

Expand Down
4 changes: 2 additions & 2 deletions docs/tasks/MpsExecute.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ Parameters:

* `projectLocation` - the location of the MPS project. Default is the Gradle project directory.
* `additionalExecuteBackendClasspath` - any extra libraries that should be on the classpath of the execute backend.
* `macros` - variables/macros that are necessary to open the project.
* `folderMacros` - folder/path macros that are necessary to open the project.
* `mpsHome` - the home directory of the MPS distribution (or RCP) to use for testing.
* `mpsVersion` - the MPS version, such as "2021.3". Default is autodetection by reading `$mpsHome/build.properties`.
* `pluginRoots` - directories containing additional plugins to load.
* `pluginRoots` - directories that will be searched (recursively) for additional plugins to load.
* `module` - the module that contains the generated class.
* `className` - fully qualified name of the generated class, that contains the method to execute.
* `method` - name of the method. The method should be public and static. Supported signatures are `(Project)` (from
Expand Down
5 changes: 2 additions & 3 deletions docs/tasks/MpsGenerate.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,10 @@ Parameters:
backend.
* `folderMacros` - path variables/macros that are necessary to open the project. Path macros are not considered part of
Gradle build cache key.
* `varMacros` - non-path variables/macros that are necessary to open the project. Variable macros *are* considered part
of Gradle build cache key.
* `varMacros` - Deprecated and will be removed (only folder macros are supported by MPS).
* `mpsHome` - the home directory of the MPS distribution (or RCP) to use for testing.
* `mpsVersion` - the MPS version, such as "2021.3". Autodetected by reading `$mpsHome/build.properties` by default.
* `pluginRoots` - directories with additional plugins to load.
* `pluginRoots` - directories that will be searched (recursively) for additional plugins to load.
* `environmentKind` - the environment to use for generation (`MPS` or `IDEA`). MPS environment is used by default,
matching the standard `<generate>` Ant task. IDEA environment can be used when generating screenshots.
See [MPS vs IDEA environment](../notes/mps-vs-idea-environment.md).
Expand Down
7 changes: 7 additions & 0 deletions src/main/kotlin/de/itemis/mps/gradle/common.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
package de.itemis.mps.gradle

import de.itemis.mps.gradle.launcher.MpsVersionDetection
import de.itemis.mps.gradle.tasks.MpsTask

/**
* A side effect of this plugin is that it lets us use `plugins` block rather than `buildscript` to put the task classes
* ([RunAntScript], [BuildLanguages], etc.) onto the classpath.
*/

tasks.withType(MpsTask::class.java).configureEach {
mpsVersion.convention(MpsVersionDetection.fromMpsHome(project.layout, providers, mpsHome.asFile))
}

val modelcheckBackend = configurations.create(BackendConfigurations.MODELCHECK_BACKEND_CONFIGURATION_NAME)
val generateBackend = configurations.create(BackendConfigurations.GENERATE_BACKEND_CONFIGURATION_NAME)
val executeBackend = configurations.create(BackendConfigurations.EXECUTE_BACKEND_CONFIGURATION_NAME)
Expand Down
33 changes: 5 additions & 28 deletions src/main/kotlin/de/itemis/mps/gradle/tasks/MpsCheck.kt
Original file line number Diff line number Diff line change
@@ -1,45 +1,25 @@
package de.itemis.mps.gradle.tasks

import de.itemis.mps.gradle.BackendConfigurations
import de.itemis.mps.gradle.ErrorMessages
import de.itemis.mps.gradle.TaskGroups
import de.itemis.mps.gradle.launcher.MpsBackendBuilder
import de.itemis.mps.gradle.launcher.MpsVersionDetection
import org.gradle.api.GradleException
import org.gradle.api.Incubating
import org.gradle.api.file.*
import org.gradle.api.logging.LogLevel
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.MapProperty
import org.gradle.api.provider.Property
import org.gradle.api.provider.SetProperty
import org.gradle.api.tasks.*
import org.gradle.kotlin.dsl.*
import org.gradle.language.base.plugins.LifecycleBasePlugin
import org.gradle.process.CommandLineArgumentProvider

@CacheableTask
@Incubating
abstract class MpsCheck : JavaExec(), VerificationTask {

@get:Internal("covered by mpsVersion, initialModelcheckBackendClasspath()")
val mpsHome: DirectoryProperty = objectFactory.directoryProperty()

@get:Input
@get:Optional
val mpsVersion: Property<String> = objectFactory.property<String>()
.convention(MpsVersionDetection.fromMpsHome(project.layout, providerFactory, mpsHome.asFile))

abstract class MpsCheck : JavaExec(), MpsTask, VerificationTask {
@get:Internal("only modules and models matter, covered by #sources")
val projectLocation: DirectoryProperty =
objectFactory.directoryProperty().convention(project.layout.projectDirectory)

@get:Classpath
val pluginRoots: SetProperty<Directory> = objectFactory.setProperty()

@get:Internal("Folder macros are ignored for the purposes of up-to-date checks and caching")
val folderMacros: MapProperty<String, Directory> = objectFactory.mapProperty()

@Deprecated("All macros should point to directories, property will be removed in a later release")
@get:Input
val varMacros: MapProperty<String, String> = objectFactory.mapProperty()

Expand Down Expand Up @@ -97,15 +77,14 @@ abstract class MpsCheck : JavaExec(), VerificationTask {
val backendBuilder: MpsBackendBuilder = project.objects.newInstance(MpsBackendBuilder::class)
backendBuilder.withMpsHomeDirectory(mpsHome).withMpsVersion(mpsVersion).configure(this)

argumentProviders.add(backendArguments())
argumentProviders.add(CommandLineArgumentProvider {
val result = mutableListOf<String>()
@Suppress("DEPRECATION")
addVarMacros(result, varMacros, this)

result.add("--project=${projectLocation.get().asFile}")

addPluginRoots(result, pluginRoots.get())
addFolderMacros(result, folderMacros)
addVarMacros(result, varMacros)

// Only a limited subset of checkers is registered in MPS environment, IDEA environment is necessary for
// proper checking.
result.add("--environment=IDEA")
Expand Down Expand Up @@ -135,8 +114,6 @@ abstract class MpsCheck : JavaExec(), VerificationTask {
result.add("--parallel")
}

addLogLevel(result)

result
})

Expand Down
27 changes: 6 additions & 21 deletions src/main/kotlin/de/itemis/mps/gradle/tasks/MpsExecute.kt
Original file line number Diff line number Diff line change
@@ -1,40 +1,26 @@
package de.itemis.mps.gradle.tasks

import de.itemis.mps.gradle.BackendConfigurations
import de.itemis.mps.gradle.ErrorMessages
import de.itemis.mps.gradle.launcher.MpsBackendBuilder
import de.itemis.mps.gradle.launcher.MpsVersionDetection
import org.gradle.api.GradleException
import org.gradle.api.Incubating
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.Directory
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.logging.LogLevel
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.MapProperty
import org.gradle.api.provider.Property
import org.gradle.api.provider.SetProperty
import org.gradle.api.tasks.*
import org.gradle.kotlin.dsl.newInstance
import org.gradle.work.DisableCachingByDefault


@DisableCachingByDefault(because = "calls arbitrary user code")
@Incubating
abstract class MpsExecute : JavaExec() {

@get:Internal
abstract val mpsHome: DirectoryProperty

@get:Internal
abstract val mpsVersion: Property<String>

abstract class MpsExecute : MpsTask, JavaExec() {
@get:Internal
abstract val projectLocation: DirectoryProperty

@get:Classpath
abstract val pluginRoots: SetProperty<Directory>

@Deprecated("Use [folderMacros].")
@get:Internal
abstract val macros: MapProperty<String, String>

Expand Down Expand Up @@ -63,19 +49,18 @@ abstract class MpsExecute : JavaExec() {
.withMpsVersion(mpsVersion)
.configure(this)

argumentProviders.add(backendArguments())
argumentProviders.add {
mutableListOf<String>().apply {
add("--project=${projectLocation.get().asFile}")
@Suppress("DEPRECATION")
addVarMacros(this, macros, this@MpsExecute, "macros")

addPluginRoots(this, pluginRoots.get())
addVarMacros(this, macros)
add("--project=${projectLocation.get().asFile}")

add("--module=${module.get()}")
add("--class=${className.get()}")
add("--method=${method.get()}")
methodArguments.get().forEach { add("--arg=$it") }

addLogLevel(this)
}
}

Expand Down
Loading

0 comments on commit 67ec69e

Please sign in to comment.