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