aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.editorconfig5
-rw-r--r--build.gradle6
-rw-r--r--build.gradle.kts8
-rw-r--r--buildSrc/build.gradle14
-rw-r--r--buildSrc/build.gradle.kts19
-rw-r--r--buildSrc/settings.gradle7
-rw-r--r--buildSrc/settings.gradle.kts7
-rw-r--r--buildSrc/src/main/groovy/refinery-eclipse.gradle28
-rw-r--r--buildSrc/src/main/groovy/refinery-frontend-conventions.gradle14
-rw-r--r--buildSrc/src/main/groovy/refinery-frontend-workspace.gradle29
-rw-r--r--buildSrc/src/main/groovy/refinery-frontend-worktree.gradle95
-rw-r--r--buildSrc/src/main/groovy/refinery-java-application.gradle11
-rw-r--r--buildSrc/src/main/groovy/refinery-java-conventions.gradle93
-rw-r--r--buildSrc/src/main/groovy/refinery-java-library.gradle4
-rw-r--r--buildSrc/src/main/groovy/refinery-java-test-fixtures.gradle35
-rw-r--r--buildSrc/src/main/groovy/refinery-jmh.gradle64
-rw-r--r--buildSrc/src/main/groovy/refinery-mwe2.gradle16
-rw-r--r--buildSrc/src/main/groovy/refinery-sonarqube.gradle8
-rw-r--r--buildSrc/src/main/groovy/refinery-xtext-conventions.gradle21
-rw-r--r--buildSrc/src/main/java/tools/refinery/buildsrc/EclipseUtils.java72
-rw-r--r--buildSrc/src/main/java/tools/refinery/buildsrc/SonarPropertiesUtils.java44
-rw-r--r--buildSrc/src/main/kotlin/refinery-eclipse.gradle.kts30
-rw-r--r--buildSrc/src/main/kotlin/refinery-frontend-conventions.gradle.kts18
-rw-r--r--buildSrc/src/main/kotlin/refinery-frontend-workspace.gradle.kts32
-rw-r--r--buildSrc/src/main/kotlin/refinery-frontend-worktree.gradle.kts84
-rw-r--r--buildSrc/src/main/kotlin/refinery-java-application.gradle.kts12
-rw-r--r--buildSrc/src/main/kotlin/refinery-java-conventions.gradle.kts96
-rw-r--r--buildSrc/src/main/kotlin/refinery-java-library.gradle.kts5
-rw-r--r--buildSrc/src/main/kotlin/refinery-java-test-fixtures.gradle.kts31
-rw-r--r--buildSrc/src/main/kotlin/refinery-jmh.gradle.kts63
-rw-r--r--buildSrc/src/main/kotlin/refinery-mwe2.gradle.kts18
-rw-r--r--buildSrc/src/main/kotlin/refinery-sonarqube.gradle.kts3
-rw-r--r--buildSrc/src/main/kotlin/refinery-xtext-conventions.gradle.kts21
-rw-r--r--settings.gradle18
-rw-r--r--settings.gradle.kts20
-rw-r--r--subprojects/frontend/build.gradle131
-rw-r--r--subprojects/frontend/build.gradle.kts127
-rw-r--r--subprojects/language-ide/build.gradle18
-rw-r--r--subprojects/language-ide/build.gradle.kts18
-rw-r--r--subprojects/language-model/build.gradle55
-rw-r--r--subprojects/language-model/build.gradle.kts53
-rw-r--r--subprojects/language-semantics/build.gradle11
-rw-r--r--subprojects/language-semantics/build.gradle.kts11
-rw-r--r--subprojects/language-web/build.gradle87
-rw-r--r--subprojects/language-web/build.gradle.kts91
-rw-r--r--subprojects/language/build.gradle73
-rw-r--r--subprojects/language/build.gradle.kts65
-rw-r--r--subprojects/store-query-viatra/build.gradle16
-rw-r--r--subprojects/store-query-viatra/build.gradle.kts16
-rw-r--r--subprojects/store-query/build.gradle9
-rw-r--r--subprojects/store-query/build.gradle.kts9
-rw-r--r--subprojects/store-reasoning/build.gradle7
-rw-r--r--subprojects/store-reasoning/build.gradle.kts7
-rw-r--r--subprojects/store/build.gradle4
-rw-r--r--subprojects/store/build.gradle.kts4
55 files changed, 988 insertions, 875 deletions
diff --git a/.editorconfig b/.editorconfig
index 81e5fda1..64f6b1ac 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -8,7 +8,7 @@ insert_final_newline = true
8max_line_length = 80 8max_line_length = 80
9ij_wrap_on_typing = true 9ij_wrap_on_typing = true
10 10
11[*.{gradle,java,mwe2,xtend,xtext}] 11[*.{gradle,java,kts,mwe2,xtend,xtext}]
12indent_style = tab 12indent_style = tab
13indent_size = 4 13indent_size = 4
14# Mimic Eclipse continuation indent style in IntelliJ 14# Mimic Eclipse continuation indent style in IntelliJ
@@ -19,3 +19,6 @@ ij_any_indent_case_from_switch = false
19[*.{grammar,html,js,json,jsx,scss,ts,tsx,yml}] 19[*.{grammar,html,js,json,jsx,scss,ts,tsx,yml}]
20indent_style = space 20indent_style = space
21indent_size = 2 21indent_size = 2
22
23[libs.versions.toml]
24max_line_length = 999 \ No newline at end of file
diff --git a/build.gradle b/build.gradle
deleted file mode 100644
index a632b457..00000000
--- a/build.gradle
+++ /dev/null
@@ -1,6 +0,0 @@
1plugins {
2 alias libs.plugins.versions
3 id 'refinery-eclipse'
4 id 'refinery-frontend-worktree'
5 id 'refinery-sonarqube'
6}
diff --git a/build.gradle.kts b/build.gradle.kts
new file mode 100644
index 00000000..8e50da65
--- /dev/null
+++ b/build.gradle.kts
@@ -0,0 +1,8 @@
1plugins {
2 // Workaround for https://github.com/gradle/gradle/issues/22797
3 @Suppress("DSL_SCOPE_VIOLATION")
4 alias(libs.plugins.versions)
5 id("refinery-eclipse")
6 id("refinery-frontend-worktree")
7 id("refinery-sonarqube")
8}
diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
deleted file mode 100644
index cd3101be..00000000
--- a/buildSrc/build.gradle
+++ /dev/null
@@ -1,14 +0,0 @@
1plugins {
2 id 'groovy-gradle-plugin'
3 alias libs.plugins.versions
4}
5
6repositories {
7 gradlePluginPortal()
8}
9
10dependencies {
11 implementation libs.gradlePlugin.frontend
12 implementation libs.gradlePlugin.shadow
13 implementation libs.gradlePlugin.sonarqube
14}
diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts
new file mode 100644
index 00000000..7a5ee5c4
--- /dev/null
+++ b/buildSrc/build.gradle.kts
@@ -0,0 +1,19 @@
1plugins {
2 `kotlin-dsl`
3 // Workaround for https://github.com/gradle/gradle/issues/22797
4 @Suppress("DSL_SCOPE_VIOLATION")
5 alias(libs.plugins.versions)
6}
7
8repositories {
9 gradlePluginPortal()
10 mavenCentral()
11}
12
13dependencies {
14 implementation(libs.gradlePlugin.frontend)
15 implementation(libs.gradlePlugin.shadow)
16 implementation(libs.gradlePlugin.sonarqube)
17 // https://github.com/gradle/gradle/issues/15383
18 implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location))
19}
diff --git a/buildSrc/settings.gradle b/buildSrc/settings.gradle
deleted file mode 100644
index b54c8e5d..00000000
--- a/buildSrc/settings.gradle
+++ /dev/null
@@ -1,7 +0,0 @@
1dependencyResolutionManagement {
2 versionCatalogs {
3 libs {
4 from files('../gradle/libs.versions.toml')
5 }
6 }
7}
diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts
new file mode 100644
index 00000000..8e6efa3d
--- /dev/null
+++ b/buildSrc/settings.gradle.kts
@@ -0,0 +1,7 @@
1dependencyResolutionManagement {
2 versionCatalogs {
3 create("libs") {
4 from(files("../gradle/libs.versions.toml"))
5 }
6 }
7}
diff --git a/buildSrc/src/main/groovy/refinery-eclipse.gradle b/buildSrc/src/main/groovy/refinery-eclipse.gradle
deleted file mode 100644
index 15dcb5ce..00000000
--- a/buildSrc/src/main/groovy/refinery-eclipse.gradle
+++ /dev/null
@@ -1,28 +0,0 @@
1plugins {
2 id 'eclipse'
3}
4
5// Workaround from https://github.com/gradle/gradle/issues/898#issuecomment-885765821
6def eclipseResourceEncoding = tasks.register('eclipseResourceEncoding') {
7 ext.outputFile = file('.settings/org.eclipse.core.resources.prefs')
8 def compileTask = tasks.findByName('compileJava')
9 ext.encoding = provider({ compileTask?.options?.encoding }).orElse(providers.systemProperty('file.encoding'))
10
11 inputs.property('file.encoding', encoding)
12 outputs.file(outputFile).withPropertyName('outputFile')
13
14 doLast {
15 Properties eclipseEncodingProperties =
16 new Properties(Collections.singletonMap('eclipse.preferences.version', '1'))
17 eclipseEncodingProperties.put('encoding/<project>', encoding.get())
18 outputFile.withOutputStream {
19 eclipseEncodingProperties.store(it, 'generated by ' + name)
20 }
21 }
22}
23
24tasks.named('eclipse') {
25 dependsOn(eclipseResourceEncoding)
26}
27
28eclipse.synchronizationTasks(eclipseResourceEncoding)
diff --git a/buildSrc/src/main/groovy/refinery-frontend-conventions.gradle b/buildSrc/src/main/groovy/refinery-frontend-conventions.gradle
deleted file mode 100644
index da9370fe..00000000
--- a/buildSrc/src/main/groovy/refinery-frontend-conventions.gradle
+++ /dev/null
@@ -1,14 +0,0 @@
1plugins {
2 id 'org.siouan.frontend-jdk11'
3}
4
5frontend {
6 nodeVersion = project.ext['frontend.nodeVersion']
7 nodeInstallDirectory = file("${rootDir}/.node")
8 yarnEnabled = true
9 yarnVersion = project.ext['frontend.yarnVersion']
10}
11
12tasks.named('enableYarnBerry') {
13 enabled = false
14}
diff --git a/buildSrc/src/main/groovy/refinery-frontend-workspace.gradle b/buildSrc/src/main/groovy/refinery-frontend-workspace.gradle
deleted file mode 100644
index 9c6d7b13..00000000
--- a/buildSrc/src/main/groovy/refinery-frontend-workspace.gradle
+++ /dev/null
@@ -1,29 +0,0 @@
1plugins {
2 id 'refinery-eclipse'
3 id 'refinery-frontend-conventions'
4}
5
6tasks.named('installNode') {
7 dependsOn rootProject.tasks.named('installNode')
8 enabled = false
9}
10
11tasks.named('installYarnGlobally') {
12 dependsOn rootProject.tasks.named('installYarnGlobally')
13 enabled = false
14}
15
16tasks.named('installYarn') {
17 dependsOn rootProject.tasks.named('installYarn')
18 enabled = false
19}
20
21def rootInstallFrontend = rootProject.tasks.named('installFrontend')
22rootInstallFrontend.configure {
23 inputs.file "${projectDir}/package.json"
24}
25
26tasks.named('installFrontend') {
27 dependsOn rootInstallFrontend
28 enabled = false
29}
diff --git a/buildSrc/src/main/groovy/refinery-frontend-worktree.gradle b/buildSrc/src/main/groovy/refinery-frontend-worktree.gradle
deleted file mode 100644
index 1d239fd5..00000000
--- a/buildSrc/src/main/groovy/refinery-frontend-worktree.gradle
+++ /dev/null
@@ -1,95 +0,0 @@
1plugins {
2 id 'refinery-frontend-conventions'
3}
4
5frontend {
6 yarnGlobalInstallScript = "install -g yarn@${project.ext['frontend.yarn1Version']}"
7 yarnInstallScript = "set version ${frontend.yarnVersion.get()} --only-if-needed"
8 if (project.hasProperty('ci')) {
9 installScript = 'install --immutable --inline-builds'
10 } else {
11 installScript = 'install'
12 }
13}
14
15ext.frontedPropertiesFile = "${frontend.nodeInstallDirectory.get()}/frontend.properties"
16
17String getFrontendProperty(String propertyName) {
18 FileInputStream inputStream = null
19 Properties props = new Properties()
20 try {
21 inputStream = new FileInputStream(frontedPropertiesFile)
22 props.load(inputStream)
23 } catch (IOException ignored) {
24 return null
25 } finally {
26 if (inputStream != null) {
27 inputStream.close()
28 }
29 }
30 return props.get(propertyName)
31}
32
33void putFrontedProperty(String propertyName, String propertyValue) {
34 FileInputStream inputStream = null
35 Properties props = new Properties()
36 try {
37 inputStream = new FileInputStream(frontedPropertiesFile)
38 props.load(inputStream)
39 } catch (FileNotFoundException ignored) {
40 // Use an empty Properties object instead
41 } finally {
42 if (inputStream != null) {
43 inputStream.close()
44 }
45 }
46 props.put(propertyName, propertyValue)
47 FileOutputStream outputStream = null
48 try {
49 outputStream = new FileOutputStream(frontedPropertiesFile)
50 props.store(outputStream, null)
51 } catch (IOException ignored) {
52 } finally {
53 if (outputStream != null) {
54 outputStream.close()
55 }
56 }
57}
58
59tasks.named('installNode') {
60 onlyIf {
61 getFrontendProperty('installedNodeVersion') != frontend.nodeVersion.get()
62 }
63 doLast {
64 putFrontedProperty('installedNodeVersion', frontend.nodeVersion.get())
65 }
66}
67
68tasks.named('installYarnGlobally') {
69 onlyIf {
70 getFrontendProperty('installedYarn1Version') != project.ext['frontend.yarn1Version']
71 }
72 doLast {
73 putFrontedProperty('installedYarn1Version', project.ext['frontend.yarn1Version'])
74 }
75 outputs.dir "${frontend.nodeInstallDirectory.get()}/lib/node_modules/yarn"
76}
77
78tasks.named('installYarn') {
79 outputs.file ".yarn/releases/yarn-${frontend.yarnVersion.get()}.cjs"
80}
81
82tasks.named('installFrontend') {
83 inputs.files('package.json', 'yarn.lock')
84 outputs.files('.pnp.cjs', '.pnp.loader.mjs')
85}
86
87tasks.register('clobberFrontend', Delete) {
88 delete frontend.nodeInstallDirectory.get()
89 delete '.yarn/cache'
90 delete '.yarn/install-state.gz'
91 delete '.yarn/sdks'
92 delete '.yarn/unplugged'
93 delete '.pnp.cjs'
94 delete '.pnp.loader.mjs'
95}
diff --git a/buildSrc/src/main/groovy/refinery-java-application.gradle b/buildSrc/src/main/groovy/refinery-java-application.gradle
deleted file mode 100644
index c38ccdb3..00000000
--- a/buildSrc/src/main/groovy/refinery-java-application.gradle
+++ /dev/null
@@ -1,11 +0,0 @@
1plugins {
2 id 'application'
3 id 'com.github.johnrengelman.shadow'
4 id 'refinery-java-conventions'
5}
6
7for (taskName in ['distTar', 'distZip', 'shadowDistTar', 'shadowDistZip']) {
8 tasks.named(taskName) {
9 enabled = false
10 }
11}
diff --git a/buildSrc/src/main/groovy/refinery-java-conventions.gradle b/buildSrc/src/main/groovy/refinery-java-conventions.gradle
deleted file mode 100644
index fdf5818a..00000000
--- a/buildSrc/src/main/groovy/refinery-java-conventions.gradle
+++ /dev/null
@@ -1,93 +0,0 @@
1plugins {
2 id 'jacoco'
3 id 'java'
4 id 'refinery-eclipse'
5}
6
7repositories {
8 mavenCentral()
9 maven {
10 url 'https://repo.eclipse.org/content/groups/releases/'
11 }
12}
13
14dependencies {
15 compileOnly libs.jetbrainsAnnotations
16 testCompileOnly libs.jetbrainsAnnotations
17 testImplementation libs.hamcrest
18 testImplementation libs.junit.api
19 testRuntimeOnly libs.junit.engine
20 testImplementation libs.junit.params
21 testImplementation libs.mockito.core
22 testImplementation libs.mockito.junit
23}
24
25java.toolchain {
26 languageVersion = JavaLanguageVersion.of(19)
27}
28
29tasks.withType(JavaCompile) {
30 options.release.set(17)
31}
32
33def jacocoTestReport = tasks.named('jacocoTestReport')
34jacocoTestReport.configure {
35 dependsOn test
36 reports {
37 xml.required = true
38 }
39}
40
41tasks.named('test') {
42 useJUnitPlatform {
43 excludeTags 'slow'
44 }
45 finalizedBy jacocoTestReport
46}
47
48tasks.register('slowTest', Test) {
49 useJUnitPlatform()
50 finalizedBy jacocoTestReport
51}
52
53tasks.named('jar') {
54 manifest {
55 attributes(
56 'Bundle-SymbolicName': "${project.group}.${project.name}",
57 'Bundle-Version': project.version
58 )
59 }
60}
61
62def generateEclipseSourceFolders = tasks.register('generateEclipseSourceFolders')
63
64tasks.register('prepareEclipse') {
65 dependsOn generateEclipseSourceFolders
66 dependsOn tasks.named('eclipseJdt')
67}
68
69tasks.named('eclipseClasspath') {
70 dependsOn generateEclipseSourceFolders
71}
72
73eclipse {
74 classpath.file.whenMerged {
75 for (entry in entries) {
76 if (entry.path.endsWith('-gen')) {
77 entry.entryAttributes['ignore_optional_problems'] = true
78 }
79 // If a project has a main dependency on a project and an test dependency on the testFixtures of a project,
80 // it will be erroneously added as a test-only dependency to Eclipse.
81 // As a workaround, we add all project dependencies as main dependencies
82 // (we do not deliberately use test-only project dependencies).
83 if (entry in org.gradle.plugins.ide.eclipse.model.ProjectDependency) {
84 entry.entryAttributes.remove('test')
85 }
86 }
87 }
88
89 jdt.file.withProperties { properties ->
90 // Allow @SuppressWarnings to suppress SonarLint warnings
91 properties['org.eclipse.jdt.core.compiler.problem.unhandledWarningToken'] = 'ignore'
92 }
93}
diff --git a/buildSrc/src/main/groovy/refinery-java-library.gradle b/buildSrc/src/main/groovy/refinery-java-library.gradle
deleted file mode 100644
index daa80f17..00000000
--- a/buildSrc/src/main/groovy/refinery-java-library.gradle
+++ /dev/null
@@ -1,4 +0,0 @@
1plugins {
2 id 'java-library'
3 id 'refinery-java-conventions'
4}
diff --git a/buildSrc/src/main/groovy/refinery-java-test-fixtures.gradle b/buildSrc/src/main/groovy/refinery-java-test-fixtures.gradle
deleted file mode 100644
index 02568abd..00000000
--- a/buildSrc/src/main/groovy/refinery-java-test-fixtures.gradle
+++ /dev/null
@@ -1,35 +0,0 @@
1import org.gradle.plugins.ide.eclipse.model.AbstractClasspathEntry
2
3plugins {
4 id 'java-test-fixtures'
5 id 'refinery-java-conventions'
6}
7
8eclipse.classpath {
9 containsTestFixtures = true
10
11 file.whenMerged { classpath ->
12 def hasTest = classpath.entries.any { entry ->
13 entry in AbstractClasspathEntry &&
14 entry.entryAttributes['gradle_scope'] == 'test'
15 }
16 for (entry in classpath.entries) {
17 // Workaround https://github.com/gradle/gradle/issues/11845 based on
18 // https://discuss.gradle.org/t/gradle-used-by-scope-not-correctly-generated-when-the-java-test-fixtures-plugin-is-used/39935/2
19 if (entry in AbstractClasspathEntry) {
20 def usedBy = new LinkedHashSet(
21 Arrays.asList((entry.entryAttributes['gradle_used_by_scope'] ?: '').split(','))
22 )
23 if (usedBy.contains('main')) {
24 usedBy += 'testFixtures'
25 }
26 if (hasTest && usedBy.contains('testFixtures')) {
27 usedBy += 'test'
28 }
29 if (!usedBy.empty) {
30 entry.entryAttributes['gradle_used_by_scope'] = usedBy.join(',')
31 }
32 }
33 }
34 }
35}
diff --git a/buildSrc/src/main/groovy/refinery-jmh.gradle b/buildSrc/src/main/groovy/refinery-jmh.gradle
deleted file mode 100644
index 1ab9edc3..00000000
--- a/buildSrc/src/main/groovy/refinery-jmh.gradle
+++ /dev/null
@@ -1,64 +0,0 @@
1import org.gradle.plugins.ide.eclipse.model.AbstractClasspathEntry
2
3plugins {
4 id 'refinery-java-conventions'
5 id 'refinery-sonarqube'
6}
7
8configurations {
9 jmh {
10 extendsFrom implementation
11 }
12}
13
14sourceSets {
15 jmh {
16 java.srcDirs = ['src/jmh/java']
17 resources.srcDirs = ['src/jmh/resources']
18 compileClasspath += sourceSets.main.runtimeClasspath
19 compileClasspath += sourceSets.test.runtimeClasspath
20 }
21}
22
23dependencies {
24 jmhImplementation libs.jmh.core
25 jmhAnnotationProcessor libs.jmh.annprocess
26}
27
28tasks.register('jmh', JavaExec) {
29 dependsOn tasks.named('jmhClasses')
30 mainClass = 'org.openjdk.jmh.Main'
31 classpath = sourceSets.jmh.compileClasspath + sourceSets.jmh.runtimeClasspath
32}
33
34eclipse.classpath.file.whenMerged { classpath ->
35 for (entry in classpath.entries) {
36 if (entry in AbstractClasspathEntry) {
37 // Workaround from https://github.com/gradle/gradle/issues/4802#issuecomment-407902081
38 if (entry.entryAttributes['gradle_scope'] == 'jmh') {
39 // Allow test helper classes to be used in benchmarks from Eclipse
40 // and do not expose JMH dependencies to the main source code.
41 entry.entryAttributes['test'] = true
42 } else {
43 // Workaround based on
44 // https://discuss.gradle.org/t/gradle-used-by-scope-not-correctly-generated-when-the-java-test-fixtures-plugin-is-used/39935/2
45 def usedBy = new LinkedHashSet(
46 Arrays.asList((entry.entryAttributes['gradle_used_by_scope'] ?: '').split(','))
47 )
48 if (['main', 'test', 'testFixtures'].any { e -> usedBy.contains(e) }) {
49 // main and test sources are also used by jmh sources.
50 usedBy += 'jmh'
51 }
52 if (!usedBy.empty) {
53 entry.entryAttributes['gradle_used_by_scope'] = usedBy.join(',')
54 }
55 }
56 }
57 }
58}
59
60sonarqube.properties {
61 properties['sonar.tests'] += [
62 'src/jmh/java',
63 ]
64}
diff --git a/buildSrc/src/main/groovy/refinery-mwe2.gradle b/buildSrc/src/main/groovy/refinery-mwe2.gradle
deleted file mode 100644
index c7f15e82..00000000
--- a/buildSrc/src/main/groovy/refinery-mwe2.gradle
+++ /dev/null
@@ -1,16 +0,0 @@
1plugins {
2 id 'eclipse'
3 id 'refinery-java-conventions'
4}
5
6configurations {
7 mwe2 {
8 extendsFrom implementation
9 }
10}
11
12dependencies {
13 mwe2 libs.mwe2.launch
14}
15
16eclipse.classpath.plusConfigurations += [configurations.mwe2]
diff --git a/buildSrc/src/main/groovy/refinery-sonarqube.gradle b/buildSrc/src/main/groovy/refinery-sonarqube.gradle
deleted file mode 100644
index d84f4ada..00000000
--- a/buildSrc/src/main/groovy/refinery-sonarqube.gradle
+++ /dev/null
@@ -1,8 +0,0 @@
1plugins {
2 id 'org.sonarqube'
3}
4
5sonarqube.properties {
6 // Make sure `exclusions` is a List in every subproject
7 property 'sonar.exclusions', []
8}
diff --git a/buildSrc/src/main/groovy/refinery-xtext-conventions.gradle b/buildSrc/src/main/groovy/refinery-xtext-conventions.gradle
deleted file mode 100644
index 0c7c82f0..00000000
--- a/buildSrc/src/main/groovy/refinery-xtext-conventions.gradle
+++ /dev/null
@@ -1,21 +0,0 @@
1plugins {
2 id 'refinery-java-conventions'
3 id 'refinery-sonarqube'
4}
5
6sourceSets {
7 main {
8 java.srcDirs += ['src/main/xtext-gen']
9 resources.srcDirs += ['src/main/xtext-gen']
10 }
11}
12
13tasks.named('clean') {
14 delete 'src/main/xtext-gen'
15}
16
17sonarqube.properties {
18 properties['sonar.exclusions'] += [
19 'src/main/xtext-gen/**',
20 ]
21}
diff --git a/buildSrc/src/main/java/tools/refinery/buildsrc/EclipseUtils.java b/buildSrc/src/main/java/tools/refinery/buildsrc/EclipseUtils.java
new file mode 100644
index 00000000..0014a35d
--- /dev/null
+++ b/buildSrc/src/main/java/tools/refinery/buildsrc/EclipseUtils.java
@@ -0,0 +1,72 @@
1package tools.refinery.buildsrc;
2
3import groovy.lang.Closure;
4import org.gradle.api.Action;
5import org.gradle.plugins.ide.api.XmlFileContentMerger;
6import org.gradle.plugins.ide.eclipse.model.AbstractClasspathEntry;
7import org.gradle.plugins.ide.eclipse.model.Classpath;
8import org.gradle.plugins.ide.eclipse.model.EclipseModel;
9
10import java.util.LinkedHashSet;
11import java.util.List;
12import java.util.Set;
13import java.util.function.Consumer;
14
15public final class EclipseUtils {
16 private static final String GRADLE_USED_BY_SCOPE_ATTRIBUTE = "gradle_used_by_scope";
17 private static final String GRADLE_USED_BY_SCOPE_SEPARATOR = ",";
18
19 private EclipseUtils() {
20 throw new IllegalStateException("This is a static utility class and should not be instantiated directly");
21 }
22
23 public static void patchClasspathEntries(EclipseModel eclipseModel, Consumer<AbstractClasspathEntry> consumer) {
24 whenClasspathFileMerged(eclipseModel.getClasspath().getFile(),
25 classpath -> patchClasspathEntries(classpath, consumer));
26 }
27
28 public static void patchClasspathEntries(Classpath eclipseClasspath, Consumer<AbstractClasspathEntry> consumer) {
29 for (var entry : eclipseClasspath.getEntries()) {
30 if (entry instanceof AbstractClasspathEntry abstractClasspathEntry) {
31 consumer.accept(abstractClasspathEntry);
32 }
33 }
34 }
35
36 /**
37 * Avoids ambiguous call to ({@link XmlFileContentMerger#whenMerged(Closure)} versus
38 * {@link XmlFileContentMerger#whenMerged(Action)}) in Kotlin build scripts.
39 * <p>
40 * The {@code Closure} variant will use the build script itself as {@code this}, and Kotlin will consider any
41 * type ascription as a cast of {@code this} (instead of the argument of the {@code Action<?>}). This results in
42 * a mysterious {@link ClassCastException}, since the class generated from the build script doesn't extend from
43 * {@link Classpath}. Using this helper method selects the correct call and applies the cast properly.
44 *
45 * @param file The Eclipse classpath file.
46 * @param consumer The lambda to run on when the classpath file is merged.
47 */
48 public static void whenClasspathFileMerged(XmlFileContentMerger file, Consumer<Classpath> consumer) {
49 file.whenMerged(untypedClasspath -> {
50 var classpath = (Classpath) untypedClasspath;
51 consumer.accept(classpath);
52 });
53 }
54
55 public static void patchGradleUsedByScope(AbstractClasspathEntry entry, Consumer<Set<String>> consumer) {
56 var entryAttributes = entry.getEntryAttributes();
57 var usedByValue = entryAttributes.get(GRADLE_USED_BY_SCOPE_ATTRIBUTE);
58 Set<String> usedBySet;
59 if (usedByValue instanceof String usedByString) {
60 usedBySet = new LinkedHashSet<>(List.of(usedByString.split(GRADLE_USED_BY_SCOPE_SEPARATOR)));
61 } else {
62 usedBySet = new LinkedHashSet<>();
63 }
64 consumer.accept(usedBySet);
65 if (usedBySet.isEmpty()) {
66 entryAttributes.remove(GRADLE_USED_BY_SCOPE_ATTRIBUTE);
67 } else {
68 var newUsedByString = String.join(GRADLE_USED_BY_SCOPE_SEPARATOR, usedBySet);
69 entryAttributes.put(GRADLE_USED_BY_SCOPE_ATTRIBUTE, newUsedByString);
70 }
71 }
72}
diff --git a/buildSrc/src/main/java/tools/refinery/buildsrc/SonarPropertiesUtils.java b/buildSrc/src/main/java/tools/refinery/buildsrc/SonarPropertiesUtils.java
new file mode 100644
index 00000000..1d89841e
--- /dev/null
+++ b/buildSrc/src/main/java/tools/refinery/buildsrc/SonarPropertiesUtils.java
@@ -0,0 +1,44 @@
1package tools.refinery.buildsrc;
2
3import java.util.ArrayList;
4import java.util.Collections;
5import java.util.Map;
6
7public final class SonarPropertiesUtils {
8 private SonarPropertiesUtils() {
9 throw new IllegalStateException("This is a static utility class and should not be instantiated directly");
10 }
11
12 /**
13 * Adds the entries to a Sonar property of list type.
14 * <p>
15 * According to the Sonar Gradle documentation for {@link org.sonarqube.gradle.SonarProperties}, property values
16 * are converted to Strings as follows:
17 * <ul>
18 * <li>{@code Iterable}s are recursively converted and joined into a comma-separated String.</li>
19 * <li>All other values are converted to Strings by calling their {@code toString()} method.</li>
20 * </ul>
21 * Therefore, we use {@link ArrayList} to retain lists entries, which will be recursively converted later.
22 *
23 * @param properties The sonar properties map returned by
24 * {@link org.sonarqube.gradle.SonarProperties#getProperties()}.
25 * @param propertyName The name of the property to append to.
26 * @param entries The entries to append.
27 */
28 public static void addToList(Map<String, Object> properties, String propertyName, String... entries) {
29 ArrayList<Object> newValue;
30 var currentValue = properties.get(propertyName);
31 if (currentValue instanceof ArrayList<?> currentList) {
32 @SuppressWarnings("unchecked")
33 var objectList = (ArrayList<Object>) currentList;
34 newValue = objectList;
35 } else if (currentValue == null) {
36 newValue = new ArrayList<>(entries.length);
37 } else {
38 newValue = new ArrayList<>(entries.length + 1);
39 newValue.add(currentValue);
40 }
41 Collections.addAll(newValue, entries);
42 properties.put(propertyName, newValue);
43 }
44}
diff --git a/buildSrc/src/main/kotlin/refinery-eclipse.gradle.kts b/buildSrc/src/main/kotlin/refinery-eclipse.gradle.kts
new file mode 100644
index 00000000..ed7c5250
--- /dev/null
+++ b/buildSrc/src/main/kotlin/refinery-eclipse.gradle.kts
@@ -0,0 +1,30 @@
1import org.gradle.plugins.ide.eclipse.model.EclipseModel
2import java.util.*
3
4plugins {
5 eclipse
6}
7
8// Workaround from https://github.com/gradle/gradle/issues/898#issuecomment-885765821
9val eclipseResourceEncoding by tasks.registering {
10 val outputFile = file(".settings/org.eclipse.core.resources.prefs")
11 val encoding = providers.systemProperty("file.encoding")
12
13 inputs.property("file.encoding", encoding)
14 outputs.file(outputFile)
15
16 doLast {
17 val eclipseEncodingProperties = Properties(2)
18 eclipseEncodingProperties["eclipse.preferences.version"] = "1"
19 eclipseEncodingProperties["encoding/<project>"] = encoding.get()
20 outputFile.outputStream().use { outputStream ->
21 eclipseEncodingProperties.store(outputStream, "generated by $name")
22 }
23 }
24}
25
26tasks.named("eclipse") {
27 dependsOn(eclipseResourceEncoding)
28}
29
30the<EclipseModel>().synchronizationTasks(eclipseResourceEncoding)
diff --git a/buildSrc/src/main/kotlin/refinery-frontend-conventions.gradle.kts b/buildSrc/src/main/kotlin/refinery-frontend-conventions.gradle.kts
new file mode 100644
index 00000000..c4658948
--- /dev/null
+++ b/buildSrc/src/main/kotlin/refinery-frontend-conventions.gradle.kts
@@ -0,0 +1,18 @@
1import org.siouan.frontendgradleplugin.infrastructure.gradle.EnableYarnBerryTask
2import org.siouan.frontendgradleplugin.infrastructure.gradle.FrontendExtension
3
4plugins {
5 id("org.siouan.frontend-jdk11")
6}
7
8configure<FrontendExtension> {
9 nodeVersion.set(providers.gradleProperty("frontend.nodeVersion"))
10 nodeInstallDirectory.set(file("$rootDir/.node"))
11 yarnEnabled.set(true)
12 yarnVersion.set(providers.gradleProperty("frontend.yarnVersion"))
13}
14
15tasks.named<EnableYarnBerryTask>("enableYarnBerry") {
16 // There is no need to enable berry manually, because berry files are already committed to the repo.
17 enabled = false
18}
diff --git a/buildSrc/src/main/kotlin/refinery-frontend-workspace.gradle.kts b/buildSrc/src/main/kotlin/refinery-frontend-workspace.gradle.kts
new file mode 100644
index 00000000..198f73f3
--- /dev/null
+++ b/buildSrc/src/main/kotlin/refinery-frontend-workspace.gradle.kts
@@ -0,0 +1,32 @@
1import org.siouan.frontendgradleplugin.infrastructure.gradle.*
2
3plugins {
4 id("refinery-eclipse")
5 id("refinery-frontend-conventions")
6}
7
8tasks.named<NodeInstallTask>("installNode") {
9 dependsOn(rootProject.tasks.named("installNode"))
10 enabled = false
11}
12
13tasks.named<YarnGlobalInstallTask>("installYarnGlobally") {
14 dependsOn(rootProject.tasks.named("installYarnGlobally"))
15 enabled = false
16}
17
18tasks.named<InstallYarnTask>("installYarn") {
19 dependsOn(rootProject.tasks.named("installYarn"))
20 enabled = false
21}
22
23val rootInstallFrontend = rootProject.tasks.named("installFrontend")
24
25rootInstallFrontend.configure {
26 inputs.file("$projectDir/package.json")
27}
28
29tasks.named("installFrontend") {
30 dependsOn(rootInstallFrontend)
31 enabled = false
32}
diff --git a/buildSrc/src/main/kotlin/refinery-frontend-worktree.gradle.kts b/buildSrc/src/main/kotlin/refinery-frontend-worktree.gradle.kts
new file mode 100644
index 00000000..d8c3d51f
--- /dev/null
+++ b/buildSrc/src/main/kotlin/refinery-frontend-worktree.gradle.kts
@@ -0,0 +1,84 @@
1import org.siouan.frontendgradleplugin.infrastructure.gradle.*
2import java.io.FileInputStream
3import java.io.FileNotFoundException
4import java.io.FileOutputStream
5import java.util.*
6
7plugins {
8 id("refinery-frontend-conventions")
9}
10
11val frontend = the<FrontendExtension>()
12
13val yarn1Version = providers.gradleProperty("frontend.yarn1Version")
14
15frontend.yarnGlobalInstallScript.set(yarn1Version.map { version -> "install -g yarn@$version" })
16frontend.yarnInstallScript.set(frontend.yarnVersion.map { version -> "set version $version --only-if-needed" })
17frontend.installScript.set(provider {
18 if (project.hasProperty("ci")) "install --immutable --inline-builds" else "install"
19})
20
21val frontendPropertiesFile = frontend.nodeInstallDirectory.map { dir -> "$dir/frontend.properties" }
22
23fun readFrontendProperties(): Properties {
24 val props = Properties()
25 try {
26 FileInputStream(frontendPropertiesFile.get()).use { inputStream ->
27 props.load(inputStream)
28 }
29 } catch (ignored: FileNotFoundException) {
30 // Ignore missing file.
31 }
32 return props
33}
34
35fun getFrontendProperty(propertyName: String): String? {
36 val props = readFrontendProperties()
37 return props[propertyName]?.toString()
38}
39
40fun putFrontedProperty(propertyName: String, propertyValue: String) {
41 val props = readFrontendProperties()
42 props[propertyName] = propertyValue
43 FileOutputStream(frontendPropertiesFile.get()).use { outputStream ->
44 props.store(outputStream, "generated by refinery-frontend-worktree")
45 }
46}
47
48tasks.named<NodeInstallTask>("installNode") {
49 onlyIf {
50 getFrontendProperty("installedNodeVersion") != frontend.nodeVersion.get()
51 }
52 doLast {
53 putFrontedProperty("installedNodeVersion", frontend.nodeVersion.get())
54 }
55}
56
57tasks.named<YarnGlobalInstallTask>("installYarnGlobally") {
58 onlyIf {
59 getFrontendProperty("installedYarn1Version") != yarn1Version.get()
60 }
61 doLast {
62 putFrontedProperty("installedYarn1Version", yarn1Version.get())
63 }
64 outputs.dir(frontend.nodeInstallDirectory.map { dir -> "$dir/lib/node_modules/yarn" })
65}
66
67tasks.named<InstallYarnTask>("installYarn") {
68 outputs.file(frontend.yarnVersion.map { version -> ".yarn/releases/yarn-$version.cjs" })
69}
70
71tasks.named<InstallDependenciesTask>("installFrontend") {
72 inputs.files("package.json", "yarn.lock")
73 outputs.files(".pnp.cjs", ".pnp.loader.mjs")
74}
75
76tasks.register("clobberFrontend", Delete::class) {
77 delete(frontend.nodeInstallDirectory)
78 delete(".yarn/cache")
79 delete(".yarn/install-state.gz")
80 delete(".yarn/sdks")
81 delete(".yarn/unplugged")
82 delete(".pnp.cjs")
83 delete(".pnp.loader.mjs")
84}
diff --git a/buildSrc/src/main/kotlin/refinery-java-application.gradle.kts b/buildSrc/src/main/kotlin/refinery-java-application.gradle.kts
new file mode 100644
index 00000000..b3fab1fa
--- /dev/null
+++ b/buildSrc/src/main/kotlin/refinery-java-application.gradle.kts
@@ -0,0 +1,12 @@
1plugins {
2 application
3 id("com.github.johnrengelman.shadow")
4}
5
6apply(plugin = "refinery-java-conventions")
7
8for (taskName in listOf("distTar", "distZip", "shadowDistTar", "shadowDistZip")) {
9 tasks.named(taskName) {
10 enabled = false
11 }
12}
diff --git a/buildSrc/src/main/kotlin/refinery-java-conventions.gradle.kts b/buildSrc/src/main/kotlin/refinery-java-conventions.gradle.kts
new file mode 100644
index 00000000..2d5ce8b5
--- /dev/null
+++ b/buildSrc/src/main/kotlin/refinery-java-conventions.gradle.kts
@@ -0,0 +1,96 @@
1import org.gradle.accessors.dm.LibrariesForLibs
2import org.gradle.plugins.ide.eclipse.model.EclipseModel
3import org.gradle.plugins.ide.eclipse.model.ProjectDependency
4import tools.refinery.buildsrc.EclipseUtils
5
6plugins {
7 jacoco
8 java
9}
10
11apply(plugin = "refinery-eclipse")
12
13repositories {
14 mavenCentral()
15 maven {
16 url = uri("https://repo.eclipse.org/content/groups/releases/")
17 }
18}
19
20val libs = the<LibrariesForLibs>()
21
22dependencies {
23 compileOnly(libs.jetbrainsAnnotations)
24 testCompileOnly(libs.jetbrainsAnnotations)
25 testImplementation(libs.hamcrest)
26 testImplementation(libs.junit.api)
27 testRuntimeOnly(libs.junit.engine)
28 testImplementation(libs.junit.params)
29 testImplementation(libs.mockito.core)
30 testImplementation(libs.mockito.junit)
31}
32
33java.toolchain {
34 languageVersion.set(JavaLanguageVersion.of(19))
35}
36
37tasks.withType(JavaCompile::class) {
38 options.release.set(17)
39}
40
41val test = tasks.named<Test>("test")
42
43val jacocoTestReport = tasks.named<JacocoReport>("jacocoTestReport")
44
45test.configure {
46 useJUnitPlatform {
47 excludeTags("slow")
48 }
49 finalizedBy(jacocoTestReport)
50}
51
52jacocoTestReport.configure {
53 dependsOn(test)
54 reports {
55 xml.required.set(true)
56 }
57}
58
59tasks.named<org.gradle.jvm.tasks.Jar>("jar") {
60 manifest {
61 attributes(
62 "Bundle-SymbolicName" to "${project.group}.${project.name}",
63 "Bundle-Version" to project.version
64 )
65 }
66}
67
68val generateEclipseSourceFolders by tasks.registering
69
70tasks.register("prepareEclipse") {
71 dependsOn(generateEclipseSourceFolders)
72 dependsOn(tasks.named("eclipseJdt"))
73}
74
75tasks.named("eclipseClasspath") {
76 dependsOn(generateEclipseSourceFolders)
77}
78
79configure<EclipseModel> {
80 EclipseUtils.patchClasspathEntries(this) { entry ->
81 if (entry.path.endsWith("-gen")) {
82 entry.entryAttributes["ignore_optional_problems"] = true
83 }
84 // If a project has a main dependency on a project and a test dependency on the testFixtures of a project,
85 // it will be erroneously added as a test-only dependency to Eclipse. As a workaround, we add all project
86 // dependencies as main dependencies (we do not deliberately use test-only project dependencies).
87 if (entry is ProjectDependency) {
88 entry.entryAttributes.remove("test")
89 }
90 }
91
92 jdt.file.withProperties {
93 // Allow @SuppressWarnings to suppress SonarLint warnings
94 this["org.eclipse.jdt.core.compiler.problem.unhandledWarningToken"] = "ignore"
95 }
96}
diff --git a/buildSrc/src/main/kotlin/refinery-java-library.gradle.kts b/buildSrc/src/main/kotlin/refinery-java-library.gradle.kts
new file mode 100644
index 00000000..5a6200e0
--- /dev/null
+++ b/buildSrc/src/main/kotlin/refinery-java-library.gradle.kts
@@ -0,0 +1,5 @@
1plugins {
2 `java-library`
3}
4
5apply(plugin = "refinery-java-conventions")
diff --git a/buildSrc/src/main/kotlin/refinery-java-test-fixtures.gradle.kts b/buildSrc/src/main/kotlin/refinery-java-test-fixtures.gradle.kts
new file mode 100644
index 00000000..86b0a04b
--- /dev/null
+++ b/buildSrc/src/main/kotlin/refinery-java-test-fixtures.gradle.kts
@@ -0,0 +1,31 @@
1import org.gradle.plugins.ide.eclipse.model.AbstractClasspathEntry
2import org.gradle.plugins.ide.eclipse.model.EclipseModel
3import tools.refinery.buildsrc.EclipseUtils
4
5plugins {
6 `java-test-fixtures`
7}
8
9apply(plugin = "refinery-java-conventions")
10
11the<EclipseModel>().classpath {
12 containsTestFixtures.set(true)
13
14 EclipseUtils.whenClasspathFileMerged(file) { eclipseClasspath ->
15 val hasTest = eclipseClasspath.entries.any { entry ->
16 entry is AbstractClasspathEntry && entry.entryAttributes["gradle_scope"] == "test"
17 }
18 EclipseUtils.patchClasspathEntries(eclipseClasspath) { entry ->
19 // Workaround https://github.com/gradle/gradle/issues/11845 based on
20 // https://discuss.gradle.org/t/gradle-used-by-scope-not-correctly-generated-when-the-java-test-fixtures-plugin-is-used/39935/2
21 EclipseUtils.patchGradleUsedByScope(entry) { usedBy ->
22 if (usedBy.contains("main")) {
23 usedBy += "testFixtures"
24 }
25 if (hasTest && usedBy.contains("testFixtures")) {
26 usedBy += "test"
27 }
28 }
29 }
30 }
31}
diff --git a/buildSrc/src/main/kotlin/refinery-jmh.gradle.kts b/buildSrc/src/main/kotlin/refinery-jmh.gradle.kts
new file mode 100644
index 00000000..11888b59
--- /dev/null
+++ b/buildSrc/src/main/kotlin/refinery-jmh.gradle.kts
@@ -0,0 +1,63 @@
1import org.gradle.accessors.dm.LibrariesForLibs
2import org.gradle.plugins.ide.eclipse.model.EclipseModel
3import org.sonarqube.gradle.SonarExtension
4import tools.refinery.buildsrc.EclipseUtils
5import tools.refinery.buildsrc.SonarPropertiesUtils
6
7apply(plugin = "refinery-java-conventions")
8apply(plugin = "refinery-sonarqube")
9
10val sourceSets = the<SourceSetContainer>()
11
12val main: SourceSet by sourceSets.getting
13
14val test: SourceSet by sourceSets.getting
15
16val jmh: SourceSet by sourceSets.creating {
17 compileClasspath += main.output
18 runtimeClasspath += main.output
19 // Allow using test classes in benchmarks for now.
20 compileClasspath += test.output
21 runtimeClasspath += test.output
22}
23
24val jmhImplementation: Configuration by configurations.getting {
25 extendsFrom(configurations["implementation"], configurations["testImplementation"])
26}
27
28val jmhAnnotationProcessor: Configuration by configurations.getting
29
30configurations["jmhRuntimeOnly"].extendsFrom(configurations["runtimeOnly"], configurations["testRuntimeOnly"])
31
32val libs = the<LibrariesForLibs>()
33
34dependencies {
35 jmhImplementation(libs.jmh.core)
36 jmhAnnotationProcessor(libs.jmh.annprocess)
37}
38
39tasks.register("jmh", JavaExec::class) {
40 dependsOn(tasks.named("jmhClasses"))
41 mainClass.set("org.openjdk.jmh.Main")
42 classpath = jmh.runtimeClasspath
43}
44
45EclipseUtils.patchClasspathEntries(the<EclipseModel>()) { entry ->
46 // Workaround from https://github.com/gradle/gradle/issues/4802#issuecomment-407902081
47 if (entry.entryAttributes["gradle_scope"] == "jmh") {
48 // Allow test helper classes to be used in benchmarks from Eclipse
49 // and do not expose JMH dependencies to the main source code.
50 entry.entryAttributes["test"] = true
51 } else {
52 EclipseUtils.patchGradleUsedByScope(entry) { usedBy ->
53 if (listOf("main", "test", "testFixtures").any { e -> usedBy.contains(e) }) {
54 // main and test sources are also used by jmh sources.
55 usedBy += "jmh"
56 }
57 }
58 }
59}
60
61the<SonarExtension>().properties {
62 SonarPropertiesUtils.addToList(properties, "sonar.tests", "src/jmh/java")
63}
diff --git a/buildSrc/src/main/kotlin/refinery-mwe2.gradle.kts b/buildSrc/src/main/kotlin/refinery-mwe2.gradle.kts
new file mode 100644
index 00000000..26963837
--- /dev/null
+++ b/buildSrc/src/main/kotlin/refinery-mwe2.gradle.kts
@@ -0,0 +1,18 @@
1import org.gradle.accessors.dm.LibrariesForLibs
2import org.gradle.plugins.ide.eclipse.model.EclipseModel
3
4apply(plugin = "refinery-java-conventions")
5
6val mwe2: Configuration by configurations.creating {
7 isCanBeConsumed = false
8 isCanBeResolved = true
9 extendsFrom(configurations["implementation"])
10}
11
12val libs = the<LibrariesForLibs>()
13
14dependencies {
15 mwe2(libs.mwe2.launch)
16}
17
18the<EclipseModel>().classpath.plusConfigurations += mwe2
diff --git a/buildSrc/src/main/kotlin/refinery-sonarqube.gradle.kts b/buildSrc/src/main/kotlin/refinery-sonarqube.gradle.kts
new file mode 100644
index 00000000..6a1dbbf6
--- /dev/null
+++ b/buildSrc/src/main/kotlin/refinery-sonarqube.gradle.kts
@@ -0,0 +1,3 @@
1plugins {
2 id("org.sonarqube")
3}
diff --git a/buildSrc/src/main/kotlin/refinery-xtext-conventions.gradle.kts b/buildSrc/src/main/kotlin/refinery-xtext-conventions.gradle.kts
new file mode 100644
index 00000000..34fbae99
--- /dev/null
+++ b/buildSrc/src/main/kotlin/refinery-xtext-conventions.gradle.kts
@@ -0,0 +1,21 @@
1import org.gradle.api.tasks.SourceSetContainer
2import org.sonarqube.gradle.SonarExtension
3import tools.refinery.buildsrc.SonarPropertiesUtils
4
5apply(plugin = "refinery-java-conventions")
6apply(plugin = "refinery-sonarqube")
7
8val xtextGenPath = "src/main/xtext-gen"
9
10the<SourceSetContainer>().named("main") {
11 java.srcDir(xtextGenPath)
12 resources.srcDir(xtextGenPath)
13}
14
15tasks.named<Delete>("clean") {
16 delete(xtextGenPath)
17}
18
19the<SonarExtension>().properties {
20 SonarPropertiesUtils.addToList(properties, "sonar.exclusions", "$xtextGenPath/**")
21}
diff --git a/settings.gradle b/settings.gradle
deleted file mode 100644
index 81bcb53b..00000000
--- a/settings.gradle
+++ /dev/null
@@ -1,18 +0,0 @@
1rootProject.name = 'refinery'
2
3include 'frontend'
4include 'language'
5include 'language-ide'
6include 'language-model'
7include 'language-semantics'
8include 'language-web'
9include 'store'
10include 'store-query'
11include 'store-query-viatra'
12include 'store-reasoning'
13
14for (project in rootProject.children) {
15 def projectName = project.name
16 project.name = "${rootProject.name}-${projectName}"
17 project.projectDir = file("subprojects/${projectName}")
18}
diff --git a/settings.gradle.kts b/settings.gradle.kts
new file mode 100644
index 00000000..cca283dc
--- /dev/null
+++ b/settings.gradle.kts
@@ -0,0 +1,20 @@
1rootProject.name = "refinery"
2
3include(
4 "frontend",
5 "language",
6 "language-ide",
7 "language-model",
8 "language-semantics",
9 "language-web",
10 "store",
11 "store-query",
12 "store-query-viatra",
13 "store-reasoning",
14)
15
16for (project in rootProject.children) {
17 val projectName = project.name
18 project.name = "${rootProject.name}-$projectName"
19 project.projectDir = file("subprojects/$projectName")
20}
diff --git a/subprojects/frontend/build.gradle b/subprojects/frontend/build.gradle
deleted file mode 100644
index 4cc2c5d7..00000000
--- a/subprojects/frontend/build.gradle
+++ /dev/null
@@ -1,131 +0,0 @@
1plugins {
2 id 'refinery-frontend-workspace'
3 id 'refinery-sonarqube'
4}
5
6import org.siouan.frontendgradleplugin.infrastructure.gradle.RunYarn
7
8def viteOutputDir = "${buildDir}/vite"
9def productionResources = file("${viteOutputDir}/production")
10
11frontend {
12 assembleScript = 'run build'
13}
14
15configurations {
16 productionAssets {
17 canBeConsumed = true
18 canBeResolved = false
19 }
20}
21
22def installFrontend = tasks.named('installFrontend')
23
24def sourcesWithoutTypegen = fileTree('src') {
25 exclude '**/*.typegen.ts'
26}
27
28def assembleFrontend = tasks.named('assembleFrontend')
29assembleFrontend.configure {
30 dependsOn generateXStateTypes
31 inputs.dir 'public'
32 inputs.files sourcesWithoutTypegen
33 inputs.file 'index.html'
34 inputs.files('package.json', 'tsconfig.json', 'tsconfig.base.json', 'vite.config.ts')
35 inputs.file rootProject.file('yarn.lock')
36 outputs.dir productionResources
37}
38
39artifacts {
40 productionAssets(productionResources) {
41 builtBy assembleFrontend
42 }
43}
44
45def generateXStateTypes = tasks.register('generateXStateTypes', RunYarn) {
46 dependsOn installFrontend
47 inputs.files sourcesWithoutTypegen
48 inputs.file 'package.json'
49 inputs.file rootProject.file('yarn.lock')
50 outputs.dir 'src'
51 script = 'run typegen'
52 description = 'Generate TypeScript typings for XState state machines.'
53}
54
55def typecheckFrontend = tasks.register('typecheckFrontend', RunYarn) {
56 dependsOn installFrontend
57 dependsOn generateXStateTypes
58 inputs.dir 'src'
59 inputs.dir 'types'
60 inputs.files('package.json', 'tsconfig.json', 'tsconfig.base.json', 'tsconfig.node.json')
61 inputs.file rootProject.file('yarn.lock')
62 outputs.dir "${buildDir}/typescript"
63 script = 'run typecheck'
64 group = 'verification'
65 description = 'Check for TypeScript type errors.'
66}
67
68def lintFrontend = tasks.register('lintFrontend', RunYarn) {
69 dependsOn installFrontend
70 dependsOn generateXStateTypes
71 dependsOn typecheckFrontend
72 inputs.dir 'src'
73 inputs.dir 'types'
74 inputs.files('.eslintrc.cjs', 'prettier.config.cjs')
75 inputs.files('package.json', 'tsconfig.json', 'tsconfig.base.json', 'tsconfig.node.json')
76 inputs.file rootProject.file('yarn.lock')
77 if (project.hasProperty('ci')) {
78 outputs.file "${buildDir}/eslint.json"
79 script = 'run lint:ci'
80 } else {
81 script = 'run lint'
82 }
83 group = 'verification'
84 description = 'Check for TypeScript lint errors and warnings.'
85}
86
87def prettier = tasks.register('fixFrontend', RunYarn) {
88 dependsOn installFrontend
89 dependsOn generateXStateTypes
90 dependsOn typecheckFrontend
91 inputs.dir 'src'
92 inputs.dir 'types'
93 inputs.files('.eslintrc.cjs', 'prettier.config.cjs')
94 inputs.files('package.json', 'tsconfig.json', 'tsconfig.base.json', 'tsconfig.node.json')
95 inputs.file rootProject.file('yarn.lock')
96 script = 'run lint:fix'
97 group = 'verification'
98 description = 'Fix TypeScript lint errors and warnings.'
99}
100
101tasks.named('check') {
102 dependsOn(typecheckFrontend)
103 dependsOn(lintFrontend)
104}
105
106tasks.register('serveFrontend', RunYarn) {
107 dependsOn installFrontend
108 dependsOn generateXStateTypes
109 inputs.dir 'public'
110 inputs.files sourcesWithoutTypegen
111 inputs.file 'index.html'
112 inputs.files('package.json', 'tsconfig.json', 'tsconfig.base.json', 'vite.config.ts')
113 inputs.file rootProject.file('yarn.lock')
114 outputs.dir "${viteOutputDir}/development"
115 script = 'run serve'
116 group = 'run'
117 description = 'Start a Vite dev server with hot module replacement.'
118}
119
120tasks.named('clean') {
121 delete 'dev-dist'
122 delete fileTree('src') {
123 include '**/*.typegen.ts'
124 }
125}
126
127sonarqube.properties {
128 properties['sonar.sources'] = 'src'
129 property 'sonar.nodejs.executable', "${frontend.nodeInstallDirectory.get()}/bin/node"
130 property 'sonar.eslint.reportPaths', "${buildDir}/eslint.json"
131}
diff --git a/subprojects/frontend/build.gradle.kts b/subprojects/frontend/build.gradle.kts
new file mode 100644
index 00000000..4a51c74e
--- /dev/null
+++ b/subprojects/frontend/build.gradle.kts
@@ -0,0 +1,127 @@
1import org.siouan.frontendgradleplugin.infrastructure.gradle.RunYarn
2import tools.refinery.buildsrc.SonarPropertiesUtils
3
4plugins {
5 id("refinery-frontend-workspace")
6 id("refinery-sonarqube")
7}
8
9val viteOutputDir = "$buildDir/vite"
10val productionResources = file("$viteOutputDir/production")
11
12frontend {
13 assembleScript.set("run build")
14}
15
16val productionAssets: Configuration by configurations.creating {
17 isCanBeConsumed = true
18 isCanBeResolved = false
19}
20
21val sourcesWithoutTypeGen = fileTree("src") {
22 exclude("**/*.typegen.ts")
23}
24
25val generateXStateTypes by tasks.registering(RunYarn::class) {
26 dependsOn(tasks.installFrontend)
27 inputs.files(sourcesWithoutTypeGen)
28 inputs.file("package.json")
29 inputs.file(rootProject.file("yarn.lock"))
30 outputs.dir("src")
31 script.set("run typegen")
32 description = "Generate TypeScript typings for XState state machines."
33}
34
35tasks.assembleFrontend {
36 dependsOn(generateXStateTypes)
37 inputs.dir("public")
38 inputs.files(sourcesWithoutTypeGen)
39 inputs.file("index.html")
40 inputs.files("package.json", "tsconfig.json", "tsconfig.base.json", "vite.config.ts")
41 inputs.file(rootProject.file("yarn.lock"))
42 outputs.dir(productionResources)
43}
44
45artifacts {
46 add("productionAssets", productionResources) {
47 builtBy(tasks.assembleFrontend)
48 }
49}
50
51val typeCheckFrontend by tasks.registering(RunYarn::class) {
52 dependsOn(tasks.installFrontend)
53 dependsOn(generateXStateTypes)
54 inputs.dir("src")
55 inputs.dir("types")
56 inputs.files("package.json", "tsconfig.json", "tsconfig.base.json", "tsconfig.node.json")
57 inputs.file(rootProject.file("yarn.lock"))
58 outputs.dir("$buildDir/typescript")
59 script.set("run typecheck")
60 group = "verification"
61 description = "Check for TypeScript type errors."
62}
63
64val lintFrontend by tasks.registering(RunYarn::class) {
65 dependsOn(tasks.installFrontend)
66 dependsOn(generateXStateTypes)
67 dependsOn(typeCheckFrontend)
68 inputs.dir("src")
69 inputs.dir("types")
70 inputs.files(".eslintrc.cjs", "prettier.config.cjs")
71 inputs.files("package.json", "tsconfig.json", "tsconfig.base.json", "tsconfig.node.json")
72 inputs.file(rootProject.file("yarn.lock"))
73 if (project.hasProperty("ci")) {
74 outputs.file("$buildDir/eslint.json")
75 script.set("run lint:ci")
76 } else {
77 script.set("run lint")
78 }
79 group = "verification"
80 description = "Check for TypeScript lint errors and warnings."
81}
82
83val fixFrontend by tasks.registering(RunYarn::class) {
84 dependsOn(tasks.installFrontend)
85 dependsOn(generateXStateTypes)
86 dependsOn(typeCheckFrontend)
87 inputs.dir("src")
88 inputs.dir("types")
89 inputs.files(".eslintrc.cjs", "prettier.config.cjs")
90 inputs.files("package.json", "tsconfig.json", "tsconfig.base.json", "tsconfig.node.json")
91 inputs.file(rootProject.file("yarn.lock"))
92 script.set("run lint:fix")
93 group = "verification"
94 description = "Fix TypeScript lint errors and warnings."
95}
96
97tasks.check {
98 dependsOn(typeCheckFrontend)
99 dependsOn(lintFrontend)
100}
101
102tasks.register("serveFrontend", RunYarn::class) {
103 dependsOn(tasks.installFrontend)
104 dependsOn(generateXStateTypes)
105 inputs.dir("public")
106 inputs.files(sourcesWithoutTypeGen)
107 inputs.file("index.html")
108 inputs.files("package.json", "tsconfig.json", "tsconfig.base.json", "vite.config.ts")
109 inputs.file(rootProject.file("yarn.lock"))
110 outputs.dir("$viteOutputDir/development")
111 script.set("run serve")
112 group = "run"
113 description = "Start a Vite dev server with hot module replacement."
114}
115
116tasks.clean {
117 delete("dev-dist")
118 delete(fileTree("src") {
119 include("**/*.typegen.ts")
120 })
121}
122
123sonarqube.properties {
124 SonarPropertiesUtils.addToList(properties, "sonar.sources", "src")
125 property("sonar.nodejs.executable", "${frontend.nodeInstallDirectory.get()}/bin/node")
126 property("sonar.eslint.reportPaths", "$buildDir/eslint.json")
127}
diff --git a/subprojects/language-ide/build.gradle b/subprojects/language-ide/build.gradle
deleted file mode 100644
index 3786762b..00000000
--- a/subprojects/language-ide/build.gradle
+++ /dev/null
@@ -1,18 +0,0 @@
1plugins {
2 id 'refinery-java-library'
3 id 'refinery-xtext-conventions'
4}
5
6dependencies {
7 api project(':refinery-language')
8 api libs.xtext.ide
9 api libs.xtext.xbase.ide
10}
11
12def generateXtextLanguage = project(':refinery-language').tasks.named('generateXtextLanguage')
13
14for (taskName in ['compileJava', 'processResources']) {
15 tasks.named(taskName) {
16 dependsOn generateXtextLanguage
17 }
18}
diff --git a/subprojects/language-ide/build.gradle.kts b/subprojects/language-ide/build.gradle.kts
new file mode 100644
index 00000000..b2e6d4c1
--- /dev/null
+++ b/subprojects/language-ide/build.gradle.kts
@@ -0,0 +1,18 @@
1plugins {
2 id("refinery-java-library")
3 id("refinery-xtext-conventions")
4}
5
6dependencies {
7 api(project(":refinery-language"))
8 api(libs.xtext.ide)
9 api(libs.xtext.xbase.ide)
10}
11
12val generateXtextLanguage = project(":refinery-language").tasks.named("generateXtextLanguage")
13
14for (taskName in listOf("compileJava", "processResources")) {
15 tasks.named(taskName) {
16 dependsOn(generateXtextLanguage)
17 }
18}
diff --git a/subprojects/language-model/build.gradle b/subprojects/language-model/build.gradle
deleted file mode 100644
index 275db188..00000000
--- a/subprojects/language-model/build.gradle
+++ /dev/null
@@ -1,55 +0,0 @@
1plugins {
2 id 'refinery-java-library'
3 id 'refinery-mwe2'
4 id 'refinery-sonarqube'
5}
6
7dependencies {
8 api libs.ecore
9 api libs.ecore.xmi
10 mwe2 libs.ecore.codegen
11 mwe2 libs.mwe.utils
12 mwe2 libs.mwe2.lib
13 mwe2 libs.xtext.core
14 mwe2 libs.xtext.xbase
15}
16
17sourceSets {
18 main {
19 java.srcDirs += ['src/main/emf-gen']
20 }
21}
22
23def generateEPackage = tasks.register('generateEPackage', JavaExec) {
24 mainClass = 'org.eclipse.emf.mwe2.launch.runtime.Mwe2Launcher'
25 classpath = configurations.mwe2
26 inputs.file 'src/main/java/tools/refinery/language/model/GenerateProblemModel.mwe2'
27 inputs.file 'src/main/resources/model/problem.ecore'
28 inputs.file 'src/main/resources/model/problem.genmodel'
29 outputs.dir 'src/main/emf-gen'
30 args += 'src/main/java/tools/refinery/language/model/GenerateProblemModel.mwe2'
31 args += '-p'
32 args += "rootPath=/${projectDir}"
33}
34
35for (taskName in ['compileJava', 'processResources', 'generateEclipseSourceFolders']) {
36 tasks.named(taskName) {
37 dependsOn generateEPackage
38 }
39}
40
41tasks.named('clean') {
42 delete 'src/main/emf-gen'
43}
44
45sonarqube.properties {
46 properties['sonar.exclusions'] += [
47 'src/main/emf-gen/**',
48 ]
49}
50
51eclipse.project.natures += [
52 'org.eclipse.sirius.nature.modelingproject',
53 'org.eclipse.pde.PluginNature',
54 'org.eclipse.xtext.ui.shared.xtextNature'
55]
diff --git a/subprojects/language-model/build.gradle.kts b/subprojects/language-model/build.gradle.kts
new file mode 100644
index 00000000..2804c698
--- /dev/null
+++ b/subprojects/language-model/build.gradle.kts
@@ -0,0 +1,53 @@
1import tools.refinery.buildsrc.SonarPropertiesUtils
2
3plugins {
4 id("refinery-java-library")
5 id("refinery-mwe2")
6 id("refinery-sonarqube")
7}
8
9dependencies {
10 api(libs.ecore)
11 api(libs.ecore.xmi)
12 mwe2(libs.ecore.codegen)
13 mwe2(libs.mwe.utils)
14 mwe2(libs.mwe2.lib)
15 mwe2(libs.xtext.core)
16 mwe2(libs.xtext.xbase)
17}
18
19sourceSets {
20 main {
21 java.srcDir("src/main/emf-gen")
22 }
23}
24
25val generateEPackage by tasks.registering(JavaExec::class) {
26 mainClass.set("org.eclipse.emf.mwe2.launch.runtime.Mwe2Launcher")
27 classpath(configurations.mwe2)
28 inputs.file("src/main/java/tools/refinery/language/model/GenerateProblemModel.mwe2")
29 inputs.file("src/main/resources/model/problem.ecore")
30 inputs.file("src/main/resources/model/problem.genmodel")
31 outputs.dir("src/main/emf-gen")
32 args("src/main/java/tools/refinery/language/model/GenerateProblemModel.mwe2", "-p", "rootPath=/$projectDir")
33}
34
35for (taskName in listOf("compileJava", "processResources", "generateEclipseSourceFolders")) {
36 tasks.named(taskName) {
37 dependsOn(generateEPackage)
38 }
39}
40
41tasks.clean {
42 delete("src/main/emf-gen")
43}
44
45sonarqube.properties {
46 SonarPropertiesUtils.addToList(properties, "sonar.exclusions", "src/main/emf-gen/**")
47}
48
49eclipse.project.natures.plusAssign(listOf(
50 "org.eclipse.sirius.nature.modelingproject",
51 "org.eclipse.pde.PluginNature",
52 "org.eclipse.xtext.ui.shared.xtextNature",
53))
diff --git a/subprojects/language-semantics/build.gradle b/subprojects/language-semantics/build.gradle
deleted file mode 100644
index 4f43ad24..00000000
--- a/subprojects/language-semantics/build.gradle
+++ /dev/null
@@ -1,11 +0,0 @@
1plugins {
2 id 'refinery-java-library'
3}
4
5dependencies {
6 implementation libs.eclipseCollections
7 implementation libs.eclipseCollections.api
8 api project(':refinery-language')
9 api project(':refinery-store')
10 testImplementation testFixtures(project(':refinery-language'))
11}
diff --git a/subprojects/language-semantics/build.gradle.kts b/subprojects/language-semantics/build.gradle.kts
new file mode 100644
index 00000000..e13e5e4a
--- /dev/null
+++ b/subprojects/language-semantics/build.gradle.kts
@@ -0,0 +1,11 @@
1plugins {
2 id("refinery-java-library")
3}
4
5dependencies {
6 implementation(libs.eclipseCollections)
7 implementation(libs.eclipseCollections.api)
8 api(project(":refinery-language"))
9 api(project(":refinery-store"))
10 testImplementation(testFixtures(project(":refinery-language")))
11}
diff --git a/subprojects/language-web/build.gradle b/subprojects/language-web/build.gradle
deleted file mode 100644
index 8d277a5b..00000000
--- a/subprojects/language-web/build.gradle
+++ /dev/null
@@ -1,87 +0,0 @@
1plugins {
2 id 'refinery-java-application'
3 id 'refinery-xtext-conventions'
4}
5
6configurations {
7 webapp {
8 canBeConsumed = false
9 canBeResolved = true
10 }
11
12 all {
13 // Use log4j-over-slf4j instead of log4j 1.x
14 exclude group: 'log4j', module: 'log4j'
15 }
16}
17
18dependencies {
19 implementation project(':refinery-language')
20 implementation project(':refinery-language-ide')
21 implementation libs.jetty.server
22 implementation libs.jetty.servlet
23 implementation libs.jetty.websocket.server
24 implementation libs.slf4j.api
25 implementation libs.slf4j.simple
26 implementation libs.slf4j.log4j
27 implementation libs.xtext.web
28 webapp project(path: ':refinery-frontend', configuration: 'productionAssets')
29 testImplementation testFixtures(project(':refinery-language'))
30 testImplementation libs.jetty.websocket.client
31}
32
33def generateXtextLanguage = project(':refinery-language').tasks.named('generateXtextLanguage')
34
35for (taskName in ['compileJava', 'processResources']) {
36 tasks.named(taskName) {
37 dependsOn generateXtextLanguage
38 }
39}
40
41mainClassName = 'tools.refinery.language.web.ServerLauncher'
42
43// Enable JDK 19 preview features for virtual thread support.
44application {
45 applicationDefaultJvmArgs += '--enable-preview'
46}
47tasks.withType(JavaCompile) {
48 options.release = 19
49 options.compilerArgs += '--enable-preview'
50}
51tasks.withType(Test) {
52 jvmArgs += '--enable-preview'
53}
54
55tasks.named('jar') {
56 dependsOn project.configurations.webapp
57 from(project.configurations.webapp) {
58 into 'webapp'
59 }
60}
61
62tasks.named('shadowJar') {
63 dependsOn project.configurations.webapp
64 from(project.sourceSets.main.output)
65 configurations = [project.configurations.runtimeClasspath]
66 exclude('META-INF/INDEX.LIST', 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA','schema/*',
67 '.options', '.api_description', '*.profile', 'about.*', 'about_*.html', 'about_files/*',
68 'plugin.xml', 'systembundle.properties', 'profile.list', 'META-INF/resources/xtext/**')
69 append('plugin.properties')
70 from(project.configurations.webapp) {
71 into 'webapp'
72 }
73}
74
75tasks.register('serveBackend', JavaExec) {
76 dependsOn project.configurations.webapp
77 dependsOn sourceSets.main.runtimeClasspath
78 classpath = sourceSets.main.runtimeClasspath
79 mainClass = mainClassName
80 // Enable JDK 19 preview features for virtual thread support.
81 jvmArgs += '--enable-preview'
82 standardInput = System.in
83 def baseResource = project.configurations.webapp.incoming.artifacts.artifactFiles.first()
84 environment BASE_RESOURCE: baseResource
85 group = 'run'
86 description = 'Start a Jetty web server serving the Xtex API and assets.'
87}
diff --git a/subprojects/language-web/build.gradle.kts b/subprojects/language-web/build.gradle.kts
new file mode 100644
index 00000000..c68daa9a
--- /dev/null
+++ b/subprojects/language-web/build.gradle.kts
@@ -0,0 +1,91 @@
1plugins {
2 id("refinery-java-application")
3 id("refinery-xtext-conventions")
4}
5
6val webapp: Configuration by configurations.creating {
7 isCanBeConsumed = false
8 isCanBeResolved = true
9}
10
11configurations.all {
12 // Use log4j-over-slf4j instead of log4j 1.x
13 exclude(group = "log4j", module = "log4j")
14}
15
16dependencies {
17 implementation(project(":refinery-language"))
18 implementation(project(":refinery-language-ide"))
19 implementation(libs.jetty.server)
20 implementation(libs.jetty.servlet)
21 implementation(libs.jetty.websocket.server)
22 implementation(libs.slf4j.api)
23 implementation(libs.slf4j.simple)
24 implementation(libs.slf4j.log4j)
25 implementation(libs.xtext.web)
26 webapp(project(path = ":refinery-frontend", configuration = "productionAssets"))
27 testImplementation(testFixtures(project(":refinery-language")))
28 testImplementation(libs.jetty.websocket.client)
29}
30
31val generateXtextLanguage = project(":refinery-language").tasks.named("generateXtextLanguage")
32
33for (taskName in listOf("compileJava", "processResources")) {
34 tasks.named(taskName) {
35 dependsOn(generateXtextLanguage)
36 }
37}
38
39application {
40 mainClass.set("tools.refinery.language.web.ServerLauncher")
41 // Enable JDK 19 preview features for virtual thread support.
42 applicationDefaultJvmArgs += "--enable-preview"
43}
44
45tasks.withType(JavaCompile::class) {
46 options.release.set(19)
47 // Enable JDK 19 preview features for virtual thread support.
48 options.compilerArgs.plusAssign("--enable-preview")
49}
50
51// Enable JDK 19 preview features for virtual thread support.
52fun enablePreview(task: JavaForkOptions) {
53 task.jvmArgs("--enable-preview")
54}
55
56tasks.withType(Test::class) {
57 enablePreview(this)
58}
59
60tasks.jar {
61 dependsOn(webapp)
62 from(webapp) {
63 into("webapp")
64 }
65}
66
67tasks.shadowJar {
68 dependsOn(webapp)
69 from(project.sourceSets.main.map { it.output })
70 exclude("META-INF/INDEX.LIST", "META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA","schema/*",
71 ".options", ".api_description", "*.profile", "about.*", "about_*.html", "about_files/*",
72 "plugin.xml", "systembundle.properties", "profile.list", "META-INF/resources/xtext/**")
73 append("plugin.properties")
74 from(webapp) {
75 into("webapp")
76 }
77}
78
79tasks.register("serveBackend", JavaExec::class) {
80 dependsOn(webapp)
81 val mainRuntimeClasspath = sourceSets.main.map { it.runtimeClasspath }
82 dependsOn(mainRuntimeClasspath)
83 classpath(mainRuntimeClasspath)
84 mainClass.set(application.mainClass)
85 enablePreview(this)
86 standardInput = System.`in`
87 val baseResource = webapp.incoming.artifacts.artifactFiles.first()
88 environment("BASE_RESOURCE", baseResource)
89 group = "run"
90 description = "Start a Jetty web server serving the Xtex API and assets."
91}
diff --git a/subprojects/language/build.gradle b/subprojects/language/build.gradle
deleted file mode 100644
index 654558e3..00000000
--- a/subprojects/language/build.gradle
+++ /dev/null
@@ -1,73 +0,0 @@
1plugins {
2 id 'refinery-java-library'
3 id 'refinery-java-test-fixtures'
4 id 'refinery-mwe2'
5 id 'refinery-sonarqube'
6 id 'refinery-xtext-conventions'
7}
8
9dependencies {
10 api platform(libs.xtext.bom)
11 api libs.ecore
12 api libs.xtext.core
13 api libs.xtext.xbase
14 api project(':refinery-language-model')
15 testFixturesApi libs.xtext.testing
16 mwe2 libs.xtext.generator
17 mwe2 libs.xtext.generator.antlr
18}
19
20sourceSets {
21 testFixtures {
22 java.srcDirs += ['src/testFixtures/xtext-gen']
23 resources.srcDirs += ['src/testFixtures/xtext-gen']
24 }
25}
26
27tasks.named('jar') {
28 from(sourceSets.main.allSource) {
29 include '**/*.xtext'
30 }
31}
32
33def generateXtextLanguage = tasks.register('generateXtextLanguage', JavaExec) {
34 mainClass = 'org.eclipse.emf.mwe2.launch.runtime.Mwe2Launcher'
35 classpath = configurations.mwe2
36 inputs.file 'src/main/java/tools/refinery/language/GenerateProblem.mwe2'
37 inputs.file 'src/main/java/tools/refinery/language/Problem.xtext'
38 outputs.dir 'src/main/xtext-gen'
39 outputs.dir 'src/testFixtures/xtext-gen'
40 outputs.dir '../language-ide/src/main/xtext-gen'
41 outputs.dir '../language-web/src/main/xtext-gen'
42 args += 'src/main/java/tools/refinery/language/GenerateProblem.mwe2'
43 args += '-p'
44 args += "rootPath=/${projectDir}/.."
45}
46
47for (taskName in [
48 'compileJava',
49 'processResources',
50 'processTestFixturesResources',
51 'generateEclipseSourceFolders'
52 ]) {
53 tasks.named(taskName) {
54 dependsOn generateXtextLanguage
55 }
56}
57
58tasks.named('clean') {
59 delete 'src/main/xtext-gen'
60 delete 'src/testFixtures/xtext-gen'
61 delete '../language-ide/src/main/xtext-gen'
62 delete '../language-web/src/main/xtext-gen'
63}
64
65sonarqube.properties {
66 properties['sonar.exclusions'] += [
67 'src/testFixtures/xtext-gen/**',
68 ]
69}
70
71eclipse.project.natures += [
72 'org.eclipse.xtext.ui.shared.xtextNature'
73]
diff --git a/subprojects/language/build.gradle.kts b/subprojects/language/build.gradle.kts
new file mode 100644
index 00000000..ed4f95a5
--- /dev/null
+++ b/subprojects/language/build.gradle.kts
@@ -0,0 +1,65 @@
1import tools.refinery.buildsrc.SonarPropertiesUtils
2
3plugins {
4 id("refinery-java-library")
5 id("refinery-java-test-fixtures")
6 id("refinery-sonarqube")
7 id("refinery-mwe2")
8 id("refinery-xtext-conventions")
9}
10
11dependencies {
12 api(platform(libs.xtext.bom))
13 api(libs.ecore)
14 api(libs.xtext.core)
15 api(libs.xtext.xbase)
16 api(project(":refinery-language-model"))
17 testFixturesApi(libs.xtext.testing)
18 mwe2(libs.xtext.generator)
19 mwe2(libs.xtext.generator.antlr)
20}
21
22sourceSets {
23 testFixtures {
24 java.srcDir("src/testFixtures/xtext-gen")
25 resources.srcDir("src/testFixtures/xtext-gen")
26 }
27}
28
29tasks.jar {
30 from(sourceSets.main.map { it.allSource }) {
31 include("**/*.xtext")
32 }
33}
34
35val generateXtextLanguage by tasks.registering(JavaExec::class) {
36 mainClass.set("org.eclipse.emf.mwe2.launch.runtime.Mwe2Launcher")
37 classpath(configurations.mwe2)
38 inputs.file("src/main/java/tools/refinery/language/GenerateProblem.mwe2")
39 inputs.file("src/main/java/tools/refinery/language/Problem.xtext")
40 outputs.dir("src/main/xtext-gen")
41 outputs.dir("src/testFixtures/xtext-gen")
42 outputs.dir("../language-ide/src/main/xtext-gen")
43 outputs.dir("../language-web/src/main/xtext-gen")
44 args("src/main/java/tools/refinery/language/GenerateProblem.mwe2", "-p", "rootPath=/$projectDir/..")
45}
46
47for (taskName in listOf("compileJava", "processResources", "processTestFixturesResources",
48 "generateEclipseSourceFolders")) {
49 tasks.named(taskName) {
50 dependsOn(generateXtextLanguage)
51 }
52}
53
54tasks.clean {
55 delete("src/main/xtext-gen")
56 delete("src/testFixtures/xtext-gen")
57 delete("../language-ide/src/main/xtext-gen")
58 delete("../language-web/src/main/xtext-gen")
59}
60
61sonarqube.properties {
62 SonarPropertiesUtils.addToList(properties, "sonar.exclusions", "src/textFixtures/xtext-gen/**")
63}
64
65eclipse.project.natures.plusAssign("org.eclipse.xtext.ui.shared.xtextNature")
diff --git a/subprojects/store-query-viatra/build.gradle b/subprojects/store-query-viatra/build.gradle
deleted file mode 100644
index 13a7544f..00000000
--- a/subprojects/store-query-viatra/build.gradle
+++ /dev/null
@@ -1,16 +0,0 @@
1plugins {
2 id 'refinery-java-library'
3}
4
5configurations.testRuntimeClasspath {
6 // VIATRA requires log4j 1.x, but we use log4j-over-slf4j instead
7 exclude group: 'log4j', module: 'log4j'
8}
9
10dependencies {
11 implementation libs.ecore
12 api libs.viatra
13 api project(':refinery-store-query')
14 testImplementation libs.slf4j.simple
15 testImplementation libs.slf4j.log4j
16}
diff --git a/subprojects/store-query-viatra/build.gradle.kts b/subprojects/store-query-viatra/build.gradle.kts
new file mode 100644
index 00000000..d7a37f11
--- /dev/null
+++ b/subprojects/store-query-viatra/build.gradle.kts
@@ -0,0 +1,16 @@
1plugins {
2 id("refinery-java-library")
3}
4
5configurations.testRuntimeClasspath {
6 // VIATRA requires log4j 1.x, but we use log4j-over-slf4j instead
7 exclude(group = "log4j", module = "log4j")
8}
9
10dependencies {
11 implementation(libs.ecore)
12 api(libs.viatra)
13 api(project(":refinery-store-query"))
14 testImplementation(libs.slf4j.simple)
15 testImplementation(libs.slf4j.log4j)
16}
diff --git a/subprojects/store-query/build.gradle b/subprojects/store-query/build.gradle
deleted file mode 100644
index 97761936..00000000
--- a/subprojects/store-query/build.gradle
+++ /dev/null
@@ -1,9 +0,0 @@
1plugins {
2 id 'refinery-java-library'
3 id 'refinery-java-test-fixtures'
4}
5
6dependencies {
7 api project(':refinery-store')
8 testFixturesApi libs.hamcrest
9}
diff --git a/subprojects/store-query/build.gradle.kts b/subprojects/store-query/build.gradle.kts
new file mode 100644
index 00000000..16dbd95d
--- /dev/null
+++ b/subprojects/store-query/build.gradle.kts
@@ -0,0 +1,9 @@
1plugins {
2 id("refinery-java-library")
3 id("refinery-java-test-fixtures")
4}
5
6dependencies {
7 api(project(":refinery-store"))
8 testFixturesApi(libs.hamcrest)
9}
diff --git a/subprojects/store-reasoning/build.gradle b/subprojects/store-reasoning/build.gradle
deleted file mode 100644
index cb440d9f..00000000
--- a/subprojects/store-reasoning/build.gradle
+++ /dev/null
@@ -1,7 +0,0 @@
1plugins {
2 id 'refinery-java-library'
3}
4
5dependencies {
6 api project(':refinery-store-query')
7}
diff --git a/subprojects/store-reasoning/build.gradle.kts b/subprojects/store-reasoning/build.gradle.kts
new file mode 100644
index 00000000..fe15fc42
--- /dev/null
+++ b/subprojects/store-reasoning/build.gradle.kts
@@ -0,0 +1,7 @@
1plugins {
2 id("refinery-java-library")
3}
4
5dependencies {
6 api(project(":refinery-store-query"))
7}
diff --git a/subprojects/store/build.gradle b/subprojects/store/build.gradle
deleted file mode 100644
index 370d094b..00000000
--- a/subprojects/store/build.gradle
+++ /dev/null
@@ -1,4 +0,0 @@
1plugins {
2 id 'refinery-java-library'
3 id 'refinery-jmh'
4}
diff --git a/subprojects/store/build.gradle.kts b/subprojects/store/build.gradle.kts
new file mode 100644
index 00000000..5b4eac46
--- /dev/null
+++ b/subprojects/store/build.gradle.kts
@@ -0,0 +1,4 @@
1plugins {
2 id("refinery-java-library")
3 id("refinery-jmh")
4}