diff options
Diffstat (limited to 'buildSrc/src/main/kotlin/tools/refinery')
12 files changed, 451 insertions, 0 deletions
diff --git a/buildSrc/src/main/kotlin/tools/refinery/gradle/eclipse.gradle.kts b/buildSrc/src/main/kotlin/tools/refinery/gradle/eclipse.gradle.kts new file mode 100644 index 00000000..25e7e573 --- /dev/null +++ b/buildSrc/src/main/kotlin/tools/refinery/gradle/eclipse.gradle.kts | |||
@@ -0,0 +1,38 @@ | |||
1 | package tools.refinery.gradle | ||
2 | |||
3 | import java.util.Properties | ||
4 | |||
5 | plugins { | ||
6 | eclipse | ||
7 | } | ||
8 | |||
9 | // Workaround from https://github.com/gradle/gradle/issues/898#issuecomment-885765821 | ||
10 | val eclipseResourceEncoding by tasks.registering { | ||
11 | val outputFile = file(".settings/org.eclipse.core.resources.prefs") | ||
12 | val encoding = providers.systemProperty("file.encoding") | ||
13 | |||
14 | inputs.property("file.encoding", encoding) | ||
15 | outputs.file(outputFile) | ||
16 | |||
17 | doLast { | ||
18 | val eclipseEncodingProperties = Properties(2) | ||
19 | eclipseEncodingProperties["eclipse.preferences.version"] = "1" | ||
20 | eclipseEncodingProperties["encoding/<project>"] = encoding.get() | ||
21 | outputFile.outputStream().use { outputStream -> | ||
22 | eclipseEncodingProperties.store(outputStream, "generated by $name") | ||
23 | } | ||
24 | } | ||
25 | } | ||
26 | |||
27 | tasks.eclipse { | ||
28 | dependsOn(eclipseResourceEncoding) | ||
29 | } | ||
30 | |||
31 | eclipse.synchronizationTasks(eclipseResourceEncoding) | ||
32 | |||
33 | tasks.register<Delete>("clobberEclipse") { | ||
34 | mustRunAfter(tasks.eclipse) | ||
35 | delete(".classpath") | ||
36 | delete(".project") | ||
37 | delete(".settings") | ||
38 | } | ||
diff --git a/buildSrc/src/main/kotlin/tools/refinery/gradle/frontend-workspace.gradle.kts b/buildSrc/src/main/kotlin/tools/refinery/gradle/frontend-workspace.gradle.kts new file mode 100644 index 00000000..174a2d65 --- /dev/null +++ b/buildSrc/src/main/kotlin/tools/refinery/gradle/frontend-workspace.gradle.kts | |||
@@ -0,0 +1,34 @@ | |||
1 | package tools.refinery.gradle | ||
2 | |||
3 | plugins { | ||
4 | id("tools.refinery.gradle.eclipse") | ||
5 | id("tools.refinery.gradle.internal.frontend-conventions") | ||
6 | } | ||
7 | |||
8 | tasks { | ||
9 | installNode { | ||
10 | dependsOn(rootProject.tasks.named("installNode")) | ||
11 | enabled = false | ||
12 | } | ||
13 | |||
14 | installYarnGlobally { | ||
15 | dependsOn(rootProject.tasks.named("installYarnGlobally")) | ||
16 | enabled = false | ||
17 | } | ||
18 | |||
19 | installYarn { | ||
20 | dependsOn(rootProject.tasks.named("installYarn")) | ||
21 | enabled = false | ||
22 | } | ||
23 | |||
24 | val rootInstallFrontend = rootProject.tasks.named("installFrontend") | ||
25 | |||
26 | rootInstallFrontend.configure { | ||
27 | inputs.file("$projectDir/package.json") | ||
28 | } | ||
29 | |||
30 | installFrontend { | ||
31 | dependsOn(rootInstallFrontend) | ||
32 | enabled = false | ||
33 | } | ||
34 | } | ||
diff --git a/buildSrc/src/main/kotlin/tools/refinery/gradle/frontend-worktree.gradle.kts b/buildSrc/src/main/kotlin/tools/refinery/gradle/frontend-worktree.gradle.kts new file mode 100644 index 00000000..3225a1b1 --- /dev/null +++ b/buildSrc/src/main/kotlin/tools/refinery/gradle/frontend-worktree.gradle.kts | |||
@@ -0,0 +1,87 @@ | |||
1 | package tools.refinery.gradle | ||
2 | |||
3 | import java.io.FileInputStream | ||
4 | import java.io.FileNotFoundException | ||
5 | import java.io.FileOutputStream | ||
6 | import java.util.Properties | ||
7 | |||
8 | plugins { | ||
9 | id("tools.refinery.gradle.internal.frontend-conventions") | ||
10 | } | ||
11 | |||
12 | val yarn1Version = providers.gradleProperty("frontend.yarn1Version") | ||
13 | |||
14 | frontend { | ||
15 | yarnGlobalInstallScript.set(yarn1Version.map { version -> "install -g yarn@$version" }) | ||
16 | yarnInstallScript.set(frontend.yarnVersion.map { version -> "set version $version --only-if-needed" }) | ||
17 | installScript.set(provider { | ||
18 | if (project.hasProperty("ci")) "install --immutable --inline-builds" else "install" | ||
19 | }) | ||
20 | } | ||
21 | |||
22 | val frontendPropertiesFile = frontend.nodeInstallDirectory.map { dir -> "$dir/frontend.properties" } | ||
23 | |||
24 | fun readFrontendProperties(): Properties { | ||
25 | val props = Properties() | ||
26 | try { | ||
27 | FileInputStream(frontendPropertiesFile.get()).use { inputStream -> | ||
28 | props.load(inputStream) | ||
29 | } | ||
30 | } catch (ignored: FileNotFoundException) { | ||
31 | // Ignore missing file. | ||
32 | } | ||
33 | return props | ||
34 | } | ||
35 | |||
36 | fun getFrontendProperty(propertyName: String): String? { | ||
37 | val props = readFrontendProperties() | ||
38 | return props[propertyName]?.toString() | ||
39 | } | ||
40 | |||
41 | fun putFrontedProperty(propertyName: String, propertyValue: String) { | ||
42 | val props = readFrontendProperties() | ||
43 | props[propertyName] = propertyValue | ||
44 | FileOutputStream(frontendPropertiesFile.get()).use { outputStream -> | ||
45 | props.store(outputStream, "generated by refinery-frontend-worktree") | ||
46 | } | ||
47 | } | ||
48 | |||
49 | tasks { | ||
50 | installNode { | ||
51 | onlyIf { | ||
52 | getFrontendProperty("installedNodeVersion") != frontend.nodeVersion.get() | ||
53 | } | ||
54 | doLast { | ||
55 | putFrontedProperty("installedNodeVersion", frontend.nodeVersion.get()) | ||
56 | } | ||
57 | } | ||
58 | |||
59 | installYarnGlobally { | ||
60 | onlyIf { | ||
61 | getFrontendProperty("installedYarn1Version") != yarn1Version.get() | ||
62 | } | ||
63 | doLast { | ||
64 | putFrontedProperty("installedYarn1Version", yarn1Version.get()) | ||
65 | } | ||
66 | outputs.dir(frontend.nodeInstallDirectory.map { dir -> "$dir/lib/node_modules/yarn" }) | ||
67 | } | ||
68 | |||
69 | installYarn { | ||
70 | outputs.file(frontend.yarnVersion.map { version -> ".yarn/releases/yarn-$version.cjs" }) | ||
71 | } | ||
72 | |||
73 | installFrontend { | ||
74 | inputs.files("package.json", "yarn.lock") | ||
75 | outputs.files(".pnp.cjs", ".pnp.loader.mjs") | ||
76 | } | ||
77 | |||
78 | register("clobberFrontend", Delete::class) { | ||
79 | delete(frontend.nodeInstallDirectory) | ||
80 | delete(".yarn/cache") | ||
81 | delete(".yarn/install-state.gz") | ||
82 | delete(".yarn/sdks") | ||
83 | delete(".yarn/unplugged") | ||
84 | delete(".pnp.cjs") | ||
85 | delete(".pnp.loader.mjs") | ||
86 | } | ||
87 | } | ||
diff --git a/buildSrc/src/main/kotlin/tools/refinery/gradle/internal/frontend-conventions.gradle.kts b/buildSrc/src/main/kotlin/tools/refinery/gradle/internal/frontend-conventions.gradle.kts new file mode 100644 index 00000000..b15de515 --- /dev/null +++ b/buildSrc/src/main/kotlin/tools/refinery/gradle/internal/frontend-conventions.gradle.kts | |||
@@ -0,0 +1,17 @@ | |||
1 | package tools.refinery.gradle.internal | ||
2 | |||
3 | plugins { | ||
4 | id("org.siouan.frontend-jdk11") | ||
5 | } | ||
6 | |||
7 | frontend { | ||
8 | nodeVersion.set(providers.gradleProperty("frontend.nodeVersion")) | ||
9 | nodeInstallDirectory.set(file("$rootDir/.node")) | ||
10 | yarnEnabled.set(true) | ||
11 | yarnVersion.set(providers.gradleProperty("frontend.yarnVersion")) | ||
12 | } | ||
13 | |||
14 | tasks.enableYarnBerry { | ||
15 | // There is no need to enable berry manually, because berry files are already committed to the repo. | ||
16 | enabled = false | ||
17 | } | ||
diff --git a/buildSrc/src/main/kotlin/tools/refinery/gradle/internal/java-conventions.gradle.kts b/buildSrc/src/main/kotlin/tools/refinery/gradle/internal/java-conventions.gradle.kts new file mode 100644 index 00000000..67bb5d88 --- /dev/null +++ b/buildSrc/src/main/kotlin/tools/refinery/gradle/internal/java-conventions.gradle.kts | |||
@@ -0,0 +1,101 @@ | |||
1 | package tools.refinery.gradle.internal | ||
2 | |||
3 | import org.gradle.accessors.dm.LibrariesForLibs | ||
4 | import org.gradle.plugins.ide.eclipse.model.ProjectDependency | ||
5 | import tools.refinery.gradle.utils.EclipseUtils | ||
6 | |||
7 | plugins { | ||
8 | jacoco | ||
9 | java | ||
10 | id("tools.refinery.gradle.eclipse") | ||
11 | } | ||
12 | |||
13 | repositories { | ||
14 | mavenCentral() | ||
15 | maven { | ||
16 | url = uri("https://repo.eclipse.org/content/groups/releases/") | ||
17 | } | ||
18 | } | ||
19 | |||
20 | // Use log4j-over-slf4j instead of log4j 1.x in the tests. | ||
21 | configurations.testRuntimeClasspath { | ||
22 | exclude(group = "log4j", module = "log4j") | ||
23 | } | ||
24 | |||
25 | val libs = the<LibrariesForLibs>() | ||
26 | |||
27 | dependencies { | ||
28 | compileOnly(libs.jetbrainsAnnotations) | ||
29 | testCompileOnly(libs.jetbrainsAnnotations) | ||
30 | testImplementation(libs.hamcrest) | ||
31 | testImplementation(libs.junit.api) | ||
32 | testRuntimeOnly(libs.junit.engine) | ||
33 | testImplementation(libs.junit.params) | ||
34 | testImplementation(libs.mockito.core) | ||
35 | testImplementation(libs.mockito.junit) | ||
36 | testImplementation(libs.slf4j.simple) | ||
37 | testImplementation(libs.slf4j.log4j) | ||
38 | } | ||
39 | |||
40 | java.toolchain { | ||
41 | languageVersion.set(JavaLanguageVersion.of(19)) | ||
42 | } | ||
43 | |||
44 | tasks { | ||
45 | withType(JavaCompile::class) { | ||
46 | options.release.set(17) | ||
47 | } | ||
48 | |||
49 | test { | ||
50 | useJUnitPlatform { | ||
51 | excludeTags("slow") | ||
52 | } | ||
53 | finalizedBy(tasks.jacocoTestReport) | ||
54 | } | ||
55 | |||
56 | jacocoTestReport { | ||
57 | dependsOn(tasks.test) | ||
58 | reports { | ||
59 | xml.required.set(true) | ||
60 | } | ||
61 | } | ||
62 | |||
63 | jar { | ||
64 | manifest { | ||
65 | attributes( | ||
66 | "Bundle-SymbolicName" to "${project.group}.${project.name}", | ||
67 | "Bundle-Version" to project.version | ||
68 | ) | ||
69 | } | ||
70 | } | ||
71 | |||
72 | val generateEclipseSourceFolders by tasks.registering | ||
73 | |||
74 | register("prepareEclipse") { | ||
75 | dependsOn(generateEclipseSourceFolders) | ||
76 | dependsOn(tasks.named("eclipseJdt")) | ||
77 | } | ||
78 | |||
79 | eclipseClasspath { | ||
80 | dependsOn(generateEclipseSourceFolders) | ||
81 | } | ||
82 | } | ||
83 | |||
84 | eclipse { | ||
85 | EclipseUtils.patchClasspathEntries(this) { entry -> | ||
86 | if (entry.path.endsWith("-gen")) { | ||
87 | entry.entryAttributes["ignore_optional_problems"] = true | ||
88 | } | ||
89 | // If a project has a main dependency on a project and a test dependency on the testFixtures of a project, | ||
90 | // it will be erroneously added as a test-only dependency to Eclipse. As a workaround, we add all project | ||
91 | // dependencies as main dependencies (we do not deliberately use test-only project dependencies). | ||
92 | if (entry is ProjectDependency) { | ||
93 | entry.entryAttributes.remove("test") | ||
94 | } | ||
95 | } | ||
96 | |||
97 | jdt.file.withProperties { | ||
98 | // Allow @SuppressWarnings to suppress SonarLint warnings | ||
99 | this["org.eclipse.jdt.core.compiler.problem.unhandledWarningToken"] = "ignore" | ||
100 | } | ||
101 | } | ||
diff --git a/buildSrc/src/main/kotlin/tools/refinery/gradle/java-application.gradle.kts b/buildSrc/src/main/kotlin/tools/refinery/gradle/java-application.gradle.kts new file mode 100644 index 00000000..269af11c --- /dev/null +++ b/buildSrc/src/main/kotlin/tools/refinery/gradle/java-application.gradle.kts | |||
@@ -0,0 +1,27 @@ | |||
1 | package tools.refinery.gradle | ||
2 | |||
3 | import org.gradle.accessors.dm.LibrariesForLibs | ||
4 | |||
5 | plugins { | ||
6 | application | ||
7 | id("com.github.johnrengelman.shadow") | ||
8 | id("tools.refinery.gradle.internal.java-conventions") | ||
9 | } | ||
10 | |||
11 | // Use log4j-over-slf4j instead of log4j 1.x when running the application. | ||
12 | configurations.runtimeClasspath { | ||
13 | exclude(group = "log4j", module = "log4j") | ||
14 | } | ||
15 | |||
16 | val libs = the<LibrariesForLibs>() | ||
17 | |||
18 | dependencies { | ||
19 | implementation(libs.slf4j.simple) | ||
20 | implementation(libs.slf4j.log4j) | ||
21 | } | ||
22 | |||
23 | for (taskName in listOf("distTar", "distZip", "shadowDistTar", "shadowDistZip")) { | ||
24 | tasks.named(taskName) { | ||
25 | enabled = false | ||
26 | } | ||
27 | } | ||
diff --git a/buildSrc/src/main/kotlin/tools/refinery/gradle/java-library.gradle.kts b/buildSrc/src/main/kotlin/tools/refinery/gradle/java-library.gradle.kts new file mode 100644 index 00000000..084f65ae --- /dev/null +++ b/buildSrc/src/main/kotlin/tools/refinery/gradle/java-library.gradle.kts | |||
@@ -0,0 +1,6 @@ | |||
1 | package tools.refinery.gradle | ||
2 | |||
3 | plugins { | ||
4 | `java-library` | ||
5 | id("tools.refinery.gradle.internal.java-conventions") | ||
6 | } | ||
diff --git a/buildSrc/src/main/kotlin/tools/refinery/gradle/java-test-fixtures.gradle.kts b/buildSrc/src/main/kotlin/tools/refinery/gradle/java-test-fixtures.gradle.kts new file mode 100644 index 00000000..7e599c3f --- /dev/null +++ b/buildSrc/src/main/kotlin/tools/refinery/gradle/java-test-fixtures.gradle.kts | |||
@@ -0,0 +1,31 @@ | |||
1 | package tools.refinery.gradle | ||
2 | |||
3 | import org.gradle.plugins.ide.eclipse.model.AbstractClasspathEntry | ||
4 | import tools.refinery.gradle.utils.EclipseUtils | ||
5 | |||
6 | plugins { | ||
7 | `java-test-fixtures` | ||
8 | id("tools.refinery.gradle.internal.java-conventions") | ||
9 | } | ||
10 | |||
11 | eclipse.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/tools/refinery/gradle/jmh.gradle.kts b/buildSrc/src/main/kotlin/tools/refinery/gradle/jmh.gradle.kts new file mode 100644 index 00000000..eda7d5c6 --- /dev/null +++ b/buildSrc/src/main/kotlin/tools/refinery/gradle/jmh.gradle.kts | |||
@@ -0,0 +1,61 @@ | |||
1 | package tools.refinery.gradle | ||
2 | |||
3 | import org.gradle.accessors.dm.LibrariesForLibs | ||
4 | import tools.refinery.gradle.utils.EclipseUtils | ||
5 | import tools.refinery.gradle.utils.SonarPropertiesUtils | ||
6 | |||
7 | plugins { | ||
8 | id("tools.refinery.gradle.internal.java-conventions") | ||
9 | id("tools.refinery.gradle.sonarqube") | ||
10 | } | ||
11 | |||
12 | val sourceSets = the<SourceSetContainer>() | ||
13 | |||
14 | val jmh: SourceSet by sourceSets.creating { | ||
15 | compileClasspath += sourceSets.main.get().output | ||
16 | runtimeClasspath += sourceSets.main.get().output | ||
17 | // Allow using test classes in benchmarks for now. | ||
18 | compileClasspath += sourceSets.test.get().output | ||
19 | runtimeClasspath += sourceSets.test.get().output | ||
20 | } | ||
21 | |||
22 | val jmhImplementation: Configuration by configurations.getting { | ||
23 | extendsFrom(configurations.implementation.get(), configurations.testImplementation.get()) | ||
24 | } | ||
25 | |||
26 | val jmhAnnotationProcessor: Configuration by configurations.getting | ||
27 | |||
28 | configurations["jmhRuntimeOnly"].extendsFrom(configurations.runtimeOnly.get(), configurations.testRuntimeOnly.get()) | ||
29 | |||
30 | val libs = the<LibrariesForLibs>() | ||
31 | |||
32 | dependencies { | ||
33 | jmhImplementation(libs.jmh.core) | ||
34 | jmhAnnotationProcessor(libs.jmh.annprocess) | ||
35 | } | ||
36 | |||
37 | tasks.register<JavaExec>("jmh") { | ||
38 | dependsOn(tasks.named("jmhClasses")) | ||
39 | mainClass.set("org.openjdk.jmh.Main") | ||
40 | classpath = jmh.runtimeClasspath | ||
41 | } | ||
42 | |||
43 | EclipseUtils.patchClasspathEntries(eclipse) { entry -> | ||
44 | // Workaround from https://github.com/gradle/gradle/issues/4802#issuecomment-407902081 | ||
45 | if (entry.entryAttributes["gradle_scope"] == "jmh") { | ||
46 | // Allow test helper classes to be used in benchmarks from Eclipse | ||
47 | // and do not expose JMH dependencies to the main source code. | ||
48 | entry.entryAttributes["test"] = true | ||
49 | } else { | ||
50 | EclipseUtils.patchGradleUsedByScope(entry) { usedBy -> | ||
51 | if (listOf("main", "test", "testFixtures").any { e -> usedBy.contains(e) }) { | ||
52 | // main and test sources are also used by jmh sources. | ||
53 | usedBy += "jmh" | ||
54 | } | ||
55 | } | ||
56 | } | ||
57 | } | ||
58 | |||
59 | sonarqube.properties { | ||
60 | SonarPropertiesUtils.addToList(properties, "sonar.tests", "src/jmh/java") | ||
61 | } | ||
diff --git a/buildSrc/src/main/kotlin/tools/refinery/gradle/mwe2.gradle.kts b/buildSrc/src/main/kotlin/tools/refinery/gradle/mwe2.gradle.kts new file mode 100644 index 00000000..8eeabf47 --- /dev/null +++ b/buildSrc/src/main/kotlin/tools/refinery/gradle/mwe2.gradle.kts | |||
@@ -0,0 +1,21 @@ | |||
1 | package tools.refinery.gradle | ||
2 | |||
3 | import org.gradle.accessors.dm.LibrariesForLibs | ||
4 | |||
5 | plugins { | ||
6 | id("tools.refinery.gradle.internal.java-conventions") | ||
7 | } | ||
8 | |||
9 | val mwe2: Configuration by configurations.creating { | ||
10 | isCanBeConsumed = false | ||
11 | isCanBeResolved = true | ||
12 | extendsFrom(configurations.implementation.get()) | ||
13 | } | ||
14 | |||
15 | val libs = the<LibrariesForLibs>() | ||
16 | |||
17 | dependencies { | ||
18 | mwe2(libs.mwe2.launch) | ||
19 | } | ||
20 | |||
21 | eclipse.classpath.plusConfigurations += mwe2 | ||
diff --git a/buildSrc/src/main/kotlin/tools/refinery/gradle/sonarqube.gradle.kts b/buildSrc/src/main/kotlin/tools/refinery/gradle/sonarqube.gradle.kts new file mode 100644 index 00000000..ebd9170a --- /dev/null +++ b/buildSrc/src/main/kotlin/tools/refinery/gradle/sonarqube.gradle.kts | |||
@@ -0,0 +1,5 @@ | |||
1 | package tools.refinery.gradle | ||
2 | |||
3 | plugins { | ||
4 | id("org.sonarqube") | ||
5 | } | ||
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 new file mode 100644 index 00000000..25aeb826 --- /dev/null +++ b/buildSrc/src/main/kotlin/tools/refinery/gradle/xtext-generated.gradle.kts | |||
@@ -0,0 +1,23 @@ | |||
1 | package tools.refinery.gradle | ||
2 | |||
3 | import tools.refinery.gradle.utils.SonarPropertiesUtils | ||
4 | |||
5 | plugins { | ||
6 | id("tools.refinery.gradle.internal.java-conventions") | ||
7 | id("tools.refinery.gradle.sonarqube") | ||
8 | } | ||
9 | |||
10 | val xtextGenPath = "src/main/xtext-gen" | ||
11 | |||
12 | sourceSets.main { | ||
13 | java.srcDir(xtextGenPath) | ||
14 | resources.srcDir(xtextGenPath) | ||
15 | } | ||
16 | |||
17 | tasks.clean { | ||
18 | delete(xtextGenPath) | ||
19 | } | ||
20 | |||
21 | sonarqube.properties { | ||
22 | SonarPropertiesUtils.addToList(properties, "sonar.exclusions", "$xtextGenPath/**") | ||
23 | } | ||