aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2023-04-26 17:58:36 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2023-04-26 17:58:36 +0200
commitd34b8e0f4db84f1571785592b523e675a1b2f960 (patch)
tree1e2e123ba2071a11070e8310b7e9e3033f8ffae1
parentbuild: enable parallel Gradle build (diff)
downloadrefinery-d34b8e0f4db84f1571785592b523e675a1b2f960.tar.gz
refinery-d34b8e0f4db84f1571785592b523e675a1b2f960.tar.zst
refinery-d34b8e0f4db84f1571785592b523e675a1b2f960.zip
build: improve Xtext project isolation
* Avoid writing generated source files directly into sibling projects. * Full project isolation cannot be enabled yet, because the frontend plugin still requires cross-projects task dependencies for Node.js installation.
-rw-r--r--buildSrc/src/main/kotlin/tools/refinery/gradle/xtext-generated.gradle.kts25
-rw-r--r--subprojects/frontend/build.gradle.kts8
-rw-r--r--subprojects/language-ide/build.gradle.kts8
-rw-r--r--subprojects/language-model/build.gradle.kts4
-rw-r--r--subprojects/language-web/build.gradle.kts11
-rw-r--r--subprojects/language/build.gradle.kts56
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/GenerateProblem.mwe214
7 files changed, 89 insertions, 37 deletions
diff --git a/buildSrc/src/main/kotlin/tools/refinery/gradle/xtext-generated.gradle.kts b/buildSrc/src/main/kotlin/tools/refinery/gradle/xtext-generated.gradle.kts
index 59fe921b..6cb1d7b5 100644
--- a/buildSrc/src/main/kotlin/tools/refinery/gradle/xtext-generated.gradle.kts
+++ b/buildSrc/src/main/kotlin/tools/refinery/gradle/xtext-generated.gradle.kts
@@ -14,15 +14,36 @@ plugins {
14 14
15val xtextGenPath = "src/main/xtext-gen" 15val xtextGenPath = "src/main/xtext-gen"
16 16
17val xtextGenerated: Configuration by configurations.creating {
18 isCanBeConsumed = false
19 isCanBeResolved = true
20}
21
17sourceSets.main { 22sourceSets.main {
18 java.srcDir(xtextGenPath) 23 java.srcDir(xtextGenPath)
19 resources.srcDir(xtextGenPath) 24 resources.srcDir(xtextGenPath)
20} 25}
21 26
22tasks.clean { 27tasks {
23 delete(xtextGenPath) 28 // Based on the idea from https://stackoverflow.com/a/57788355 to safely consume generated sources in sibling
29 // projects.
30 val syncXtextGeneratedSources by tasks.creating(Sync::class) {
31 from(xtextGenerated)
32 into(xtextGenPath)
33 }
34
35 for (taskName in listOf("compileJava", "processResources", "generateEclipseSourceFolders")) {
36 tasks.named(taskName) {
37 dependsOn(syncXtextGeneratedSources)
38 }
39 }
40
41 clean {
42 delete(xtextGenPath)
43 }
24} 44}
25 45
46
26sonarqube.properties { 47sonarqube.properties {
27 SonarPropertiesUtils.addToList(properties, "sonar.exclusions", "$xtextGenPath/**") 48 SonarPropertiesUtils.addToList(properties, "sonar.exclusions", "$xtextGenPath/**")
28} 49}
diff --git a/subprojects/frontend/build.gradle.kts b/subprojects/frontend/build.gradle.kts
index 9fd99742..d0839371 100644
--- a/subprojects/frontend/build.gradle.kts
+++ b/subprojects/frontend/build.gradle.kts
@@ -29,9 +29,9 @@ val sourcesWithoutTypes = fileTree("src") {
29 exclude("**/*.typegen.ts") 29 exclude("**/*.typegen.ts")
30} 30}
31 31
32val sourcesWithTypes = fileTree("src") + fileTree("types") 32val sourcesWithTypes: FileCollection = fileTree("src") + fileTree("types")
33 33
34val buildScripts = fileTree("config") + files( 34val buildScripts: FileCollection = fileTree("config") + files(
35 ".eslintrc.cjs", 35 ".eslintrc.cjs",
36 "prettier.config.cjs", 36 "prettier.config.cjs",
37 "vite.config.ts", 37 "vite.config.ts",
@@ -43,7 +43,7 @@ val installationState = files(
43 "package.json", 43 "package.json",
44) 44)
45 45
46val sharedConfigFiles = installationState + files( 46val sharedConfigFiles: FileCollection = installationState + files(
47 "tsconfig.json", 47 "tsconfig.json",
48 "tsconfig.base.json", 48 "tsconfig.base.json",
49 "tsconfig.node.json", 49 "tsconfig.node.json",
@@ -58,7 +58,7 @@ val assembleSources = sourcesWithTypes + fileTree("public") + file("index.html")
58 58
59val assembleFiles = assembleSources + assembleConfigFiles 59val assembleFiles = assembleSources + assembleConfigFiles
60 60
61val lintingFiles = sourcesWithTypes + buildScripts + sharedConfigFiles 61val lintingFiles: FileCollection = sourcesWithTypes + buildScripts + sharedConfigFiles
62 62
63tasks { 63tasks {
64 val generateXStateTypes by registering(RunYarn::class) { 64 val generateXStateTypes by registering(RunYarn::class) {
diff --git a/subprojects/language-ide/build.gradle.kts b/subprojects/language-ide/build.gradle.kts
index ff8630f9..1259cd67 100644
--- a/subprojects/language-ide/build.gradle.kts
+++ b/subprojects/language-ide/build.gradle.kts
@@ -13,12 +13,6 @@ dependencies {
13 api(project(":refinery-language")) 13 api(project(":refinery-language"))
14 api(libs.xtext.ide) 14 api(libs.xtext.ide)
15 api(libs.xtext.xbase.ide) 15 api(libs.xtext.xbase.ide)
16 xtextGenerated(project(":refinery-language", "generatedIdeSources"))
16} 17}
17 18
18val generateXtextLanguage by project(":refinery-language").tasks.existing
19
20for (taskName in listOf("compileJava", "processResources")) {
21 tasks.named(taskName) {
22 dependsOn(generateXtextLanguage)
23 }
24}
diff --git a/subprojects/language-model/build.gradle.kts b/subprojects/language-model/build.gradle.kts
index 4f15e5e6..59ff9046 100644
--- a/subprojects/language-model/build.gradle.kts
+++ b/subprojects/language-model/build.gradle.kts
@@ -35,6 +35,10 @@ tasks {
35 inputs.file("src/main/java/tools/refinery/language/model/GenerateProblemModel.mwe2") 35 inputs.file("src/main/java/tools/refinery/language/model/GenerateProblemModel.mwe2")
36 inputs.file("src/main/resources/model/problem.ecore") 36 inputs.file("src/main/resources/model/problem.ecore")
37 inputs.file("src/main/resources/model/problem.genmodel") 37 inputs.file("src/main/resources/model/problem.genmodel")
38 outputs.file("build.properties")
39 outputs.file("META-INF/MANIFEST.MF")
40 outputs.file("plugin.xml")
41 outputs.file("plugin.properties")
38 outputs.dir("src/main/emf-gen") 42 outputs.dir("src/main/emf-gen")
39 args("src/main/java/tools/refinery/language/model/GenerateProblemModel.mwe2", "-p", "rootPath=/$projectDir") 43 args("src/main/java/tools/refinery/language/model/GenerateProblemModel.mwe2", "-p", "rootPath=/$projectDir")
40 } 44 }
diff --git a/subprojects/language-web/build.gradle.kts b/subprojects/language-web/build.gradle.kts
index d398e002..7a7adac0 100644
--- a/subprojects/language-web/build.gradle.kts
+++ b/subprojects/language-web/build.gradle.kts
@@ -22,7 +22,8 @@ dependencies {
22 implementation(libs.jetty.websocket.server) 22 implementation(libs.jetty.websocket.server)
23 implementation(libs.slf4j.api) 23 implementation(libs.slf4j.api)
24 implementation(libs.xtext.web) 24 implementation(libs.xtext.web)
25 webapp(project(path = ":refinery-frontend", configuration = "productionAssets")) 25 xtextGenerated(project(":refinery-language", "generatedWebSources"))
26 webapp(project(":refinery-frontend", "productionAssets"))
26 testImplementation(testFixtures(project(":refinery-language"))) 27 testImplementation(testFixtures(project(":refinery-language")))
27 testImplementation(libs.jetty.websocket.client) 28 testImplementation(libs.jetty.websocket.client)
28} 29}
@@ -32,14 +33,6 @@ application {
32} 33}
33 34
34tasks { 35tasks {
35 val generateXtextLanguage by project(":refinery-language").tasks.existing
36
37 for (taskName in listOf("compileJava", "processResources")) {
38 named(taskName) {
39 dependsOn(generateXtextLanguage)
40 }
41 }
42
43 jar { 36 jar {
44 dependsOn(webapp) 37 dependsOn(webapp)
45 from(webapp) { 38 from(webapp) {
diff --git a/subprojects/language/build.gradle.kts b/subprojects/language/build.gradle.kts
index aa799c3b..bac1e586 100644
--- a/subprojects/language/build.gradle.kts
+++ b/subprojects/language/build.gradle.kts
@@ -14,6 +14,16 @@ plugins {
14 id("tools.refinery.gradle.xtext-generated") 14 id("tools.refinery.gradle.xtext-generated")
15} 15}
16 16
17val generatedIdeSources: Configuration by configurations.creating {
18 isCanBeConsumed = true
19 isCanBeResolved = false
20}
21
22val generatedWebSources: Configuration by configurations.creating {
23 isCanBeConsumed = true
24 isCanBeResolved = false
25}
26
17dependencies { 27dependencies {
18 api(platform(libs.xtext.bom)) 28 api(platform(libs.xtext.bom))
19 api(libs.ecore) 29 api(libs.ecore)
@@ -32,6 +42,20 @@ sourceSets {
32 } 42 }
33} 43}
34 44
45val generateXtextLanguage by tasks.registering(JavaExec::class) {
46 mainClass.set("org.eclipse.emf.mwe2.launch.runtime.Mwe2Launcher")
47 classpath(configurations.mwe2)
48 inputs.file("src/main/java/tools/refinery/language/GenerateProblem.mwe2")
49 inputs.file("src/main/java/tools/refinery/language/Problem.xtext")
50 inputs.file("../language-model/src/main/resources/model/problem.ecore")
51 inputs.file("../language-model/src/main/resources/model/problem.genmodel")
52 outputs.dir("src/main/xtext-gen")
53 outputs.dir("src/testFixtures/xtext-gen")
54 outputs.dir("$buildDir/generated/sources/xtext/ide")
55 outputs.dir("$buildDir/generated/sources/xtext/web")
56 args("src/main/java/tools/refinery/language/GenerateProblem.mwe2", "-p", "rootPath=/$projectDir/..")
57}
58
35tasks { 59tasks {
36 jar { 60 jar {
37 from(sourceSets.main.map { it.allSource }) { 61 from(sourceSets.main.map { it.allSource }) {
@@ -39,20 +63,16 @@ tasks {
39 } 63 }
40 } 64 }
41 65
42 val generateXtextLanguage by registering(JavaExec::class) { 66 syncXtextGeneratedSources {
43 mainClass.set("org.eclipse.emf.mwe2.launch.runtime.Mwe2Launcher") 67 // We generate Xtext runtime sources directly to {@code src/main/xtext-gen}, so there is no need to copy them
44 classpath(configurations.mwe2) 68 // from an artifact. We expose the {@code generatedIdeSources} and {@code generatedWebSources} artifacts to
45 inputs.file("src/main/java/tools/refinery/language/GenerateProblem.mwe2") 69 // sibling IDE and web projects which can use this task to consume them and copy the appropriate sources to
46 inputs.file("src/main/java/tools/refinery/language/Problem.xtext") 70 // their own {@code src/main/xtext-gen} directory.
47 outputs.dir("src/main/xtext-gen") 71 enabled = false
48 outputs.dir("src/testFixtures/xtext-gen")
49 outputs.dir("../language-ide/src/main/xtext-gen")
50 outputs.dir("../language-web/src/main/xtext-gen")
51 args("src/main/java/tools/refinery/language/GenerateProblem.mwe2", "-p", "rootPath=/$projectDir/..")
52 } 72 }
53 73
54 for (taskName in listOf("compileJava", "processResources", "processTestFixturesResources", 74 for (taskName in listOf("compileJava", "processResources", "compileTestFixturesJava",
55 "generateEclipseSourceFolders")) { 75 "processTestFixturesResources", "generateEclipseSourceFolders")) {
56 named(taskName) { 76 named(taskName) {
57 dependsOn(generateXtextLanguage) 77 dependsOn(generateXtextLanguage)
58 } 78 }
@@ -61,8 +81,16 @@ tasks {
61 clean { 81 clean {
62 delete("src/main/xtext-gen") 82 delete("src/main/xtext-gen")
63 delete("src/testFixtures/xtext-gen") 83 delete("src/testFixtures/xtext-gen")
64 delete("../language-ide/src/main/xtext-gen") 84 }
65 delete("../language-web/src/main/xtext-gen") 85}
86
87artifacts {
88 add(generatedIdeSources.name, file("$buildDir/generated/sources/xtext/ide")) {
89 builtBy(generateXtextLanguage)
90 }
91
92 add(generatedWebSources.name, file("$buildDir/generated/sources/xtext/web")) {
93 builtBy(generateXtextLanguage)
66 } 94 }
67} 95}
68 96
diff --git a/subprojects/language/src/main/java/tools/refinery/language/GenerateProblem.mwe2 b/subprojects/language/src/main/java/tools/refinery/language/GenerateProblem.mwe2
index d8d89173..59eba8f7 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/GenerateProblem.mwe2
+++ b/subprojects/language/src/main/java/tools/refinery/language/GenerateProblem.mwe2
@@ -16,16 +16,28 @@ Workflow {
16 project = StandardProjectConfig { 16 project = StandardProjectConfig {
17 baseName = 'language' 17 baseName = 'language'
18 rootPath = rootPath 18 rootPath = rootPath
19 runtime = {
20 // Do not generate new files into src/main/java
21 src = null
22 }
19 runtimeTest = { 23 runtimeTest = {
20 enabled = true 24 enabled = true
21 srcGen = 'src/testFixtures/xtext-gen' 25 // Only generate the xtext-gen files and leave the rest of the project alone
26 root = null
27 srcGen = '${rootPath}/language/src/testFixtures/xtext-gen'
22 } 28 }
23 genericIde = { 29 genericIde = {
24 name = 'language-ide' 30 name = 'language-ide'
31 // Only generate the xtext-gen files and leave the rest of the project alone
32 root = null
33 srcGen = "${rootPath}/language/build/generated/sources/xtext/ide"
25 } 34 }
26 web = { 35 web = {
27 enabled = true 36 enabled = true
28 name = 'language-web' 37 name = 'language-web'
38 // Only generate the xtext-gen files and leave the rest of the project alone
39 root = null
40 srcGen = "${rootPath}/language/build/generated/sources/xtext/web"
29 } 41 }
30 mavenLayout = true 42 mavenLayout = true
31 } 43 }