Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,8 @@ public void enable(Project project, LegacyForgeModdingSettings settings, LegacyF
configurations.getByName(DataFileCollections.CONFIGURATION_ACCESS_TRANSFORMERS),
configurations.getByName(DataFileCollections.CONFIGURATION_INTERFACE_INJECTION_DATA),
versionCapabilities,
settings.isDisableRecompilation());
settings.isDisableRecompilation(),
false);

var runs = ModDevRunWorkflow.create(
project,
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/net/neoforged/moddevgradle/dsl/ModModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public ModModel() {
// TODO: We could potentially do a bit of name validation
getModSourceSets().convention(List.of());
getModSourceSets().finalizeValueOnRead();
getModClientSourceSets().convention(List.of());
getModClientSourceSets().finalizeValueOnRead();
}

@Override
Expand All @@ -23,7 +25,13 @@ public ModModel() {
// Do not name getSourceSets or it will conflict with project.sourceSets in scripts.
public abstract ListProperty<SourceSet> getModSourceSets();

public abstract ListProperty<SourceSet> getModClientSourceSets();

public void sourceSet(SourceSet sourceSet) {
getModSourceSets().add(sourceSet);
}

public void clientSourceSet(SourceSet sourceSet) {
getModClientSourceSets().add(sourceSet);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public abstract class ModdingVersionSettings {
@Nullable
private String neoFormVersion;

private boolean splitDist = false;

private Set<SourceSet> enabledSourceSets = new HashSet<>();

private boolean disableRecompilation = "true".equals(System.getenv("CI"));
Expand Down Expand Up @@ -77,4 +79,12 @@ public boolean isDisableRecompilation() {
public void setDisableRecompilation(boolean disableRecompilation) {
this.disableRecompilation = disableRecompilation;
}

public boolean isSplitDist() {
return splitDist;
}

public void setSplitDist(boolean enable) {
this.splitDist = enable;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ private void addEclipseLaunchConfiguration(Project project,
}

// This is the actual main launch configuration that launches the game
var modFoldersProvider = getModFoldersProvider(project, run.getLoadedMods(), null);
var modFoldersProvider = getModFoldersProvider(project, run.getLoadedMods(), null, run.getType());
var config = JavaApplicationLaunchConfig.builder(eclipseProjectName)
.vmArgs(
RunUtils.escapeJvmArg(RunUtils.getArgFileParameter(prepareTask.getVmArgsFile().get())),
Expand All @@ -168,12 +168,13 @@ private void addEclipseLaunchConfiguration(Project project,

protected static ModFoldersProvider getModFoldersProvider(Project project,
Provider<Set<ModModel>> modsProvider,
@Nullable Provider<ModModel> testedMod) {
@Nullable Provider<ModModel> testedMod,
Provider<String> runType) {
var folders = RunUtils.buildModFolders(project, modsProvider, testedMod, (sourceSet, output) -> {
output.from(RunUtils.findSourceSetProject(project, sourceSet).getProjectDir().toPath()
.resolve("bin")
.resolve(sourceSet.getName()));
});
}, runType);

var modFoldersProvider = project.getObjects().newInstance(ModFoldersProvider.class);
modFoldersProvider.getModFolders().set(folders);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public void configureTesting(Provider<Set<ModModel>> loadedMods,
var intellijVmArgsFile = runArgsDir.map(dir -> dir.file("intellijVmArgs.txt"));

var outputDirectory = IntelliJOutputDirectoryValueSource.getIntellijOutputDirectory(project);
var ideSpecificVmArgs = RunUtils.escapeJvmArg(getModFoldersProvider(project, outputDirectory, loadedMods, testedMod).getArgument());
var ideSpecificVmArgs = RunUtils.escapeJvmArg(getModFoldersProvider(project, outputDirectory, loadedMods, testedMod, project.provider(() -> "client")).getArgument());
try {
var vmArgsFilePath = intellijVmArgsFile.get().getAsFile().toPath();
Files.createDirectories(vmArgsFilePath.getParent());
Expand Down Expand Up @@ -185,7 +185,7 @@ private static void addIntelliJRunConfiguration(Project project,
}
appRun.setModuleName(getIntellijModuleName(project, sourceSet));
appRun.setWorkingDirectory(run.getGameDirectory().get().getAsFile().getAbsolutePath());
var modFoldersProvider = getModFoldersProvider(project, outputDirectory, run.getLoadedMods(), null);
var modFoldersProvider = getModFoldersProvider(project, outputDirectory, run.getLoadedMods(), null, run.getType());
appRun.setEnvs(RunUtils.replaceModClassesEnv(run, modFoldersProvider));
appRun.setJvmArgs(
RunUtils.escapeJvmArg(RunUtils.getArgFileParameter(prepareTask.getVmArgsFile().get()))
Expand Down Expand Up @@ -232,15 +232,16 @@ public boolean shouldUseCombinedSourcesAndClassesArtifact() {
private static ModFoldersProvider getModFoldersProvider(Project project,
@Nullable Function<Project, File> outputDirectory,
Provider<Set<ModModel>> modsProvider,
@Nullable Provider<ModModel> testedMod) {
@Nullable Provider<ModModel> testedMod,
Provider<String> runType) {
Provider<Map<String, ModFolder>> folders;
if (outputDirectory != null) {
folders = RunUtils.buildModFolders(project, modsProvider, testedMod, (sourceSet, output) -> {
var sourceSetDir = outputDirectory.apply(RunUtils.findSourceSetProject(project, sourceSet)).toPath().resolve(getIdeaOutName(sourceSet));
output.from(sourceSetDir.resolve("classes"), sourceSetDir.resolve("resources"));
});
}, runType);
} else {
folders = RunUtils.getModFoldersForGradle(project, modsProvider, testedMod);
folders = RunUtils.getModFoldersForGradle(project, modsProvider, testedMod, runType);
}

var modFoldersProvider = project.getObjects().newInstance(ModFoldersProvider.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import net.neoforged.moddevgradle.internal.utils.VersionCapabilitiesInternal;
import net.neoforged.nfrtgradle.CreateMinecraftArtifacts;
import net.neoforged.nfrtgradle.DownloadAssets;
import net.neoforged.nfrtgradle.SplitMergedJar;
import org.gradle.api.GradleException;
import org.gradle.api.InvalidUserCodeException;
import org.gradle.api.Named;
Expand All @@ -28,6 +29,7 @@
import org.gradle.api.plugins.JavaPluginExtension;
import org.gradle.api.provider.Provider;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.api.tasks.TaskProvider;
import org.gradle.jvm.toolchain.JavaLanguageVersion;
import org.gradle.jvm.toolchain.JavaToolchainService;
Expand All @@ -47,6 +49,7 @@ public record ModDevArtifactsWorkflow(
TaskProvider<DownloadAssets> downloadAssets,
Configuration runtimeDependencies,
Configuration compileDependencies,
Configuration clientExtraCompileDependencies,
Provider<Directory> modDevBuildDir,
Provider<Directory> artifactsBuildDir) {

Expand All @@ -68,7 +71,8 @@ public static ModDevArtifactsWorkflow create(Project project,
Configuration accessTransformers,
Configuration interfaceInjectionData,
VersionCapabilitiesInternal versionCapabilities,
boolean disableRecompilation) {
boolean disableRecompilation,
boolean splitDist) {
if (project.getExtensions().findByName(EXTENSION_NAME) != null) {
throw new InvalidUserCodeException("You cannot enable modding in the same project twice.");
}
Expand Down Expand Up @@ -115,6 +119,8 @@ public static ModDevArtifactsWorkflow create(Project project,
spec.getDependencies().addLater(parchment.getParchmentArtifact().map(dependencyFactory::create));
});

Function<WorkflowArtifact, Provider<RegularFile>> artifactPathStrategy = artifact -> artifactsBuildDir.map(dir -> dir.file(artifactNamingStrategy.getFilename(artifact)));

// it has to contain client-extra to be loaded by FML, and it must be added to the legacy CP
var createArtifacts = tasks.register("createMinecraftArtifacts", CreateMinecraftArtifacts.class, task -> {
task.setGroup(branding.internalTaskGroup());
Expand Down Expand Up @@ -151,8 +157,6 @@ public static ModDevArtifactsWorkflow create(Project project,
task.getParchmentEnabled().set(parchment.getEnabled());
task.getParchmentConflictResolutionPrefix().set(parchment.getConflictResolutionPrefix());

Function<WorkflowArtifact, Provider<RegularFile>> artifactPathStrategy = artifact -> artifactsBuildDir.map(dir -> dir.file(artifactNamingStrategy.getFilename(artifact)));

task.getIncludeNeoForgeInGameJar().set(versionCapabilities.needsNeoForgeInMinecraftJar());
task.getGameJarArtifact().set(artifactPathStrategy.apply(WorkflowArtifact.COMPILED));
if (disableRecompilation) {
Expand Down Expand Up @@ -185,6 +189,24 @@ public static ModDevArtifactsWorkflow create(Project project,
task.getNeoFormArtifact().set(moddingDependencies.neoFormDependencyNotation());
});

var splitMergedJar = tasks.register("splitMergedJar", SplitMergedJar.class, task -> {
task.getClientResourcesJar().set(createArtifacts.flatMap(CreateMinecraftArtifacts::getResourcesArtifact));
task.getClientJar().set(artifactPathStrategy.apply(WorkflowArtifact.CLIENT));
task.getCommonJar().set(artifactPathStrategy.apply(WorkflowArtifact.COMMON));
if (!disableRecompilation) {
task.getMergedJar().set(createArtifacts.flatMap(CreateMinecraftArtifacts::getGameJarWithSourcesArtifact));
task.getClientSourcesJar().set(artifactPathStrategy.apply(WorkflowArtifact.CLIENT_SOURCES));
task.getCommonSourcesJar().set(artifactPathStrategy.apply(WorkflowArtifact.COMMON_SOURCES));
} else {
task.getMergedJar().set(createArtifacts.flatMap(CreateMinecraftArtifacts::getGameJarArtifact));
}

});

if (splitDist) {
ideIntegration.runTaskOnProjectSync(splitMergedJar);
}

// For IntelliJ, we attach a combined sources+classes artifact which enables an "Attach Sources..." link for IJ users
// Otherwise, attaching sources is a pain for IJ users.
Provider<? extends Dependency> minecraftClassesDependency;
Expand Down Expand Up @@ -218,13 +240,26 @@ public static ModDevArtifactsWorkflow create(Project project,
config.setDescription("The compile-time dependencies to develop a mod, including Minecraft and modding platform classes.");
config.setCanBeResolved(false);
config.setCanBeConsumed(false);
config.getDependencies().addLater(minecraftClassesDependency);
if (!splitDist) {
config.getDependencies().addLater(minecraftClassesDependency);
} else {
config.getDependencies().addLater(splitMergedJar.map(task -> project.files(task.getCommonJar())).map(dependencyFactory::create));
}
config.getDependencies().add(moddingDependencies.gameLibrariesDependency());
if (!versionCapabilities.needsNeoForgeInMinecraftJar() && moddingDependencies.neoForgeDependency() != null) {
config.getDependencies().add(moddingDependencies.neoForgeDependency());
}
});

var clientExtraCompileDependencies = configurations.create("modDevClientCompileDependencies", config -> {
config.setDescription("The extra client compile-time dependencies to develop a mod, including Minecraft and modding platform classes.");
config.setCanBeResolved(false);
config.setCanBeConsumed(false);
if (splitDist) {
config.getDependencies().addLater(splitMergedJar.map(task -> project.files(task.getClientJar())).map(dependencyFactory::create));
}
});

// For IDEs that support it, link the source/binary artifacts if we use separated ones
if (!disableRecompilation && !ideIntegration.shouldUseCombinedSourcesAndClassesArtifact()) {
ideIntegration.attachSources(
Expand All @@ -242,13 +277,22 @@ public static ModDevArtifactsWorkflow create(Project project,
downloadAssets,
runtimeDependencies,
compileDependencies,
clientExtraCompileDependencies,
modDevBuildDir,
artifactsBuildDir);

project.getExtensions().add(ModDevArtifactsWorkflow.class, EXTENSION_NAME, result);

for (var sourceSets : enabledSourceSets) {
result.addToSourceSet(sourceSets);
result.addToSourceSet(sourceSets, !splitDist);
}

if (splitDist) {
SourceSetContainer sourceSets = ExtensionUtils.getSourceSets(project);
var main = sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
SourceSet client = sourceSets.create("client");
client.setCompileClasspath(client.getCompileClasspath().plus(main.getOutput()));
result.addToSourceSet(client, true);
}

return result;
Expand Down Expand Up @@ -351,14 +395,23 @@ private static List<Configuration> configureArtifactManifestConfigurations(
* Adds the compile-time and runtime-dependencies needed to compile mod code to the source-set of the given name.
*/
public void addToSourceSet(SourceSet sourceSet) {
addToSourceSet(sourceSet, true);
}

public void addToSourceSet(SourceSet sourceSet, boolean includeClient) {
var configurations = project.getConfigurations();
var sourceSets = ExtensionUtils.getSourceSets(project);
if (!sourceSets.contains(sourceSet)) {
throw new GradleException("Cannot add to the source set in another project: " + sourceSet);
}

configurations.getByName(sourceSet.getRuntimeClasspathConfigurationName()).extendsFrom(runtimeDependencies);
configurations.getByName(sourceSet.getCompileClasspathConfigurationName()).extendsFrom(compileDependencies);
Configuration runtime = configurations.getByName(sourceSet.getRuntimeClasspathConfigurationName());
runtime.extendsFrom(runtimeDependencies);
Configuration compile = configurations.getByName(sourceSet.getCompileClasspathConfigurationName());
compile.extendsFrom(compileDependencies);
if (includeClient) {
compile.extendsFrom(clientExtraCompileDependencies);
}
}

public Provider<RegularFile> requestAdditionalMinecraftArtifact(String id, String filename) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ public void enable(
configurations.getByName(DataFileCollections.CONFIGURATION_ACCESS_TRANSFORMERS),
configurations.getByName(DataFileCollections.CONFIGURATION_INTERFACE_INJECTION_DATA),
versionCapabilities,
settings.isDisableRecompilation());
settings.isDisableRecompilation(),
settings.isSplitDist());

ModDevRunWorkflow.create(
project,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ public static void setupRuns(
if (!versionCapabilities.modLocatorRework()) {
// TODO: do this properly now that we have a flag in the version capabilities
// This will explicitly be replaced in RunUtils to make this work for IDEs
run.getEnvironment().put("MOD_CLASSES", RunUtils.getGradleModFoldersProvider(project, run.getLoadedMods(), null).getClassesArgument());
run.getEnvironment().put("MOD_CLASSES", RunUtils.getGradleModFoldersProvider(project, run.getLoadedMods(), null, run.getType()).getClassesArgument());
}
var prepareRunTask = setupRunInGradle(
project,
Expand Down Expand Up @@ -405,7 +405,7 @@ private static TaskProvider<PrepareRun> setupRunInGradle(
task.getVmArgsFile().set(prepareRunTask.get().getVmArgsFile().map(d -> d.getAsFile().getAbsolutePath()));
task.getProgramArgsFile().set(prepareRunTask.get().getProgramArgsFile().map(d -> d.getAsFile().getAbsolutePath()));
task.getEnvironment().set(run.getEnvironment());
task.getModFolders().set(RunUtils.getGradleModFoldersProvider(project, run.getLoadedMods(), null));
task.getModFolders().set(RunUtils.getGradleModFoldersProvider(project, run.getLoadedMods(), null, run.getType()));
});
createLaunchScriptsTask.configure(task -> task.dependsOn(launchScriptTask));

Expand All @@ -428,8 +428,7 @@ private static TaskProvider<PrepareRun> setupRunInGradle(
// Of course we need the arg files to be up-to-date ;)
task.dependsOn(prepareRunTask);
task.dependsOn(run.getTasksBefore());

task.getJvmArgumentProviders().add(RunUtils.getGradleModFoldersProvider(project, run.getLoadedMods(), null));
task.getJvmArgumentProviders().add(RunUtils.getGradleModFoldersProvider(project, run.getLoadedMods(), null, run.getType()));
});

return prepareRunTask;
Expand Down Expand Up @@ -524,7 +523,7 @@ static void setupTestTask(Project project,
task.systemProperty("fml.junit.argsfile", programArgsFile.get().getAsFile().getAbsolutePath());
task.jvmArgs(RunUtils.getArgFileParameter(vmArgsFile.get()));

var modFoldersProvider = RunUtils.getGradleModFoldersProvider(project, loadedMods, testedMod);
var modFoldersProvider = RunUtils.getGradleModFoldersProvider(project, loadedMods, testedMod, project.provider(() -> "client"));
task.getJvmArgumentProviders().add(modFoldersProvider);
});

Expand Down
Loading
Loading