PageRenderTime 22ms CodeModel.GetById 8ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/hudson-core/src/main/java/hudson/model/Build.java

http://github.com/hudson/hudson
Java | 182 lines | 89 code | 18 blank | 75 comment | 16 complexity | 121cb4cb062545b28ba77ec5154550b6 MD5 | raw file
  1/*
  2 * The MIT License
  3 * 
  4 * Copyright (c) 2004-2011, Oracle Corporation, Kohsuke Kawaguchi, Martin Eigenbrodt, Anton Kozak
  5 * 
  6 * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 * of this software and associated documentation files (the "Software"), to deal
  8 * in the Software without restriction, including without limitation the rights
  9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 10 * copies of the Software, and to permit persons to whom the Software is
 11 * furnished to do so, subject to the following conditions:
 12 * 
 13 * The above copyright notice and this permission notice shall be included in
 14 * all copies or substantial portions of the Software.
 15 * 
 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 22 * THE SOFTWARE.
 23 */
 24package hudson.model;
 25
 26import hudson.tasks.BuildStep;
 27import hudson.tasks.BuildWrapper;
 28import hudson.tasks.Builder;
 29import hudson.tasks.Recorder;
 30import hudson.tasks.Notifier;
 31
 32import java.io.File;
 33import java.io.IOException;
 34import java.util.ArrayList;
 35import java.util.Calendar;
 36import java.util.Collection;
 37import java.util.List;
 38import java.util.logging.Logger;
 39
 40import static hudson.model.Result.FAILURE;
 41import static hudson.model.Result.ABORTED;
 42/**
 43 * A build of a {@link Project}.
 44 *
 45 * <h2>Steps of a build</h2>
 46 * <p>
 47 * Roughly speaking, a {@link Build} goes through the following stages:
 48 *
 49 * <dl>
 50 * <dt>SCM checkout
 51 * <dd>Hudson decides which directory to use for a build, then the source code is checked out
 52 *
 53 * <dt>Pre-build steps
 54 * <dd>Everyone gets their {@link BuildStep#prebuild(AbstractBuild, BuildListener)} invoked
 55 * to indicate that the build is starting
 56 *
 57 * <dt>Build wrapper set up
 58 * <dd>{@link BuildWrapper#setUp(AbstractBuild, Launcher, BuildListener)} is invoked. This is normally
 59 * to prepare an environment for the build.
 60 *
 61 * <dt>Builder runs
 62 * <dd>{@link Builder#perform(AbstractBuild, Launcher, BuildListener)} is invoked. This is where
 63 * things that are useful to users happen, like calling Ant, Make, etc.
 64 *
 65 * <dt>Recorder runs
 66 * <dd>{@link Recorder#perform(AbstractBuild, Launcher, BuildListener)} is invoked. This is normally
 67 * to record the output from the build, such as test results.
 68 *
 69 * <dt>Notifier runs
 70 * <dd>{@link Notifier#perform(AbstractBuild, Launcher, BuildListener)} is invoked. This is normally
 71 * to send out notifications, based on the results determined so far.
 72 * </dl>
 73 *
 74 * <p>
 75 * And beyond that, the build is considered complete, and from then on {@link Build} object is there to
 76 * keep the record of what happened in this build. 
 77 *
 78 * @author Kohsuke Kawaguchi
 79 */
 80public abstract class Build <P extends BaseBuildableProject<P,B>,B extends Build<P,B>>
 81    extends AbstractBuild<P,B> {
 82
 83    /**
 84     * Creates a new build.
 85     */
 86    protected Build(P project) throws IOException {
 87        super(project);
 88    }
 89
 90    protected Build(P job, Calendar timestamp) {
 91        super(job, timestamp);
 92    }
 93
 94    /**
 95     * Loads a build from a log file.
 96     */
 97    protected Build(P project, File buildDir) throws IOException {
 98        super(project,buildDir);
 99    }
100
101//
102//
103// actions
104//
105//
106    @Override
107    public void run() {
108        run(createRunner());
109    }
110
111    protected Runner createRunner() {
112        return new RunnerImpl();
113    }
114    
115    protected class RunnerImpl extends AbstractRunner {
116        protected Result doRun(BuildListener listener) throws Exception {
117            if(!preBuild(listener,project.getBuilders()))
118                return FAILURE;
119            if(!preBuild(listener,project.getPublishers()))
120                return FAILURE;
121
122            Result r = null;
123            try {
124                List<BuildWrapper> wrappers = new ArrayList<BuildWrapper>(project.getBuildWrappers().values());
125                
126                ParametersAction parameters = getAction(ParametersAction.class);
127                if (parameters != null)
128                    parameters.createBuildWrappers(Build.this,wrappers);
129
130                for( BuildWrapper w : wrappers ) {
131                    Environment e = w.setUp((AbstractBuild<?,?>)Build.this, launcher, listener);
132                    if(e==null)
133                        return (r = FAILURE);
134                    buildEnvironments.add(e);
135                }
136
137                if(!build(listener,project.getBuilders()))
138                    r = FAILURE;
139            } catch (InterruptedException e) {
140                r = ABORTED;
141                throw e;
142            } finally {
143                if (r != null) setResult(r);
144                // tear down in reverse order
145                boolean failed=false;
146                for( int i=buildEnvironments.size()-1; i>=0; i-- ) {
147                    if (!buildEnvironments.get(i).tearDown(Build.this,listener)) {
148                        failed=true;
149                    }                    
150                }
151                // WARNING The return in the finally clause will trump any return before
152                if (failed) return FAILURE;
153            }
154
155            return r;
156        }
157
158        public void post2(BuildListener listener) throws IOException, InterruptedException {
159            if (!performAllBuildSteps(listener, project.getPublishers(), true))
160                setResult(FAILURE);
161            if (!performAllBuildSteps(listener, project.getProperties(), true))
162                setResult(FAILURE);
163        }
164
165        @Override
166        public void cleanUp(BuildListener listener) throws Exception {
167            // at this point it's too late to mark the build as a failure, so ignore return value.
168            performAllBuildSteps(listener, project.getPublishers(), false);
169            performAllBuildSteps(listener, project.getProperties(), false);
170            super.cleanUp(listener);
171        }
172
173        private boolean build(BuildListener listener, Collection<Builder> steps) throws IOException, InterruptedException {
174            for( BuildStep bs : steps )
175                if(!perform(bs,listener))
176                    return false;
177            return true;
178        }
179    }
180
181    private static final Logger LOGGER = Logger.getLogger(Build.class.getName());
182}