From d904e2150319439053d89c723733463c4810bde9 Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Sun, 9 Apr 2023 02:54:51 +0200 Subject: build: organize build scripts into packages Also take advantage of precompiled Kotlin scripts to write build scripts in a more straightforward manner through generated accessors. Might increase memory usage of Gradle. --- .../java/tools/refinery/buildsrc/EclipseUtils.java | 72 -------------- .../refinery/buildsrc/SonarPropertiesUtils.java | 44 --------- .../tools/refinery/gradle/utils/EclipseUtils.java | 72 ++++++++++++++ .../gradle/utils/SonarPropertiesUtils.java | 44 +++++++++ .../src/main/kotlin/refinery-eclipse.gradle.kts | 37 -------- .../refinery-frontend-conventions.gradle.kts | 18 ---- .../kotlin/refinery-frontend-workspace.gradle.kts | 32 ------- .../kotlin/refinery-frontend-worktree.gradle.kts | 84 ----------------- .../kotlin/refinery-java-application.gradle.kts | 26 ------ .../kotlin/refinery-java-conventions.gradle.kts | 103 --------------------- .../main/kotlin/refinery-java-library.gradle.kts | 5 - .../kotlin/refinery-java-test-fixtures.gradle.kts | 31 ------- buildSrc/src/main/kotlin/refinery-jmh.gradle.kts | 63 ------------- buildSrc/src/main/kotlin/refinery-mwe2.gradle.kts | 18 ---- .../src/main/kotlin/refinery-sonarqube.gradle.kts | 3 - .../kotlin/refinery-xtext-conventions.gradle.kts | 21 ----- .../tools/refinery/gradle/eclipse.gradle.kts | 38 ++++++++ .../refinery/gradle/frontend-workspace.gradle.kts | 34 +++++++ .../refinery/gradle/frontend-worktree.gradle.kts | 87 +++++++++++++++++ .../internal/frontend-conventions.gradle.kts | 17 ++++ .../gradle/internal/java-conventions.gradle.kts | 101 ++++++++++++++++++++ .../refinery/gradle/java-application.gradle.kts | 27 ++++++ .../tools/refinery/gradle/java-library.gradle.kts | 6 ++ .../refinery/gradle/java-test-fixtures.gradle.kts | 31 +++++++ .../kotlin/tools/refinery/gradle/jmh.gradle.kts | 61 ++++++++++++ .../kotlin/tools/refinery/gradle/mwe2.gradle.kts | 21 +++++ .../tools/refinery/gradle/sonarqube.gradle.kts | 5 + .../refinery/gradle/xtext-generated.gradle.kts | 23 +++++ 28 files changed, 567 insertions(+), 557 deletions(-) delete mode 100644 buildSrc/src/main/java/tools/refinery/buildsrc/EclipseUtils.java delete mode 100644 buildSrc/src/main/java/tools/refinery/buildsrc/SonarPropertiesUtils.java create mode 100644 buildSrc/src/main/java/tools/refinery/gradle/utils/EclipseUtils.java create mode 100644 buildSrc/src/main/java/tools/refinery/gradle/utils/SonarPropertiesUtils.java delete mode 100644 buildSrc/src/main/kotlin/refinery-eclipse.gradle.kts delete mode 100644 buildSrc/src/main/kotlin/refinery-frontend-conventions.gradle.kts delete mode 100644 buildSrc/src/main/kotlin/refinery-frontend-workspace.gradle.kts delete mode 100644 buildSrc/src/main/kotlin/refinery-frontend-worktree.gradle.kts delete mode 100644 buildSrc/src/main/kotlin/refinery-java-application.gradle.kts delete mode 100644 buildSrc/src/main/kotlin/refinery-java-conventions.gradle.kts delete mode 100644 buildSrc/src/main/kotlin/refinery-java-library.gradle.kts delete mode 100644 buildSrc/src/main/kotlin/refinery-java-test-fixtures.gradle.kts delete mode 100644 buildSrc/src/main/kotlin/refinery-jmh.gradle.kts delete mode 100644 buildSrc/src/main/kotlin/refinery-mwe2.gradle.kts delete mode 100644 buildSrc/src/main/kotlin/refinery-sonarqube.gradle.kts delete mode 100644 buildSrc/src/main/kotlin/refinery-xtext-conventions.gradle.kts create mode 100644 buildSrc/src/main/kotlin/tools/refinery/gradle/eclipse.gradle.kts create mode 100644 buildSrc/src/main/kotlin/tools/refinery/gradle/frontend-workspace.gradle.kts create mode 100644 buildSrc/src/main/kotlin/tools/refinery/gradle/frontend-worktree.gradle.kts create mode 100644 buildSrc/src/main/kotlin/tools/refinery/gradle/internal/frontend-conventions.gradle.kts create mode 100644 buildSrc/src/main/kotlin/tools/refinery/gradle/internal/java-conventions.gradle.kts create mode 100644 buildSrc/src/main/kotlin/tools/refinery/gradle/java-application.gradle.kts create mode 100644 buildSrc/src/main/kotlin/tools/refinery/gradle/java-library.gradle.kts create mode 100644 buildSrc/src/main/kotlin/tools/refinery/gradle/java-test-fixtures.gradle.kts create mode 100644 buildSrc/src/main/kotlin/tools/refinery/gradle/jmh.gradle.kts create mode 100644 buildSrc/src/main/kotlin/tools/refinery/gradle/mwe2.gradle.kts create mode 100644 buildSrc/src/main/kotlin/tools/refinery/gradle/sonarqube.gradle.kts create mode 100644 buildSrc/src/main/kotlin/tools/refinery/gradle/xtext-generated.gradle.kts (limited to 'buildSrc/src/main') diff --git a/buildSrc/src/main/java/tools/refinery/buildsrc/EclipseUtils.java b/buildSrc/src/main/java/tools/refinery/buildsrc/EclipseUtils.java deleted file mode 100644 index 0014a35d..00000000 --- a/buildSrc/src/main/java/tools/refinery/buildsrc/EclipseUtils.java +++ /dev/null @@ -1,72 +0,0 @@ -package tools.refinery.buildsrc; - -import groovy.lang.Closure; -import org.gradle.api.Action; -import org.gradle.plugins.ide.api.XmlFileContentMerger; -import org.gradle.plugins.ide.eclipse.model.AbstractClasspathEntry; -import org.gradle.plugins.ide.eclipse.model.Classpath; -import org.gradle.plugins.ide.eclipse.model.EclipseModel; - -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; -import java.util.function.Consumer; - -public final class EclipseUtils { - private static final String GRADLE_USED_BY_SCOPE_ATTRIBUTE = "gradle_used_by_scope"; - private static final String GRADLE_USED_BY_SCOPE_SEPARATOR = ","; - - private EclipseUtils() { - throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); - } - - public static void patchClasspathEntries(EclipseModel eclipseModel, Consumer consumer) { - whenClasspathFileMerged(eclipseModel.getClasspath().getFile(), - classpath -> patchClasspathEntries(classpath, consumer)); - } - - public static void patchClasspathEntries(Classpath eclipseClasspath, Consumer consumer) { - for (var entry : eclipseClasspath.getEntries()) { - if (entry instanceof AbstractClasspathEntry abstractClasspathEntry) { - consumer.accept(abstractClasspathEntry); - } - } - } - - /** - * Avoids ambiguous call to ({@link XmlFileContentMerger#whenMerged(Closure)} versus - * {@link XmlFileContentMerger#whenMerged(Action)}) in Kotlin build scripts. - *

- * The {@code Closure} variant will use the build script itself as {@code this}, and Kotlin will consider any - * type ascription as a cast of {@code this} (instead of the argument of the {@code Action}). This results in - * a mysterious {@link ClassCastException}, since the class generated from the build script doesn't extend from - * {@link Classpath}. Using this helper method selects the correct call and applies the cast properly. - * - * @param file The Eclipse classpath file. - * @param consumer The lambda to run on when the classpath file is merged. - */ - public static void whenClasspathFileMerged(XmlFileContentMerger file, Consumer consumer) { - file.whenMerged(untypedClasspath -> { - var classpath = (Classpath) untypedClasspath; - consumer.accept(classpath); - }); - } - - public static void patchGradleUsedByScope(AbstractClasspathEntry entry, Consumer> consumer) { - var entryAttributes = entry.getEntryAttributes(); - var usedByValue = entryAttributes.get(GRADLE_USED_BY_SCOPE_ATTRIBUTE); - Set usedBySet; - if (usedByValue instanceof String usedByString) { - usedBySet = new LinkedHashSet<>(List.of(usedByString.split(GRADLE_USED_BY_SCOPE_SEPARATOR))); - } else { - usedBySet = new LinkedHashSet<>(); - } - consumer.accept(usedBySet); - if (usedBySet.isEmpty()) { - entryAttributes.remove(GRADLE_USED_BY_SCOPE_ATTRIBUTE); - } else { - var newUsedByString = String.join(GRADLE_USED_BY_SCOPE_SEPARATOR, usedBySet); - entryAttributes.put(GRADLE_USED_BY_SCOPE_ATTRIBUTE, newUsedByString); - } - } -} diff --git a/buildSrc/src/main/java/tools/refinery/buildsrc/SonarPropertiesUtils.java b/buildSrc/src/main/java/tools/refinery/buildsrc/SonarPropertiesUtils.java deleted file mode 100644 index 1d89841e..00000000 --- a/buildSrc/src/main/java/tools/refinery/buildsrc/SonarPropertiesUtils.java +++ /dev/null @@ -1,44 +0,0 @@ -package tools.refinery.buildsrc; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Map; - -public final class SonarPropertiesUtils { - private SonarPropertiesUtils() { - throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); - } - - /** - * Adds the entries to a Sonar property of list type. - *

- * According to the Sonar Gradle documentation for {@link org.sonarqube.gradle.SonarProperties}, property values - * are converted to Strings as follows: - *

    - *
  • {@code Iterable}s are recursively converted and joined into a comma-separated String.
  • - *
  • All other values are converted to Strings by calling their {@code toString()} method.
  • - *
- * Therefore, we use {@link ArrayList} to retain lists entries, which will be recursively converted later. - * - * @param properties The sonar properties map returned by - * {@link org.sonarqube.gradle.SonarProperties#getProperties()}. - * @param propertyName The name of the property to append to. - * @param entries The entries to append. - */ - public static void addToList(Map properties, String propertyName, String... entries) { - ArrayList newValue; - var currentValue = properties.get(propertyName); - if (currentValue instanceof ArrayList currentList) { - @SuppressWarnings("unchecked") - var objectList = (ArrayList) currentList; - newValue = objectList; - } else if (currentValue == null) { - newValue = new ArrayList<>(entries.length); - } else { - newValue = new ArrayList<>(entries.length + 1); - newValue.add(currentValue); - } - Collections.addAll(newValue, entries); - properties.put(propertyName, newValue); - } -} diff --git a/buildSrc/src/main/java/tools/refinery/gradle/utils/EclipseUtils.java b/buildSrc/src/main/java/tools/refinery/gradle/utils/EclipseUtils.java new file mode 100644 index 00000000..1e33a95d --- /dev/null +++ b/buildSrc/src/main/java/tools/refinery/gradle/utils/EclipseUtils.java @@ -0,0 +1,72 @@ +package tools.refinery.gradle.utils; + +import groovy.lang.Closure; +import org.gradle.api.Action; +import org.gradle.plugins.ide.api.XmlFileContentMerger; +import org.gradle.plugins.ide.eclipse.model.AbstractClasspathEntry; +import org.gradle.plugins.ide.eclipse.model.Classpath; +import org.gradle.plugins.ide.eclipse.model.EclipseModel; + +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Consumer; + +public final class EclipseUtils { + private static final String GRADLE_USED_BY_SCOPE_ATTRIBUTE = "gradle_used_by_scope"; + private static final String GRADLE_USED_BY_SCOPE_SEPARATOR = ","; + + private EclipseUtils() { + throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); + } + + public static void patchClasspathEntries(EclipseModel eclipseModel, Consumer consumer) { + whenClasspathFileMerged(eclipseModel.getClasspath().getFile(), + classpath -> patchClasspathEntries(classpath, consumer)); + } + + public static void patchClasspathEntries(Classpath eclipseClasspath, Consumer consumer) { + for (var entry : eclipseClasspath.getEntries()) { + if (entry instanceof AbstractClasspathEntry abstractClasspathEntry) { + consumer.accept(abstractClasspathEntry); + } + } + } + + /** + * Avoids ambiguous call to ({@link XmlFileContentMerger#whenMerged(Closure)} versus + * {@link XmlFileContentMerger#whenMerged(Action)}) in Kotlin build scripts. + *

+ * The {@code Closure} variant will use the build script itself as {@code this}, and Kotlin will consider any + * type ascription as a cast of {@code this} (instead of the argument of the {@code Action}). This results in + * a mysterious {@link ClassCastException}, since the class generated from the build script doesn't extend from + * {@link Classpath}. Using this helper method selects the correct call and applies the cast properly. + * + * @param file The Eclipse classpath file. + * @param consumer The lambda to run on when the classpath file is merged. + */ + public static void whenClasspathFileMerged(XmlFileContentMerger file, Consumer consumer) { + file.whenMerged(untypedClasspath -> { + var classpath = (Classpath) untypedClasspath; + consumer.accept(classpath); + }); + } + + public static void patchGradleUsedByScope(AbstractClasspathEntry entry, Consumer> consumer) { + var entryAttributes = entry.getEntryAttributes(); + var usedByValue = entryAttributes.get(GRADLE_USED_BY_SCOPE_ATTRIBUTE); + Set usedBySet; + if (usedByValue instanceof String usedByString) { + usedBySet = new LinkedHashSet<>(List.of(usedByString.split(GRADLE_USED_BY_SCOPE_SEPARATOR))); + } else { + usedBySet = new LinkedHashSet<>(); + } + consumer.accept(usedBySet); + if (usedBySet.isEmpty()) { + entryAttributes.remove(GRADLE_USED_BY_SCOPE_ATTRIBUTE); + } else { + var newUsedByString = String.join(GRADLE_USED_BY_SCOPE_SEPARATOR, usedBySet); + entryAttributes.put(GRADLE_USED_BY_SCOPE_ATTRIBUTE, newUsedByString); + } + } +} diff --git a/buildSrc/src/main/java/tools/refinery/gradle/utils/SonarPropertiesUtils.java b/buildSrc/src/main/java/tools/refinery/gradle/utils/SonarPropertiesUtils.java new file mode 100644 index 00000000..3810fccf --- /dev/null +++ b/buildSrc/src/main/java/tools/refinery/gradle/utils/SonarPropertiesUtils.java @@ -0,0 +1,44 @@ +package tools.refinery.gradle.utils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Map; + +public final class SonarPropertiesUtils { + private SonarPropertiesUtils() { + throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); + } + + /** + * Adds the entries to a Sonar property of list type. + *

+ * According to the Sonar Gradle documentation for {@link org.sonarqube.gradle.SonarProperties}, property values + * are converted to Strings as follows: + *

    + *
  • {@code Iterable}s are recursively converted and joined into a comma-separated String.
  • + *
  • All other values are converted to Strings by calling their {@code toString()} method.
  • + *
+ * Therefore, we use {@link ArrayList} to retain lists entries, which will be recursively converted later. + * + * @param properties The sonar properties map returned by + * {@link org.sonarqube.gradle.SonarProperties#getProperties()}. + * @param propertyName The name of the property to append to. + * @param entries The entries to append. + */ + public static void addToList(Map properties, String propertyName, String... entries) { + ArrayList newValue; + var currentValue = properties.get(propertyName); + if (currentValue instanceof ArrayList currentList) { + @SuppressWarnings("unchecked") + var objectList = (ArrayList) currentList; + newValue = objectList; + } else if (currentValue == null) { + newValue = new ArrayList<>(entries.length); + } else { + newValue = new ArrayList<>(entries.length + 1); + newValue.add(currentValue); + } + Collections.addAll(newValue, entries); + properties.put(propertyName, newValue); + } +} diff --git a/buildSrc/src/main/kotlin/refinery-eclipse.gradle.kts b/buildSrc/src/main/kotlin/refinery-eclipse.gradle.kts deleted file mode 100644 index 85e47370..00000000 --- a/buildSrc/src/main/kotlin/refinery-eclipse.gradle.kts +++ /dev/null @@ -1,37 +0,0 @@ -import org.gradle.plugins.ide.eclipse.model.EclipseModel -import java.util.* - -plugins { - eclipse -} - -// Workaround from https://github.com/gradle/gradle/issues/898#issuecomment-885765821 -val eclipseResourceEncoding by tasks.registering { - val outputFile = file(".settings/org.eclipse.core.resources.prefs") - val encoding = providers.systemProperty("file.encoding") - - inputs.property("file.encoding", encoding) - outputs.file(outputFile) - - doLast { - val eclipseEncodingProperties = Properties(2) - eclipseEncodingProperties["eclipse.preferences.version"] = "1" - eclipseEncodingProperties["encoding/"] = encoding.get() - outputFile.outputStream().use { outputStream -> - eclipseEncodingProperties.store(outputStream, "generated by $name") - } - } -} - -val eclipse by tasks.existing { - dependsOn(eclipseResourceEncoding) -} - -the().synchronizationTasks(eclipseResourceEncoding) - -tasks.register("clobberEclipse") { - mustRunAfter(eclipse) - delete(".classpath") - delete(".project") - delete(".settings") -} diff --git a/buildSrc/src/main/kotlin/refinery-frontend-conventions.gradle.kts b/buildSrc/src/main/kotlin/refinery-frontend-conventions.gradle.kts deleted file mode 100644 index c4658948..00000000 --- a/buildSrc/src/main/kotlin/refinery-frontend-conventions.gradle.kts +++ /dev/null @@ -1,18 +0,0 @@ -import org.siouan.frontendgradleplugin.infrastructure.gradle.EnableYarnBerryTask -import org.siouan.frontendgradleplugin.infrastructure.gradle.FrontendExtension - -plugins { - id("org.siouan.frontend-jdk11") -} - -configure { - nodeVersion.set(providers.gradleProperty("frontend.nodeVersion")) - nodeInstallDirectory.set(file("$rootDir/.node")) - yarnEnabled.set(true) - yarnVersion.set(providers.gradleProperty("frontend.yarnVersion")) -} - -tasks.named("enableYarnBerry") { - // There is no need to enable berry manually, because berry files are already committed to the repo. - enabled = false -} diff --git a/buildSrc/src/main/kotlin/refinery-frontend-workspace.gradle.kts b/buildSrc/src/main/kotlin/refinery-frontend-workspace.gradle.kts deleted file mode 100644 index 198f73f3..00000000 --- a/buildSrc/src/main/kotlin/refinery-frontend-workspace.gradle.kts +++ /dev/null @@ -1,32 +0,0 @@ -import org.siouan.frontendgradleplugin.infrastructure.gradle.* - -plugins { - id("refinery-eclipse") - id("refinery-frontend-conventions") -} - -tasks.named("installNode") { - dependsOn(rootProject.tasks.named("installNode")) - enabled = false -} - -tasks.named("installYarnGlobally") { - dependsOn(rootProject.tasks.named("installYarnGlobally")) - enabled = false -} - -tasks.named("installYarn") { - dependsOn(rootProject.tasks.named("installYarn")) - enabled = false -} - -val rootInstallFrontend = rootProject.tasks.named("installFrontend") - -rootInstallFrontend.configure { - inputs.file("$projectDir/package.json") -} - -tasks.named("installFrontend") { - dependsOn(rootInstallFrontend) - enabled = false -} diff --git a/buildSrc/src/main/kotlin/refinery-frontend-worktree.gradle.kts b/buildSrc/src/main/kotlin/refinery-frontend-worktree.gradle.kts deleted file mode 100644 index d8c3d51f..00000000 --- a/buildSrc/src/main/kotlin/refinery-frontend-worktree.gradle.kts +++ /dev/null @@ -1,84 +0,0 @@ -import org.siouan.frontendgradleplugin.infrastructure.gradle.* -import java.io.FileInputStream -import java.io.FileNotFoundException -import java.io.FileOutputStream -import java.util.* - -plugins { - id("refinery-frontend-conventions") -} - -val frontend = the() - -val yarn1Version = providers.gradleProperty("frontend.yarn1Version") - -frontend.yarnGlobalInstallScript.set(yarn1Version.map { version -> "install -g yarn@$version" }) -frontend.yarnInstallScript.set(frontend.yarnVersion.map { version -> "set version $version --only-if-needed" }) -frontend.installScript.set(provider { - if (project.hasProperty("ci")) "install --immutable --inline-builds" else "install" -}) - -val frontendPropertiesFile = frontend.nodeInstallDirectory.map { dir -> "$dir/frontend.properties" } - -fun readFrontendProperties(): Properties { - val props = Properties() - try { - FileInputStream(frontendPropertiesFile.get()).use { inputStream -> - props.load(inputStream) - } - } catch (ignored: FileNotFoundException) { - // Ignore missing file. - } - return props -} - -fun getFrontendProperty(propertyName: String): String? { - val props = readFrontendProperties() - return props[propertyName]?.toString() -} - -fun putFrontedProperty(propertyName: String, propertyValue: String) { - val props = readFrontendProperties() - props[propertyName] = propertyValue - FileOutputStream(frontendPropertiesFile.get()).use { outputStream -> - props.store(outputStream, "generated by refinery-frontend-worktree") - } -} - -tasks.named("installNode") { - onlyIf { - getFrontendProperty("installedNodeVersion") != frontend.nodeVersion.get() - } - doLast { - putFrontedProperty("installedNodeVersion", frontend.nodeVersion.get()) - } -} - -tasks.named("installYarnGlobally") { - onlyIf { - getFrontendProperty("installedYarn1Version") != yarn1Version.get() - } - doLast { - putFrontedProperty("installedYarn1Version", yarn1Version.get()) - } - outputs.dir(frontend.nodeInstallDirectory.map { dir -> "$dir/lib/node_modules/yarn" }) -} - -tasks.named("installYarn") { - outputs.file(frontend.yarnVersion.map { version -> ".yarn/releases/yarn-$version.cjs" }) -} - -tasks.named("installFrontend") { - inputs.files("package.json", "yarn.lock") - outputs.files(".pnp.cjs", ".pnp.loader.mjs") -} - -tasks.register("clobberFrontend", Delete::class) { - delete(frontend.nodeInstallDirectory) - delete(".yarn/cache") - delete(".yarn/install-state.gz") - delete(".yarn/sdks") - delete(".yarn/unplugged") - delete(".pnp.cjs") - delete(".pnp.loader.mjs") -} diff --git a/buildSrc/src/main/kotlin/refinery-java-application.gradle.kts b/buildSrc/src/main/kotlin/refinery-java-application.gradle.kts deleted file mode 100644 index 65409acf..00000000 --- a/buildSrc/src/main/kotlin/refinery-java-application.gradle.kts +++ /dev/null @@ -1,26 +0,0 @@ -import org.gradle.accessors.dm.LibrariesForLibs - -plugins { - application - id("com.github.johnrengelman.shadow") -} - -apply(plugin = "refinery-java-conventions") - -// Use log4j-over-slf4j instead of log4j 1.x when running the application. -configurations.named("runtimeClasspath") { - exclude(group = "log4j", module = "log4j") -} - -val libs = the() - -dependencies { - implementation(libs.slf4j.simple) - implementation(libs.slf4j.log4j) -} - -for (taskName in listOf("distTar", "distZip", "shadowDistTar", "shadowDistZip")) { - tasks.named(taskName) { - enabled = false - } -} diff --git a/buildSrc/src/main/kotlin/refinery-java-conventions.gradle.kts b/buildSrc/src/main/kotlin/refinery-java-conventions.gradle.kts deleted file mode 100644 index a55350df..00000000 --- a/buildSrc/src/main/kotlin/refinery-java-conventions.gradle.kts +++ /dev/null @@ -1,103 +0,0 @@ -import org.gradle.accessors.dm.LibrariesForLibs -import org.gradle.plugins.ide.eclipse.model.EclipseModel -import org.gradle.plugins.ide.eclipse.model.ProjectDependency -import tools.refinery.buildsrc.EclipseUtils - -plugins { - jacoco - java -} - -apply(plugin = "refinery-eclipse") - -repositories { - mavenCentral() - maven { - url = uri("https://repo.eclipse.org/content/groups/releases/") - } -} - -// Use log4j-over-slf4j instead of log4j 1.x in the tests. -configurations.testRuntimeClasspath { - exclude(group = "log4j", module = "log4j") -} - -val libs = the() - -dependencies { - compileOnly(libs.jetbrainsAnnotations) - testCompileOnly(libs.jetbrainsAnnotations) - testImplementation(libs.hamcrest) - testImplementation(libs.junit.api) - testRuntimeOnly(libs.junit.engine) - testImplementation(libs.junit.params) - testImplementation(libs.mockito.core) - testImplementation(libs.mockito.junit) - testImplementation(libs.slf4j.simple) - testImplementation(libs.slf4j.log4j) -} - -java.toolchain { - languageVersion.set(JavaLanguageVersion.of(19)) -} - -tasks.withType(JavaCompile::class) { - options.release.set(17) -} - -val test = tasks.named("test") - -val jacocoTestReport = tasks.named("jacocoTestReport") - -test.configure { - useJUnitPlatform { - excludeTags("slow") - } - finalizedBy(jacocoTestReport) -} - -jacocoTestReport.configure { - dependsOn(test) - reports { - xml.required.set(true) - } -} - -tasks.named("jar") { - manifest { - attributes( - "Bundle-SymbolicName" to "${project.group}.${project.name}", - "Bundle-Version" to project.version - ) - } -} - -val generateEclipseSourceFolders by tasks.registering - -tasks.register("prepareEclipse") { - dependsOn(generateEclipseSourceFolders) - dependsOn(tasks.named("eclipseJdt")) -} - -tasks.named("eclipseClasspath") { - dependsOn(generateEclipseSourceFolders) -} - -configure { - EclipseUtils.patchClasspathEntries(this) { entry -> - if (entry.path.endsWith("-gen")) { - entry.entryAttributes["ignore_optional_problems"] = true - } - // If a project has a main dependency on a project and a test dependency on the testFixtures of a project, - // it will be erroneously added as a test-only dependency to Eclipse. As a workaround, we add all project - // dependencies as main dependencies (we do not deliberately use test-only project dependencies). - if (entry is ProjectDependency) { - entry.entryAttributes.remove("test") - } - } - - jdt.file.withProperties { - // Allow @SuppressWarnings to suppress SonarLint warnings - this["org.eclipse.jdt.core.compiler.problem.unhandledWarningToken"] = "ignore" - } -} diff --git a/buildSrc/src/main/kotlin/refinery-java-library.gradle.kts b/buildSrc/src/main/kotlin/refinery-java-library.gradle.kts deleted file mode 100644 index 5a6200e0..00000000 --- a/buildSrc/src/main/kotlin/refinery-java-library.gradle.kts +++ /dev/null @@ -1,5 +0,0 @@ -plugins { - `java-library` -} - -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 deleted file mode 100644 index 86b0a04b..00000000 --- a/buildSrc/src/main/kotlin/refinery-java-test-fixtures.gradle.kts +++ /dev/null @@ -1,31 +0,0 @@ -import org.gradle.plugins.ide.eclipse.model.AbstractClasspathEntry -import org.gradle.plugins.ide.eclipse.model.EclipseModel -import tools.refinery.buildsrc.EclipseUtils - -plugins { - `java-test-fixtures` -} - -apply(plugin = "refinery-java-conventions") - -the().classpath { - containsTestFixtures.set(true) - - EclipseUtils.whenClasspathFileMerged(file) { eclipseClasspath -> - val hasTest = eclipseClasspath.entries.any { entry -> - entry is AbstractClasspathEntry && entry.entryAttributes["gradle_scope"] == "test" - } - EclipseUtils.patchClasspathEntries(eclipseClasspath) { entry -> - // Workaround https://github.com/gradle/gradle/issues/11845 based on - // https://discuss.gradle.org/t/gradle-used-by-scope-not-correctly-generated-when-the-java-test-fixtures-plugin-is-used/39935/2 - EclipseUtils.patchGradleUsedByScope(entry) { usedBy -> - if (usedBy.contains("main")) { - usedBy += "testFixtures" - } - if (hasTest && usedBy.contains("testFixtures")) { - usedBy += "test" - } - } - } - } -} diff --git a/buildSrc/src/main/kotlin/refinery-jmh.gradle.kts b/buildSrc/src/main/kotlin/refinery-jmh.gradle.kts deleted file mode 100644 index 6512ef23..00000000 --- a/buildSrc/src/main/kotlin/refinery-jmh.gradle.kts +++ /dev/null @@ -1,63 +0,0 @@ -import org.gradle.accessors.dm.LibrariesForLibs -import org.gradle.plugins.ide.eclipse.model.EclipseModel -import org.sonarqube.gradle.SonarExtension -import tools.refinery.buildsrc.EclipseUtils -import tools.refinery.buildsrc.SonarPropertiesUtils - -apply(plugin = "refinery-java-conventions") -apply(plugin = "refinery-sonarqube") - -val sourceSets = the() - -val main: SourceSet by sourceSets.getting - -val test: SourceSet by sourceSets.getting - -val jmh: SourceSet by sourceSets.creating { - compileClasspath += main.output - runtimeClasspath += main.output - // Allow using test classes in benchmarks for now. - compileClasspath += test.output - runtimeClasspath += test.output -} - -val jmhImplementation: Configuration by configurations.getting { - extendsFrom(configurations["implementation"], configurations["testImplementation"]) -} - -val jmhAnnotationProcessor: Configuration by configurations.getting - -configurations["jmhRuntimeOnly"].extendsFrom(configurations["runtimeOnly"], configurations["testRuntimeOnly"]) - -val libs = the() - -dependencies { - jmhImplementation(libs.jmh.core) - jmhAnnotationProcessor(libs.jmh.annprocess) -} - -tasks.register("jmh") { - dependsOn(tasks.named("jmhClasses")) - mainClass.set("org.openjdk.jmh.Main") - classpath = jmh.runtimeClasspath -} - -EclipseUtils.patchClasspathEntries(the()) { entry -> - // Workaround from https://github.com/gradle/gradle/issues/4802#issuecomment-407902081 - if (entry.entryAttributes["gradle_scope"] == "jmh") { - // Allow test helper classes to be used in benchmarks from Eclipse - // and do not expose JMH dependencies to the main source code. - entry.entryAttributes["test"] = true - } else { - EclipseUtils.patchGradleUsedByScope(entry) { usedBy -> - if (listOf("main", "test", "testFixtures").any { e -> usedBy.contains(e) }) { - // main and test sources are also used by jmh sources. - usedBy += "jmh" - } - } - } -} - -the().properties { - SonarPropertiesUtils.addToList(properties, "sonar.tests", "src/jmh/java") -} diff --git a/buildSrc/src/main/kotlin/refinery-mwe2.gradle.kts b/buildSrc/src/main/kotlin/refinery-mwe2.gradle.kts deleted file mode 100644 index 26963837..00000000 --- a/buildSrc/src/main/kotlin/refinery-mwe2.gradle.kts +++ /dev/null @@ -1,18 +0,0 @@ -import org.gradle.accessors.dm.LibrariesForLibs -import org.gradle.plugins.ide.eclipse.model.EclipseModel - -apply(plugin = "refinery-java-conventions") - -val mwe2: Configuration by configurations.creating { - isCanBeConsumed = false - isCanBeResolved = true - extendsFrom(configurations["implementation"]) -} - -val libs = the() - -dependencies { - mwe2(libs.mwe2.launch) -} - -the().classpath.plusConfigurations += mwe2 diff --git a/buildSrc/src/main/kotlin/refinery-sonarqube.gradle.kts b/buildSrc/src/main/kotlin/refinery-sonarqube.gradle.kts deleted file mode 100644 index 6a1dbbf6..00000000 --- a/buildSrc/src/main/kotlin/refinery-sonarqube.gradle.kts +++ /dev/null @@ -1,3 +0,0 @@ -plugins { - id("org.sonarqube") -} diff --git a/buildSrc/src/main/kotlin/refinery-xtext-conventions.gradle.kts b/buildSrc/src/main/kotlin/refinery-xtext-conventions.gradle.kts deleted file mode 100644 index 34fbae99..00000000 --- a/buildSrc/src/main/kotlin/refinery-xtext-conventions.gradle.kts +++ /dev/null @@ -1,21 +0,0 @@ -import org.gradle.api.tasks.SourceSetContainer -import org.sonarqube.gradle.SonarExtension -import tools.refinery.buildsrc.SonarPropertiesUtils - -apply(plugin = "refinery-java-conventions") -apply(plugin = "refinery-sonarqube") - -val xtextGenPath = "src/main/xtext-gen" - -the().named("main") { - java.srcDir(xtextGenPath) - resources.srcDir(xtextGenPath) -} - -tasks.named("clean") { - delete(xtextGenPath) -} - -the().properties { - SonarPropertiesUtils.addToList(properties, "sonar.exclusions", "$xtextGenPath/**") -} 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 @@ +package tools.refinery.gradle + +import java.util.Properties + +plugins { + eclipse +} + +// Workaround from https://github.com/gradle/gradle/issues/898#issuecomment-885765821 +val eclipseResourceEncoding by tasks.registering { + val outputFile = file(".settings/org.eclipse.core.resources.prefs") + val encoding = providers.systemProperty("file.encoding") + + inputs.property("file.encoding", encoding) + outputs.file(outputFile) + + doLast { + val eclipseEncodingProperties = Properties(2) + eclipseEncodingProperties["eclipse.preferences.version"] = "1" + eclipseEncodingProperties["encoding/"] = encoding.get() + outputFile.outputStream().use { outputStream -> + eclipseEncodingProperties.store(outputStream, "generated by $name") + } + } +} + +tasks.eclipse { + dependsOn(eclipseResourceEncoding) +} + +eclipse.synchronizationTasks(eclipseResourceEncoding) + +tasks.register("clobberEclipse") { + mustRunAfter(tasks.eclipse) + delete(".classpath") + delete(".project") + delete(".settings") +} 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 @@ +package tools.refinery.gradle + +plugins { + id("tools.refinery.gradle.eclipse") + id("tools.refinery.gradle.internal.frontend-conventions") +} + +tasks { + installNode { + dependsOn(rootProject.tasks.named("installNode")) + enabled = false + } + + installYarnGlobally { + dependsOn(rootProject.tasks.named("installYarnGlobally")) + enabled = false + } + + installYarn { + dependsOn(rootProject.tasks.named("installYarn")) + enabled = false + } + + val rootInstallFrontend = rootProject.tasks.named("installFrontend") + + rootInstallFrontend.configure { + inputs.file("$projectDir/package.json") + } + + installFrontend { + dependsOn(rootInstallFrontend) + enabled = false + } +} 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 @@ +package tools.refinery.gradle + +import java.io.FileInputStream +import java.io.FileNotFoundException +import java.io.FileOutputStream +import java.util.Properties + +plugins { + id("tools.refinery.gradle.internal.frontend-conventions") +} + +val yarn1Version = providers.gradleProperty("frontend.yarn1Version") + +frontend { + yarnGlobalInstallScript.set(yarn1Version.map { version -> "install -g yarn@$version" }) + yarnInstallScript.set(frontend.yarnVersion.map { version -> "set version $version --only-if-needed" }) + installScript.set(provider { + if (project.hasProperty("ci")) "install --immutable --inline-builds" else "install" + }) +} + +val frontendPropertiesFile = frontend.nodeInstallDirectory.map { dir -> "$dir/frontend.properties" } + +fun readFrontendProperties(): Properties { + val props = Properties() + try { + FileInputStream(frontendPropertiesFile.get()).use { inputStream -> + props.load(inputStream) + } + } catch (ignored: FileNotFoundException) { + // Ignore missing file. + } + return props +} + +fun getFrontendProperty(propertyName: String): String? { + val props = readFrontendProperties() + return props[propertyName]?.toString() +} + +fun putFrontedProperty(propertyName: String, propertyValue: String) { + val props = readFrontendProperties() + props[propertyName] = propertyValue + FileOutputStream(frontendPropertiesFile.get()).use { outputStream -> + props.store(outputStream, "generated by refinery-frontend-worktree") + } +} + +tasks { + installNode { + onlyIf { + getFrontendProperty("installedNodeVersion") != frontend.nodeVersion.get() + } + doLast { + putFrontedProperty("installedNodeVersion", frontend.nodeVersion.get()) + } + } + + installYarnGlobally { + onlyIf { + getFrontendProperty("installedYarn1Version") != yarn1Version.get() + } + doLast { + putFrontedProperty("installedYarn1Version", yarn1Version.get()) + } + outputs.dir(frontend.nodeInstallDirectory.map { dir -> "$dir/lib/node_modules/yarn" }) + } + + installYarn { + outputs.file(frontend.yarnVersion.map { version -> ".yarn/releases/yarn-$version.cjs" }) + } + + installFrontend { + inputs.files("package.json", "yarn.lock") + outputs.files(".pnp.cjs", ".pnp.loader.mjs") + } + + register("clobberFrontend", Delete::class) { + delete(frontend.nodeInstallDirectory) + delete(".yarn/cache") + delete(".yarn/install-state.gz") + delete(".yarn/sdks") + delete(".yarn/unplugged") + delete(".pnp.cjs") + delete(".pnp.loader.mjs") + } +} 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 @@ +package tools.refinery.gradle.internal + +plugins { + id("org.siouan.frontend-jdk11") +} + +frontend { + nodeVersion.set(providers.gradleProperty("frontend.nodeVersion")) + nodeInstallDirectory.set(file("$rootDir/.node")) + yarnEnabled.set(true) + yarnVersion.set(providers.gradleProperty("frontend.yarnVersion")) +} + +tasks.enableYarnBerry { + // There is no need to enable berry manually, because berry files are already committed to the repo. + enabled = false +} 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 @@ +package tools.refinery.gradle.internal + +import org.gradle.accessors.dm.LibrariesForLibs +import org.gradle.plugins.ide.eclipse.model.ProjectDependency +import tools.refinery.gradle.utils.EclipseUtils + +plugins { + jacoco + java + id("tools.refinery.gradle.eclipse") +} + +repositories { + mavenCentral() + maven { + url = uri("https://repo.eclipse.org/content/groups/releases/") + } +} + +// Use log4j-over-slf4j instead of log4j 1.x in the tests. +configurations.testRuntimeClasspath { + exclude(group = "log4j", module = "log4j") +} + +val libs = the() + +dependencies { + compileOnly(libs.jetbrainsAnnotations) + testCompileOnly(libs.jetbrainsAnnotations) + testImplementation(libs.hamcrest) + testImplementation(libs.junit.api) + testRuntimeOnly(libs.junit.engine) + testImplementation(libs.junit.params) + testImplementation(libs.mockito.core) + testImplementation(libs.mockito.junit) + testImplementation(libs.slf4j.simple) + testImplementation(libs.slf4j.log4j) +} + +java.toolchain { + languageVersion.set(JavaLanguageVersion.of(19)) +} + +tasks { + withType(JavaCompile::class) { + options.release.set(17) + } + + test { + useJUnitPlatform { + excludeTags("slow") + } + finalizedBy(tasks.jacocoTestReport) + } + + jacocoTestReport { + dependsOn(tasks.test) + reports { + xml.required.set(true) + } + } + + jar { + manifest { + attributes( + "Bundle-SymbolicName" to "${project.group}.${project.name}", + "Bundle-Version" to project.version + ) + } + } + + val generateEclipseSourceFolders by tasks.registering + + register("prepareEclipse") { + dependsOn(generateEclipseSourceFolders) + dependsOn(tasks.named("eclipseJdt")) + } + + eclipseClasspath { + dependsOn(generateEclipseSourceFolders) + } +} + +eclipse { + EclipseUtils.patchClasspathEntries(this) { entry -> + if (entry.path.endsWith("-gen")) { + entry.entryAttributes["ignore_optional_problems"] = true + } + // If a project has a main dependency on a project and a test dependency on the testFixtures of a project, + // it will be erroneously added as a test-only dependency to Eclipse. As a workaround, we add all project + // dependencies as main dependencies (we do not deliberately use test-only project dependencies). + if (entry is ProjectDependency) { + entry.entryAttributes.remove("test") + } + } + + jdt.file.withProperties { + // Allow @SuppressWarnings to suppress SonarLint warnings + this["org.eclipse.jdt.core.compiler.problem.unhandledWarningToken"] = "ignore" + } +} 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 @@ +package tools.refinery.gradle + +import org.gradle.accessors.dm.LibrariesForLibs + +plugins { + application + id("com.github.johnrengelman.shadow") + id("tools.refinery.gradle.internal.java-conventions") +} + +// Use log4j-over-slf4j instead of log4j 1.x when running the application. +configurations.runtimeClasspath { + exclude(group = "log4j", module = "log4j") +} + +val libs = the() + +dependencies { + implementation(libs.slf4j.simple) + implementation(libs.slf4j.log4j) +} + +for (taskName in listOf("distTar", "distZip", "shadowDistTar", "shadowDistZip")) { + tasks.named(taskName) { + enabled = false + } +} 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 @@ +package tools.refinery.gradle + +plugins { + `java-library` + id("tools.refinery.gradle.internal.java-conventions") +} 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 @@ +package tools.refinery.gradle + +import org.gradle.plugins.ide.eclipse.model.AbstractClasspathEntry +import tools.refinery.gradle.utils.EclipseUtils + +plugins { + `java-test-fixtures` + id("tools.refinery.gradle.internal.java-conventions") +} + +eclipse.classpath { + containsTestFixtures.set(true) + + EclipseUtils.whenClasspathFileMerged(file) { eclipseClasspath -> + val hasTest = eclipseClasspath.entries.any { entry -> + entry is AbstractClasspathEntry && entry.entryAttributes["gradle_scope"] == "test" + } + EclipseUtils.patchClasspathEntries(eclipseClasspath) { entry -> + // Workaround https://github.com/gradle/gradle/issues/11845 based on + // https://discuss.gradle.org/t/gradle-used-by-scope-not-correctly-generated-when-the-java-test-fixtures-plugin-is-used/39935/2 + EclipseUtils.patchGradleUsedByScope(entry) { usedBy -> + if (usedBy.contains("main")) { + usedBy += "testFixtures" + } + if (hasTest && usedBy.contains("testFixtures")) { + usedBy += "test" + } + } + } + } +} 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 @@ +package tools.refinery.gradle + +import org.gradle.accessors.dm.LibrariesForLibs +import tools.refinery.gradle.utils.EclipseUtils +import tools.refinery.gradle.utils.SonarPropertiesUtils + +plugins { + id("tools.refinery.gradle.internal.java-conventions") + id("tools.refinery.gradle.sonarqube") +} + +val sourceSets = the() + +val jmh: SourceSet by sourceSets.creating { + compileClasspath += sourceSets.main.get().output + runtimeClasspath += sourceSets.main.get().output + // Allow using test classes in benchmarks for now. + compileClasspath += sourceSets.test.get().output + runtimeClasspath += sourceSets.test.get().output +} + +val jmhImplementation: Configuration by configurations.getting { + extendsFrom(configurations.implementation.get(), configurations.testImplementation.get()) +} + +val jmhAnnotationProcessor: Configuration by configurations.getting + +configurations["jmhRuntimeOnly"].extendsFrom(configurations.runtimeOnly.get(), configurations.testRuntimeOnly.get()) + +val libs = the() + +dependencies { + jmhImplementation(libs.jmh.core) + jmhAnnotationProcessor(libs.jmh.annprocess) +} + +tasks.register("jmh") { + dependsOn(tasks.named("jmhClasses")) + mainClass.set("org.openjdk.jmh.Main") + classpath = jmh.runtimeClasspath +} + +EclipseUtils.patchClasspathEntries(eclipse) { entry -> + // Workaround from https://github.com/gradle/gradle/issues/4802#issuecomment-407902081 + if (entry.entryAttributes["gradle_scope"] == "jmh") { + // Allow test helper classes to be used in benchmarks from Eclipse + // and do not expose JMH dependencies to the main source code. + entry.entryAttributes["test"] = true + } else { + EclipseUtils.patchGradleUsedByScope(entry) { usedBy -> + if (listOf("main", "test", "testFixtures").any { e -> usedBy.contains(e) }) { + // main and test sources are also used by jmh sources. + usedBy += "jmh" + } + } + } +} + +sonarqube.properties { + SonarPropertiesUtils.addToList(properties, "sonar.tests", "src/jmh/java") +} 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 @@ +package tools.refinery.gradle + +import org.gradle.accessors.dm.LibrariesForLibs + +plugins { + id("tools.refinery.gradle.internal.java-conventions") +} + +val mwe2: Configuration by configurations.creating { + isCanBeConsumed = false + isCanBeResolved = true + extendsFrom(configurations.implementation.get()) +} + +val libs = the() + +dependencies { + mwe2(libs.mwe2.launch) +} + +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 @@ +package tools.refinery.gradle + +plugins { + id("org.sonarqube") +} 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 @@ +package tools.refinery.gradle + +import tools.refinery.gradle.utils.SonarPropertiesUtils + +plugins { + id("tools.refinery.gradle.internal.java-conventions") + id("tools.refinery.gradle.sonarqube") +} + +val xtextGenPath = "src/main/xtext-gen" + +sourceSets.main { + java.srcDir(xtextGenPath) + resources.srcDir(xtextGenPath) +} + +tasks.clean { + delete(xtextGenPath) +} + +sonarqube.properties { + SonarPropertiesUtils.addToList(properties, "sonar.exclusions", "$xtextGenPath/**") +} -- cgit v1.2.3-54-g00ecf