Skip to content

Commit

Permalink
Use distinct branding for tasks when they're being used as part of Ne…
Browse files Browse the repository at this point in the history
…oDev (#186)
  • Loading branch information
shartte authored Nov 23, 2024
1 parent 12ce9e2 commit 703cf83
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 34 deletions.
12 changes: 12 additions & 0 deletions src/main/java/net/neoforged/moddevgradle/internal/Branding.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package net.neoforged.moddevgradle.internal;

/**
* Used to customize the groups of tasks generated by MDG.
*
* @param publicTaskGroup Use this group for tasks that are considered to be part of the user-interface of MDG.
* @param internalTaskGroup Use this group for tasks that are considered to be an implementation detail of MDG.
*/
record Branding(String publicTaskGroup, String internalTaskGroup) {
public static final Branding MDG = new Branding("mod development", "mod development/internal");
public static final Branding NEODEV = new Branding("neoforge development", "neoforge development/internal");
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ sealed class EclipseIntegration extends IdeIntegration permits VsCodeIntegration

protected final EclipseModel eclipseModel;

protected EclipseIntegration(Project project) {
super(project);
protected EclipseIntegration(Project project, Branding branding) {
super(project, branding);
this.eclipseModel = getOrCreateEclipseModel(project);
LOG.debug("Configuring Eclipse model for Eclipse project '{}'.", eclipseModel.getProject().getName());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,36 +31,36 @@ sealed abstract class IdeIntegration permits IntelliJIntegration, EclipseIntegra

protected final Project project;

public IdeIntegration(Project project) {
public IdeIntegration(Project project, Branding branding) {
this.project = project;
this.ideSyncTask = project.getTasks().register("neoForgeIdeSync", task -> {
task.setGroup(ModDevPlugin.INTERNAL_TASK_GROUP);
task.setGroup(branding.internalTaskGroup());
task.setDescription("A utility task that is used to create necessary files when the Gradle project is synchronized with the IDE project.");
});
}

public static IdeIntegration of(Project project) {
public static IdeIntegration of(Project project, Branding branding) {
var ideIntegration = ExtensionUtils.findExtension(project, "mdgInternalIdeIntegration", IdeIntegration.class);
if (ideIntegration == null) {
ideIntegration = createForProject(project);
ideIntegration = createForProject(project, branding);
project.getExtensions().add(IdeIntegration.class, "mdgInternalIdeIntegration", ideIntegration);
}
return ideIntegration;
}

private static IdeIntegration createForProject(Project project) {
private static IdeIntegration createForProject(Project project, Branding branding) {
if (IdeDetection.isVsCode()) {
// VSCode internally uses Eclipse and as such, we need to prioritize it over the pure Eclipse integration
LOG.debug("Activating VSCode integration for project {}.", project.getPath());
return new VsCodeIntegration(project);
return new VsCodeIntegration(project, branding);
} else if (IdeDetection.isEclipse()) {
LOG.debug("Activating Eclipse integration for project {}.", project.getPath());
return new EclipseIntegration(project);
return new EclipseIntegration(project, branding);
} else if (IdeDetection.isIntelliJSync()) {
LOG.debug("Activating IntelliJ integration for project {}.", project.getPath());
return new IntelliJIntegration(project);
return new IntelliJIntegration(project, branding);
} else {
return new NoIdeIntegration(project);
return new NoIdeIntegration(project, branding);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ final class IntelliJIntegration extends IdeIntegration {

private final IdeaModel rootIdeaModel;

IntelliJIntegration(Project project) {
super(project);
IntelliJIntegration(Project project, Branding branding) {
super(project, branding);

// While the IDEA model on the root project is the only sensible place to adjust IntelliJ project-wide settings
// such as run configurations.
Expand Down
35 changes: 19 additions & 16 deletions src/main/java/net/neoforged/moddevgradle/internal/ModDevPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,6 @@ public class ModDevPlugin implements Plugin<Project> {
*/
static final String JUNIT_GAME_DIR = "build/minecraft-junit";

private static final String TASK_GROUP = "mod development";
static final String INTERNAL_TASK_GROUP = "mod development/internal";

/**
* Name of the configuration in which we place the required dependencies to develop mods for use in the runtime-classpath.
* We cannot use "runtimeOnly", since the contents of that are published.
Expand Down Expand Up @@ -110,7 +107,7 @@ public void apply(Project project) {
var layout = project.getLayout();
var tasks = project.getTasks();

var ideIntegration = IdeIntegration.of(project);
var ideIntegration = IdeIntegration.of(project, Branding.MDG);

// We use this directory to store intermediate files used during moddev
var modDevBuildDir = layout.getBuildDirectory().dir("moddev");
Expand Down Expand Up @@ -182,7 +179,7 @@ public void apply(Project project) {

// 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(INTERNAL_TASK_GROUP);
task.setGroup(Branding.MDG.internalTaskGroup());
task.setDescription("Creates the NeoForge and Minecraft artifacts by invoking NFRT.");
for (var configuration : createManifestConfigurations) {
task.addArtifactsToManifest(configuration);
Expand Down Expand Up @@ -215,7 +212,7 @@ public void apply(Project project) {

var downloadAssets = tasks.register("downloadAssets", DownloadAssets.class, task -> {
// Not in the internal group in case someone wants to "preload" the asset before they go offline
task.setGroup(TASK_GROUP);
task.setGroup(Branding.MDG.publicTaskGroup());
task.setDescription("Downloads the Minecraft assets and asset index needed to run a Minecraft client or generate client-side resources.");
// While downloadAssets does not require *all* of the dependencies, it does need NeoForge/NeoForm to benefit
// from any caching/overrides applied to these dependencies in Gradle
Expand Down Expand Up @@ -306,6 +303,7 @@ public void apply(Project project) {

setupRuns(
project,
Branding.MDG,
modDevBuildDir,
extension.getRuns(),
userDevConfigOnly,
Expand Down Expand Up @@ -342,6 +340,7 @@ public void apply(Project project) {

setupTestTask(
project,
Branding.MDG,
userDevConfigOnly,
tasks.named("test", Test.class),
extension.getUnitTest().getLoadedMods(),
Expand Down Expand Up @@ -473,14 +472,15 @@ private List<Configuration> configureArtifactManifestConfigurations(Project proj
}

static void setupRuns(Project project,
Branding branding,
Provider<Directory> argFileDir,
DomainObjectCollection<RunModel> runs,
Object runTemplatesSourceFile,
Consumer<Configuration> configureModulePath,
Consumer<Configuration> configureLegacyClasspath,
Provider<RegularFile> assetPropertiesFile
) {
var ideIntegration = IdeIntegration.of(project);
var ideIntegration = IdeIntegration.of(project, branding);

// Create a configuration to resolve DevLaunch without leaking it to consumers
var devLaunchConfig = project.getConfigurations().create("devLaunchConfig", spec -> {
Expand All @@ -492,6 +492,7 @@ static void setupRuns(Project project,
runs.all(run -> {
var prepareRunTask = setupRunInGradle(
project,
branding,
argFileDir,
run,
runTemplatesSourceFile,
Expand All @@ -513,6 +514,7 @@ static void setupRuns(Project project,
*/
private static TaskProvider<PrepareRun> setupRunInGradle(
Project project,
Branding branding,
Provider<Directory> argFileDir,
RunModel run,
Object runTemplatesFile,
Expand All @@ -521,7 +523,7 @@ private static TaskProvider<PrepareRun> setupRunInGradle(
Provider<RegularFile> assetPropertiesFile,
Configuration devLaunchConfig
) {
var ideIntegration = IdeIntegration.of(project);
var ideIntegration = IdeIntegration.of(project, branding);
var configurations = project.getConfigurations();
var javaExtension = ExtensionUtils.getExtension(project, "java", JavaPluginExtension.class);
var tasks = project.getTasks();
Expand Down Expand Up @@ -561,14 +563,14 @@ private static TaskProvider<PrepareRun> setupRunInGradle(
});

var writeLcpTask = tasks.register(InternalModelHelper.nameOfRun(run, "write", "legacyClasspath"), WriteLegacyClasspath.class, writeLcp -> {
writeLcp.setGroup(INTERNAL_TASK_GROUP);
writeLcp.setGroup(branding.internalTaskGroup());
writeLcp.setDescription("Writes the legacyClasspath file for the " + run.getName() + " Minecraft run, containing all dependencies that shouldn't be considered boot modules.");
writeLcp.getLegacyClasspathFile().set(argFileDir.map(dir -> dir.file(InternalModelHelper.nameOfRun(run, "", "legacyClasspath") + ".txt")));
writeLcp.addEntries(legacyClasspathConfiguration);
});

var prepareRunTask = tasks.register(InternalModelHelper.nameOfRun(run, "prepare", "run"), PrepareRun.class, task -> {
task.setGroup(INTERNAL_TASK_GROUP);
task.setGroup(branding.internalTaskGroup());
task.setDescription("Prepares all files needed to launch the " + run.getName() + " Minecraft run.");

task.getGameDirectory().set(run.getGameDirectory());
Expand All @@ -592,7 +594,7 @@ private static TaskProvider<PrepareRun> setupRunInGradle(
ideIntegration.runTaskOnProjectSync(prepareRunTask);

var createLaunchScriptTask = tasks.register(InternalModelHelper.nameOfRun(run, "create", "launchScript"), CreateLaunchScriptTask.class, task -> {
task.setGroup(INTERNAL_TASK_GROUP);
task.setGroup(branding.internalTaskGroup());
task.setDescription("Creates a bash/shell-script to launch the " + run.getName() + " Minecraft run from outside Gradle or your IDE.");

task.getWorkingDirectory().set(run.getGameDirectory().map(d -> d.getAsFile().getAbsolutePath()));
Expand All @@ -619,7 +621,7 @@ private static TaskProvider<PrepareRun> setupRunInGradle(
ideIntegration.runTaskOnProjectSync(createLaunchScriptTask);

tasks.register(InternalModelHelper.nameOfRun(run, "run", ""), RunGameTask.class, task -> {
task.setGroup(TASK_GROUP);
task.setGroup(branding.publicTaskGroup());
task.setDescription("Runs the " + run.getName() + " Minecraft run configuration.");

// Launch with the Java version used in the project
Expand Down Expand Up @@ -656,6 +658,7 @@ public void setupTestTask() {
* @see #setupRunInGradle for a description of the parameters
*/
static void setupTestTask(Project project,
Branding branding,
Object runTemplatesSourceFile,
TaskProvider<Test> testTask,
SetProperty<ModModel> loadedMods,
Expand All @@ -667,7 +670,7 @@ static void setupTestTask(Project project,
) {
var gameDirectory = new File(project.getProjectDir(), JUNIT_GAME_DIR);

var ideIntegration = IdeIntegration.of(project);
var ideIntegration = IdeIntegration.of(project, branding);

var tasks = project.getTasks();
var configurations = project.getConfigurations();
Expand Down Expand Up @@ -698,7 +701,7 @@ static void setupTestTask(Project project,
var runArgsDir = argFileDir.map(dir -> dir.dir("junit"));

var writeLcpTask = tasks.register("writeNeoForgeTestClasspath", WriteLegacyClasspath.class, writeLcp -> {
writeLcp.setGroup(INTERNAL_TASK_GROUP);
writeLcp.setGroup(branding.internalTaskGroup());
writeLcp.setDescription("Writes the legacyClasspath file for the test run, containing all dependencies that shouldn't be considered boot modules.");
writeLcp.getLegacyClasspathFile().convention(runArgsDir.map(dir -> dir.file("legacyClasspath.txt")));
writeLcp.addEntries(legacyClasspathConfiguration);
Expand All @@ -708,7 +711,7 @@ static void setupTestTask(Project project,
var programArgsFile = runArgsDir.map(dir -> dir.file("programArgs.txt"));
var log4j2ConfigFile = runArgsDir.map(dir -> dir.file("log4j2.xml"));
var prepareTask = tasks.register("prepareNeoForgeTestFiles", PrepareTest.class, task -> {
task.setGroup(INTERNAL_TASK_GROUP);
task.setGroup(branding.internalTaskGroup());
task.setDescription("Prepares all files needed to run the JUnit test task.");
task.getGameDirectory().set(gameDirectory);
task.getVmArgsFile().set(vmArgsFile);
Expand Down Expand Up @@ -748,7 +751,7 @@ private static void setupJarJar(Project project) {
SourceSetContainer sourceSets = ExtensionUtils.getExtension(project, "sourceSets", SourceSetContainer.class);
sourceSets.all(sourceSet -> {
var jarJarTask = JarJar.registerWithConfiguration(project, sourceSet.getTaskName(null, "jarJar"));
jarJarTask.configure(task -> task.setGroup(INTERNAL_TASK_GROUP));
jarJarTask.configure(task -> task.setGroup(Branding.MDG.internalTaskGroup()));

// The target jar task for this source set might not exist, and #named(String) requires the task to exist
var jarTaskName = sourceSet.getJarTaskName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public static void setupRuns(Project project,
) {
ModDevPlugin.setupRuns(
project,
Branding.NEODEV,
argFileDir,
runs,
runTemplatesSourceFile,
Expand All @@ -57,6 +58,7 @@ public static void setupTestTask(Project project,
) {
ModDevPlugin.setupTestTask(
project,
Branding.NEODEV,
runTemplatesSourceFile,
testTask,
loadedMods,
Expand All @@ -69,6 +71,6 @@ public static void setupTestTask(Project project,
}

public static void runTaskOnProjectSync(Project project, Object task) {
IdeIntegration.of(project).runTaskOnProjectSync(task);
IdeIntegration.of(project, Branding.NEODEV).runTaskOnProjectSync(task);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* This implementation of {@link IdeIntegration} is used when no IDE was detected to host Gradle.
*/
final class NoIdeIntegration extends IdeIntegration {
public NoIdeIntegration(Project project) {
super(project);
public NoIdeIntegration(Project project, Branding branding) {
super(project, branding);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
final class VsCodeIntegration extends EclipseIntegration {
private static final Logger LOG = LoggerFactory.getLogger(VsCodeIntegration.class);

VsCodeIntegration(Project project) {
super(project);
VsCodeIntegration(Project project, Branding branding) {
super(project, branding);
}

@Override
Expand Down

0 comments on commit 703cf83

Please sign in to comment.