Skip to content

Commit c9a2b31

Browse files
committed
Fix offline mode support and enhance task caching mechanisms
1 parent 2cdd454 commit c9a2b31

23 files changed

Lines changed: 444 additions & 181 deletions

File tree

common/src/main/java/net/neoforged/gradle/common/runtime/extensions/CommonRuntimeExtension.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@
1515
import net.neoforged.gradle.dsl.common.extensions.subsystems.Subsystems;
1616
import net.neoforged.gradle.dsl.common.runtime.extensions.CommonRuntimes;
1717
import net.neoforged.gradle.dsl.common.runtime.spec.Specification;
18+
import net.neoforged.gradle.dsl.common.runtime.tasks.AsPartOfStep;
1819
import net.neoforged.gradle.dsl.common.runtime.tasks.Runtime;
1920
import net.neoforged.gradle.dsl.common.runtime.tasks.tree.TaskCustomizer;
2021
import net.neoforged.gradle.dsl.common.tasks.WithOutput;
2122
import net.neoforged.gradle.dsl.common.util.CacheableMinecraftVersion;
2223
import net.neoforged.gradle.dsl.common.util.CommonRuntimeUtils;
2324
import net.neoforged.gradle.dsl.common.util.GameArtifact;
24-
import net.neoforged.gradle.util.TransformerUtils;
2525
import org.gradle.api.Action;
2626
import org.gradle.api.Project;
2727
import org.gradle.api.Task;
@@ -77,6 +77,15 @@ public static void configureCommonRuntimeTaskParameters(Runtime runtimeTask, Map
7777
}
7878
}
7979

80+
public static <T extends WithOutput & Task & AsPartOfStep> void configureOutputForSimpleStepTaskParameters(T runtimeTask, String step, Specification spec, File runtimeDirectory) {
81+
runtimeTask.getStepName().set(step);
82+
runtimeTask.getRuntimeDirectory().set(runtimeDirectory);
83+
84+
for (TaskCustomizer<?> taskCustomizer : spec.getTaskCustomizers().get(step)) {
85+
taskCustomizer.apply(runtimeTask);
86+
}
87+
}
88+
8089
public static void configureCommonRuntimeTaskParameters(Runtime runtime, CommonRuntimeDefinition<?> runtimeDefinition, File workingDirectory) {
8190
configureCommonRuntimeTaskParameters(runtime, runtimeDefinition.getSpecification(), workingDirectory);
8291
runtime.getJavaVersion().set(runtimeDefinition.getRequiredJavaVersion());
@@ -299,16 +308,12 @@ protected final TaskProvider<DownloadAssets> createDownloadAssetsTasks(final Com
299308
});
300309
}
301310

302-
protected final TaskProvider<ExtractNatives> createExtractNativesTasks(final CommonRuntimeSpecification specification, final Map<String, String> symbolicDataSources, final File runtimeDirectory, final Provider<VersionJson> versionJson) {
311+
protected final TaskProvider<ExtractNatives> createExtractNativesTasks(final CommonRuntimeSpecification specification, final File runtimeDirectory, final Provider<VersionJson> versionJson) {
303312
return specification.getProject().getTasks().register(CommonRuntimeUtils.buildTaskName(specification, "extractNatives"), ExtractNatives.class, task -> {
304313
task.getVersionJson().set(versionJson);
305314

306-
configureCommonRuntimeTaskParameters(task, symbolicDataSources, "extractNatives", specification, runtimeDirectory);
315+
configureOutputForSimpleStepTaskParameters(task, "extractNatives", specification, runtimeDirectory);
307316
task.getOutputDirectory().set(task.getStepsDirectory().map(dir -> dir.dir("extractNatives")));
308317
});
309318
}
310-
311-
protected final TaskProvider<ExtractNatives> createExtractNativesTasks(final CommonRuntimeSpecification specification, final File runtimeDirectory, final Provider<VersionJson> versionJson) {
312-
return createExtractNativesTasks(specification, Collections.emptyMap(), runtimeDirectory, versionJson);
313-
}
314319
}

