diff options
author | 2023-04-08 22:56:44 +0200 | |
---|---|---|
committer | 2023-04-08 22:58:21 +0200 | |
commit | 561fac70fd3dc3ebe1cfbc50146757495fb828d5 (patch) | |
tree | 20aa72bbe438aaa70c8de264ff0d366758e7772d /buildSrc/src/main/kotlin | |
parent | refactor: remove TupleLike (diff) | |
download | refinery-561fac70fd3dc3ebe1cfbc50146757495fb828d5.tar.gz refinery-561fac70fd3dc3ebe1cfbc50146757495fb828d5.tar.zst refinery-561fac70fd3dc3ebe1cfbc50146757495fb828d5.zip |
build: convert Gradle scripts to Kotlin
Improves IDE support build scripts in IntelliJ.
There is no Eclipse IDE support, but Eclipse didn't have support for Groovy
either, so there is no degradation of functionality.
Diffstat (limited to 'buildSrc/src/main/kotlin')
12 files changed, 413 insertions, 0 deletions
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 @@ | |||
1 | import org.gradle.plugins.ide.eclipse.model.EclipseModel | ||
2 | import java.util.* | ||
3 | |||
4 | plugins { | ||
5 | eclipse | ||
6 | } | ||
7 | |||
8 | // Workaround from https://github.com/gradle/gradle/issues/898#issuecomment-885765821 | ||
9 | val 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 | |||
26 | tasks.named("eclipse") { | ||
27 | dependsOn(eclipseResourceEncoding) | ||
28 | } | ||
29 | |||
30 | the<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 @@ | |||
1 | import org.siouan.frontendgradleplugin.infrastructure.gradle.EnableYarnBerryTask | ||
2 | import org.siouan.frontendgradleplugin.infrastructure.gradle.FrontendExtension | ||
3 | |||
4 | plugins { | ||
5 | id("org.siouan.frontend-jdk11") | ||
6 | } | ||
7 | |||
8 | configure<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 | |||
15 | tasks.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 @@ | |||
1 | import org.siouan.frontendgradleplugin.infrastructure.gradle.* | ||
2 | |||
3 | plugins { | ||
4 | id("refinery-eclipse") | ||
5 | id("refinery-frontend-conventions") | ||
6 | } | ||
7 | |||
8 | tasks.named<NodeInstallTask>("installNode") { | ||
9 | dependsOn(rootProject.tasks.named("installNode")) | ||
10 | enabled = false | ||
11 | } | ||
12 | |||
13 | tasks.named<YarnGlobalInstallTask>("installYarnGlobally") { | ||
14 | dependsOn(rootProject.tasks.named("installYarnGlobally")) | ||
15 | enabled = false | ||
16 | } | ||
17 | |||
18 | tasks.named<InstallYarnTask>("installYarn") { | ||
19 | dependsOn(rootProject.tasks.named("installYarn")) | ||
20 | enabled = false | ||
21 | } | ||
22 | |||
23 | val rootInstallFrontend = rootProject.tasks.named("installFrontend") | ||
24 | |||
25 | rootInstallFrontend.configure { | ||
26 | inputs.file("$projectDir/package.json") | ||
27 | } | ||
28 | |||
29 | tasks.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 @@ | |||
1 | import org.siouan.frontendgradleplugin.infrastructure.gradle.* | ||
2 | import java.io.FileInputStream | ||
3 | import java.io.FileNotFoundException | ||
4 | import java.io.FileOutputStream | ||
5 | import java.util.* | ||
6 | |||
7 | plugins { | ||
8 | id("refinery-frontend-conventions") | ||
9 | } | ||
10 | |||
11 | val frontend = the<FrontendExtension>() | ||
12 | |||
13 | val yarn1Version = providers.gradleProperty("frontend.yarn1Version") | ||
14 | |||
15 | frontend.yarnGlobalInstallScript.set(yarn1Version.map { version -> "install -g yarn@$version" }) | ||
16 | frontend.yarnInstallScript.set(frontend.yarnVersion.map { version -> "set version $version --only-if-needed" }) | ||
17 | frontend.installScript.set(provider { | ||
18 | if (project.hasProperty("ci")) "install --immutable --inline-builds" else "install" | ||
19 | }) | ||
20 | |||
21 | val frontendPropertiesFile = frontend.nodeInstallDirectory.map { dir -> "$dir/frontend.properties" } | ||
22 | |||
23 | fun 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 | |||
35 | fun getFrontendProperty(propertyName: String): String? { | ||
36 | val props = readFrontendProperties() | ||
37 | return props[propertyName]?.toString() | ||
38 | } | ||
39 | |||
40 | fun 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 | |||
48 | tasks.named<NodeInstallTask>("installNode") { | ||
49 | onlyIf { | ||
50 | getFrontendProperty("installedNodeVersion") != frontend.nodeVersion.get() | ||
51 | } | ||
52 | doLast { | ||
53 | putFrontedProperty("installedNodeVersion", frontend.nodeVersion.get()) | ||
54 | } | ||
55 | } | ||
56 | |||
57 | tasks.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 | |||
67 | tasks.named<InstallYarnTask>("installYarn") { | ||
68 | outputs.file(frontend.yarnVersion.map { version -> ".yarn/releases/yarn-$version.cjs" }) | ||
69 | } | ||
70 | |||
71 | tasks.named<InstallDependenciesTask>("installFrontend") { | ||
72 | inputs.files("package.json", "yarn.lock") | ||
73 | outputs.files(".pnp.cjs", ".pnp.loader.mjs") | ||
74 | } | ||
75 | |||
76 | tasks.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 @@ | |||
1 | plugins { | ||
2 | application | ||
3 | id("com.github.johnrengelman.shadow") | ||
4 | } | ||
5 | |||
6 | apply(plugin = "refinery-java-conventions") | ||
7 | |||
8 | for (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 @@ | |||
1 | import org.gradle.accessors.dm.LibrariesForLibs | ||
2 | import org.gradle.plugins.ide.eclipse.model.EclipseModel | ||
3 | import org.gradle.plugins.ide.eclipse.model.ProjectDependency | ||
4 | import tools.refinery.buildsrc.EclipseUtils | ||
5 | |||
6 | plugins { | ||
7 | jacoco | ||
8 | java | ||
9 | } | ||
10 | |||
11 | apply(plugin = "refinery-eclipse") | ||
12 | |||
13 | repositories { | ||
14 | mavenCentral() | ||
15 | maven { | ||
16 | url = uri("https://repo.eclipse.org/content/groups/releases/") | ||
17 | } | ||
18 | } | ||
19 | |||
20 | val libs = the<LibrariesForLibs>() | ||
21 | |||
22 | dependencies { | ||
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 | |||
33 | java.toolchain { | ||
34 | languageVersion.set(JavaLanguageVersion.of(19)) | ||
35 | } | ||
36 | |||
37 | tasks.withType(JavaCompile::class) { | ||
38 | options.release.set(17) | ||
39 | } | ||
40 | |||
41 | val test = tasks.named<Test>("test") | ||
42 | |||
43 | val jacocoTestReport = tasks.named<JacocoReport>("jacocoTestReport") | ||
44 | |||
45 | test.configure { | ||
46 | useJUnitPlatform { | ||
47 | excludeTags("slow") | ||
48 | } | ||
49 | finalizedBy(jacocoTestReport) | ||
50 | } | ||
51 | |||
52 | jacocoTestReport.configure { | ||
53 | dependsOn(test) | ||
54 | reports { | ||
55 | xml.required.set(true) | ||
56 | } | ||
57 | } | ||
58 | |||
59 | tasks.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 | |||
68 | val generateEclipseSourceFolders by tasks.registering | ||
69 | |||
70 | tasks.register("prepareEclipse") { | ||
71 | dependsOn(generateEclipseSourceFolders) | ||
72 | dependsOn(tasks.named("eclipseJdt")) | ||
73 | } | ||
74 | |||
75 | tasks.named("eclipseClasspath") { | ||
76 | dependsOn(generateEclipseSourceFolders) | ||
77 | } | ||
78 | |||
79 | configure<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 @@ | |||
1 | plugins { | ||
2 | `java-library` | ||
3 | } | ||
4 | |||
5 | apply(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 @@ | |||
1 | import org.gradle.plugins.ide.eclipse.model.AbstractClasspathEntry | ||
2 | import org.gradle.plugins.ide.eclipse.model.EclipseModel | ||
3 | import tools.refinery.buildsrc.EclipseUtils | ||
4 | |||
5 | plugins { | ||
6 | `java-test-fixtures` | ||
7 | } | ||
8 | |||
9 | apply(plugin = "refinery-java-conventions") | ||
10 | |||
11 | the<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 @@ | |||
1 | import org.gradle.accessors.dm.LibrariesForLibs | ||
2 | import org.gradle.plugins.ide.eclipse.model.EclipseModel | ||
3 | import org.sonarqube.gradle.SonarExtension | ||
4 | import tools.refinery.buildsrc.EclipseUtils | ||
5 | import tools.refinery.buildsrc.SonarPropertiesUtils | ||
6 | |||
7 | apply(plugin = "refinery-java-conventions") | ||
8 | apply(plugin = "refinery-sonarqube") | ||
9 | |||
10 | val sourceSets = the<SourceSetContainer>() | ||
11 | |||
12 | val main: SourceSet by sourceSets.getting | ||
13 | |||
14 | val test: SourceSet by sourceSets.getting | ||
15 | |||
16 | val 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 | |||
24 | val jmhImplementation: Configuration by configurations.getting { | ||
25 | extendsFrom(configurations["implementation"], configurations["testImplementation"]) | ||
26 | } | ||
27 | |||
28 | val jmhAnnotationProcessor: Configuration by configurations.getting | ||
29 | |||
30 | configurations["jmhRuntimeOnly"].extendsFrom(configurations["runtimeOnly"], configurations["testRuntimeOnly"]) | ||
31 | |||
32 | val libs = the<LibrariesForLibs>() | ||
33 | |||
34 | dependencies { | ||
35 | jmhImplementation(libs.jmh.core) | ||
36 | jmhAnnotationProcessor(libs.jmh.annprocess) | ||
37 | } | ||
38 | |||
39 | tasks.register("jmh", JavaExec::class) { | ||
40 | dependsOn(tasks.named("jmhClasses")) | ||
41 | mainClass.set("org.openjdk.jmh.Main") | ||
42 | classpath = jmh.runtimeClasspath | ||
43 | } | ||
44 | |||
45 | EclipseUtils.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 | |||
61 | the<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 @@ | |||
1 | import org.gradle.accessors.dm.LibrariesForLibs | ||
2 | import org.gradle.plugins.ide.eclipse.model.EclipseModel | ||
3 | |||
4 | apply(plugin = "refinery-java-conventions") | ||
5 | |||
6 | val mwe2: Configuration by configurations.creating { | ||
7 | isCanBeConsumed = false | ||
8 | isCanBeResolved = true | ||
9 | extendsFrom(configurations["implementation"]) | ||
10 | } | ||
11 | |||
12 | val libs = the<LibrariesForLibs>() | ||
13 | |||
14 | dependencies { | ||
15 | mwe2(libs.mwe2.launch) | ||
16 | } | ||
17 | |||
18 | the<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 @@ | |||
1 | plugins { | ||
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 @@ | |||
1 | import org.gradle.api.tasks.SourceSetContainer | ||
2 | import org.sonarqube.gradle.SonarExtension | ||
3 | import tools.refinery.buildsrc.SonarPropertiesUtils | ||
4 | |||
5 | apply(plugin = "refinery-java-conventions") | ||
6 | apply(plugin = "refinery-sonarqube") | ||
7 | |||
8 | val xtextGenPath = "src/main/xtext-gen" | ||
9 | |||
10 | the<SourceSetContainer>().named("main") { | ||
11 | java.srcDir(xtextGenPath) | ||
12 | resources.srcDir(xtextGenPath) | ||
13 | } | ||
14 | |||
15 | tasks.named<Delete>("clean") { | ||
16 | delete(xtextGenPath) | ||
17 | } | ||
18 | |||
19 | the<SonarExtension>().properties { | ||
20 | SonarPropertiesUtils.addToList(properties, "sonar.exclusions", "$xtextGenPath/**") | ||
21 | } | ||