Skip to content

Commit

Permalink
Merge branch 'main' into junit
Browse files Browse the repository at this point in the history
  • Loading branch information
Technici4n committed May 28, 2024
2 parents 49c8476 + e8f7997 commit b2d9e53
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 44 deletions.
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ In `build.gradle`:
```groovy
plugins {
// Apply the plugin. You can find the latest version at https://github.com/neoforged/ModDevGradle/packages/2159800.
id 'net.neoforged.moddev' version '0.1.34-pr-1-pr-publish'
id 'net.neoforged.moddev' version '0.1.44-pr-1-pr-publish'
}
neoForge {
// For now we require a special NeoForge build. You can find the latest version at https://github.com/neoforged/NeoForge/pull/959.
version = "20.6.84-beta-pr-959-features-gradle-metadata"
version = "20.6.91-beta-pr-959-features-gradle-metadata"
runs {
client {
Expand Down Expand Up @@ -112,7 +112,10 @@ neoForge {
systemProperty("a.b.c", "xyz")
// Optionally set the log-level used by the game
logLevel = org.slf4j.event.Level.INFO
logLevel = org.slf4j.event.Level.DEBUG
// You can change the name used for this run in your IDE
ideName = "Run Game Tests"
}
}
}
Expand Down
12 changes: 11 additions & 1 deletion src/main/java/net/neoforged/moddevgradle/dsl/RunModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,24 @@ public RunModel(String name, Project project) {
configuration.setCanBeConsumed(false);
});

getLogLevel().convention(Level.DEBUG);
getLogLevel().convention(Level.INFO);

// Build a nicer name for the IDE run configuration
boolean isSubProject = project.getRootProject() != project;
var ideName = StringUtils.capitalize(name);
if (isSubProject) {
ideName = project.getName() + " - " + ideName;
}
getIdeName().convention(ideName);
}

@Override
public String getName() {
return name;
}

public abstract Property<String> getIdeName();

public abstract DirectoryProperty getGameDirectory();

public abstract MapProperty<String, String> getSystemProperties();
Expand Down
105 changes: 84 additions & 21 deletions src/main/java/net/neoforged/moddevgradle/internal/ModDevPlugin.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package net.neoforged.moddevgradle.internal;

import net.neoforged.elc.configs.JavaApplicationLaunchConfig;
import net.neoforged.moddevgradle.dsl.InternalModelHelper;
import net.neoforged.moddevgradle.dsl.NeoForgeExtension;
import net.neoforged.moddevgradle.dsl.Parchment;
import net.neoforged.moddevgradle.dsl.RunModel;
import net.neoforged.moddevgradle.internal.utils.ExtensionUtils;
import net.neoforged.moddevgradle.internal.utils.StringUtils;
import net.neoforged.moddevgradle.tasks.JarJar;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
Expand Down Expand Up @@ -47,7 +47,11 @@
import org.jetbrains.gradle.ext.RunConfigurationContainer;
import org.slf4j.event.Level;

import javax.xml.stream.XMLStreamException;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
Expand All @@ -71,7 +75,6 @@ public void apply(Project project) {
project.getPlugins().apply(JavaLibraryPlugin.class);
var javaExtension = ExtensionUtils.getExtension(project, "java", JavaPluginExtension.class);

project.getPlugins().apply(IdeaExtPlugin.class);
var extension = project.getExtensions().create(NeoForgeExtension.NAME, NeoForgeExtension.class);
var dependencyFactory = project.getDependencyFactory();
var neoForgeModDevLibrariesDependency = extension.getVersion().map(version -> {
Expand Down Expand Up @@ -343,11 +346,11 @@ public void apply(Project project) {
writeLcp.getEntries().from(createArtifacts.get().getResourcesArtifact());
});

var runDirectory = layout.getProjectDirectory().dir("run");
var prepareRunTask = tasks.register(InternalModelHelper.nameOfRun(run, "prepare", "run"), PrepareRunForIde.class, task -> {
task.getGameDirectory().set(runDirectory);
task.getVmArgsFile().set(RunUtils.getArgFile(project, run, true));
task.getProgramArgsFile().set(RunUtils.getArgFile(project, run, false));
task.getGameDirectory().set(run.getGameDirectory());
task.getVmArgsFile().set(RunUtils.getArgFile(project, run, RunUtils.RunArgFile.VMARGS));
task.getProgramArgsFile().set(RunUtils.getArgFile(project, run, RunUtils.RunArgFile.PROGRAMARGS));
task.getLog4jConfigFile().set(RunUtils.getArgFile(project, run, RunUtils.RunArgFile.LOG4J_CONFIG));
task.getRunType().set(run.getType());
task.getNeoForgeModDevConfig().from(userDevConfigOnly);
task.getModules().from(neoForgeModDevModules);
Expand Down Expand Up @@ -393,7 +396,7 @@ public void apply(Project project) {

configureIntelliJModel(project, ideSyncTask, extension, prepareRunTasks);

configureEclipseModel(project, ideSyncTask, createArtifacts);
configureEclipseModel(project, ideSyncTask, createArtifacts, extension, prepareRunTasks);
}

private static void configureParchmentRepository(Project project, Parchment parchment) {
Expand Down Expand Up @@ -517,10 +520,12 @@ private void setupTesting(Project project,

var testVmArgsFile = layout.getBuildDirectory().file("moddev/fmljunitrunVmArgs.txt");
var fmlJunitArgsFile = layout.getBuildDirectory().file("moddev/fmljunitrunProgramArgs.txt");
var fmlJunitLog4jConfig = layout.getBuildDirectory().file("moddev/fmljunitlog4j2.xml");
var prepareRunTask = tasks.register("prepareFmlJunitFiles", PrepareArgsForTesting.class, task -> {
task.getGameDirectory().set(unitTest.getGameDirectory());
task.getVmArgsFile().set(testVmArgsFile);
task.getProgramArgsFile().set(fmlJunitArgsFile);
task.getLog4jConfigFile().set(fmlJunitLog4jConfig);
task.getNeoForgeModDevConfig().from(userDevConfigOnly);
task.getModules().from(neoForgeModDevModules);
task.getLegacyClasspathFile().set(writeLcpTask.get().getLegacyClasspathFile());
Expand Down Expand Up @@ -597,25 +602,31 @@ private static void addIntelliJRunConfiguration(Project project,
@Nullable File outputDirectory,
RunModel run,
PrepareRunForIde prepareTask) {
var a = new Application(StringUtils.capitalize(run.getName()), project);
var appRun = new Application(run.getIdeName().get(), project);
var sourceSets = ExtensionUtils.getExtension(project, "sourceSets", SourceSetContainer.class);
a.setModuleRef(new ModuleRef(project, sourceSets.getByName("main")));
a.setWorkingDirectory(run.getGameDirectory().get().getAsFile().getAbsolutePath());
appRun.setModuleRef(new ModuleRef(project, sourceSets.getByName("main")));
appRun.setWorkingDirectory(run.getGameDirectory().get().getAsFile().getAbsolutePath());

a.setJvmArgs(
appRun.setJvmArgs(
RunUtils.escapeJvmArg(RunUtils.getArgFileParameter(prepareTask.getVmArgsFile().get()))
+ " "
+ RunUtils.escapeJvmArg(RunUtils.getIdeaModFoldersProvider(project, outputDirectory, run.getMods(), false).getArgument())
);
a.setMainClass(RunUtils.DEV_LAUNCH_MAIN_CLASS);
a.setProgramParameters(RunUtils.escapeJvmArg(RunUtils.getArgFileParameter(prepareTask.getProgramArgsFile().get())));
runConfigurations.add(a);
appRun.setMainClass(RunUtils.DEV_LAUNCH_MAIN_CLASS);
appRun.setProgramParameters(RunUtils.escapeJvmArg(RunUtils.getArgFileParameter(prepareTask.getProgramArgsFile().get())));
runConfigurations.add(appRun);
}

private static void configureIntelliJModel(Project project, TaskProvider<Task> ideSyncTask, NeoForgeExtension extension, Map<RunModel, TaskProvider<PrepareRunForIde>> prepareRunTasks) {
var rootProject = project.getRootProject();

if (!rootProject.getPlugins().hasPlugin(IdeaExtPlugin.class)) {
rootProject.getPlugins().apply(IdeaExtPlugin.class);
}

// IDEA Sync has no real notion of tasks or providers or similar
project.afterEvaluate(ignored -> {
var settings = getIntelliJProjectSettings(project);
var settings = getIntelliJProjectSettings(rootProject);
if (settings != null && Boolean.getBoolean("idea.sync.active")) {
// Also run the sync task directly as part of the sync. (Thanks Loom).
var startParameter = project.getGradle().getStartParameter();
Expand All @@ -625,21 +636,21 @@ private static void configureIntelliJModel(Project project, TaskProvider<Task> i
startParameter.setTaskRequests(taskRequests);
}

var runConfigurations = getIntelliJRunConfigurations(project); // TODO: Consider making this a value source
var runConfigurations = getIntelliJRunConfigurations(rootProject); // TODO: Consider making this a value source

if (runConfigurations == null) {
project.getLogger().debug("Failed to find IntelliJ run configuration container. Not adding run configurations.");
} else {
var outputDirectory = RunUtils.getIntellijOutputDirectory(project);

extension.getRuns().forEach(run -> {
for (var run : extension.getRuns()) {
var prepareTask = prepareRunTasks.get(run).get();
if (!prepareTask.getEnabled()) {
project.getLogger().lifecycle("Not creating IntelliJ run {} since its prepare task {} is disabled", run, prepareTask);
return;
continue;
}
addIntelliJRunConfiguration(project, runConfigurations, outputDirectory, run, prepareTask);
});
}
}
});
}
Expand Down Expand Up @@ -706,7 +717,10 @@ static String guessMavenGav(ResolvedArtifactResult result) {

private static void configureEclipseModel(Project project,
TaskProvider<Task> ideSyncTask,
TaskProvider<CreateMinecraftArtifactsTask> createArtifacts) {
TaskProvider<CreateMinecraftArtifactsTask> createArtifacts,
NeoForgeExtension extension,
Map<RunModel, TaskProvider<PrepareRunForIde>> prepareRunTasks) {

// Set up stuff for Eclipse
var eclipseModel = ExtensionUtils.findExtension(project, "eclipse", EclipseModel.class);
if (eclipseModel == null) {
Expand All @@ -732,7 +746,56 @@ private static void configureEclipseModel(Project project,
});
}

// Set up runs
// Set up runs if running under buildship
// 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;
}
addEclipseLaunchConfiguration(project, null, run, prepareTask);
}
});
}
}

private static void addEclipseLaunchConfiguration(Project project,
@Nullable File outputDirectory,
RunModel run,
PrepareRunForIde prepareTask) {
//Grab the eclipse model so we can extend it. -> Done on the root project so that the model is available to all subprojects.
//And so that post sync tasks are only ran once for all subprojects.
EclipseModel model = project.getExtensions().findByType(EclipseModel.class);

var config = JavaApplicationLaunchConfig.builder(model.getProject().getName())
.vmArgs(
RunUtils.escapeJvmArg(RunUtils.getArgFileParameter(prepareTask.getVmArgsFile().get())),
// TODO: Eclipse output folders, are those relevant for Eclipse runs?
RunUtils.escapeJvmArg(RunUtils.getIdeaModFoldersProvider(project, outputDirectory, run.getMods(), false).getArgument())
)
.args(RunUtils.escapeJvmArg(RunUtils.getArgFileParameter(prepareTask.getProgramArgsFile().get())))
.workingDirectory(run.getGameDirectory().get().getAsFile().getAbsolutePath())
.jreContainer("JavaSE-21") // TODO
.build(RunUtils.DEV_LAUNCH_MAIN_CLASS);

var filename = run.getIdeName().get();

var file = project.file(".eclipse/configurations/" + filename + ".launch");
System.out.println("Writing eclipse run " + file);

file.getParentFile().mkdirs();
try (var writer = new FileWriter(file, false)) {
config.write(writer);
} catch (IOException e) {
throw new UncheckedIOException("Failed to write launch file: " + file, e);
} catch (XMLStreamException e) {
throw new RuntimeException("Failed to write launch file: " + file, e);
}
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
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.PathSensitive;
import org.gradle.api.tasks.PathSensitivity;
Expand Down Expand Up @@ -40,6 +41,10 @@ abstract class PrepareArgsForTesting extends DefaultTask {
@OutputFile
public abstract RegularFileProperty getProgramArgsFile();

@OutputFile
@Optional
public abstract RegularFileProperty getLog4jConfigFile();

@Classpath
public abstract ConfigurableFileCollection getNeoForgeModDevConfig();

Expand Down Expand Up @@ -89,19 +94,22 @@ public void prepareRun() throws IOException {
throw new GradleException("The unit testing plugin requires a 'junit' run-type to be made available by NeoForge. Available run types: " + userDevConfig.runs().keySet());
}

writeJvmArguments(runDir, runConfig);
writeJvmArguments(runConfig);
writeProgramArguments(runConfig);
}

private void writeJvmArguments(File runDir, UserDevRunType runConfig) throws IOException {
private void writeJvmArguments(UserDevRunType runConfig) throws IOException {
var lines = new ArrayList<String>();

lines.addAll(getInterpolatedJvmArgs(runConfig));

// Write log4j2 configuration file
File log4j2xml = RunUtils.writeLog4j2Configuration(getGameLogLevel().get(), runDir);
if (getLog4jConfigFile().isPresent()) {
var log4jConfigFile = getLog4jConfigFile().get().getAsFile();
RunUtils.writeLog4j2Configuration(getGameLogLevel().get(), log4jConfigFile.toPath());
lines.add(RunUtils.escapeJvmArg("-Dlog4j2.configurationFile=" + log4jConfigFile.getAbsolutePath()));
}

lines.add(RunUtils.escapeJvmArg("-Dlog4j2.configurationFile=" + log4j2xml.getAbsolutePath()));
for (var prop : runConfig.props().entrySet()) {
var propValue = prop.getValue();
if (propValue.equals("{minecraft_classpath_file}")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import net.neoforged.moddevgradle.internal.utils.FileUtils;
import org.gradle.api.DefaultTask;
import org.gradle.api.GradleException;
import org.gradle.api.Project;
import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.RegularFileProperty;
Expand Down Expand Up @@ -46,6 +47,10 @@ abstract class PrepareRunForIde extends DefaultTask {
@OutputFile
public abstract RegularFileProperty getProgramArgsFile();

@OutputFile
@Optional
public abstract RegularFileProperty getLog4jConfigFile();

@Classpath
public abstract ConfigurableFileCollection getNeoForgeModDevConfig();

Expand Down Expand Up @@ -114,11 +119,11 @@ public void prepareRun() throws IOException {
throw new GradleException("Trying to prepare unknown run: " + getRunType().get() + ". Available run types: " + userDevConfig.runs().keySet());
}

writeJvmArguments(runDir, runConfig);
writeJvmArguments(runConfig);
writeProgramArguments(runConfig);
}

private void writeJvmArguments(File runDir, UserDevRunType runConfig) throws IOException {
private void writeJvmArguments(UserDevRunType runConfig) throws IOException {
var lines = new ArrayList<String>();

lines.addAll(getInterpolatedJvmArgs(runConfig));
Expand All @@ -133,10 +138,12 @@ private void writeJvmArguments(File runDir, UserDevRunType runConfig) throws IOE
lines.add("");
}

// Write log4j2 configuration file
File log4j2xml = RunUtils.writeLog4j2Configuration(getGameLogLevel().get(), runDir);
if (getLog4jConfigFile().isPresent()) {
var log4jConfigFile = getLog4jConfigFile().get().getAsFile();
RunUtils.writeLog4j2Configuration(getGameLogLevel().get(), log4jConfigFile.toPath());
lines.add(RunUtils.escapeJvmArg("-Dlog4j2.configurationFile=" + log4jConfigFile.getAbsolutePath()));
}

lines.add(RunUtils.escapeJvmArg("-Dlog4j2.configurationFile=" + log4j2xml.getAbsolutePath()));
for (var prop : runConfig.props().entrySet()) {
var propValue = prop.getValue();
if (propValue.equals("{minecraft_classpath_file}")) {
Expand Down
Loading

0 comments on commit b2d9e53

Please sign in to comment.