Skip to content

Commit

Permalink
Properly pass the artifact manifest
Browse files Browse the repository at this point in the history
  • Loading branch information
shartte committed Jun 2, 2024
1 parent 4d8256a commit 1b7af25
Show file tree
Hide file tree
Showing 9 changed files with 118 additions and 108 deletions.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
2 changes: 1 addition & 1 deletion gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import javax.inject.Inject;

public abstract class NeoFormRuntime {
private static final String DEFAULT_NFRT_VERSION = "0.1.36";
private static final String DEFAULT_NFRT_VERSION = "0.1.38";

@Inject
public NeoFormRuntime(Project project) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,26 @@
import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Classpath;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.Internal;
import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;
import org.gradle.work.DisableCachingByDefault;

import javax.inject.Inject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;

@DisableCachingByDefault(because = "Implements its own caching")
abstract class CreateMinecraftArtifactsTask extends NeoFormRuntimeTask {
@Inject
public CreateMinecraftArtifactsTask() {
// When cache is disabled, the task is NEVER up-to-date to aid with debugging problems
getOutputs().upToDateWhen(task -> ((CreateMinecraftArtifactsTask) task).getEnableCache().get());
}

@InputFile
Expand All @@ -36,10 +39,6 @@ public CreateMinecraftArtifactsTask() {
@Input
abstract Property<String> getNeoForgeArtifact();

@Classpath
@InputFiles
abstract ConfigurableFileCollection getCompileClasspath();

@InputFiles
abstract ConfigurableFileCollection getAccessTransformers();

Expand Down
189 changes: 95 additions & 94 deletions src/main/java/net/neoforged/moddevgradle/internal/ModDevPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.ExternalModuleDependency;
import org.gradle.api.artifacts.ModuleDependency;
import org.gradle.api.artifacts.dsl.RepositoryHandler;
import org.gradle.api.artifacts.repositories.MavenArtifactRepository;
Expand Down Expand Up @@ -103,47 +104,11 @@ public void apply(Project project) {
}));
addTemporaryRepositories(repositories);

// Configuration for all artifact that should be passed to NFRT for preventing repeated downloads
var neoFormRuntimeArtifactManifestNeoForgeClasses = configurations.create("neoFormRuntimeArtifactManifestNeoForgeClasses", spec -> {
spec.setCanBeConsumed(false);
spec.setCanBeResolved(true);
spec.withDependencies(dependencies -> {
// Add the dep on NeoForge itself
dependencies.addLater(extension.getVersion().map(version -> {
return dependencyFactory.create("net.neoforged:neoforge:" + version)
.capabilities(caps -> {
caps.requireCapability("net.neoforged:neoforge-moddev-bundle");
});
}));
});
});
// Configuration for all artifact that should be passed to NFRT for preventing repeated downloads
var neoFormRuntimeArtifactManifestNeoForgeSources = configurations.create("neoFormRuntimeArtifactManifestNeoForgeSources", spec -> {
spec.setCanBeConsumed(false);
spec.setCanBeResolved(true);
spec.withDependencies(dependencies -> {
// Add the dep on NeoForge itself
dependencies.addLater(extension.getVersion().map(version -> {
return dependencyFactory.create("net.neoforged:neoforge:" + version)
.attributes(attributes -> {
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.getObjects().named(Category.class, Category.DOCUMENTATION));
attributes.attribute(DocsType.DOCS_TYPE_ATTRIBUTE, project.getObjects().named(DocsType.class, DocsType.SOURCES));
});
}));
});
});
var neoFormRuntimeArtifactManifestNeoForm = configurations.create("neoFormRuntimeArtifactManifestNeoForm", spec -> {
spec.setCanBeConsumed(false);
spec.setCanBeResolved(true);
spec.withDependencies(dependencies -> {
dependencies.addLater(extension.getVersion().map(version -> {
return dependencyFactory.create("net.neoforged:neoforge:" + version)
.capabilities(caps -> {
caps.requireCapability("net.neoforged:neoforge-dependencies");
});
}));
});
var createManifest = tasks.register("createArtifactManifest", CreateArtifactManifestTask.class, task -> {
configureArtifactManifestTask(task, extension);
task.getManifestFile().set(modDevBuildDir.map(dir -> dir.file("nfrt_artifact_manifest.properties")));
});

var neoFormRuntimeConfig = configurations.create("neoFormRuntime", files -> {
files.setCanBeConsumed(false);
files.setCanBeResolved(true);
Expand All @@ -167,50 +132,6 @@ public void apply(Project project) {
});
});

// This configuration will include the classpath needed to decompile and recompile Minecraft,
// and has to include the libraries added by NeoForm and NeoForge.
var minecraftCompileClasspath = configurations.create("minecraftCompileClasspath", spec -> {
spec.setCanBeResolved(true);
spec.setCanBeConsumed(false);
spec.setVisible(false);
spec.withDependencies(set -> set.addLater(neoForgeModDevLibrariesDependency));
spec.attributes(attributes -> {
attributes.attribute(Usage.USAGE_ATTRIBUTE, project.getObjects().named(Usage.class, Usage.JAVA_API));
attributes.attribute(ATTRIBUTE_DISTRIBUTION, "client");
});
});

var createManifest = tasks.register("createArtifactManifest", CreateArtifactManifestTask.class, task -> {
task.getNeoForgeModDevArtifacts().addAll(neoFormRuntimeArtifactManifestNeoForgeClasses.getIncoming().getArtifacts().getResolvedArtifacts().map(results -> {
return results.stream().map(result -> {
var gav = guessMavenGav(result);
return new ArtifactManifestEntry(
gav,
result.getFile()
);
}).collect(Collectors.toSet());
}));
task.getNeoForgeModDevArtifacts().addAll(neoFormRuntimeArtifactManifestNeoForgeSources.getIncoming().getArtifacts().getResolvedArtifacts().map(results -> {
return results.stream().map(result -> {
var gav = guessMavenGav(result);
return new ArtifactManifestEntry(
gav,
result.getFile()
);
}).collect(Collectors.toSet());
}));
task.getNeoForgeModDevArtifacts().addAll(neoFormRuntimeArtifactManifestNeoForm.getIncoming().getArtifacts().getResolvedArtifacts().map(results -> {
return results.stream().map(result -> {
var gav = guessMavenGav(result);
return new ArtifactManifestEntry(
gav,
result.getFile()
);
}).collect(Collectors.toSet());
}));
task.getManifestFile().set(modDevBuildDir.map(dir -> dir.file("nfrt_artifact_manifest.properties")));
});

// Add a filtered parchment repository automatically if enabled
var parchment = extension.getParchment();
configureParchmentRepository(project, parchment);
Expand All @@ -235,7 +156,6 @@ public void apply(Project project) {
task.getAccessTransformers().from(accessTransformers);
task.getParchmentData().from(parchmentData);
task.getNeoFormRuntime().from(neoFormRuntimeConfig);
task.getCompileClasspath().from(minecraftCompileClasspath);

var minecraftArtifactsDir = modDevBuildDir.map(dir -> dir.dir("artifacts"));
task.getCompiledArtifact().set(minecraftArtifactsDir.map(dir -> dir.file("neoforge-minecraft-joined-local.jar")));
Expand Down Expand Up @@ -405,6 +325,87 @@ public void apply(Project project) {
configureEclipseModel(project, ideSyncTask, createArtifacts, extension, prepareRunTasks);
}

/**
* Collects all dependencies needed by the NeoFormRuntime and adds them to the task for creating
* an artifact manifest for NFRT.
*/
private void configureArtifactManifestTask(CreateArtifactManifestTask task, NeoForgeExtension extension) {
var project = task.getProject();
var configurations = project.getConfigurations();
var dependencyFactory = project.getDependencyFactory();

var configurationPrefix = "neoFormRuntimeDependencies";

Provider<ExternalModuleDependency> neoForgeDependency = extension.getVersion().map(version -> dependencyFactory.create("net.neoforged:neoforge:" + version));

// Gradle prevents us from having dependencies with "incompatible attributes" in the same configuration.
// What constitutes incompatible cannot be overridden on a per-configuration basis.
var neoForgeClasses = configurations.create(configurationPrefix + "NeoForgeClasses", spec -> {
spec.setDescription("Dependencies needed for running NeoFormRuntime for the selected NeoForge/NeoForm version (NeoForge classes)");
spec.setCanBeConsumed(false);
spec.setCanBeResolved(true);
spec.withDependencies(depSpec -> depSpec.addLater(neoForgeDependency.map(dependency -> dependency.copy()
.capabilities(caps -> {
caps.requireCapability("net.neoforged:neoforge-moddev-bundle");
}))));
});

var neoForgeSources = configurations.create(configurationPrefix + "NeoForgeSources", spec -> {
spec.setDescription("Dependencies needed for running NeoFormRuntime for the selected NeoForge/NeoForm version (NeoForge sources)");
spec.setCanBeConsumed(false);
spec.setCanBeResolved(true);
spec.withDependencies(depSpec -> depSpec.addLater(neoForgeDependency));
spec.attributes(attributes -> {
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.getObjects().named(Category.class, Category.DOCUMENTATION));
attributes.attribute(DocsType.DOCS_TYPE_ATTRIBUTE, project.getObjects().named(DocsType.class, DocsType.SOURCES));
});
});

// Compile-time dependencies used by NeoForm, NeoForge and Minecraft.
// Also includes any classes referenced by compiled Minecraft code (used by decompilers, renamers, etc.)
var compileClasspath = configurations.create(configurationPrefix + "CompileClasspath", spec -> {
spec.setDescription("Dependencies needed for running NeoFormRuntime for the selected NeoForge/NeoForm version (Classpath)");
spec.setCanBeConsumed(false);
spec.setCanBeResolved(true);
spec.withDependencies(depSpec -> depSpec.addLater(neoForgeDependency.map(dependency -> dependency.copy()
.capabilities(caps -> {
caps.requireCapability("net.neoforged:neoforge-dependencies");
}))));
spec.attributes(attributes -> {
attributes.attribute(Usage.USAGE_ATTRIBUTE, project.getObjects().named(Usage.class, Usage.JAVA_API));
attributes.attribute(ATTRIBUTE_DISTRIBUTION, "client");
});
});

// Runtime-time dependencies used by NeoForm, NeoForge and Minecraft.
var runtimeClasspath = configurations.create(configurationPrefix + "RuntimeClasspath", spec -> {
spec.setDescription("Dependencies needed for running NeoFormRuntime for the selected NeoForge/NeoForm version (Classpath)");
spec.setCanBeConsumed(false);
spec.setCanBeResolved(true);
spec.withDependencies(depSpec -> depSpec.addLater(neoForgeDependency.map(dependency -> dependency.copy()
.capabilities(caps -> {
caps.requireCapability("net.neoforged:neoforge-dependencies");
}))));
spec.attributes(attributes -> {
attributes.attribute(Usage.USAGE_ATTRIBUTE, project.getObjects().named(Usage.class, Usage.JAVA_RUNTIME));
attributes.attribute(ATTRIBUTE_DISTRIBUTION, "client");
});
});

for (var configuration : List.of(neoForgeClasses, neoForgeSources, compileClasspath, runtimeClasspath)) {
// Convert to a serializable representation for the task.
task.getNeoForgeModDevArtifacts().addAll(configuration.getIncoming().getArtifacts().getResolvedArtifacts().map(results -> {
return results.stream().map(result -> {
var gav = guessMavenGav(result);
return new ArtifactManifestEntry(
gav,
result.getFile()
);
}).collect(Collectors.toSet());
}));
}
}

private static void configureParchmentRepository(Project project, Parchment parchment) {
project.afterEvaluate(p -> {
if (!parchment.getEnabled().get() || !parchment.getAddRepository().get()) {
Expand Down Expand Up @@ -757,16 +758,16 @@ private static void configureEclipseModel(Project project,
// TODO: This should be moved into its own task being triggered via eclipseModel.synchronizationTask
System.out.println(System.getProperties());
if (System.getProperty("eclipse.application") != null) {
project.afterEvaluate(ignored -> {
for (var run : extension.getRuns()) {
var prepareTask = prepareRunTasks.get(run).get();
if (!prepareTask.getEnabled()) {
project.getLogger().lifecycle("Not creating Eclipse run {} since its prepare task {} is disabled", run, prepareTask);
continue;
project.afterEvaluate(ignored -> {
for (var run : extension.getRuns()) {
var prepareTask = prepareRunTasks.get(run).get();
if (!prepareTask.getEnabled()) {
project.getLogger().lifecycle("Not creating Eclipse run {} since its prepare task {} is disabled", run, prepareTask);
continue;
}
addEclipseLaunchConfiguration(project, null, run, prepareTask);
}
addEclipseLaunchConfiguration(project, null, run, prepareTask);
}
});
});
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
import org.gradle.api.DefaultTask;
import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Classpath;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.Internal;
import org.gradle.jvm.toolchain.JavaLanguageVersion;
import org.gradle.jvm.toolchain.JavaLauncher;
import org.gradle.jvm.toolchain.JavaToolchainService;
import org.gradle.process.ExecOperations;

Expand All @@ -21,6 +23,12 @@ abstract public class NeoFormRuntimeTask extends DefaultTask {
@InputFiles
abstract ConfigurableFileCollection getNeoFormRuntime();

/**
* Launcher for the java version used by NFRT itself.
*/
@Internal
abstract Property<JavaLauncher> getNeoFormRuntimeLauncher();

@Inject
protected abstract JavaToolchainService getJavaToolchainService();

Expand Down Expand Up @@ -50,11 +58,12 @@ public NeoFormRuntimeTask() {

// Store temporary working directories in this projects build directory such that gradle clean removes them
getWorkDirectory().set(project.getLayout().getBuildDirectory().dir("tmp/neoformruntime"));

// Default to J21 for NFRT
getNeoFormRuntimeLauncher().convention(getJavaToolchainService().launcherFor(spec -> spec.getLanguageVersion().set(JavaLanguageVersion.of(21))));
}

protected final void run(List<String> args) {
var launcher = getJavaToolchainService().launcherFor(spec -> spec.getLanguageVersion().set(JavaLanguageVersion.of(21)));

// Use Gradle-specific directories when running NFRT
var realArgs = new ArrayList<>(args);
realArgs.add(0, "--home-dir");
Expand All @@ -65,7 +74,7 @@ protected final void run(List<String> args) {
getExecOperations().javaexec(execSpec -> {
// See https://github.com/gradle/gradle/issues/28959
execSpec.jvmArgs("-Dstdout.encoding=UTF-8", "-Dstderr.encoding=UTF-8");
execSpec.executable(launcher.get().getExecutablePath().getAsFile());
execSpec.executable(getNeoFormRuntimeLauncher().get().getExecutablePath().getAsFile());
execSpec.classpath(getNeoFormRuntime());
execSpec.args(realArgs);
});
Expand Down
3 changes: 2 additions & 1 deletion testproject/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ repositories {
}

dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter:5.7.1'
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.2'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testImplementation "net.neoforged:testframework:${project.neoforge_version}"
}
Expand Down Expand Up @@ -43,6 +43,7 @@ neoForge {

neoFormRuntime {
useEclipseCompiler = true
// enableCache = false
}

parchment {
Expand Down
2 changes: 1 addition & 1 deletion testproject/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ org.gradle.configuration-cache=true
org.gradle.warning.mode=fail

# Dependency versions
neoforge_version=20.6.91-beta-pr-959-features-gradle-metadata
neoforge_version=20.6.104-beta-pr-959-features-gradle-metadata

2 changes: 1 addition & 1 deletion testproject/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-all.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down

0 comments on commit 1b7af25

Please sign in to comment.