Skip to content

Commit

Permalink
More configuration cache support for IDE tasks (#1166)
Browse files Browse the repository at this point in the history
  • Loading branch information
modmuss50 authored Sep 6, 2024
1 parent 039b435 commit d18c109
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;
Expand All @@ -42,10 +43,17 @@
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.commons.io.FileUtils;
import org.gradle.api.Project;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.ListProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.Nested;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;
import org.jetbrains.annotations.VisibleForTesting;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
Expand All @@ -58,33 +66,32 @@
import net.fabricmc.loom.util.Constants;

public abstract class IdeaSyncTask extends AbstractLoomTask {
private static final Logger LOGGER = LoggerFactory.getLogger(IdeaSyncTask.class);

@Nested
protected abstract ListProperty<IntelijRunConfig> getIdeaRunConfigs();

@Inject
public IdeaSyncTask() {
// Always re-run this task.
getOutputs().upToDateWhen(element -> false);
setGroup(Constants.TaskGroup.IDE);

notCompatibleWithConfigurationCache("Not yet supported");
getIdeaRunConfigs().set(getProject().provider(this::getRunConfigs));
}

@TaskAction
public void runTask() throws IOException {
File projectDir = getProject().getRootProject().file(".idea");
projectDir.mkdirs();

generateRunConfigs();
for (IntelijRunConfig config : getIdeaRunConfigs().get()) {
config.writeLaunchFile();
}
}

// See: https://github.com/FabricMC/fabric-loom/pull/206#issuecomment-986054254 for the reason why XML's are still used to provide the run configs
private void generateRunConfigs() throws IOException {
private List<IntelijRunConfig> getRunConfigs() throws IOException {
Project rootProject = getProject().getRootProject();
LoomGradleExtension extension = LoomGradleExtension.get(getProject());
String projectPath = getProject() == rootProject ? "" : getProject().getPath().replace(':', '_');
File runConfigsDir = new File(rootProject.file(".idea"), "runConfigurations");

if (!runConfigsDir.exists()) {
runConfigsDir.mkdirs();
}
List<IntelijRunConfig> configs = new ArrayList<>();

for (RunConfigSettings settings : extension.getRunConfigs()) {
if (!settings.isIdeConfigGenerated()) {
Expand All @@ -94,33 +101,53 @@ private void generateRunConfigs() throws IOException {
RunConfig config = RunConfig.runConfig(getProject(), settings);
String name = config.configName.replaceAll("[^a-zA-Z0-9$_]", "_");

File runConfigs = new File(runConfigsDir, name + projectPath + ".xml");
File runConfigFile = new File(runConfigsDir, name + projectPath + ".xml");
String runConfigXml = config.fromDummy("idea_run_config_template.xml", true, getProject());
final List<String> excludedLibraryPaths = config.getExcludedLibraryPaths(getProject());

if (!runConfigs.exists()) {
FileUtils.writeStringToFile(runConfigs, runConfigXml, StandardCharsets.UTF_8);
}
IntelijRunConfig irc = getProject().getObjects().newInstance(IntelijRunConfig.class);
irc.getRunConfigXml().set(runConfigXml);
irc.getExcludedLibraryPaths().set(excludedLibraryPaths);
irc.getLaunchFile().set(runConfigFile);
}

return configs;
}

settings.makeRunDir();
public interface IntelijRunConfig {
@Input
Property<String> getRunConfigXml();

final List<String> excludedLibraryPaths = config.getExcludedLibraryPaths(getProject());
@Input
ListProperty<String> getExcludedLibraryPaths();

@OutputFile
RegularFileProperty getLaunchFile();

default void writeLaunchFile() throws IOException {
Path launchFile = getLaunchFile().get().getAsFile().toPath();

if (Files.notExists(launchFile)) {
Files.createDirectories(launchFile.getParent());
Files.writeString(launchFile, getRunConfigXml().get(), StandardCharsets.UTF_8);
}

try {
setClasspathModifications(runConfigs.toPath(), excludedLibraryPaths);
setClasspathModifications(launchFile, getExcludedLibraryPaths().get());
} catch (Exception e) {
getProject().getLogger().error("Failed to modify run configuration xml", e);
LOGGER.error("Failed to modify run configuration xml", e);
}
}
}

private void setClasspathModifications(Path runConfig, List<String> exclusions) throws IOException {
private static void setClasspathModifications(Path runConfig, List<String> exclusions) throws IOException {
final String inputXml = Files.readString(runConfig, StandardCharsets.UTF_8);
final String outputXml;

try {
outputXml = setClasspathModificationsInXml(inputXml, exclusions);
} catch (Exception e) {
getLogger().error("Failed to modify idea xml", e);
LOGGER.error("Failed to modify idea xml", e);

return;
}
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/net/fabricmc/loom/task/GenEclipseRunsTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,15 @@
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.configuration.ide.RunConfig;
import net.fabricmc.loom.configuration.ide.RunConfigSettings;
import net.fabricmc.loom.util.Constants;

public abstract class GenEclipseRunsTask extends AbstractLoomTask {
@Nested
protected abstract ListProperty<EclipseRunConfig> getEclipseRunConfigs();

@Inject
public GenEclipseRunsTask() {
setGroup(Constants.TaskGroup.IDE);
getEclipseRunConfigs().set(getProject().provider(() -> getRunConfigs(getProject())));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import net.fabricmc.loom.LoomGradlePlugin;
import net.fabricmc.loom.configuration.ide.RunConfig;
import net.fabricmc.loom.configuration.ide.RunConfigSettings;
import net.fabricmc.loom.util.Constants;
import net.fabricmc.loom.util.gradle.SyncTaskBuildService;

// Recommended vscode plugin pack:
Expand All @@ -70,10 +71,9 @@ public abstract class GenVsCodeProjectTask extends AbstractLoomTask {

@Inject
public GenVsCodeProjectTask() {
setGroup(Constants.TaskGroup.IDE);
getLaunchConfigurations().set(getProject().provider(this::getConfigurations));
getLaunchJson().convention(getProject().getRootProject().getLayout().getProjectDirectory().file("vscode/launch.json"));

notCompatibleWithConfigurationCache("Not yet supported");
}

private List<VsCodeConfiguration> getConfigurations() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ class ConfigurationCacheTest extends Specification implements GradleProjectTestT
}
""".stripIndent()
when:
def result = gradle.run(task: task, configurationCache: true, isloatedProjects: false)
def result2 = gradle.run(task: task, configurationCache: true, isloatedProjects: false)
def result = gradle.run(task: task, isloatedProjects: false)
def result2 = gradle.run(task: task, isloatedProjects: false)
then:
result.task(":${task}").outcome != FAILED
Expand Down Expand Up @@ -97,10 +97,10 @@ class ConfigurationCacheTest extends Specification implements GradleProjectTestT
fabricModJson.text = fmj("1.0.0")
when:
def result = gradle.run(task: "testTask", configurationCache: true)
def result2 = gradle.run(task: "testTask", configurationCache: true)
def result = gradle.run(task: "testTask")
def result2 = gradle.run(task: "testTask")
fabricModJson.text = fmj("2.0.0")
def result3 = gradle.run(task: "testTask", configurationCache: true)
def result3 = gradle.run(task: "testTask")
then:
// Test that the cache is created
Expand Down

0 comments on commit d18c109

Please sign in to comment.