diff --git a/core/src/main/java/jenkins/tasks/SimpleBuildWrapper.java b/core/src/main/java/jenkins/tasks/SimpleBuildWrapper.java new file mode 100644 index 0000000000..bd4feec638 --- /dev/null +++ b/core/src/main/java/jenkins/tasks/SimpleBuildWrapper.java @@ -0,0 +1,171 @@ +/* + * The MIT License + * + * Copyright 2015 Jesse Glick. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jenkins.tasks; + +import hudson.AbortException; +import hudson.EnvVars; +import hudson.FilePath; +import hudson.Launcher; +import hudson.model.AbstractBuild; +import hudson.model.AbstractProject; +import hudson.model.Action; +import hudson.model.BuildListener; +import hudson.model.Run; +import hudson.model.TaskListener; +import hudson.tasks.BuildWrapper; +import java.io.IOException; +import java.io.OutputStream; +import java.io.Serializable; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Set; + +/** + * A generalization of {@link BuildWrapper} that, like {@link SimpleBuildStep}, may be called at various points within a build. + *
Such a build wrapper would typically be written according to make few assumptions about how it is being used.
+ * @since TODO
+ */
+@SuppressWarnings("rawtypes") // inherited
+public abstract class SimpleBuildWrapper extends BuildWrapper {
+
+ /**
+ * Called when a segment of a build is started that is to be enhanced with this wrapper.
+ * @param context a way of collecting modifications to the environment for nested steps
+ * @param build a build being run
+ * @param workspace a workspace of the build
+ * @param launcher a way to start commands
+ * @param listener a way to report progress
+ * @param initialEnvironment the environment variables set at the outset
+ * @throws IOException if something fails; {@link AbortException} for user errors
+ * @throws InterruptedException if setup is interrupted
+ */
+ public abstract void setUp(Context context, Run,?> build, FilePath workspace, Launcher launcher, TaskListener listener, EnvVars initialEnvironment) throws IOException, InterruptedException;
+
+ public static final class Context {
+ // TODO convert to bean or builder pattern
+ public Disposer disposer;
+ public EnvVars env;
+ }
+
+ /**
+ * An optional callback to run at the end of the wrapped block.
+ */
+ public static abstract class Disposer implements Serializable {
+ public abstract void tearDown(Run,?> build, FilePath workspace, Launcher launcher, TaskListener listener);
+ }
+
+ /**
+ * By default, when run as part of an {@link AbstractBuild}, will run late, in the {@link #setUp(AbstractBuild, Launcher, BuildListener)} phase.
+ * May be overridden to return true, in which case this will run earlier, in the {@link #preCheckout} phase.
+ * Ignored when not run as part of an {@link AbstractBuild}.
+ */
+ protected boolean runPreCheckout() {
+ return false;
+ }
+
+ @Override public final Environment setUp(AbstractBuild build, final Launcher launcher, BuildListener listener) throws IOException, InterruptedException {
+ if (runPreCheckout()) {
+ return new Environment() {};
+ } else {
+ final Context c = new Context();
+ setUp(c, build, build.getWorkspace(), launcher, listener, build.getEnvironment(listener));
+ return new EnvironmentWrapper(c, launcher);
+ }
+ }
+
+ @Override public final void preCheckout(AbstractBuild build, final Launcher launcher, BuildListener listener) throws IOException, InterruptedException {
+ if (runPreCheckout()) {
+ final Context c = new Context();
+ setUp(c, build, build.getWorkspace(), launcher, listener, build.getEnvironment(listener));
+ build.getEnvironments().add(new EnvironmentWrapper(c, launcher));
+ }
+ }
+
+ private static class EnvironmentWrapper extends Environment {
+ private final Context c;
+ private final Launcher launcher;
+ EnvironmentWrapper(Context c, Launcher launcher) {
+ this.c = c;
+ this.launcher = launcher;
+ }
+ @Override public void buildEnvVars(Map