diff options
author | Kristóf Marussy <kristof@marussy.com> | 2023-04-08 22:56:44 +0200 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2023-04-08 22:58:21 +0200 |
commit | 561fac70fd3dc3ebe1cfbc50146757495fb828d5 (patch) | |
tree | 20aa72bbe438aaa70c8de264ff0d366758e7772d /buildSrc/src/main/java/tools | |
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/java/tools')
-rw-r--r-- | buildSrc/src/main/java/tools/refinery/buildsrc/EclipseUtils.java | 72 | ||||
-rw-r--r-- | buildSrc/src/main/java/tools/refinery/buildsrc/SonarPropertiesUtils.java | 44 |
2 files changed, 116 insertions, 0 deletions
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 @@ | |||
1 | package tools.refinery.buildsrc; | ||
2 | |||
3 | import groovy.lang.Closure; | ||
4 | import org.gradle.api.Action; | ||
5 | import org.gradle.plugins.ide.api.XmlFileContentMerger; | ||
6 | import org.gradle.plugins.ide.eclipse.model.AbstractClasspathEntry; | ||
7 | import org.gradle.plugins.ide.eclipse.model.Classpath; | ||
8 | import org.gradle.plugins.ide.eclipse.model.EclipseModel; | ||
9 | |||
10 | import java.util.LinkedHashSet; | ||
11 | import java.util.List; | ||
12 | import java.util.Set; | ||
13 | import java.util.function.Consumer; | ||
14 | |||
15 | public 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 @@ | |||
1 | package tools.refinery.buildsrc; | ||
2 | |||
3 | import java.util.ArrayList; | ||
4 | import java.util.Collections; | ||
5 | import java.util.Map; | ||
6 | |||
7 | public 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 | } | ||