Skip to content

Commit dc417e7

Browse files
authored
Rewrite installer tasks (#3)
1 parent 3dcecb6 commit dc417e7

20 files changed

+1177
-105
lines changed

src/main/groovy/net/minecraftforge/forgedev/ForgeDevExtension.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@
44
*/
55
package net.minecraftforge.forgedev;
66

7+
import net.minecraftforge.forgedev.legacy.tasks.DownloadDependency;
8+
import net.minecraftforge.forgedev.legacy.values.CIRuntime;
79
import net.minecraftforge.forgedev.tasks.compat.LegacyExtractZip;
810
import net.minecraftforge.forgedev.tasks.compat.LegacyMergeFilesTask;
911
import net.minecraftforge.forgedev.tasks.filtering.LegacyFilterNewJar;
1012
import net.minecraftforge.forgedev.tasks.generation.GeneratePatcherConfigV2;
13+
import net.minecraftforge.forgedev.tasks.installer.Installer;
1114
import net.minecraftforge.forgedev.tasks.installertools.DownloadMappings;
1215
import net.minecraftforge.forgedev.tasks.launcher.SlimeLauncherExec;
1316
import net.minecraftforge.forgedev.tasks.mappings.LegacyApplyMappings;
@@ -35,6 +38,7 @@
3538
import org.gradle.api.attributes.Attribute;
3639
import org.gradle.api.file.Directory;
3740
import org.gradle.api.file.DirectoryProperty;
41+
import org.gradle.api.file.DuplicatesStrategy;
3842
import org.gradle.api.file.ProjectLayout;
3943
import org.gradle.api.model.ObjectFactory;
4044
import org.gradle.api.plugins.JavaPlugin;
@@ -47,6 +51,7 @@
4751
import org.gradle.api.tasks.bundling.Jar;
4852
import org.gradle.api.tasks.bundling.Zip;
4953
import org.gradle.api.tasks.compile.JavaCompile;
54+
import org.gradle.internal.Actions;
5055
import org.gradle.language.base.plugins.LifecycleBasePlugin;
5156
import org.gradle.plugins.ide.eclipse.model.EclipseModel;
5257
import org.jetbrains.annotations.VisibleForTesting;
@@ -77,9 +82,14 @@ public abstract class ForgeDevExtension {
7782

7883
protected abstract @Inject ProjectLayout getProjectLayout();
7984

85+
private final Project project;
86+
private final Provider<Boolean> isCi;
87+
8088
@Inject
8189
public ForgeDevExtension(ForgeDevPlugin plugin, Project project) {
8290
this.mavenizerRepo.set(plugin.globalCaches().dir("repo").map(this.problems.ensureFileLocation()));
91+
this.project = project;
92+
this.isCi = getProviders().of(CIRuntime.class, it -> {});
8393
this.setup(plugin, project);
8494
}
8595

@@ -101,6 +111,25 @@ public Configuration getMinecraftConfiguration() {
101111
return this.minecraftDepsConfiguration;
102112
}
103113

114+
public Installer installer() {
115+
return installer(Installer.DEFAULT_NAME);
116+
}
117+
public Installer installer(Action<Installer> action) {
118+
return installer(Installer.DEFAULT_NAME, action);
119+
}
120+
public Installer installer(String name) {
121+
return installer(name, i -> {});
122+
}
123+
public Installer installer(String name, Action<Installer> action) {
124+
var ret = Installer.register(this.project, this, name);
125+
action.execute(ret);
126+
return ret;
127+
}
128+
129+
public boolean isCi() {
130+
return this.isCi.get();
131+
}
132+
104133
private void setup(ForgeDevPlugin plugin, Project project) {
105134
var tasks = project.getTasks();
106135

src/main/groovy/net/minecraftforge/forgedev/Tools.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ private Tools() { }
1414
public static final Tool DIFFPATCH = Tool.of("diffpatch", "io.codechicken:DiffPatch:2.1.0.42:all", Constants.MAVEN_CENTRAL, 8);
1515
public static final Tool BINPATCH = Tool.ofForge("binpatcher", "net.minecraftforge:binarypatcher:1.2.2:fatjar", 8);
1616
public static final Tool INSTALLERTOOLS = Tool.ofForge("installertools", "net.minecraftforge:installertools:1.4.4:fatjar", 8);
17+
public static final Tool INSTALLER = Tool.ofForge("installer", "net.minecraftforge:installer:2.2.9:fatjar", 8);
1718
public static final Tool JARCOMPATIBILITYCHECKER = Tool.ofForge("jarcompatibilitychecker", "net.minecraftforge:JarCompatibilityChecker:0.1.28:all", 8);
1819
public static final Tool RENAMER = Tool.ofForge("renamer", "net.minecraftforge:ForgeAutoRenamingTool:1.1.1:all", 8);
1920
public static final Tool SRG2SRC = Tool.ofForge("srg2source", "net.minecraftforge:Srg2Source:8.1.1:fatjar", 17);

src/main/groovy/net/minecraftforge/forgedev/Util.java

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,7 @@
55
package net.minecraftforge.forgedev;
66

77
import net.minecraftforge.gradleutils.shared.SharedUtil;
8-
import org.gradle.TaskExecutionRequest;
9-
import org.gradle.api.Action;
10-
import org.gradle.api.Project;
11-
import org.gradle.api.plugins.JavaPluginExtension;
12-
import org.gradle.api.provider.Provider;
138
import org.gradle.api.specs.Spec;
14-
import org.gradle.api.tasks.TaskProvider;
15-
import org.gradle.jvm.toolchain.JavaLanguageVersion;
16-
import org.gradle.jvm.toolchain.JavaLauncher;
17-
import org.gradle.jvm.toolchain.JavaToolchainService;
18-
import org.gradle.jvm.toolchain.JavaToolchainSpec;
19-
import org.jetbrains.annotations.Nullable;
20-
21-
import java.io.File;
22-
import java.io.OutputStream;
23-
import java.util.ArrayList;
24-
import java.util.Collections;
25-
import java.util.List;
26-
import java.util.Objects;
27-
import java.util.concurrent.Callable;
289

2910
public final class Util extends SharedUtil {
3011
private Util() { }

src/main/groovy/net/minecraftforge/forgedev/legacy/tasks/CheckForgeJarCompatibility.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,17 @@ public static TaskProvider<CheckJarCompatibility> register(Project project, Stri
104104
task.getInputJar().set(reobfJar.flatMap(LegacyReobfuscateJar::getOutput));
105105
});
106106
checkJarCompatibility.configure(action);
107+
108+
var providers = project.getProviders();
109+
var hasMaven = providers.environmentVariable("MAVEN_USER").isPresent() && providers.environmentVariable("MAVEN_PASSWORD").isPresent();
110+
var checkCompatibility = providers.gradleProperty("net.minecraftforge.forge.build.check.compatibility").map(Boolean::parseBoolean).getOrElse(false);
111+
112+
if (!hasMaven && checkCompatibility) {
113+
project.getTasks().named("check", task -> {
114+
task.dependsOn(checkJarCompatibility);
115+
});
116+
}
117+
107118
return checkJarCompatibility;
108119
}
109120

src/main/groovy/net/minecraftforge/forgedev/legacy/tasks/DownloadDependency.groovy

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ import javax.inject.Inject
2323
@CompileStatic
2424
abstract class DownloadDependency extends DefaultTask {
2525
static TaskProvider<DownloadDependency> register(Project project, String name, Object dependency) {
26+
return project.tasks.register(name, DownloadDependency) {
27+
it.artifact = dependency;
28+
}
29+
}
30+
31+
public void setArtifact(Object dependency) {
2632
final def unpacked
2733
if (dependency instanceof ProviderConvertible<?>)
2834
unpacked = dependency.asProvider().get()
@@ -42,15 +48,13 @@ abstract class DownloadDependency extends DefaultTask {
4248
}
4349
)
4450

45-
project.tasks.register(name, DownloadDependency) {
46-
it.output.fileProvider(it.providers.provider {
47-
try {
48-
configuration.singleFile
49-
} catch (IllegalStateException e) {
50-
throw new IllegalArgumentException('Downloaded dependency variant is not a single file', e)
51-
}
52-
})
53-
}
51+
output.fileProvider(providers.provider {
52+
try {
53+
configuration.singleFile
54+
} catch (IllegalStateException e) {
55+
throw new IllegalArgumentException('Downloaded dependency variant is not a single file', e)
56+
}
57+
})
5458
}
5559

5660
abstract @OutputFile RegularFileProperty getOutput()

src/main/groovy/net/minecraftforge/forgedev/legacy/tasks/Util.groovy

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@ import groovy.transform.stc.ClosureParams
1212
import groovy.transform.stc.SimpleType
1313
import net.minecraftforge.forgedev.legacy.values.LibraryInfo
1414
import net.minecraftforge.forgedev.legacy.values.MinimalResolvedArtifact
15+
import net.minecraftforge.gradleutils.shared.SharedUtil
1516
import org.gradle.api.Project
1617
import org.gradle.api.Task
1718
import org.gradle.api.artifacts.Configuration
19+
import org.gradle.api.artifacts.Dependency
1820
import org.gradle.api.artifacts.ResolvedArtifact
21+
import org.gradle.api.provider.HasConfigurableValue
1922
import org.gradle.api.provider.MapProperty
2023
import org.gradle.api.provider.Provider
2124
import org.gradle.api.provider.SetProperty
@@ -181,11 +184,11 @@ final class Util {
181184
}
182185

183186
@CompileDynamic
184-
private static Provider<Map<String, MinimalResolvedArtifact>> artifactTree(Project project, String artifact, boolean transitive = true) {
187+
static Provider<Map<String, MinimalResolvedArtifact>> artifactTree(Project project, String artifact, boolean transitive = true) {
185188
return MinimalResolvedArtifact.from(project, project.configurations.detachedConfiguration(
186189
project.dependencies.create(artifact)
187190
).tap { it.transitive = transitive }).map { list ->
188-
var map = new HashMap<String, MinimalResolvedArtifact>(list.size())
191+
var map = new LinkedHashMap<String, MinimalResolvedArtifact>(list.size())
189192
for (var minimal in list) {
190193
map.put(minimal.info().key(), minimal)
191194
}
@@ -239,4 +242,32 @@ final class Util {
239242
}
240243
}
241244
}
245+
246+
@CompileDynamic
247+
static String asArtifactString(Object artifact) {
248+
def value = SharedUtil.unpack(artifact)
249+
if (!(value instanceof Dependency))
250+
throw new IllegalArgumentException("Cannot get non-dependency as artifact string! Found: $value.class")
251+
252+
def classifier = value.hasProperty('classifier') ? ":$value.classifier" : ''
253+
def extension = value.hasProperty('artifactType') ? "@$value.artifactType" : value.hasProperty('extension') ? "@$value.extension" : ''
254+
classifier = classifier != ':null' ? classifier : ''
255+
extension = extension != '@null' ? extension : ''
256+
257+
"$value.group:$value.name:$value.version$classifier$extension".toString()
258+
}
259+
260+
static <R extends HasConfigurableValue> R finalize(Project project, R ret) {
261+
ret.disallowChanges();
262+
ret.finalizeValueOnRead();
263+
return ret;
264+
}
265+
266+
static String capitalize(String s) {
267+
return s.capitalize();
268+
}
269+
270+
static String kebab(String s) {
271+
s.replaceAll('([A-Z])', '-$1').toLowerCase()
272+
}
242273
}

src/main/groovy/net/minecraftforge/forgedev/legacy/values/LibraryInfo.java

Lines changed: 58 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,39 @@
55
package net.minecraftforge.forgedev.legacy.values;
66

77
import net.minecraftforge.forgedev.legacy.tasks.Util;
8+
import org.gradle.api.Action;
89
import org.gradle.api.Project;
10+
import org.gradle.api.Transformer;
911
import org.gradle.api.artifacts.Configuration;
1012
import org.gradle.api.provider.Provider;
1113
import org.gradle.api.tasks.TaskProvider;
1214
import org.gradle.api.tasks.bundling.AbstractArchiveTask;
15+
import org.gradle.plugins.ide.eclipse.model.Library;
1316

1417
import java.io.File;
1518
import java.io.Serializable;
1619
import java.util.Collection;
1720
import java.util.HashMap;
21+
import java.util.LinkedHashMap;
22+
import java.util.List;
1823
import java.util.Map;
1924
import java.util.concurrent.Semaphore;
2025

2126
public record LibraryInfo(String name, Downloads downloads) implements Serializable {
2227
public record Downloads(ArtifactInfo artifact) implements Serializable {
23-
public record ArtifactInfo(String path, String url, String sha1, long size) implements Serializable {
28+
public static class ArtifactInfo implements Serializable {
29+
public String path;
30+
public String url;
31+
public String sha1;
32+
public long size;
33+
34+
public ArtifactInfo(String path, String url, String sha1, long size) {
35+
this.path = path;
36+
this.url = url;
37+
this.sha1 = sha1;
38+
this.size = size;
39+
}
40+
2441
public ArtifactInfo validateUrl(boolean offline) {
2542
if (offline || !url.startsWith("https://libraries.minecraft.net/"))
2643
return this;
@@ -57,41 +74,48 @@ public static Map<String, LibraryInfo> from(Collection<MinimalResolvedArtifact>
5774
return from(dependencies, Boolean.valueOf(validateUrl));
5875
}
5976

77+
public static LibraryInfo from(MinimalResolvedArtifact dependency) {
78+
var info = dependency.info();
79+
var url = "https://libraries.minecraft.net/" + info.path();
80+
if (!Util.checkExists(url))
81+
url = "https://maven.minecraftforge.net/" + info.path();
82+
83+
var file = dependency.file();
84+
var sha1 = Util.sha1(dependency.file());
85+
86+
return new LibraryInfo(
87+
info.name(),
88+
info.path(),
89+
url,
90+
sha1,
91+
file.length()
92+
);
93+
}
94+
6095
private static Map<String, LibraryInfo> from(Collection<MinimalResolvedArtifact> dependencies, Boolean offline) {
61-
var ret = new HashMap<String, LibraryInfo>(dependencies.size());
96+
var ret = new LinkedHashMap<String, LibraryInfo>(dependencies.size());
6297
var semaphore = new Semaphore(1, true);
6398
dependencies.parallelStream().forEachOrdered(dependency -> {
64-
var info = dependency.info();
65-
var url = "https://libraries.minecraft.net/" + info.path();
66-
if (!Util.checkExists(url))
67-
url = "https://maven.minecraftforge.net/" + info.path();
68-
69-
var file = dependency.file();
70-
var sha1 = Util.sha1(dependency.file());
99+
var library = from(dependency);
100+
if (offline != null)
101+
library = library.validateUrl(offline);
71102

72103
try {
73104
semaphore.acquire();
105+
ret.put(dependency.info().key(), library);
106+
semaphore.release();
74107
} catch (InterruptedException e) {
75108
throw new RuntimeException("Interrupted while trying to get library info for " + dependency.info(), e);
76109
}
77-
78-
var library = new LibraryInfo(
79-
info.name(),
80-
info.path(),
81-
url,
82-
sha1,
83-
file.length()
84-
);
85-
if (offline != null)
86-
library = library.validateUrl(offline);
87-
ret.put(info.key(), library);
88-
89-
semaphore.release();
90110
});
91111

92112
return ret;
93113
}
94114

115+
public static Provider<LibraryInfo> from(Project project, TaskProvider<? extends AbstractArchiveTask> task) {
116+
return MinimalResolvedArtifact.from(project, task).map(LibraryInfo::from);
117+
}
118+
95119
@SafeVarargs
96120
public static Provider<Map<String, LibraryInfo>> from(Project project, TaskProvider<? extends AbstractArchiveTask>... tasks) {
97121
var dependencies = project.getObjects().listProperty(MinimalResolvedArtifact.class);
@@ -100,17 +124,21 @@ public static Provider<Map<String, LibraryInfo>> from(Project project, TaskProvi
100124
}
101125

102126
var ret = project.getObjects().mapProperty(String.class, LibraryInfo.class).value(dependencies.map(LibraryInfo::from));
103-
104-
ret.disallowChanges();
105-
ret.finalizeValueOnRead();
106-
if (project.getState().getExecuted()) {
107-
ret.finalizeValue();
108-
}
109-
110-
return ret;
127+
return Util.finalize(project, ret);
111128
}
112129

113130
public static Provider<Map<String, LibraryInfo>> from(Project project, Configuration configuration) {
114131
return MinimalResolvedArtifact.from(project, configuration).map(LibraryInfo::from);
115132
}
133+
134+
public static List<LibraryInfo> toList(List<MinimalResolvedArtifact> list) {
135+
return list.stream().map(LibraryInfo::from).toList();
136+
}
137+
138+
public static Transformer<LibraryInfo, LibraryInfo> apply(Action<LibraryInfo> action) {
139+
return info -> {
140+
action.execute(info);
141+
return info;
142+
};
143+
}
116144
}

src/main/groovy/net/minecraftforge/forgedev/legacy/values/MavenInfo.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,32 @@ public int compareTo(MavenInfo that) {
2727
return this.key.compareTo(that.key);
2828
}
2929

30+
public static MavenInfo from(String gav) {
31+
var parts = gav.split(":");
32+
var group = parts[0];
33+
var name = parts[1];
34+
var version = parts[2];
35+
36+
String classifier = null;
37+
String extension = null;
38+
39+
if (parts.length > 3) {
40+
classifier = parts[3];
41+
var idx = classifier.indexOf('@');
42+
if (idx != -1) {
43+
classifier = classifier.substring(0, idx);
44+
extension = classifier.substring(idx + 1);
45+
}
46+
} else {
47+
var idx = version.indexOf('@');
48+
if (idx != -1) {
49+
version = version.substring(0, idx);
50+
extension = version.substring(idx + 1);
51+
}
52+
}
53+
return from(group, name, version, classifier, extension);
54+
}
55+
3056
public static MavenInfo from(String artGroup, String artName, String artVersion, @Nullable String artClassifier, @Nullable String artExtension) {
3157
if (artExtension == null)
3258
artExtension = "jar";

0 commit comments

Comments
 (0)