Skip to content

Commit

Permalink
Implement delayed resolve of dev config artifacts. (#140)
Browse files Browse the repository at this point in the history
  • Loading branch information
marchermans authored Apr 27, 2024
1 parent 993b9c3 commit 1bc3f8b
Show file tree
Hide file tree
Showing 60 changed files with 678 additions and 703 deletions.
8 changes: 4 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,9 @@ subprojects.forEach { Project subProject ->
subProject.dependencies.testImplementation "org.mockito:mockito-junit-jupiter:${project.mockito_version}"
subProject.dependencies.testImplementation "org.mockito:mockito-core:${project.mockito_version}"
subProject.dependencies.testImplementation "org.mockito:mockito-inline:${project.mockito_version}"
subProject.dependencies.testImplementation "net.neoforged.trainingwheels:trainingwheels-base:${project.trainingwheels_version}"
subProject.dependencies.testImplementation "net.neoforged.trainingwheels:trainingwheels-gradle-base:${project.trainingwheels_version}"
subProject.dependencies.testImplementation "net.neoforged.trainingwheels:trainingwheels-gradle-functional:${project.trainingwheels_version}"
subProject.dependencies.testImplementation "net.neoforged.trainingwheels:base:${project.trainingwheels_version}"
subProject.dependencies.testImplementation "net.neoforged.trainingwheels:gradle-base:${project.trainingwheels_version}"
subProject.dependencies.testImplementation "net.neoforged.trainingwheels:gradle-functional:${project.trainingwheels_version}"

//Exclude duplicates.
subProject.tasks.withType(Jar).configureEach { jarTask ->
Expand Down Expand Up @@ -163,7 +163,7 @@ subprojects.forEach { subProject ->
evalSubProject.dependencies.functionalTestImplementation("org.spockframework:spock-core:${project.spock_version}-groovy-${project.groovy_version}") { spec ->
spec.exclude group: 'org.codehaus.groovy'
}
evalSubProject.dependencies.functionalTestImplementation "net.neoforged.trainingwheels:trainingwheels-gradle-functional:${project.trainingwheels_version}"
evalSubProject.dependencies.functionalTestImplementation "net.neoforged.trainingwheels:gradle-functional:${project.trainingwheels_version}"

//Configure the plugin metadata, so we can publish it.
evalSubProject.gradlePlugin.plugins { NamedDomainObjectContainer<PluginDeclaration> plugins ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
import org.gradle.api.Project;
import org.gradle.api.artifacts.repositories.MavenArtifactRepository;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.provider.Provider;
import org.gradle.api.tasks.Delete;
import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.plugins.ide.eclipse.EclipsePlugin;
import org.gradle.plugins.ide.idea.IdeaPlugin;
Expand Down Expand Up @@ -72,6 +74,7 @@ public void apply(Project project) {
project.getExtensions().create(AccessTransformers.class, "accessTransformers", AccessTransformersExtension.class, project);
project.getExtensions().create("extensionManager", ExtensionManager.class, project);
project.getExtensions().create("clientExtraJarDependencyManager", ExtraJarDependencyManager.class, project);
final ConfigurationData configurationData = project.getExtensions().create( ConfigurationData.class, "configurationData", ConfigurationDataExtension.class, project);

final ExtensionManager extensionManager = project.getExtensions().getByType(ExtensionManager.class);

Expand Down Expand Up @@ -115,6 +118,10 @@ public void apply(Project project) {
);

IdeRunIntegrationManager.getInstance().setup(project);

project.getTasks().named("clean", Delete.class, delete -> {
delete.delete(configurationData.getLocation());
});
}

private void applyAfterEvaluate(final Project project) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package net.neoforged.gradle.common.extensions;

import net.minecraftforge.gdi.ConfigurableDSLElement;
import net.neoforged.gradle.dsl.common.extensions.ConfigurationData;
import org.gradle.api.Project;
import org.jetbrains.annotations.NotNull;

public abstract class ConfigurationDataExtension implements ConfigurableDSLElement<ConfigurationData>, ConfigurationData {

private final Project project;

public ConfigurationDataExtension(Project project) {
this.project = project;
getLocation().convention(getProject().getLayout().getProjectDirectory().dir(".gradle").dir("configuration"));
}

@Override
public Project getProject() {
return project;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@
import net.neoforged.gradle.dsl.common.util.CacheFileSelector;
import net.neoforged.gradle.dsl.common.util.DistributionType;
import net.neoforged.gradle.dsl.common.util.GameArtifact;
import net.neoforged.gradle.dsl.common.util.MinecraftVersionAndUrl;
import net.neoforged.gradle.util.HashFunction;
import net.neoforged.gradle.util.UrlConstants;
import org.gradle.api.Project;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.provider.Provider;
import org.gradle.api.tasks.TaskProvider;
import org.jetbrains.annotations.NotNull;

Expand Down Expand Up @@ -87,44 +89,36 @@ public final Map<CacheFileSelector, File> getCacheFiles() {

@Override
public final Map<GameArtifact, File> cacheGameVersion(String gameVersion, DistributionType side) {
gameVersion = resolveVersion(gameVersion);
final MinecraftVersionAndUrl resolvedVersion = resolveVersion(gameVersion);

final Map<GameArtifact, File> result = new EnumMap<>(GameArtifact.class);

final String finalGameVersion = gameVersion;

GameArtifact.LAUNCHER_MANIFEST.doWhenRequired(side, () -> result.put(GameArtifact.LAUNCHER_MANIFEST, this.cacheLauncherMetadata()));
GameArtifact.LAUNCHER_MANIFEST.doWhenRequired(side, () -> result.put(GameArtifact.LAUNCHER_MANIFEST, this.cacheLauncherMetadata()));
GameArtifact.VERSION_MANIFEST.doWhenRequired(side, () -> result.put(GameArtifact.VERSION_MANIFEST, this.cacheVersionManifest(finalGameVersion)));
GameArtifact.CLIENT_JAR.doWhenRequired(side, () -> result.put(GameArtifact.CLIENT_JAR, this.cacheVersionArtifact(finalGameVersion, DistributionType.CLIENT)));
GameArtifact.SERVER_JAR.doWhenRequired(side, () -> result.put(GameArtifact.SERVER_JAR, this.cacheVersionArtifact(finalGameVersion, DistributionType.SERVER)));
GameArtifact.CLIENT_MAPPINGS.doWhenRequired(side, () -> result.put(GameArtifact.CLIENT_MAPPINGS, this.cacheVersionMappings(finalGameVersion, DistributionType.CLIENT)));
GameArtifact.SERVER_MAPPINGS.doWhenRequired(side, () -> result.put(GameArtifact.SERVER_MAPPINGS, this.cacheVersionMappings(finalGameVersion, DistributionType.SERVER)));
GameArtifact.VERSION_MANIFEST.doWhenRequired(side, () -> result.put(GameArtifact.VERSION_MANIFEST, this.cacheVersionManifest(resolvedVersion)));
GameArtifact.CLIENT_JAR.doWhenRequired(side, () -> result.put(GameArtifact.CLIENT_JAR, this.cacheVersionArtifact(resolvedVersion, DistributionType.CLIENT)));
GameArtifact.SERVER_JAR.doWhenRequired(side, () -> result.put(GameArtifact.SERVER_JAR, this.cacheVersionArtifact(resolvedVersion, DistributionType.SERVER)));
GameArtifact.CLIENT_MAPPINGS.doWhenRequired(side, () -> result.put(GameArtifact.CLIENT_MAPPINGS, this.cacheVersionMappings(resolvedVersion, DistributionType.CLIENT)));
GameArtifact.SERVER_MAPPINGS.doWhenRequired(side, () -> result.put(GameArtifact.SERVER_MAPPINGS, this.cacheVersionMappings(resolvedVersion, DistributionType.SERVER)));

return result;
}

@Override
@NotNull
public final Map<GameArtifact, TaskProvider<? extends WithOutput>> cacheGameVersionTasks(final Project project, String gameVersion, final DistributionType side) {
gameVersion = resolveVersion(gameVersion);

final TaskKey key = new TaskKey(project, gameVersion, side);
final MinecraftVersionAndUrl resolvedVersion = resolveVersion(gameVersion);

final String finalGameVersion = gameVersion;
final TaskKey key = new TaskKey(project, resolvedVersion.getVersion(), side);

return tasks.computeIfAbsent(key, k -> {
final Map<GameArtifact, TaskProvider<? extends WithOutput>> results = new EnumMap<>(GameArtifact.class);

final TaskProvider<MinecraftLauncherFileCacheProvider> launcher = FileCacheUtils.createLauncherMetadataFileCacheProvidingTask(project);
final TaskProvider<MinecraftVersionManifestFileCacheProvider> manifest = FileCacheUtils.createVersionManifestFileCacheProvidingTask(project, finalGameVersion, launcher);
final TaskProvider<MinecraftVersionManifestFileCacheProvider> manifest = FileCacheUtils.createVersionManifestFileCacheProvidingTask(project, resolvedVersion.getVersion());

GameArtifact.LAUNCHER_MANIFEST.doWhenRequired(side, () -> results.put(GameArtifact.LAUNCHER_MANIFEST, launcher));
GameArtifact.VERSION_MANIFEST.doWhenRequired(side, () -> results.put(GameArtifact.VERSION_MANIFEST, manifest));
GameArtifact.CLIENT_JAR.doWhenRequired(side, () -> results.put(GameArtifact.CLIENT_JAR, FileCacheUtils.createArtifactFileCacheProvidingTask(project, finalGameVersion, DistributionType.CLIENT, MinecraftArtifactType.EXECUTABLE, manifest, results.values())));
GameArtifact.SERVER_JAR.doWhenRequired(side, () -> results.put(GameArtifact.SERVER_JAR, FileCacheUtils.createArtifactFileCacheProvidingTask(project, finalGameVersion, DistributionType.SERVER, MinecraftArtifactType.EXECUTABLE, manifest, results.values())));
GameArtifact.CLIENT_MAPPINGS.doWhenRequired(side, () -> results.put(GameArtifact.CLIENT_MAPPINGS, FileCacheUtils.createArtifactFileCacheProvidingTask(project, finalGameVersion, DistributionType.CLIENT, MinecraftArtifactType.MAPPINGS, manifest, results.values())));
GameArtifact.SERVER_MAPPINGS.doWhenRequired(side, () -> results.put(GameArtifact.SERVER_MAPPINGS, FileCacheUtils.createArtifactFileCacheProvidingTask(project, finalGameVersion, DistributionType.SERVER, MinecraftArtifactType.MAPPINGS, manifest, results.values())));
GameArtifact.CLIENT_JAR.doWhenRequired(side, () -> results.put(GameArtifact.CLIENT_JAR, FileCacheUtils.createArtifactFileCacheProvidingTask(project, resolvedVersion.getVersion(), DistributionType.CLIENT, MinecraftArtifactType.EXECUTABLE, manifest, results.values())));
GameArtifact.SERVER_JAR.doWhenRequired(side, () -> results.put(GameArtifact.SERVER_JAR, FileCacheUtils.createArtifactFileCacheProvidingTask(project, resolvedVersion.getVersion(), DistributionType.SERVER, MinecraftArtifactType.EXECUTABLE, manifest, results.values())));
GameArtifact.CLIENT_MAPPINGS.doWhenRequired(side, () -> results.put(GameArtifact.CLIENT_MAPPINGS, FileCacheUtils.createArtifactFileCacheProvidingTask(project, resolvedVersion.getVersion(), DistributionType.CLIENT, MinecraftArtifactType.MAPPINGS, manifest, results.values())));
GameArtifact.SERVER_MAPPINGS.doWhenRequired(side, () -> results.put(GameArtifact.SERVER_MAPPINGS, FileCacheUtils.createArtifactFileCacheProvidingTask(project, resolvedVersion.getVersion(), DistributionType.SERVER, MinecraftArtifactType.MAPPINGS, manifest, results.values())));

return results;
});
Expand All @@ -137,29 +131,40 @@ public final File cacheLauncherMetadata() {

@Override
public final File cacheVersionManifest(String gameVersion) {
gameVersion = resolveVersion(gameVersion);
final MinecraftVersionAndUrl resolvedVersion = resolveVersion(gameVersion);

return this.cacheVersionManifest(resolvedVersion);
}

final CacheFileSelector cacheFileSelector = CacheFileSelector.forVersionJson(gameVersion);
final String finalGameVersion = gameVersion;
return this.cacheFiles.computeIfAbsent(cacheFileSelector, selector -> downloadVersionManifestToCache(project, getCacheDirectory().get().getAsFile(), finalGameVersion));
public final File cacheVersionManifest(MinecraftVersionAndUrl resolvedVersion) {
final CacheFileSelector cacheFileSelector = CacheFileSelector.forVersionJson(resolvedVersion.getVersion());
return this.cacheFiles.computeIfAbsent(cacheFileSelector, selector -> downloadVersionManifestToCache(project, getCacheDirectory().get().getAsFile(), resolvedVersion.getVersion()));
}

@Override
public final File cacheVersionArtifact(String gameVersion, DistributionType side) {
gameVersion = resolveVersion(gameVersion);
final MinecraftVersionAndUrl resolvedVersion = resolveVersion(gameVersion);

final CacheFileSelector cacheFileSelector = CacheFileSelector.forVersionJar(resolvedVersion.getVersion(), side.getName());
return this.cacheFiles.computeIfAbsent(cacheFileSelector, selector -> downloadVersionArtifactToCache(project, getCacheDirectory().get().getAsFile(), resolvedVersion.getVersion(), side));
}

final CacheFileSelector cacheFileSelector = CacheFileSelector.forVersionJar(gameVersion, side.getName());
final String finalGameVersion = gameVersion;
return this.cacheFiles.computeIfAbsent(cacheFileSelector, selector -> downloadVersionArtifactToCache(project, getCacheDirectory().get().getAsFile(), finalGameVersion, side));
public final File cacheVersionArtifact(MinecraftVersionAndUrl resolvedVersion, DistributionType side) {
final CacheFileSelector cacheFileSelector = CacheFileSelector.forVersionJar(resolvedVersion.getVersion(), side.getName());
return this.cacheFiles.computeIfAbsent(cacheFileSelector, selector -> downloadVersionArtifactToCache(project, getCacheDirectory().get().getAsFile(), resolvedVersion.getVersion(), side));
}

@Override
public final File cacheVersionMappings(String gameVersion, DistributionType side) {
gameVersion = resolveVersion(gameVersion);
public final File cacheVersionMappings(@NotNull String gameVersion, DistributionType side) {
final MinecraftVersionAndUrl resolvedVersion = resolveVersion(gameVersion);

final CacheFileSelector cacheFileSelector = CacheFileSelector.forVersionMappings(gameVersion, side.getName());
final String finalGameVersion = gameVersion;
return this.cacheFiles.computeIfAbsent(cacheFileSelector, selector -> downloadVersionMappingsToCache(project, getCacheDirectory().get().getAsFile(), finalGameVersion, side));
final CacheFileSelector cacheFileSelector = CacheFileSelector.forVersionMappings(resolvedVersion.getVersion(), side.getName());
return this.cacheFiles.computeIfAbsent(cacheFileSelector, selector -> downloadVersionMappingsToCache(project, getCacheDirectory().get().getAsFile(), resolvedVersion.getVersion(), side));
}

public final File cacheVersionMappings(@NotNull MinecraftVersionAndUrl resolvedVersion, DistributionType side) {
final CacheFileSelector cacheFileSelector = CacheFileSelector.forVersionMappings(resolvedVersion.getVersion(), side.getName());
return this.cacheFiles.computeIfAbsent(cacheFileSelector, selector -> downloadVersionMappingsToCache(project, getCacheDirectory().get().getAsFile(), resolvedVersion.getVersion(), side));
}

@Override
Expand Down Expand Up @@ -195,31 +200,31 @@ private File downloadVersionManifestToCache(Project project, final File cacheDir
}

private File downloadVersionArtifactToCache(final Project project, final File cacheDirectory, String minecraftVersion, final DistributionType side) {
minecraftVersion = resolveVersion(minecraftVersion);
final MinecraftVersionAndUrl resolvedVersion = resolveVersion(minecraftVersion);

return doDownloadVersionDownloadToCache(project,
cacheDirectory,
minecraftVersion,
resolvedVersion.getVersion(),
side.getName(),
CacheFileSelector.forVersionJar(minecraftVersion, side.getName()),
String.format("Failed to download game artifact %s for %s", side.getName(), minecraftVersion));
CacheFileSelector.forVersionJar(resolvedVersion.getVersion(), side.getName()),
String.format("Failed to download game artifact %s for %s", side.getName(), resolvedVersion.getVersion()));
}

private File downloadVersionMappingsToCache(final Project project, final File cacheDirectory, String minecraftVersion, final DistributionType side) {
minecraftVersion = resolveVersion(minecraftVersion);
final MinecraftVersionAndUrl resolvedVersion = resolveVersion(minecraftVersion);

return doDownloadVersionDownloadToCache(project,
cacheDirectory,
minecraftVersion,
resolvedVersion.getVersion(),
String.format("%s_mappings", side.getName()),
CacheFileSelector.forVersionMappings(minecraftVersion, side.getName()),
String.format("Failed to download game mappings of %s for %s", side.getName(), minecraftVersion));
CacheFileSelector.forVersionMappings(resolvedVersion.getVersion(), side.getName()),
String.format("Failed to download game mappings of %s for %s", side.getName(), resolvedVersion.getVersion()));
}

private File doDownloadVersionDownloadToCache(Project project, File cacheDirectory, String minecraftVersion, final String artifact, final CacheFileSelector cacheFileSelector, final String potentialError) {
minecraftVersion = resolveVersion(minecraftVersion);
final MinecraftVersionAndUrl minecraftVersionAndUrl = resolveVersion(minecraftVersion);

final File versionManifestFile = this.cacheVersionManifest(minecraftVersion);
final File versionManifestFile = this.cacheVersionManifest(minecraftVersionAndUrl);

try {
JsonObject json = SerializationUtils.fromJson(versionManifestFile, JsonObject.class);
Expand Down Expand Up @@ -258,18 +263,21 @@ private void downloadJsonTo(Project project, String url, File file) {
}

@Override
public String resolveVersion(final String gameVersion) {
if (!Objects.equals(gameVersion, "+"))
return gameVersion;

public MinecraftVersionAndUrl resolveVersion(final String gameVersion) {
final File launcherMetadata = this.cacheLauncherMetadata();

JsonObject json = SerializationUtils.fromJson(launcherMetadata, JsonObject.class);

for (JsonElement e : json.getAsJsonArray("versions")) {
return e.getAsJsonObject().get("id").getAsString();
if (gameVersion.equals("+") || e.getAsJsonObject().get("id").getAsString().equals(gameVersion)) {
return new MinecraftVersionAndUrl(e.getAsJsonObject().get("id").getAsString(), e.getAsJsonObject().get("url").getAsString());
}
}

throw new IllegalStateException("Could not find the correct version json.");
}

public Provider<MinecraftVersionAndUrl> resolveVersion(Provider<String> gameVersion) {
return gameVersion.map(this::resolveVersion);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
import javax.inject.Inject;
import javax.xml.stream.XMLStreamException;
import java.io.IOException;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.function.Consumer;
Expand Down Expand Up @@ -164,18 +166,15 @@ private void writeDummyDataIfNeeded(
final Path baseDir = jarFile.getParent();
final Path metaFile = baseDir.resolve(String.format("ivy-%s-fg%d.xml", entry.getVersion(), METADATA_VERSION));

if (Files.exists(metaFile)) {
FileUtils.delete(metaFile);
writeIvyMetadataFile(entry, jarFile, baseDir, metaFile);
return;
}

writeIvyMetadataFile(entry, jarFile, baseDir, metaFile);

Files.deleteIfExists(jarFile);
Files.createFile(jarFile);

final Path sourcesFile = entry.asSources().buildArtifactPath(getRepositoryDirectory().get().getAsFile().toPath());
Files.deleteIfExists(sourcesFile);
Files.createFile(sourcesFile);

writeDummyDependencyDataIfNeeded(entry);
}

Expand Down
Loading

0 comments on commit 1bc3f8b

Please sign in to comment.