##// END OF EJS Templates
woring on exec spec
cin -
r3:56bc6876834e default
parent child
Show More
@@ -1,66 +1,78
1 1 package org.implab.gradle.common;
2 2
3 3 import javax.inject.Inject;
4 4
5 5 import org.gradle.api.Action;
6 6 import org.gradle.api.NamedDomainObjectProvider;
7 7 import org.gradle.api.Plugin;
8 8 import org.gradle.api.Project;
9 9 import org.gradle.api.Task;
10 10 import org.gradle.api.artifacts.Configuration;
11 11 import org.gradle.api.file.Directory;
12 import org.gradle.api.tasks.TaskContainer;
13 import org.implab.gradle.common.dsl.TaskGroup;
12 14 import org.implab.gradle.common.dsl.TaskSpec;
13 15 import org.implab.gradle.common.dsl.TasksMixin;
14 16 import org.implab.gradle.common.utils.ExtraProps;
15 17
16 18 /** Project configuration traits */
17 19 public interface ProjectMixin extends TasksMixin {
18 20 @Inject
19 21 Project getProject();
20 22
21 23 @Override
22 24 default <T extends Task> TaskSpec<T> task(String name, Class<T> clazz) {
23 25 var provider = getProject().getTasks().register(name, clazz);
24 26 return new TaskSpec<>(provider);
25 27 }
26 28
29 /** Creates a new task group */
30 default TaskGroup taskGroup(String name) {
31 return new TaskGroup(name) {
32 @Override
33 protected TaskContainer tasks() {
34 return getProject().getTasks();
35 }
36 };
37 }
38
27 39 /** Registers the new configuration */
28 40 default NamedDomainObjectProvider<Configuration> configuration(String name, Action<? super Configuration> configure) {
29 41 return getProject().getConfigurations().register(name, configure);
30 42 }
31 43
32 44 /** Returns the project directory */
33 45 default Directory projectDirectory() {
34 46 return getProject().getLayout().getProjectDirectory();
35 47 }
36 48
37 49 /** Applies and returns the specified plugin, the plugin is applied only once. */
38 50 default <T extends Plugin<Project>> T plugin(Class<T> clazz) {
39 51 getProject().getPluginManager().apply(clazz);
40 52 return getProject().getPlugins().findPlugin(clazz);
41 53 }
42 54
43 55 /**
44 56 * @param classes The list of classes to register as extensions
45 57 */
46 58 default void exportClasses(Class<?>... classes) {
47 59 var props = ExtraProps.of(getProject());
48 60 for (var clazz : classes)
49 61 props.put(clazz.getSimpleName(), clazz);
50 62 }
51 63
52 64 /** Creates and register a new project extension.
53 65 *
54 66 * @param <T> The type of the extension
55 67 * @param extensionName The name of the extension in the project
56 68 * @param clazz The class of the extension
57 69 * @return the newly created extension
58 70 */
59 71 default <T> T extension(String extensionName, Class<T> clazz) {
60 72 T extension = getProject().getObjects().newInstance(clazz);
61 73 getProject().getExtensions().add(extensionName, extension);
62 74 return extension;
63 75 }
64 76
65 77 }
66 78
@@ -1,112 +1,78
1 package org.implab.gradle.common.exec;
1 package org.implab.gradle.common.dsl;
2 2
3 3 import java.io.File;
4 import java.io.IOException;
5 import java.lang.ProcessBuilder.Redirect;
6 4 import java.util.ArrayList;
7 5 import java.util.Collection;
8 6 import java.util.List;
9 import java.util.concurrent.CompletableFuture;
10 import java.util.concurrent.ExecutionException;
7
8 import org.implab.gradle.common.exec.Executor;
9 import org.implab.gradle.common.exec.RedirectFrom;
10 import org.implab.gradle.common.exec.RedirectTo;
11 11
12 12 public class ProcessSpec {
13 private final ProcessBuilder builder;
14
15 13 private RedirectFrom inputRedirect;
16 14
17 15 private RedirectTo outputRedirect;
18 16
19 17 private RedirectTo errorRedirect;
20 18
21 19 private List<String> command = new ArrayList<>();
22 20
23 21 private File directory;
24 22
25 public ProcessSpec() {
26 builder = new ProcessBuilder();
27 }
28
29 public CompletableFuture<Integer> start() throws IOException {
30 var tasks = new ArrayList<CompletableFuture<?>>();
31
32 builder.command(command);
33 builder.directory(directory);
34
35 // discard stdout if not redirected
36 if (outputRedirect == null)
37 builder.redirectOutput(Redirect.DISCARD);
38
39 // discard stderr if not redirected
40 if (errorRedirect == null)
41 builder.redirectError(Redirect.DISCARD);
42
43 // run process
44 var proc = builder.start();
45
46 tasks.add(proc.onExit());
47
48 if (inputRedirect != null)
49 tasks.add(inputRedirect.redirect(proc.getOutputStream()));
50
51 if (outputRedirect != null)
52 tasks.add(outputRedirect.redirect(proc.getInputStream()));
53
54 if (errorRedirect != null)
55 tasks.add(errorRedirect.redirect(proc.getErrorStream()));
56
57 return CompletableFuture
58 .allOf(tasks.toArray(new CompletableFuture<?>[0]))
59 .thenApply(t -> proc.exitValue());
60 }
61
62 public Integer exec() throws InterruptedException, ExecutionException, IOException {
63 return start().get();
64 }
65
66 public List<String> command() {
67 return command;
68 }
69
70 23 public ProcessSpec command(String... args) {
71 24 command = new ArrayList<>();
72 25 args(args);
73 26 return this;
74 27 }
75 28
76 29 public ProcessSpec directory(File workingDir) {
77 30 directory = workingDir;
78 31 return this;
79 32 }
80 33
81 34 public ProcessSpec command(Collection<String> args) {
82 35 command = new ArrayList<>();
83 36 args(args);
84 37 return this;
85 38 }
86 39
87 40 public ProcessSpec args(String... args) {
88 41 for (String arg : args)
89 42 command.add(arg);
90 43 return this;
91 44 }
92 45
93 46 public ProcessSpec args(Collection<String> args) {
94 47 command.addAll(args);
95 48 return this;
96 49 }
97 50
98 51 public ProcessSpec stderr(RedirectTo to) {
99 52 errorRedirect = to;
100 53 return this;
101 54 }
102 55
103 56 public ProcessSpec stdin(RedirectFrom from) {
104 57 inputRedirect = from;
105 58 return this;
106 59 }
107 60
108 61 public ProcessSpec stdout(RedirectTo to) {
109 62 outputRedirect = to;
110 63 return this;
111 64 }
65
66 public void accept(Executor executor) {
67 command.forEach(executor::argument);
68 executor.directory(directory);
69 if (inputRedirect != null)
70 executor.stdin(inputRedirect);
71 if (outputRedirect != null)
72 executor.stdout(outputRedirect);
73 if (errorRedirect != null)
74 executor.stderr(errorRedirect);
112 75 }
76
77
78 }
@@ -1,22 +1,22
1 1 package org.implab.gradle.common.dsl;
2 2
3 3 import org.gradle.api.Buildable;
4 4 import org.gradle.api.tasks.TaskProvider;
5 5
6 public interface TaskReference {
6 public interface TaskDependency {
7 7
8 8 Object reference();
9 9
10 public static TaskReference named(String name) {
10 public static TaskDependency named(String name) {
11 11 return () -> name;
12 12 }
13 13
14 public static TaskReference provider(TaskProvider<?> provider) {
14 public static TaskDependency provider(TaskProvider<?> provider) {
15 15 return () -> provider;
16 16 }
17 17
18 public static TaskReference buildable(Buildable dependency) {
18 public static TaskDependency buildable(Buildable dependency) {
19 19 return () -> dependency;
20 20 }
21 21
22 22 }
@@ -1,54 +1,58
1 1 package org.implab.gradle.common.dsl;
2 2
3 3 import java.util.stream.Stream;
4 4
5 5 import org.gradle.api.Action;
6 6 import org.gradle.api.Task;
7 7 import org.gradle.api.tasks.TaskProvider;
8 8
9 public class TaskSpec<T extends Task> implements TaskReference {
9 /**
10 * Wrapper around TaskProvider for simplified lazy task configuration
11 */
12 public class TaskSpec<T extends Task> implements TaskDependency {
10 13 private final TaskProvider<T> taskProvider;
11 14
12 15 public TaskSpec(TaskProvider<T> taskProvider) {
13 16 this.taskProvider = taskProvider;
14 17 }
15 18
16 19 public TaskSpec<T> configure(Action<T> configure) {
17 20 taskProvider.configure(configure);
18 21 return this;
19 22 }
20 23
21 public TaskSpec<T> dependsOn(TaskReference... other) {
24 public TaskSpec<T> dependsOn(TaskDependency... other) {
22 25 taskProvider.configure(t -> t.dependsOn(references(other)));
23 26 return this;
24 27 }
25 28
26 public TaskSpec<T> finalizedBy(TaskReference... other) {
29 public TaskSpec<T> finalizedBy(TaskDependency... other) {
27 30 taskProvider.configure(t -> t.finalizedBy(references(other)));
28 31 return this;
29 32 }
30 33
31 public TaskSpec<T> mustRunAfter(TaskReference... other) {
34 public TaskSpec<T> mustRunAfter(TaskDependency... other) {
32 35 taskProvider.configure(t -> t.mustRunAfter(references(other)));
33 36 return this;
34 37 }
35 38
36 39 public TaskSpec<T> doLast(Action<T> action) {
37 40 taskProvider.configure(t -> t.doLast(self -> action.execute(t)));
38 41 return this;
39 42 }
40 43
41 44 public TaskSpec<T> doFirst(Action<T> action) {
42 45 taskProvider.configure(t -> t.doFirst(self -> action.execute(t)));
43 46 return this;
44 47 }
45 48
49 /** Returns a task provider for this task, can be used as dependency object */
46 50 @Override
47 51 public Object reference() {
48 52 return taskProvider;
49 53 }
50 54
51 private static Object[] references(TaskReference[] other) {
52 return Stream.of(other).map(TaskReference::reference).toArray(Object[]::new);
55 private static Object[] references(TaskDependency[] other) {
56 return Stream.of(other).map(TaskDependency::reference).toArray(Object[]::new);
53 57 }
54 58 }
General Comments 0
You need to be logged in to leave comments. Login now