common/src/main/java/net/neoforged/gradle/common/runtime/specification/CommonRuntimeSpecification.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import net.neoforged.gradle.common.runtime.definition.CommonRuntimeDefinition;
77
import net.neoforged.gradle.common.runtime.extensions.CommonRuntimeExtension;
88
import net.neoforged.gradle.dsl.common.runtime.spec.Specification;
9+
import net.neoforged.gradle.dsl.common.runtime.tasks.AsPartOfStep;
910
import net.neoforged.gradle.dsl.common.runtime.tasks.tree.TaskCustomizer;
1011
import net.neoforged.gradle.dsl.common.runtime.tasks.tree.TaskTreeAdapter;
1112
import net.neoforged.gradle.dsl.common.util.DistributionType;
@@ -107,7 +108,7 @@ public Multimap<String, TaskTreeAdapter> getPostTypeAdapters() {
107108

108109
@NotNull
109110
@Override
110-
public Multimap<String, TaskCustomizer<? extends Task>> getTaskCustomizers() {
111+
public Multimap<String, TaskCustomizer<?>> getTaskCustomizers() {
111112
return taskCustomizers;
112113
}
113114

@@ -228,7 +229,7 @@ public final B withPostTaskAdapter(final String taskTypeName, final TaskTreeAdap
228229

229230
@Override
230231
@NotNull
231-
public final <T extends Task> B withTaskCustomizer(final String taskTypeName, Class<T> taskType, Consumer<T> customizer) {
232+
public final <T extends Task & AsPartOfStep> B withTaskCustomizer(final String taskTypeName, Class<T> taskType, Consumer<T> customizer) {
232233
this.taskCustomizers.put(taskTypeName, new TaskCustomizer<>(taskType, customizer));
233234
return getThis();
234235
}

common/src/main/java/net/neoforged/gradle/common/runtime/tasks/DownloadAssets.java

Lines changed: 64 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.google.common.collect.Maps;
44
import net.neoforged.gradle.common.runtime.tasks.action.DownloadFileAction;
55
import net.neoforged.gradle.common.services.caching.CachedExecutionService;
6+
import net.neoforged.gradle.common.services.caching.hasher.TaskHashingAware;
67
import net.neoforged.gradle.common.services.caching.jobs.ICacheableJob;
78
import net.neoforged.gradle.common.util.FileCacheUtils;
89
import net.neoforged.gradle.common.util.SerializationUtils;
@@ -25,16 +26,18 @@
2526
import javax.inject.Inject;
2627
import java.io.File;
2728
import java.io.IOException;
29+
import java.util.HashMap;
2830
import java.util.Map;
2931

30-
@SuppressWarnings({"UnstableApiUsage"})
3132
@CacheableTask
32-
public abstract class DownloadAssets extends DefaultTask implements WithWorkspace {
33+
public abstract class DownloadAssets extends DefaultTask implements WithWorkspace, TaskHashingAware
34+
{
3335

3436
private final Provider<Directory> assetsCache;
3537
private final Provider<Directory> assetsObjects;
3638

37-
public DownloadAssets() {
39+
public DownloadAssets()
40+
{
3841
this.assetsCache = getAssetsDirectory(getProject());
3942
this.assetsObjects = assetsCache.map(directory -> directory.dir("objects"));
4043

@@ -47,40 +50,54 @@ public DownloadAssets() {
4750
getIsOffline().convention(getProject().getGradle().getStartParameter().isOffline());
4851
}
4952

50-
public static @NotNull Provider<Directory> getAssetsDirectory(final Project project) {
53+
@Override
54+
public Map<String, Object> getHashableProperties()
55+
{
56+
var properties = new HashMap<>(getInputs().getProperties());
57+
properties.remove("isOffline"); //We don't care about the offline mode!
58+
return properties;
59+
}
60+
61+
public static @NotNull Provider<Directory> getAssetsDirectory(final Project project)
62+
{
5163
return FileCacheUtils.getAssetsCacheDirectory(project).map(TransformerUtils.ensureExists());
5264
}
5365

5466
@Deprecated
55-
public static @NotNull Provider<Directory> getAssetsDirectory(final Project project, final Provider<VersionJson> versionJsonProvider) {
67+
public static @NotNull Provider<Directory> getAssetsDirectory(final Project project, final Provider<VersionJson> versionJsonProvider)
68+
{
5669
return getAssetsDirectory(project);
5770
}
5871

59-
protected Provider<File> getFileInAssetsDirectory(final String fileName) {
72+
protected Provider<File> getFileInAssetsDirectory(final String fileName)
73+
{
6074
return assetsObjects.map(directory -> directory.file(fileName).getAsFile());
6175
}
6276

63-
protected Provider<RegularFile> getRegularFileInAssetsDirectory(final Provider<String> fileName) {
77+
protected Provider<RegularFile> getRegularFileInAssetsDirectory(final Provider<String> fileName)
78+
{
6479
return assetsCache.flatMap(directory -> fileName.map(directory::file));
6580
}
6681

6782
@ServiceReference(CachedExecutionService.NAME)
6883
public abstract Property<CachedExecutionService> getCache();
6984

7085
@TaskAction
71-
public void run() throws IOException {
86+
public void run() throws IOException
87+
{
7288
getCache().get()
73-
.cached(
74-
this,
75-
ICacheableJob.Initial.file("assetIndex", this::downloadAssetIndex, getAssetIndexFile())
76-
)
77-
.withStage(
78-
ICacheableJob.Initial.directory("assets", assetsObjects, this::downloadAssets)
79-
)
80-
.execute();
89+
.cached(
90+
this,
91+
ICacheableJob.Initial.file("assetIndex", this::downloadAssetIndex, getAssetIndexFile())
92+
)
93+
.withStage(
94+
ICacheableJob.Initial.directory("assets", assetsObjects, this::downloadAssets)
95+
)
96+
.execute();
8197
}
8298

83-
private Void downloadAssetIndex() {
99+
private Void downloadAssetIndex()
100+
{
84101
final VersionJson json = getVersionJson().get();
85102
final VersionJson.AssetIndex assetIndexData = json.getAssetIndex();
86103

@@ -98,16 +115,17 @@ private Void downloadAssetIndex() {
98115
return null;
99116
}
100117

101-
private Void downloadAssets() {
118+
private Void downloadAssets()
119+
{
102120
final AssetIndex assetIndex = SerializationUtils.fromJson(getAssetIndexFile().getAsFile().get(), AssetIndex.class);
103121

104122
final WorkQueue executor = getWorkerExecutor().noIsolation();
105123

106124
assetIndex.getObjects().values().stream().distinct().forEach((asset) -> {
107125
final Provider<File> assetFile = getFileInAssetsDirectory(asset.getPath());
108126
final Provider<String> assetUrl = getAssetRepository()
109-
.map(repo -> repo.endsWith("/") ? repo : repo + "/")
110-
.map(TransformerUtils.guard(repository -> repository + asset.getPath()));
127+
.map(repo -> repo.endsWith("/") ? repo : repo + "/")
128+
.map(TransformerUtils.guard(repository -> repository + asset.getPath()));
111129

112130
executor.submit(DownloadFileAction.class, params -> {
113131
params.getIsOffline().set(getIsOffline());
@@ -152,45 +170,60 @@ private Void downloadAssets() {
152170
@Input
153171
public abstract Property<Boolean> getIsOffline();
154172

155-
private static class AssetIndex {
173+
private static class AssetIndex
174+
{
156175
private Map<String, Asset> objects = Maps.newHashMap();
157176

158-
public Map<String, Asset> getObjects() {
177+
public Map<String, Asset> getObjects()
178+
{
159179
return objects;
160180
}
161181

162-
public void setObjects(Map<String, Asset> objects) {
182+
public void setObjects(Map<String, Asset> objects)
183+
{
163184
this.objects = objects;
164185
}
165186
}
166187

167-
private static class Asset {
188+
private static class Asset
189+
{
168190
private String hash;
169191

170-
public String getHash() {
192+
public String getHash()
193+
{
171194
return hash;
172195
}
173196

174-
public void setHash(String hash) {
197+
public void setHash(String hash)
198+
{
175199
this.hash = hash;
176200
}
177201

178-
public String getPath() {
202+
public String getPath()
203+
{
179204
return hash.substring(0, 2) + '/' + hash;
180205
}
181206

182207
@Override
183-
public boolean equals(Object o) {
184-
if (this == o) return true;
185-
if (!(o instanceof Asset)) return false;
208+
public boolean equals(Object o)
209+
{
210+
if (this == o)
211+
{
212+
return true;
213+
}
214+
if (!(o instanceof Asset))
215+
{
216+
return false;
217+
}
186218

187219
Asset asset = (Asset) o;
188220

189221
return getHash().equals(asset.getHash());
190222
}
191223

192224
@Override
193-
public int hashCode() {
225+
public int hashCode()
226+
{
194227
return getHash().hashCode();
195228
}
196229
}

common/src/main/java/net/neoforged/gradle/common/runtime/tasks/ExtractNatives.java

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
package net.neoforged.gradle.common.runtime.tasks;
22

3+
import net.neoforged.gradle.common.services.caching.CachedExecutionService;
4+
import net.neoforged.gradle.common.services.caching.hasher.TaskHashingAware;
5+
import net.neoforged.gradle.common.services.caching.jobs.ICacheableJob;
6+
import net.neoforged.gradle.dsl.common.runtime.tasks.AsPartOfStep;
7+
import net.neoforged.gradle.dsl.common.tasks.NeoGradleBase;
8+
import net.neoforged.gradle.dsl.common.tasks.WithOutput;
39
import net.neoforged.gradle.util.TransformerUtils;
410
import net.neoforged.gradle.common.runtime.tasks.action.DownloadFileAction;
511
import net.neoforged.gradle.common.runtime.tasks.action.ExtractFileAction;
@@ -9,28 +15,65 @@
915
import org.gradle.api.file.RegularFileProperty;
1016
import org.gradle.api.provider.Property;
1117
import org.gradle.api.provider.Provider;
18+
import org.gradle.api.services.ServiceReference;
1219
import org.gradle.api.tasks.*;
1320
import org.gradle.workers.WorkQueue;
1421
import org.gradle.workers.WorkerExecutor;
1522

1623
import javax.inject.Inject;
1724
import java.io.File;
25+
import java.io.IOException;
26+
import java.util.HashMap;
27+
import java.util.Map;
1828

1929
@CacheableTask()
20-
public abstract class ExtractNatives extends DefaultRuntime {
30+
public abstract class ExtractNatives extends NeoGradleBase implements TaskHashingAware, WithOutput, AsPartOfStep
31+
{
2132

2233
public ExtractNatives() {
34+
//Sets up the base configuration for directories and outputs.
35+
getStepsDirectory().convention(getRuntimeDirectory().dir("steps"));
36+
getOutputDirectory().convention(getStepsDirectory().flatMap(d -> getStepName().map(d::dir)));
37+
2338
getVersionJson().convention(getVersionJsonFile().map(TransformerUtils.guard(file -> VersionJson.get(file.getAsFile()))));
2439
getLibrariesDirectory().convention(getOutputDirectory().map(dir -> dir.dir("libraries")));
40+
getIsOffline().convention(getProject().getGradle().getStartParameter().isOffline());
41+
}
42+
43+
@ServiceReference(CachedExecutionService.NAME)
44+
public abstract Property<CachedExecutionService> getCache();
45+
46+
@Override
47+
public Map<String, Object> getHashableProperties()
48+
{
49+
var properties = new HashMap<>(getInputs().getProperties());
50+
properties.remove("isOffline"); //We don't care about the offline mode!
51+
return properties;
2552
}
2653

2754
@TaskAction
28-
public void extract() {
55+
public void run() throws IOException
56+
{
57+
getCache().get()
58+
.cached(
59+
this,
60+
ICacheableJob.Initial.directory("nativesAndLibraries", getLibrariesDirectory(), this::doDownloadAndExtract)
61+
)
62+
.execute();
63+
}
64+
65+
private File doDownloadAndExtract() {
2966
downloadNatives();
3067
extractNatives();
68+
69+
final File librariesDirectory = ensureFileWorkspaceReady(getLibrariesDirectory().get().getAsFile());
70+
if (!librariesDirectory.exists())
71+
librariesDirectory.mkdirs();
72+
73+
return librariesDirectory;
3174
}
3275

33-
private void downloadNatives() {
76+
private File downloadNatives() {
3477
final VersionJson versionJson = getVersionJson().get();
3578

3679
final WorkQueue executor = getWorkerExecutor().noIsolation();
@@ -39,7 +82,7 @@ private void downloadNatives() {
3982
versionJson.getNatives().forEach(library -> {
4083
final File outputFile = new File(librariesDirectory, library.getPath());
4184
executor.submit(DownloadFileAction.class, params -> {
42-
params.getIsOffline().set(getProject().getGradle().getStartParameter().isOffline());
85+
params.getIsOffline().set(getIsOffline());
4386
params.getShouldValidateHash().set(true);
4487
params.getOutputFile().set(outputFile);
4588
params.getUrl().set(library.getUrl().toString());
@@ -48,6 +91,8 @@ private void downloadNatives() {
4891
});
4992

5093
executor.await();
94+
95+
return librariesDirectory;
5196
}
5297

5398
private void extractNatives() {
@@ -90,6 +135,9 @@ private void extractNatives() {
90135
@OutputDirectory
91136
public abstract DirectoryProperty getLibrariesDirectory();
92137

138+
@Input
139+
public abstract Property<Boolean> getIsOffline();
140+
93141
@Override
94142
public Provider<FileTree> getOutputAsTree()
95143
{

0 commit comments

Comments
 (0)