Skip to content

Commit 56c1827

Browse files
author
Oleksandr Dzhychko
authored
Merge pull request #982 from modelix/fix/mps-runner-configuration-for-server-sources-with-base-revision
fix(bulk-model-sync-gradle): fix MPS Runner configuration for server …
2 parents 4bf5241 + 6d2639e commit 56c1827

File tree

4 files changed

+213
-60
lines changed

4 files changed

+213
-60
lines changed

bulk-model-sync-gradle/build.gradle.kts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ dependencies {
1111
implementation(libs.modelix.buildtools.lib)
1212
implementation(libs.ktor.client.core)
1313
implementation(libs.ktor.client.cio)
14+
testImplementation(libs.kotest.assertions.coreJvm)
15+
testImplementation(kotlin("test"))
1416
}
1517

1618
kotlin {
@@ -36,3 +38,7 @@ val writeVersionFile by tasks.registering {
3638
tasks.named("processResources") {
3739
dependsOn(writeVersionFile)
3840
}
41+
42+
tasks.test {
43+
useJUnitPlatform()
44+
}

bulk-model-sync-gradle/src/main/kotlin/org/modelix/model/sync/bulk/gradle/ModelSyncGradlePlugin.kt

Lines changed: 3 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,10 @@ import org.gradle.api.Plugin
2020
import org.gradle.api.Project
2121
import org.gradle.api.artifacts.Configuration
2222
import org.gradle.api.tasks.TaskProvider
23-
import org.modelix.buildtools.runner.BundledPluginPath
24-
import org.modelix.buildtools.runner.ExternalPluginPath
25-
import org.modelix.buildtools.runner.MPSRunnerConfig
26-
import org.modelix.buildtools.runner.PluginConfig
2723
import org.modelix.gradle.mpsbuild.MPSBuildPlugin
28-
import org.modelix.model.sync.bulk.gradle.config.BundledPluginSpec
29-
import org.modelix.model.sync.bulk.gradle.config.ExternalPluginSpec
3024
import org.modelix.model.sync.bulk.gradle.config.LocalSource
3125
import org.modelix.model.sync.bulk.gradle.config.LocalTarget
3226
import org.modelix.model.sync.bulk.gradle.config.ModelSyncGradleSettings
33-
import org.modelix.model.sync.bulk.gradle.config.PluginSpec
3427
import org.modelix.model.sync.bulk.gradle.config.ServerSource
3528
import org.modelix.model.sync.bulk.gradle.config.ServerTarget
3629
import org.modelix.model.sync.bulk.gradle.config.SyncDirection
@@ -148,25 +141,8 @@ class ModelSyncGradlePlugin : Plugin<Project> {
148141
previousTask: TaskProvider<*>,
149142
jsonDir: File,
150143
): TaskProvider<*> {
151-
val localSource = syncDirection.source as LocalSource
152144
val resolvedDependencies = mpsDependencies.resolvedConfiguration.files
153-
val config = MPSRunnerConfig(
154-
mainClassName = "org.modelix.mps.model.sync.bulk.MPSBulkSynchronizer",
155-
mainMethodName = "exportRepository",
156-
classPathElements = resolvedDependencies.toList(),
157-
mpsHome = localSource.mpsHome,
158-
workDir = jsonDir,
159-
additionalModuleDirs = localSource.mpsLibraries.toList() + listOfNotNull(localSource.repositoryDir),
160-
plugins = createPluginConfig(localSource.mpsPlugins),
161-
jvmArgs = listOfNotNull(
162-
"-Dmodelix.mps.model.sync.bulk.output.path=${jsonDir.absolutePath}",
163-
"-Dmodelix.mps.model.sync.bulk.output.modules=${syncDirection.includedModules.joinToString(",")}",
164-
"-Dmodelix.mps.model.sync.bulk.output.modules.prefixes=${syncDirection.includedModulePrefixes.joinToString(",")}",
165-
"-Dmodelix.mps.model.sync.bulk.repo.path=${localSource.repositoryDir?.absolutePath}",
166-
"-Xmx${localSource.mpsHeapSize}",
167-
localSource.mpsDebugPort?.let { "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=$it" },
168-
),
169-
)
145+
val config = buildMpsRunConfigurationForLocalSources(syncDirection, resolvedDependencies, jsonDir)
170146
return mpsBuildPlugin.createRunMPSTask("${syncDirection.name}ExportFromMps", config, arrayOf(previousTask)).also {
171147
it.configure { task ->
172148
task.outputs.dir(jsonDir)
@@ -208,32 +184,9 @@ class ModelSyncGradlePlugin : Plugin<Project> {
208184
previousTask: TaskProvider<*>,
209185
jsonDir: File,
210186
) {
211-
val localTarget = syncDirection.target as LocalTarget
212-
val importName = "${syncDirection.name}ImportIntoMps"
213187
val resolvedDependencies = mpsDependencies.resolvedConfiguration.files
214-
val hasBaseRevision = (syncDirection.source as? ServerSource)?.baseRevision != null
215-
val config = MPSRunnerConfig(
216-
mainClassName = "org.modelix.mps.model.sync.bulk.MPSBulkSynchronizer",
217-
mainMethodName = if (hasBaseRevision) "importRepositoryFromModelServer" else "importRepository",
218-
classPathElements = resolvedDependencies.toList(),
219-
mpsHome = localTarget.mpsHome,
220-
workDir = jsonDir,
221-
additionalModuleDirs = localTarget.mpsLibraries.toList() + listOfNotNull(localTarget.repositoryDir),
222-
plugins = createPluginConfig(localTarget.mpsPlugins),
223-
jvmArgs = listOfNotNull(
224-
"-Dmodelix.mps.model.sync.bulk.input.path=${jsonDir.absolutePath}",
225-
"-Dmodelix.mps.model.sync.bulk.input.modules=${syncDirection.includedModules.joinToString(",")}",
226-
"-Dmodelix.mps.model.sync.bulk.input.modules.prefixes=${syncDirection.includedModulePrefixes.joinToString(",")}",
227-
"-Dmodelix.mps.model.sync.bulk.repo.path=${localTarget.repositoryDir?.absolutePath}",
228-
"-Dmodelix.mps.model.sync.bulk.input.continueOnError=${syncDirection.continueOnError}",
229-
"-Dmodelix.mps.model.sync.bulk.server.repository=${(syncDirection.source as ServerSource).repositoryId}".takeIf { hasBaseRevision },
230-
"-Dmodelix.mps.model.sync.bulk.server.url=${(syncDirection.source as ServerSource).url}".takeIf { hasBaseRevision },
231-
"-Dmodelix.mps.model.sync.bulk.server.version.hash=${(syncDirection.source as ServerSource).revision}".takeIf { hasBaseRevision },
232-
"-Dmodelix.mps.model.sync.bulk.server.version.base.hash=${(syncDirection.source as ServerSource).baseRevision}".takeIf { hasBaseRevision },
233-
"-Xmx${localTarget.mpsHeapSize}",
234-
localTarget.mpsDebugPort?.let { "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=$it" },
235-
),
236-
)
188+
val config = buildMpsRunConfigurationForLocalTarget(syncDirection, resolvedDependencies, jsonDir)
189+
val importName = "${syncDirection.name}ImportIntoMps"
237190
val importIntoMps = mpsBuildPlugin.createRunMPSTask(importName, config, arrayOf(previousTask)).also {
238191
it.configure { task ->
239192
task.inputs.dir(jsonDir)
@@ -246,16 +199,6 @@ class ModelSyncGradlePlugin : Plugin<Project> {
246199
}
247200
}
248201

249-
private fun createPluginConfig(mpsPlugins: Set<PluginSpec>): List<PluginConfig> {
250-
return mpsPlugins.map {
251-
val pluginPath = when (it) {
252-
is BundledPluginSpec -> BundledPluginPath(it.folder)
253-
is ExternalPluginSpec -> ExternalPluginPath(it.folder)
254-
}
255-
PluginConfig(it.id, pluginPath)
256-
}
257-
}
258-
259202
private fun getBaseDir(project: Project): File {
260203
return project.layout.buildDirectory.dir("model-sync").get().asFile
261204
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package org.modelix.model.sync.bulk.gradle
2+
3+
import org.modelix.buildtools.runner.BundledPluginPath
4+
import org.modelix.buildtools.runner.ExternalPluginPath
5+
import org.modelix.buildtools.runner.MPSRunnerConfig
6+
import org.modelix.buildtools.runner.PluginConfig
7+
import org.modelix.model.sync.bulk.gradle.config.BundledPluginSpec
8+
import org.modelix.model.sync.bulk.gradle.config.ExternalPluginSpec
9+
import org.modelix.model.sync.bulk.gradle.config.LocalSource
10+
import org.modelix.model.sync.bulk.gradle.config.LocalTarget
11+
import org.modelix.model.sync.bulk.gradle.config.PluginSpec
12+
import org.modelix.model.sync.bulk.gradle.config.ServerSource
13+
import org.modelix.model.sync.bulk.gradle.config.SyncDirection
14+
import java.io.File
15+
16+
internal fun buildMpsRunConfigurationForLocalSources(
17+
syncDirection: SyncDirection,
18+
classPathElements: Set<File>,
19+
jsonDir: File,
20+
): MPSRunnerConfig {
21+
val source = requireNotNull(syncDirection.source)
22+
val localSource = source as? LocalSource
23+
?: throw IllegalArgumentException("`syncDirection.source` is ${source::class.java} but should be ${LocalTarget::class.java}.")
24+
val config = MPSRunnerConfig(
25+
mainClassName = "org.modelix.mps.model.sync.bulk.MPSBulkSynchronizer",
26+
mainMethodName = "exportRepository",
27+
classPathElements = classPathElements.toList(),
28+
mpsHome = localSource.mpsHome,
29+
workDir = jsonDir,
30+
additionalModuleDirs = localSource.mpsLibraries.toList() + listOfNotNull(localSource.repositoryDir),
31+
plugins = createPluginConfig(localSource.mpsPlugins),
32+
jvmArgs = listOfNotNull(
33+
"-Dmodelix.mps.model.sync.bulk.output.path=${jsonDir.absolutePath}",
34+
"-Dmodelix.mps.model.sync.bulk.output.modules=${syncDirection.includedModules.joinToString(",")}",
35+
"-Dmodelix.mps.model.sync.bulk.output.modules.prefixes=${
36+
syncDirection.includedModulePrefixes.joinToString(
37+
",",
38+
)
39+
}",
40+
"-Dmodelix.mps.model.sync.bulk.repo.path=${localSource.repositoryDir?.absolutePath}",
41+
"-Xmx${localSource.mpsHeapSize}",
42+
localSource.mpsDebugPort?.let { "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=$it" },
43+
),
44+
)
45+
return config
46+
}
47+
48+
internal fun buildMpsRunConfigurationForLocalTarget(
49+
syncDirection: SyncDirection,
50+
classPathElements: Set<File>,
51+
jsonDir: File,
52+
): MPSRunnerConfig {
53+
val target = requireNotNull(syncDirection.target)
54+
val localTarget = target as? LocalTarget
55+
?: throw IllegalArgumentException("`syncDirection.target` is ${target::class.java} but should be ${LocalTarget::class.java}.")
56+
val repositoryDir = checkNotNull(localTarget.repositoryDir) {
57+
"syncDirection.target has no `repositoryDir` specified."
58+
}
59+
val source = syncDirection.source
60+
val hasBaseRevision = (source as? ServerSource)?.baseRevision != null
61+
val config = MPSRunnerConfig(
62+
mainClassName = "org.modelix.mps.model.sync.bulk.MPSBulkSynchronizer",
63+
mainMethodName = if (hasBaseRevision) "importRepositoryFromModelServer" else "importRepository",
64+
classPathElements = classPathElements.toList(),
65+
mpsHome = localTarget.mpsHome,
66+
workDir = jsonDir,
67+
additionalModuleDirs = localTarget.mpsLibraries.toList() + repositoryDir,
68+
plugins = createPluginConfig(localTarget.mpsPlugins),
69+
jvmArgs = buildList {
70+
add("-Dmodelix.mps.model.sync.bulk.input.path=${jsonDir.absolutePath}")
71+
val includeModuleValue = syncDirection.includedModules.joinToString(",")
72+
add("-Dmodelix.mps.model.sync.bulk.input.modules=$includeModuleValue")
73+
val includeModulePrefixesValue = syncDirection.includedModulePrefixes.joinToString(",")
74+
add("-Dmodelix.mps.model.sync.bulk.input.modules.prefixes=$includeModulePrefixesValue")
75+
add("-Dmodelix.mps.model.sync.bulk.repo.path=${repositoryDir.absolutePath}")
76+
add("-Dmodelix.mps.model.sync.bulk.input.continueOnError=${syncDirection.continueOnError}")
77+
add("-Xmx${localTarget.mpsHeapSize}")
78+
if (localTarget.mpsDebugPort != null) {
79+
add("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=${localTarget.mpsDebugPort}")
80+
}
81+
if (source is ServerSource && source.baseRevision != null) {
82+
add("-Dmodelix.mps.model.sync.bulk.server.repository=${source.repositoryId}")
83+
add("-Dmodelix.mps.model.sync.bulk.server.url=${source.url}")
84+
add("-Dmodelix.mps.model.sync.bulk.server.version.base.hash=${source.baseRevision}")
85+
if (source.branchName != null) {
86+
add("-Dmodelix.mps.model.sync.bulk.server.branch=${source.branchName}")
87+
}
88+
if (source.revision != null) {
89+
add("-Dmodelix.mps.model.sync.bulk.server.version.hash=${source.revision}")
90+
}
91+
}
92+
},
93+
)
94+
return config
95+
}
96+
97+
private fun createPluginConfig(mpsPlugins: Set<PluginSpec>): List<PluginConfig> {
98+
return mpsPlugins.map {
99+
val pluginPath = when (it) {
100+
is BundledPluginSpec -> BundledPluginPath(it.folder)
101+
is ExternalPluginSpec -> ExternalPluginPath(it.folder)
102+
}
103+
PluginConfig(it.id, pluginPath)
104+
}
105+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package org.modelix.model.sync.bulk.gradle
2+
3+
import io.kotest.matchers.collections.shouldContainExactlyInAnyOrder
4+
import org.modelix.model.sync.bulk.gradle.config.LocalTarget
5+
import org.modelix.model.sync.bulk.gradle.config.ServerSource
6+
import org.modelix.model.sync.bulk.gradle.config.SyncDirection
7+
import java.io.File
8+
import kotlin.test.Test
9+
10+
class MpsRunnerConfigurationTest {
11+
12+
private val jsonDir = File("/jsonDir")
13+
private val classPathElements = emptySet<File>()
14+
15+
@Test
16+
fun `build configuration for local target with a server source without a base revision`() {
17+
val serverSource = ServerSource(
18+
url = "aUrl",
19+
repositoryId = "aRepositoryId",
20+
branchName = "aBranchName",
21+
)
22+
val localTarget = LocalTarget(repositoryDir = File("/repositoryDir"))
23+
val syncDirection = SyncDirection("syncDirection", serverSource, localTarget)
24+
25+
val config = buildMpsRunConfigurationForLocalTarget(syncDirection, classPathElements, jsonDir)
26+
val jvmArgs = config.jvmArgs
27+
28+
val expectedJvmArgs = listOf(
29+
"-Dmodelix.mps.model.sync.bulk.input.path=/jsonDir",
30+
"-Dmodelix.mps.model.sync.bulk.input.modules=",
31+
"-Dmodelix.mps.model.sync.bulk.input.modules.prefixes=",
32+
"-Dmodelix.mps.model.sync.bulk.repo.path=/repositoryDir",
33+
"-Dmodelix.mps.model.sync.bulk.input.continueOnError=false",
34+
"-Xmx2g",
35+
)
36+
37+
jvmArgs shouldContainExactlyInAnyOrder expectedJvmArgs
38+
}
39+
40+
@Test
41+
fun `build configuration for local target with a server source with a base revision and branch name`() {
42+
val serverSource = ServerSource(
43+
url = "aUrl",
44+
repositoryId = "aRepositoryId",
45+
branchName = "aBranchName",
46+
baseRevision = "aBaseRevision",
47+
)
48+
val localTarget = LocalTarget(repositoryDir = File("/repositoryDir"))
49+
val syncDirection = SyncDirection("syncDirection", serverSource, localTarget)
50+
51+
val config = buildMpsRunConfigurationForLocalTarget(syncDirection, classPathElements, jsonDir)
52+
val jvmArgs = config.jvmArgs
53+
54+
val expectedJvmArgs = listOf(
55+
"-Dmodelix.mps.model.sync.bulk.input.path=/jsonDir",
56+
"-Dmodelix.mps.model.sync.bulk.input.modules=",
57+
"-Dmodelix.mps.model.sync.bulk.input.modules.prefixes=",
58+
"-Dmodelix.mps.model.sync.bulk.repo.path=/repositoryDir",
59+
"-Dmodelix.mps.model.sync.bulk.input.continueOnError=false",
60+
"-Xmx2g",
61+
"-Dmodelix.mps.model.sync.bulk.server.repository=aRepositoryId",
62+
"-Dmodelix.mps.model.sync.bulk.server.branch=aBranchName",
63+
"-Dmodelix.mps.model.sync.bulk.server.url=aUrl",
64+
"-Dmodelix.mps.model.sync.bulk.server.version.base.hash=aBaseRevision",
65+
)
66+
67+
jvmArgs shouldContainExactlyInAnyOrder expectedJvmArgs
68+
}
69+
70+
@Test
71+
fun `build configuration for local target with a server source with a base revision and revision`() {
72+
val serverSource = ServerSource(
73+
url = "aUrl",
74+
repositoryId = "aRepositoryId",
75+
revision = "aRevisionToSync",
76+
baseRevision = "aBaseRevision",
77+
)
78+
val localTarget = LocalTarget(repositoryDir = File("/repositoryDir"))
79+
val syncDirection = SyncDirection("syncDirection", serverSource, localTarget)
80+
81+
val config = buildMpsRunConfigurationForLocalTarget(syncDirection, classPathElements, jsonDir)
82+
val jvmArgs = config.jvmArgs
83+
84+
val expectedJvmArgs = listOf(
85+
"-Dmodelix.mps.model.sync.bulk.input.path=/jsonDir",
86+
"-Dmodelix.mps.model.sync.bulk.input.modules=",
87+
"-Dmodelix.mps.model.sync.bulk.input.modules.prefixes=",
88+
"-Dmodelix.mps.model.sync.bulk.repo.path=/repositoryDir",
89+
"-Dmodelix.mps.model.sync.bulk.input.continueOnError=false",
90+
"-Xmx2g",
91+
"-Dmodelix.mps.model.sync.bulk.server.repository=aRepositoryId",
92+
"-Dmodelix.mps.model.sync.bulk.server.url=aUrl",
93+
"-Dmodelix.mps.model.sync.bulk.server.version.base.hash=aBaseRevision",
94+
"-Dmodelix.mps.model.sync.bulk.server.version.hash=aRevisionToSync",
95+
)
96+
97+
jvmArgs shouldContainExactlyInAnyOrder expectedJvmArgs
98+
}
99+
}

0 commit comments

Comments
 (0)