diff --git a/common/src/main/java/net/neoforged/gradle/common/runs/run/DependencyHandlerImpl.java b/common/src/main/java/net/neoforged/gradle/common/runs/run/DependencyHandlerImpl.java index 1c5177035..75d101fbf 100644 --- a/common/src/main/java/net/neoforged/gradle/common/runs/run/DependencyHandlerImpl.java +++ b/common/src/main/java/net/neoforged/gradle/common/runs/run/DependencyHandlerImpl.java @@ -1,6 +1,7 @@ package net.neoforged.gradle.common.runs.run; import net.neoforged.gradle.dsl.common.runs.run.DependencyHandler; +import net.neoforged.gradle.dsl.common.util.ConfigurationUtils; import org.gradle.api.Action; import org.gradle.api.GradleException; import org.gradle.api.Project; @@ -14,15 +15,9 @@ public abstract class DependencyHandlerImpl implements DependencyHandler { private final Project project; - private final Configuration configuration; - @Inject public DependencyHandlerImpl(Project project) { this.project = project; - this.configuration = project.getConfigurations().detachedConfiguration(); - this.configuration.setCanBeResolved(true); - this.configuration.setCanBeConsumed(false); - this.configuration.setTransitive(false); } public Project getProject() { @@ -30,64 +25,8 @@ public Project getProject() { } public Configuration getConfiguration() { + final Configuration configuration = ConfigurationUtils.temporaryConfiguration(project); + configuration.fromDependencyCollector(this.getRuntime()); return configuration; } - - @Override - public Dependency runtime(Object dependencyNotation) { - if (dependencyNotation instanceof Configuration) { - this.configuration.extendsFrom((Configuration) dependencyNotation); - return null; - } - final Dependency dependency = project.getDependencies().create(dependencyNotation); - configuration.getDependencies().add(dependency); - return dependency; - } - - @Override - public Dependency runtime(Object dependencyNotation, Action configureClosure) { - if (dependencyNotation instanceof Configuration) { - if (configureClosure != null) { - throw new GradleException("Cannot add a Configuration with a configuration closure."); - } - this.configuration.extendsFrom((Configuration) dependencyNotation); - return null; - } - final Dependency dependency = project.getDependencies().create(dependencyNotation); - configureClosure.execute(dependency); - configuration.getDependencies().add(dependency); - return dependency; - } - - @Override - public Dependency create(Object dependencyNotation) { - final Dependency dependency = project.getDependencies().create(dependencyNotation); - configuration.getDependencies().add(dependency); - return dependency; - } - - @Override - public Dependency create(Object dependencyNotation, Action configureClosure) { - final Dependency dependency = project.getDependencies().create(dependencyNotation); - configureClosure.execute(dependency); - return dependency; - } - - @Override - public Dependency module(Object notation) { - return project.getDependencies().module(notation); - } - - @Override - public Dependency module(Object notation, Action configureClosure) { - final Dependency dependency = project.getDependencies().module(notation); - configureClosure.execute(dependency); - return dependency; - } - - @Override - public Dependency project(Map notation) { - final Dependency dependency = project.getDependencies().project(notation); - return dependency; - } } diff --git a/common/src/main/java/net/neoforged/gradle/common/tasks/JavaRuntimeTask.java b/common/src/main/java/net/neoforged/gradle/common/tasks/JavaRuntimeTask.java index 1af0abe97..fd7d5381c 100644 --- a/common/src/main/java/net/neoforged/gradle/common/tasks/JavaRuntimeTask.java +++ b/common/src/main/java/net/neoforged/gradle/common/tasks/JavaRuntimeTask.java @@ -8,12 +8,13 @@ import org.gradle.api.tasks.Internal; import org.gradle.api.tasks.Nested; import org.gradle.api.tasks.Optional; +import org.gradle.internal.jvm.Jvm; import org.gradle.jvm.toolchain.JavaLanguageVersion; import org.gradle.jvm.toolchain.JavaLauncher; import org.gradle.jvm.toolchain.JavaToolchainService; -import org.gradle.jvm.toolchain.internal.CurrentJvmToolchainSpec; import java.io.File; +import java.util.Objects; public abstract class JavaRuntimeTask extends DownloadingTask implements WithJavaVersion { @@ -21,7 +22,7 @@ public JavaRuntimeTask() { getJavaVersion().convention(getProject().getExtensions().getByType(JavaPluginExtension.class).getToolchain().getLanguageVersion()); getJavaLauncher().convention(getJavaToolChain().flatMap(toolChain -> { if (!getJavaVersion().isPresent()) { - return toolChain.launcherFor(new CurrentJvmToolchainSpec(getObjectFactory())); + return toolChain.launcherFor(javaToolchainSpec -> javaToolchainSpec.getLanguageVersion().set(JavaLanguageVersion.of(Objects.requireNonNull(Jvm.current().getJavaVersion()).getMajorVersion()))); } return toolChain.launcherFor(spec -> { diff --git a/dsl/common/src/main/groovy/net/neoforged/gradle/dsl/common/runs/run/DependencyHandler.groovy b/dsl/common/src/main/groovy/net/neoforged/gradle/dsl/common/runs/run/DependencyHandler.groovy index 557852a4a..30e9bd7e3 100644 --- a/dsl/common/src/main/groovy/net/neoforged/gradle/dsl/common/runs/run/DependencyHandler.groovy +++ b/dsl/common/src/main/groovy/net/neoforged/gradle/dsl/common/runs/run/DependencyHandler.groovy @@ -6,13 +6,15 @@ import net.minecraftforge.gdi.annotations.ClosureEquivalent import org.gradle.api.Action import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.Dependency +import org.gradle.api.artifacts.dsl.Dependencies +import org.gradle.api.artifacts.dsl.DependencyCollector import org.gradle.api.tasks.Internal /** * A custom dependency handler which manages runtime dependencies for a run configuration. */ @CompileStatic -interface DependencyHandler extends BaseDSLElement { +interface DependencyHandler extends BaseDSLElement, Dependencies { /** * The dependency configuration that contains all the declared dependencies. */ @@ -20,64 +22,9 @@ interface DependencyHandler extends BaseDSLElement { Configuration getConfiguration(); /** - * Adds a runtime dependency to the run configuration. + * Adds a dependency to the runtime configuration. * - * @param dependencyNotation The dependency notation. - * @return The runtime dependency. + * @return The dependency. */ - Dependency runtime(Object dependencyNotation); - - /** - * Adds a runtime dependency to the run configuration. - * - * @param dependencyNotation The dependency notation. - * @param configureClosure The closure to configure the runtime dependency. - * @return The runtime dependency. - */ - @ClosureEquivalent - Dependency runtime(Object dependencyNotation, Action configureClosure); - - /** - * Creates a new run dependency from the given notation. - * - * @param dependencyNotation The run dependency notation. - * @return The run dependency. - */ - Dependency create(Object dependencyNotation); - - /** - * Creates a new run dependency from the given notation and configures it. - * - * @param dependencyNotation The run dependency notation. - * @param configureClosure The closure to configure the run dependency. - * @return The run dependency. - */ - @ClosureEquivalent - Dependency create(Object dependencyNotation, Action configureClosure); - - /** - * Creates a new run dependency from the given module notation. - * - * @param notation the module notation. - * @return The run dependency. - */ - Dependency module(Object notation); - - /** - * Creates a new run dependency from the given module notation and configures it. - * - * @param notation the module notation. - * @param configureClosure The closure to configure the module dependency. - * @return The run dependency. - */ - @ClosureEquivalent - Dependency module(Object notation, Action configureClosure); - - /** - * Creates a new run dependency from the given project notation. - * - * @param notation the project notation. - * @return The run dependency. - */ - Dependency project(Map notation); + DependencyCollector getRuntime(); } \ No newline at end of file diff --git a/dsl/common/src/main/groovy/net/neoforged/gradle/dsl/common/util/ConfigurationUtils.groovy b/dsl/common/src/main/groovy/net/neoforged/gradle/dsl/common/util/ConfigurationUtils.groovy index b8e982c00..4573929bd 100644 --- a/dsl/common/src/main/groovy/net/neoforged/gradle/dsl/common/util/ConfigurationUtils.groovy +++ b/dsl/common/src/main/groovy/net/neoforged/gradle/dsl/common/util/ConfigurationUtils.groovy @@ -2,6 +2,7 @@ package net.neoforged.gradle.dsl.common.util import groovy.transform.CompileStatic import net.neoforged.gradle.dsl.common.extensions.dependency.replacement.DependencyReplacement +import org.gradle.api.Action import org.gradle.api.Project import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.ConfigurationContainer @@ -11,9 +12,13 @@ import org.gradle.api.provider.Provider import org.gradle.api.tasks.SourceSet import org.gradle.api.tasks.SourceSetContainer +import java.util.concurrent.atomic.AtomicInteger + @CompileStatic class ConfigurationUtils { + private static AtomicInteger temporaryConfigurationCounter = new AtomicInteger(0) + private ConfigurationUtils() { throw new IllegalStateException("Can not instantiate an instance of: ConfigurationUtils. This is a utility class") } @@ -26,7 +31,8 @@ class ConfigurationUtils { * @return The detached configuration */ static Configuration temporaryConfiguration(final Project project, final Dependency... dependencies) { - final Configuration configuration = project.getConfigurations().detachedConfiguration(dependencies) + final Configuration configuration = project.getConfigurations().detachedConfiguration(dependencies); + configuration.setCanBeConsumed(false) configuration.setCanBeResolved(true) diff --git a/gradle.properties b/gradle.properties index c693e1993..7374f8c49 100644 --- a/gradle.properties +++ b/gradle.properties @@ -36,4 +36,4 @@ spock_version=2.1 spock_groovy_version=3.0 mockito_version=4.11.0 jimfs_version=1.2 -trainingwheels_version=1.0.42 +trainingwheels_version=1.0.43 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d64cd4917..e6441136f 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradlew b/gradlew index 1aa94a426..b740cf133 100755 --- a/gradlew +++ b/gradlew @@ -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/. diff --git a/neoform/src/main/java/net/neoforged/gradle/neoform/runtime/tasks/RecompileSourceJar.java b/neoform/src/main/java/net/neoforged/gradle/neoform/runtime/tasks/RecompileSourceJar.java index 77c103436..ce86d628a 100644 --- a/neoform/src/main/java/net/neoforged/gradle/neoform/runtime/tasks/RecompileSourceJar.java +++ b/neoform/src/main/java/net/neoforged/gradle/neoform/runtime/tasks/RecompileSourceJar.java @@ -24,6 +24,7 @@ import org.gradle.api.tasks.PathSensitivity; import org.gradle.api.tasks.TaskAction; import org.gradle.api.tasks.compile.JavaCompile; +import org.gradle.internal.jvm.Jvm; import org.gradle.jvm.toolchain.JavaLanguageVersion; import org.gradle.jvm.toolchain.JavaToolchainService; import org.gradle.jvm.toolchain.internal.CurrentJvmToolchainSpec; @@ -32,6 +33,7 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.util.Objects; import java.util.zip.ZipOutputStream; @CacheableTask @@ -63,7 +65,7 @@ public RecompileSourceJar() { getJavaVersion().convention(getProject().getExtensions().getByType(JavaPluginExtension.class).getToolchain().getLanguageVersion()); getJavaLauncher().convention(getJavaToolChain().flatMap(toolChain -> { if (!getJavaVersion().isPresent()) { - return toolChain.launcherFor(new CurrentJvmToolchainSpec(getObjectFactory())); + return toolChain.launcherFor(javaToolchainSpec -> javaToolchainSpec.getLanguageVersion().set(JavaLanguageVersion.of(Objects.requireNonNull(Jvm.current().getJavaVersion()).getMajorVersion()))); } return toolChain.launcherFor(spec -> spec.getLanguageVersion().set(getJavaVersion())); diff --git a/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/FunctionalTests.groovy b/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/FunctionalTests.groovy index 928523e65..9030f07bf 100644 --- a/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/FunctionalTests.groovy +++ b/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/FunctionalTests.groovy @@ -32,7 +32,6 @@ class FunctionalTests extends BuilderBasedTestSpecification { when: def run = project.run { it.tasks(':neoFormRecompile') - it.stacktrace() } then: diff --git a/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/RunTests.groovy b/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/RunTests.groovy new file mode 100644 index 000000000..94b6ae13a --- /dev/null +++ b/userdev/src/functionalTest/groovy/net/neoforged/gradle/userdev/RunTests.groovy @@ -0,0 +1,178 @@ +package net.neoforged.gradle.userdev + +import net.neoforged.trainingwheels.gradle.functional.BuilderBasedTestSpecification +import org.gradle.testkit.runner.TaskOutcome + +class RunTests extends BuilderBasedTestSpecification { + + @Override + protected void configurePluginUnderTest() { + pluginUnderTest = "net.neoforged.gradle.userdev"; + injectIntoAllProject = true; + } + + def "userdev supports custom run dependencies"() { + given: + def project = create("run_with_custom_dependencies", { + it.build(""" + java { + toolchain { + languageVersion = JavaLanguageVersion.of(21) + } + } + + repositories { + mavenCentral() + } + + dependencies { + implementation 'net.neoforged:neoforge:+' + } + + runs { + client { + dependencies { + runtime 'org.jgrapht:jgrapht-core:+' + } + + modSource project.sourceSets.main + } + } + """) + it.withToolchains() + }) + + when: + def run = project.run { + it.tasks(':writeMinecraftClasspathClient') + } + + then: + run.task(':writeMinecraftClasspathClient').outcome == TaskOutcome.SUCCESS + + def neoformDir = run.file(".gradle/configuration/neoForm") + def versionedNeoformDir = neoformDir.listFiles()[0] + def stepsDir = new File(versionedNeoformDir, "steps") + def stepDir = new File(stepsDir, "writeMinecraftClasspathClient") + def classpathFile = new File(stepDir, "classpath.txt") + + classpathFile.exists() + + classpathFile.text.contains("org.jgrapht/jgrapht-core") + } + + def "userdev supports custom run dependencies from configuration"() { + given: + def project = create("run_with_custom_dependencies_from_configuration", { + it.build(""" + java { + toolchain { + languageVersion = JavaLanguageVersion.of(21) + } + } + + repositories { + mavenCentral() + } + + configurations { + runRuntime + } + + dependencies { + implementation 'net.neoforged:neoforge:+' + runRuntime 'org.jgrapht:jgrapht-core:+' + } + + runs { + client { + dependencies { + runtime project.configurations.runRuntime + } + + modSource project.sourceSets.main + } + } + """) + it.withToolchains() + }) + + when: + def run = project.run { + it.tasks(':writeMinecraftClasspathClient') + } + + then: + run.task(':writeMinecraftClasspathClient').outcome == TaskOutcome.SUCCESS + + def neoformDir = run.file(".gradle/configuration/neoForm") + def versionedNeoformDir = neoformDir.listFiles()[0] + def stepsDir = new File(versionedNeoformDir, "steps") + def stepDir = new File(stepsDir, "writeMinecraftClasspathClient") + def classpathFile = new File(stepDir, "classpath.txt") + + classpathFile.exists() + + classpathFile.text.contains("org.jgrapht/jgrapht-core") + } + + def "userdev supports custom run dependencies from catalog"() { + given: + def project = create("run_with_custom_dependencies_from_configuration", { + it.file("gradle/libs.versions.toml", + """ + [libraries] + jgrapht = { group = "org.jgrapht", name = "jgrapht-core", version = "+" } + """.trim()) + + it.build(""" + java { + toolchain { + languageVersion = JavaLanguageVersion.of(21) + } + } + + repositories { + mavenCentral() + } + + configurations { + runRuntime + } + + dependencies { + implementation 'net.neoforged:neoforge:+' + } + + runs { + client { + dependencies { + runtime libs.jgrapht + } + + modSource project.sourceSets.main + } + } + """) + it.withToolchains() + }) + + when: + def run = project.run { + it.tasks(':writeMinecraftClasspathClient') + } + + then: + run.task(':writeMinecraftClasspathClient').outcome == TaskOutcome.SUCCESS + + def neoformDir = run.file(".gradle/configuration/neoForm") + def versionedNeoformDir = neoformDir.listFiles()[0] + def stepsDir = new File(versionedNeoformDir, "steps") + def stepDir = new File(stepsDir, "writeMinecraftClasspathClient") + def classpathFile = new File(stepDir, "classpath.txt") + + classpathFile.exists() + + classpathFile.text.contains("org.jgrapht/jgrapht-core") + } +} diff --git a/userdev/src/main/java/net/neoforged/gradle/userdev/runtime/definition/UserDevRuntimeDefinition.java b/userdev/src/main/java/net/neoforged/gradle/userdev/runtime/definition/UserDevRuntimeDefinition.java index ceb820e3b..64dff2c19 100644 --- a/userdev/src/main/java/net/neoforged/gradle/userdev/runtime/definition/UserDevRuntimeDefinition.java +++ b/userdev/src/main/java/net/neoforged/gradle/userdev/runtime/definition/UserDevRuntimeDefinition.java @@ -140,7 +140,6 @@ protected Map buildRunInterpolationData(RunImpl run) { task.getInputFiles().from(neoformRuntimeDefinition.getMinecraftDependenciesConfiguration()); Configuration userDependencies = run.getDependencies().get().getConfiguration(); - userDependencies.getExtendsFrom().forEach(task.getInputFiles()::from); task.getInputFiles().from(userDependencies); } ); diff --git a/userdev/src/main/java/net/neoforged/gradle/userdev/runtime/tasks/ClasspathSerializer.java b/userdev/src/main/java/net/neoforged/gradle/userdev/runtime/tasks/ClasspathSerializer.java index a2a8e3678..95b265308 100644 --- a/userdev/src/main/java/net/neoforged/gradle/userdev/runtime/tasks/ClasspathSerializer.java +++ b/userdev/src/main/java/net/neoforged/gradle/userdev/runtime/tasks/ClasspathSerializer.java @@ -14,6 +14,9 @@ public abstract class ClasspathSerializer extends DefaultRuntime { public ClasspathSerializer() { getOutputFileName().convention("classpath.txt"); + + setGroup("NeoGradle/Runs"); + setDescription("Serializes the classpath of the run to a file."); } @TaskAction