##// END OF EJS Templates
Added LazyValue, ExternalTask
cin -
r5:77543ddacb8d default
parent child
Show More
@@ -0,0 +1,52
1 package org.implab.gradle.common.tasks;
2
3 import org.gradle.api.DefaultTask;
4 import org.gradle.api.provider.ListProperty;
5 import org.gradle.api.tasks.Internal;
6 import org.implab.gradle.common.dsl.RedirectFromSpec;
7 import org.implab.gradle.common.dsl.RedirectToSpec;
8
9 public abstract class ExecuteTask extends DefaultTask {
10
11 private final RedirectToSpec redirectStderr = new RedirectToSpec();
12
13 private final RedirectToSpec redirectStdout = new RedirectToSpec();
14
15 private final RedirectFromSpec redirectStdin = new RedirectFromSpec();
16
17 @Internal
18 public abstract ListProperty<String> getCommandLine();
19
20
21 /**
22 * STDIN redirection, if not specified, no input will be passed to the command
23 */
24 @Internal
25 public RedirectFromSpec getStdin() {
26 return redirectStdin;
27 }
28
29 /**
30 * STDOUT redirection, if not specified, redirected to logger::info
31 */
32 @Internal
33 public RedirectToSpec getStdout() {
34 return redirectStdout;
35 }
36
37 /**
38 * STDERR redirection, if not specified, redirected to logger::error
39 */
40 @Internal
41 public RedirectToSpec getStderr() {
42 return redirectStderr;
43 }
44
45
46 /** Appends specified parameters to the command line */
47 void commandLine(String... args) {
48 getCommandLine().addAll(args);
49 }
50
51
52 }
@@ -0,0 +1,104
1 package org.implab.gradle.common.tasks;
2
3 import java.io.IOException;
4 import java.util.Optional;
5 import java.util.concurrent.ExecutionException;
6
7 import org.gradle.api.DefaultTask;
8 import org.implab.gradle.common.dsl.ProcessSpec;
9 import org.implab.gradle.common.exec.Executor;
10 import org.implab.gradle.common.exec.RedirectFrom;
11 import org.implab.gradle.common.exec.RedirectTo;
12
13 public abstract class ExternalTask extends DefaultTask {
14
15 /**
16 * A default redirection to the build log when loglevel is set to INFO,
17 * otherwise returns an empty redirection.
18 */
19 protected Optional<RedirectTo> loggerInfoRedirect() {
20 return getLogger().isInfoEnabled()
21 ? Optional.of(RedirectTo.consumer(getLogger()::info))
22 : Optional.empty();
23 }
24
25 /**
26 * A default redirection to the build log when loglevel is set to ERROR,
27 * otherwise returns an empty redirection. Note that ERROR level is set
28 * by default for a build runs.
29 */
30 protected Optional<RedirectTo> loggerErrorRedirect() {
31 return getLogger().isErrorEnabled()
32 ? Optional.of(RedirectTo.consumer(getLogger()::error))
33 : Optional.empty();
34 }
35
36 /**
37 * Stdout redirection for {@link #exec(ProcessSpec)}, default implementation
38 * will forward stdout to the build log through {@link #loggerErrorRedirect()}
39 */
40 protected Optional<RedirectTo> stdoutRedirection() {
41 return loggerInfoRedirect();
42 }
43
44 /**
45 * Stderr redirection for {@link #exec(ProcessSpec)}, default implementation
46 * will forward stderr to build log through {@link #loggerErrorRedirect()}.
47 */
48 protected Optional<RedirectTo> stderrRedirection() {
49 return loggerErrorRedirect();
50 }
51
52 /**
53 * Stdin redirection for {@link #exec(ProcessSpec)}, empty by default.
54 */
55 protected Optional<RedirectFrom> stdinRedirection() {
56 return Optional.empty();
57 }
58
59 /**
60 * Executes the specified process specification
61 *
62 * @param spec
63 * @throws InterruptedException
64 * @throws ExecutionException
65 * @throws IOException
66 */
67 protected void exec(ProcessSpec spec) throws InterruptedException, ExecutionException, IOException {
68 var executor = exec();
69
70 stdoutRedirection().ifPresent(executor::stdout);
71 stderrRedirection().ifPresent(executor::stderr);
72 stdinRedirection().ifPresent(executor::stdin);
73
74 getLogger().info("Staring: {}", spec.command());
75
76 spec.accept(executor);
77
78 // runs the command and checks the error code
79 var code = executor.start().get();
80
81 // check success code
82 if (code != 0)
83 throw new IOException("The process exited with error code " + code);
84 }
85
86 protected boolean checkRetCode(ProcessSpec proc, int code)
87 throws InterruptedException, ExecutionException, IOException {
88
89 var executor = exec();
90
91 if (getLogger().isInfoEnabled()) {
92 loggerInfoRedirect().ifPresent(executor::stdout);
93 loggerInfoRedirect().ifPresent(executor::stderr);
94 }
95
96 getLogger().info("Starting: {}", proc.command());
97
98 proc.accept(executor);
99
100 return executor.start().get() == code;
101 }
102
103 protected abstract Executor exec();
104 }
@@ -0,0 +1,29
1 package org.implab.gradle.common.utils;
2
3 import java.util.concurrent.atomic.AtomicReference;
4 import java.util.function.Supplier;
5
6 public class LazyValue<T> implements Supplier<T> {
7 private final AtomicReference<T> reference = new AtomicReference<>();
8
9 private final Supplier<T> innerSupplier;
10
11 public LazyValue(Supplier<T> supplier) {
12 this.innerSupplier = supplier;
13 }
14
15 @Override
16 public T get() {
17 var t = reference.get();
18 if (t != null)
19 return t;
20 return updateValue();
21 }
22
23 private T updateValue() {
24 var v = innerSupplier.get();
25 var t = reference.compareAndExchange(null, v);
26 return t != null ? t : v;
27 }
28
29 }
@@ -12,6 +12,7 java {
12 }
12 }
13
13
14 dependencies {
14 dependencies {
15 compileOnly "org.eclipse.jdt:org.eclipse.jdt.annotation:2.3.0"
15 api gradleApi()
16 api gradleApi()
16 }
17 }
17
18
@@ -8,6 +8,16
8 * in the user guide at https://docs.gradle.org/3.5/userguide/multi_project_builds.html
8 * in the user guide at https://docs.gradle.org/3.5/userguide/multi_project_builds.html
9 */
9 */
10
10
11 dependencyResolutionManagement {
12 repositories {
13 mavenCentral()
14 mavenLocal()
15 ivy {
16 url "${System.properties["user.home"]}/ivy-repo"
17 }
18 }
19 }
20
11 rootProject.name = 'gradle-common'
21 rootProject.name = 'gradle-common'
12
22
13 include 'common'
23 include 'common'
General Comments 0
You need to be logged in to leave comments. Login now