Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make EvalTask track resolved output paths #403

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
7 changes: 4 additions & 3 deletions pkl-cli/src/main/kotlin/org/pkl/cli/CliEvaluator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,10 @@ constructor(
private val consoleWriter: Writer = System.out.writer(),
) : CliCommand(options.base) {
/**
* Output files for the modules to be evaluated. Returns `null` if `options.outputPath` is `null`.
* Multiple modules may be mapped to the same output file, in which case their outputs are
* concatenated with [CliEvaluatorOptions.moduleOutputSeparator].
* Output files for the modules to be evaluated. Returns `null` if `options.outputPath` is `null`
* or if `options.multipleFileOutputPath` is not `null`. Multiple modules may be mapped to the
* same output file, in which case their outputs are concatenated with
* [CliEvaluatorOptions.moduleOutputSeparator].
*/
@Suppress("MemberVisibilityCanBePrivate")
val outputFiles: Set<File>? by lazy {
Expand Down
10 changes: 10 additions & 0 deletions pkl-gradle/src/main/java/org/pkl/gradle/task/BasePklTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,18 @@
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javax.inject.Inject;
import org.gradle.api.DefaultTask;
import org.gradle.api.InvalidUserDataException;
import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.FileSystemLocation;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.provider.ListProperty;
import org.gradle.api.provider.MapProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.provider.Provider;
import org.gradle.api.provider.ProviderFactory;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.InputFiles;
Expand Down Expand Up @@ -142,6 +145,7 @@ public void runTask() {

@LateInit protected CliBaseOptions cachedOptions;

// Must be called during task execution time only.
@Internal
protected CliBaseOptions getCliBaseOptions() {
if (cachedOptions == null) {
Expand Down Expand Up @@ -176,6 +180,12 @@ protected List<URI> getSourceModulesAsUris() {
return Collections.emptyList();
}

@Inject
protected abstract ObjectFactory getObjects();

@Inject
protected abstract ProviderFactory getProviders();

protected List<Path> parseModulePath() {
return getModulePath().getFiles().stream().map(File::toPath).collect(Collectors.toList());
}
Expand Down
72 changes: 52 additions & 20 deletions pkl-gradle/src/main/java/org/pkl/gradle/task/EvalTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,50 +16,82 @@
package org.pkl.gradle.task;

import java.io.File;
import java.util.Collections;
import java.util.Set;
import javax.annotation.Nullable;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.FileCollection;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.provider.Provider;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.Internal;
import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.OutputDirectories;
import org.gradle.api.tasks.OutputFiles;
import org.pkl.cli.CliEvaluator;
import org.pkl.cli.CliEvaluatorOptions;

public abstract class EvalTask extends ModulesTask {
@OutputFile
@Optional

// not tracked because it might contain placeholders
// required
@Internal
public abstract RegularFileProperty getOutputFile();

// not tracked because it might contain placeholders
// optional
@Internal
bioball marked this conversation as resolved.
Show resolved Hide resolved
public abstract DirectoryProperty getMultipleFileOutputDir();

@Input
@Optional
public abstract Property<String> getOutputFormat();

@Input
@Optional
public abstract Property<String> getModuleOutputSeparator();

@OutputDirectory
@Input
public abstract Property<String> getExpression();

private final Provider<CliEvaluator> cliEvaluator =
getProviders()
.provider(
() ->
new CliEvaluator(
new CliEvaluatorOptions(
getCliBaseOptions(),
getOutputFile().get().getAsFile().getAbsolutePath(),
getOutputFormat().get(),
getModuleOutputSeparator().get(),
mapAndGetOrNull(
getMultipleFileOutputDir(), it -> it.getAsFile().getAbsolutePath()),
getExpression().get())));

@SuppressWarnings("unused")
@OutputFiles
@Optional
public abstract DirectoryProperty getMultipleFileOutputDir();
public FileCollection getEffectiveOutputFiles() {
return getObjects()
.fileCollection()
.from(cliEvaluator.map(e -> nullToEmpty(e.getOutputFiles())));
}

@Input
@OutputDirectories
@Optional
public abstract Property<String> getExpression();
public FileCollection getEffectiveOutputDirectories() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor - I believe in all of the plugins we use getSomeDir() for directory properties, not getSomeDirectory(), so it might make sense to name this getEffectiveOutputDirs(). WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking, but I agree with @netvl.

return getObjects()
.fileCollection()
.from(cliEvaluator.map(e -> nullToEmpty(e.getOutputDirectories())));
}

private static <T> Set<T> nullToEmpty(@Nullable Set<T> set) {
return set == null ? Collections.emptySet() : set;
}

@Override
protected void doRunTask() {
//noinspection ResultOfMethodCallIgnored
getOutputs().getPreviousOutputFiles().forEach(File::delete);

new CliEvaluator(
new CliEvaluatorOptions(
getCliBaseOptions(),
getOutputFile().get().getAsFile().getAbsolutePath(),
getOutputFormat().get(),
getModuleOutputSeparator().get(),
mapAndGetOrNull(getMultipleFileOutputDir(), it -> it.getAsFile().getAbsolutePath()),
getExpression().get()))
.run();
cliEvaluator.get().run();
}
}
Loading