forked from FabricMC/fabric-loom
-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make Forge tools compatible with config cache
- Loading branch information
Showing
11 changed files
with
234 additions
and
137 deletions.
There are no files selected for viewing
141 changes: 141 additions & 0 deletions
141
src/main/java/dev/architectury/loom/forge/tool/ForgeToolExecutor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
package dev.architectury.loom.forge.tool; | ||
|
||
import java.util.Collection; | ||
import java.util.List; | ||
|
||
import javax.inject.Inject; | ||
|
||
import org.apache.commons.io.output.NullOutputStream; | ||
import org.gradle.api.Action; | ||
import org.gradle.api.Project; | ||
import org.gradle.api.file.ConfigurableFileCollection; | ||
import org.gradle.api.logging.LogLevel; | ||
import org.gradle.api.logging.configuration.ShowStacktrace; | ||
import org.gradle.api.provider.ListProperty; | ||
import org.gradle.api.provider.Property; | ||
import org.gradle.api.tasks.Classpath; | ||
import org.gradle.api.tasks.Input; | ||
import org.gradle.process.ExecOperations; | ||
import org.gradle.process.ExecResult; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
/** | ||
* Contains helpers for executing Forge's command line tools | ||
* with suppressed output streams to prevent annoying log spam. | ||
*/ | ||
public abstract class ForgeToolExecutor { | ||
@Inject | ||
protected abstract ExecOperations getExecOperations(); | ||
|
||
public static boolean shouldShowVerboseStdout(Project project) { | ||
// if running with INFO or DEBUG logging | ||
return project.getGradle().getStartParameter().getLogLevel().compareTo(LogLevel.LIFECYCLE) < 0; | ||
} | ||
|
||
public static boolean shouldShowVerboseStderr(Project project) { | ||
// if stdout is shown or stacktraces are visible so that errors printed to stderr show up | ||
return shouldShowVerboseStdout(project) || project.getGradle().getStartParameter().getShowStacktrace() != ShowStacktrace.INTERNAL_EXCEPTIONS; | ||
} | ||
|
||
public static Settings getDefaultSettings(Project project) { | ||
final Settings settings = project.getObjects().newInstance(Settings.class); | ||
settings.getExecutable().set(JavaExecutableFetcher.getJavaToolchainExecutable(project)); | ||
settings.getShowVerboseStdout().set(shouldShowVerboseStdout(project)); | ||
settings.getShowVerboseStderr().set(shouldShowVerboseStderr(project)); | ||
return settings; | ||
} | ||
|
||
/** | ||
* Executes an external Java process. | ||
* | ||
* <p>This method cannot be used during configuration. | ||
* Use {@link ForgeToolValueSource#exec(Project, Action)} for those cases. | ||
* | ||
* @param project the project | ||
* @param configurator the {@code javaexec} configuration action | ||
* @return the execution result | ||
*/ | ||
public static ExecResult exec(Project project, Action<? super Settings> configurator) { | ||
final Settings settings = getDefaultSettings(project); | ||
configurator.execute(settings); | ||
return project.getObjects().newInstance(ForgeToolExecutor.class).exec(settings); | ||
} | ||
|
||
private ExecResult exec(Settings settings) { | ||
return exec(getExecOperations(), settings); | ||
} | ||
|
||
public static ExecResult exec(ExecOperations execOperations, Settings settings) { | ||
return execOperations.javaexec(spec -> { | ||
final @Nullable String executable = settings.getExecutable().getOrNull(); | ||
if (executable != null) spec.setExecutable(executable); | ||
spec.getMainClass().set(settings.getMainClass()); | ||
spec.setArgs(settings.getProgramArgs().get()); | ||
spec.setJvmArgs(settings.getJvmArgs().get()); | ||
spec.setClasspath(settings.getExecClasspath()); | ||
|
||
if (settings.getShowVerboseStdout().get()) { | ||
spec.setStandardOutput(System.out); | ||
} else { | ||
spec.setStandardOutput(NullOutputStream.INSTANCE); | ||
} | ||
|
||
if (settings.getShowVerboseStderr().get()) { | ||
spec.setErrorOutput(System.err); | ||
} else { | ||
spec.setErrorOutput(NullOutputStream.INSTANCE); | ||
} | ||
}); | ||
} | ||
|
||
public interface Settings { | ||
@Input | ||
Property<String> getExecutable(); | ||
|
||
@Input | ||
ListProperty<String> getProgramArgs(); | ||
|
||
@Input | ||
ListProperty<String> getJvmArgs(); | ||
|
||
@Input | ||
Property<String> getMainClass(); | ||
|
||
@Classpath | ||
ConfigurableFileCollection getExecClasspath(); | ||
|
||
@Input | ||
Property<Boolean> getShowVerboseStdout(); | ||
|
||
@Input | ||
Property<Boolean> getShowVerboseStderr(); | ||
|
||
default void classpath(Object... paths) { | ||
getExecClasspath().from(paths); | ||
} | ||
|
||
default void setClasspath(Object... paths) { | ||
getExecClasspath().setFrom(paths); | ||
} | ||
|
||
default void args(String... args) { | ||
getProgramArgs().addAll(args); | ||
} | ||
|
||
default void args(Collection<String> args) { | ||
getProgramArgs().addAll(args); | ||
} | ||
|
||
default void setArgs(List<String> args) { | ||
getProgramArgs().set(args); | ||
} | ||
|
||
default void jvmArgs(String... args) { | ||
getJvmArgs().addAll(args); | ||
} | ||
|
||
default void jvmArgs(Collection<String> args) { | ||
getJvmArgs().addAll(args); | ||
} | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
src/main/java/dev/architectury/loom/forge/tool/ForgeToolValueSource.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package dev.architectury.loom.forge.tool; | ||
|
||
import javax.inject.Inject; | ||
|
||
import org.gradle.api.Action; | ||
import org.gradle.api.Project; | ||
import org.gradle.api.provider.Property; | ||
import org.gradle.api.provider.Provider; | ||
import org.gradle.api.provider.ValueSource; | ||
import org.gradle.api.provider.ValueSourceParameters; | ||
import org.gradle.api.tasks.Nested; | ||
import org.gradle.process.ExecOperations; | ||
import org.gradle.process.ExecResult; | ||
|
||
public abstract class ForgeToolValueSource implements ValueSource<ExecResult, ForgeToolValueSource.Parameters> { | ||
@Inject | ||
protected abstract ExecOperations getExecOperations(); | ||
|
||
public static Provider<ExecResult> create(Project project, Action<? super ForgeToolExecutor.Settings> configurator) { | ||
return project.getProviders().of(ForgeToolValueSource.class, spec -> { | ||
ForgeToolExecutor.Settings settings = ForgeToolExecutor.getDefaultSettings(project); | ||
configurator.execute(settings); | ||
spec.getParameters().getSettings().set(settings); | ||
}); | ||
} | ||
|
||
/** | ||
* Executes an external Java process during project configuration. | ||
* | ||
* @param project the project | ||
* @param configurator an action that configures the exec settings | ||
*/ | ||
public static void exec(Project project, Action<? super ForgeToolExecutor.Settings> configurator) { | ||
create(project, configurator).get().rethrowFailure().assertNormalExitValue(); | ||
} | ||
|
||
@Override | ||
public ExecResult obtain() { | ||
return ForgeToolExecutor.exec(getExecOperations(), getParameters().getSettings().get()); | ||
} | ||
|
||
public interface Parameters extends ValueSourceParameters { | ||
@Nested | ||
Property<ForgeToolExecutor.Settings> getSettings(); | ||
} | ||
} |
2 changes: 1 addition & 1 deletion
2
...v/architectury/loom/forge/ForgeTools.java → ...hitectury/loom/forge/tool/ForgeTools.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
src/main/java/dev/architectury/loom/forge/tool/JavaExecutableFetcher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package dev.architectury.loom.forge.tool; | ||
|
||
import javax.inject.Inject; | ||
|
||
import org.gradle.api.Project; | ||
import org.gradle.api.plugins.JavaPluginExtension; | ||
import org.gradle.api.provider.Provider; | ||
import org.gradle.jvm.toolchain.JavaLauncher; | ||
import org.gradle.jvm.toolchain.JavaToolchainService; | ||
import org.gradle.jvm.toolchain.JavaToolchainSpec; | ||
|
||
public abstract class JavaExecutableFetcher { | ||
@Inject | ||
protected abstract JavaToolchainService getToolchainService(); | ||
|
||
public static Provider<String> getJavaToolchainExecutable(Project project) { | ||
return project.provider(() -> { | ||
final JavaExecutableFetcher fetcher = project.getObjects().newInstance(JavaExecutableFetcher.class); | ||
final JavaPluginExtension java = project.getExtensions().getByType(JavaPluginExtension.class); | ||
final JavaToolchainSpec toolchain = java.getToolchain(); | ||
|
||
if (!toolchain.getLanguageVersion().isPresent()) { | ||
// Toolchain not configured, we'll use the runtime Java version. | ||
return null; | ||
} | ||
|
||
final JavaLauncher launcher = fetcher.getToolchainService().launcherFor(toolchain).get(); | ||
return launcher.getExecutablePath().getAsFile().getAbsolutePath(); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.