diff options
Diffstat (limited to 'buildSrc/src/main/java/tools/refinery/gradle/utils/EclipseUtils.java')
-rw-r--r-- | buildSrc/src/main/java/tools/refinery/gradle/utils/EclipseUtils.java | 72 |
1 files changed, 72 insertions, 0 deletions
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 @@ | |||
1 | package tools.refinery.gradle.utils; | ||
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 | } | ||