diff --git a/common/src/main/java/org/implab/gradle/common/ProjectMixin.java b/common/src/main/java/org/implab/gradle/common/ProjectMixin.java --- a/common/src/main/java/org/implab/gradle/common/ProjectMixin.java +++ b/common/src/main/java/org/implab/gradle/common/ProjectMixin.java @@ -9,6 +9,8 @@ import org.gradle.api.Project; import org.gradle.api.Task; import org.gradle.api.artifacts.Configuration; import org.gradle.api.file.Directory; +import org.gradle.api.tasks.TaskContainer; +import org.implab.gradle.common.dsl.TaskGroup; import org.implab.gradle.common.dsl.TaskSpec; import org.implab.gradle.common.dsl.TasksMixin; import org.implab.gradle.common.utils.ExtraProps; @@ -24,6 +26,16 @@ public interface ProjectMixin extends Ta return new TaskSpec<>(provider); } + /** Creates a new task group */ + default TaskGroup taskGroup(String name) { + return new TaskGroup(name) { + @Override + protected TaskContainer tasks() { + return getProject().getTasks(); + } + }; + } + /** Registers the new configuration */ default NamedDomainObjectProvider configuration(String name, Action configure) { return getProject().getConfigurations().register(name, configure); diff --git a/common/src/main/java/org/implab/gradle/common/exec/ProcessSpec.java b/common/src/main/java/org/implab/gradle/common/dsl/ProcessSpec.java rename from common/src/main/java/org/implab/gradle/common/exec/ProcessSpec.java rename to common/src/main/java/org/implab/gradle/common/dsl/ProcessSpec.java --- a/common/src/main/java/org/implab/gradle/common/exec/ProcessSpec.java +++ b/common/src/main/java/org/implab/gradle/common/dsl/ProcessSpec.java @@ -1,17 +1,15 @@ -package org.implab.gradle.common.exec; +package org.implab.gradle.common.dsl; import java.io.File; -import java.io.IOException; -import java.lang.ProcessBuilder.Redirect; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; + +import org.implab.gradle.common.exec.Executor; +import org.implab.gradle.common.exec.RedirectFrom; +import org.implab.gradle.common.exec.RedirectTo; public class ProcessSpec { - private final ProcessBuilder builder; - private RedirectFrom inputRedirect; private RedirectTo outputRedirect; @@ -22,51 +20,6 @@ public class ProcessSpec { private File directory; - public ProcessSpec() { - builder = new ProcessBuilder(); - } - - public CompletableFuture start() throws IOException { - var tasks = new ArrayList>(); - - builder.command(command); - builder.directory(directory); - - // discard stdout if not redirected - if (outputRedirect == null) - builder.redirectOutput(Redirect.DISCARD); - - // discard stderr if not redirected - if (errorRedirect == null) - builder.redirectError(Redirect.DISCARD); - - // run process - var proc = builder.start(); - - tasks.add(proc.onExit()); - - if (inputRedirect != null) - tasks.add(inputRedirect.redirect(proc.getOutputStream())); - - if (outputRedirect != null) - tasks.add(outputRedirect.redirect(proc.getInputStream())); - - if (errorRedirect != null) - tasks.add(errorRedirect.redirect(proc.getErrorStream())); - - return CompletableFuture - .allOf(tasks.toArray(new CompletableFuture[0])) - .thenApply(t -> proc.exitValue()); - } - - public Integer exec() throws InterruptedException, ExecutionException, IOException { - return start().get(); - } - - public List command() { - return command; - } - public ProcessSpec command(String... args) { command = new ArrayList<>(); args(args); @@ -109,4 +62,17 @@ public class ProcessSpec { outputRedirect = to; return this; } + + public void accept(Executor executor) { + command.forEach(executor::argument); + executor.directory(directory); + if (inputRedirect != null) + executor.stdin(inputRedirect); + if (outputRedirect != null) + executor.stdout(outputRedirect); + if (errorRedirect != null) + executor.stderr(errorRedirect); + } + + } diff --git a/common/src/main/java/org/implab/gradle/common/dsl/TaskReference.java b/common/src/main/java/org/implab/gradle/common/dsl/TaskDependency.java rename from common/src/main/java/org/implab/gradle/common/dsl/TaskReference.java rename to common/src/main/java/org/implab/gradle/common/dsl/TaskDependency.java --- a/common/src/main/java/org/implab/gradle/common/dsl/TaskReference.java +++ b/common/src/main/java/org/implab/gradle/common/dsl/TaskDependency.java @@ -3,19 +3,19 @@ package org.implab.gradle.common.dsl; import org.gradle.api.Buildable; import org.gradle.api.tasks.TaskProvider; -public interface TaskReference { +public interface TaskDependency { Object reference(); - public static TaskReference named(String name) { + public static TaskDependency named(String name) { return () -> name; } - public static TaskReference provider(TaskProvider provider) { + public static TaskDependency provider(TaskProvider provider) { return () -> provider; } - public static TaskReference buildable(Buildable dependency) { + public static TaskDependency buildable(Buildable dependency) { return () -> dependency; } diff --git a/common/src/main/java/org/implab/gradle/common/dsl/TaskSpec.java b/common/src/main/java/org/implab/gradle/common/dsl/TaskSpec.java --- a/common/src/main/java/org/implab/gradle/common/dsl/TaskSpec.java +++ b/common/src/main/java/org/implab/gradle/common/dsl/TaskSpec.java @@ -6,7 +6,10 @@ import org.gradle.api.Action; import org.gradle.api.Task; import org.gradle.api.tasks.TaskProvider; -public class TaskSpec implements TaskReference { +/** + * Wrapper around TaskProvider for simplified lazy task configuration + */ +public class TaskSpec implements TaskDependency { private final TaskProvider taskProvider; public TaskSpec(TaskProvider taskProvider) { @@ -18,17 +21,17 @@ public class TaskSpec im return this; } - public TaskSpec dependsOn(TaskReference... other) { + public TaskSpec dependsOn(TaskDependency... other) { taskProvider.configure(t -> t.dependsOn(references(other))); return this; } - public TaskSpec finalizedBy(TaskReference... other) { + public TaskSpec finalizedBy(TaskDependency... other) { taskProvider.configure(t -> t.finalizedBy(references(other))); return this; } - public TaskSpec mustRunAfter(TaskReference... other) { + public TaskSpec mustRunAfter(TaskDependency... other) { taskProvider.configure(t -> t.mustRunAfter(references(other))); return this; } @@ -43,12 +46,13 @@ public class TaskSpec im return this; } + /** Returns a task provider for this task, can be used as dependency object */ @Override public Object reference() { return taskProvider; } - private static Object[] references(TaskReference[] other) { - return Stream.of(other).map(TaskReference::reference).toArray(Object[]::new); + private static Object[] references(TaskDependency[] other) { + return Stream.of(other).map(TaskDependency::reference).toArray(Object[]::new); } }