File D:\maven-qcr-plugin-testsunitaires\qcr4java\jenkins-master\target\site\qc\core\src\main\java\hudson\cli\BuildCommand.java.html

1 /*
2 * The MIT License
3 *
4 * Copyright (c) 2004-2010, Sun Microsystems, Inc.
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 */
24 package hudson.cli;
25
26 import hudson.console.ModelHyperlinkNote;
27 import hudson.model.AbstractBuild;
28 import hudson.model.AbstractProject;
29 import hudson.model.Cause.UserIdCause;
30 import hudson.model.ParametersAction;
31 import hudson.model.ParameterValue;
32 import hudson.model.ParametersDefinitionProperty;
33 import hudson.model.ParameterDefinition;
34 import hudson.Extension;
35 import hudson.AbortException;
36 import hudson.console.ModelHyperlinkNote;
37 import hudson.model.Item;
38 import hudson.model.TaskListener;
39 import hudson.model.queue.QueueTaskFuture;
40 import hudson.scm.PollingResult.Change;
41 import hudson.util.EditDistance;
42 import hudson.util.StreamTaskListener;
43 import org.kohsuke.args4j.Argument;
44 import org.kohsuke.args4j.Option;
45
46 import java.io.IOException;
47 import java.util.Map;
48 import java.util.HashMap;
49 import java.util.List;
50 import java.util.ArrayList;
51 import java.util.Map.Entry;
52 import java.io.FileNotFoundException;
53 import java.io.PrintStream;
54 import java.util.concurrent.ExecutionException;
55
56 import jenkins.model.Jenkins;
57
58 /**
59 * Builds a job, and optionally waits until its completion.
60 *
61 * @author Kohsuke Kawaguchi
62 */
63 @Extension
64 public class BuildCommand extends CLICommand {
65 @Override
66 public String getShortDescription() {
67 return Messages.BuildCommand_ShortDescription();
68 }
69
70 @Argument(metaVar="JOB",usage="Name of the job to build",required=true)
71 public AbstractProject<?,?> job;
72
73 @Option(name="-s",usage="Wait until the completion/abortion of the command")
74 public boolean sync = false;
75
76 @Option(name="-w",usage="Wait until the start of the command")
77 public boolean wait = false;
78
79 @Option(name="-c",usage="Check for SCM changes before starting the build, and if there's no change, exit without doing a build")
80 public boolean checkSCM = false;
81
82 @Option(name="-p",usage="Specify the build parameters in the key=value format.")
83 public Map<String,String> parameters = new HashMap<String, String>();
84
85 @Option(name="-v",usage="Prints out the console output of the build. Use with -s")
86 public boolean consoleOutput = false;
87
88 @Option(name="-r", usage="Number of times to retry reading of the output log if it does not exists on first attempt. Defaults to 0. Use with -v.")
89 public String retryCntStr = "0";
90
91 // hold parsed retryCnt;
92 private int retryCnt = 0;
93
94 protected int run() throws Exception {
95 job.checkPermission(Item.BUILD);
96
97 ParametersAction a = null;
98 if (!parameters.isEmpty()) {
99 ParametersDefinitionProperty pdp = job.getProperty(ParametersDefinitionProperty.class);
100 if (pdp==null)
101 throw new AbortException(job.getFullDisplayName()+" is not parameterized but the -p option was specified");
102
103 List<ParameterValue> values = new ArrayList<ParameterValue>();
104
105 for (Entry<String, String> e : parameters.entrySet()) {
106 String name = e.getKey();
107 ParameterDefinition pd = pdp.getParameterDefinition(name);
108 if (pd==null)
109 throw new AbortException(String.format("\'%s\' is not a valid parameter. Did you mean %s?",
110 name, EditDistance.findNearest(name, pdp.getParameterDefinitionNames())));
111 values.add(pd.createValue(this,e.getValue()));
112 }
113
114 // handle missing parameters by adding as default values ISSUE JENKINS-7162
115 for(ParameterDefinition pd : pdp.getParameterDefinitions()) {
116 if (parameters.containsKey(pd.getName()))
117 continue;
118
119 // not passed in use default
120 values.add(pd.getDefaultParameterValue());
121 }
122
123 a = new ParametersAction(values);
124 }
125
126 retryCnt = Integer.parseInt(retryCntStr);
127
128 if (checkSCM) {
129 if (job.poll(new StreamTaskListener(stdout, getClientCharset())).change == Change.NONE) {
130 return 0;
131 }
132 }
133
134 QueueTaskFuture<? extends AbstractBuild> f = job.scheduleBuild2(0, new CLICause(Jenkins.getAuthentication().getName()), a);
135
136 if (wait || sync) {
137 AbstractBuild b = f.waitForStart(); // wait for the start
138 stdout.println("Started "+b.getFullDisplayName());
139
140 if (sync) {
141 try {
142 if (consoleOutput) {
143 // read output in a retry loop, by default try only once
144 // writeWholeLogTo may fail with FileNotFound
145 // exception on a slow/busy machine, if it takes
146 // longish to create the log file
147 int retryInterval = 100;
148 for (int i=0;i<=retryCnt;) {
149 try {
150 b.writeWholeLogTo(stdout);
151 break;
152 }
153 catch (FileNotFoundException e) {
154 if ( i == retryCnt ) {
155 throw e;
156 }
157 i++;
158 Thread.sleep(retryInterval);
159 }
160 }
161 }
162 f.get(); // wait for the completion
163 stdout.println("Completed "+b.getFullDisplayName()+" : "+b.getResult());
164 return b.getResult().ordinal;
165 } catch (InterruptedException e) {
166 // if the CLI is aborted, try to abort the build as well
167 f.cancel(true);
168 throw e;
169 }
170 }
171 }
172
173 return 0;
174 }
175
176 @Override
177 protected void printUsageSummary(PrintStream stderr) {
178 stderr.println(
179 "Starts a build, and optionally waits for a completion.\n" +
180 "Aside from general scripting use, this command can be\n" +
181 "used to invoke another job from within a build of one job.\n" +
182 "With the -s option, this command changes the exit code based on\n" +
183 "the outcome of the build (exit code 0 indicates a success.)\n" +
184 "With the -c option, a build will only run if there has been\n" +
185 "an SCM change"
186 );
187 }
188
189 public static class CLICause extends UserIdCause {
190
191 private String startedBy;
192
193 public CLICause(){
194 startedBy = "unknown";
195 }
196
197 public CLICause(String startedBy){
198 this.startedBy = startedBy;
199 }
200
201 @Override
202 public String getShortDescription() {
203 return Messages.BuildCommand_CLICause_ShortDescription(startedBy);
204 }
205
206 @Override
207 public void print(TaskListener listener) {
208 listener.getLogger().println(Messages.BuildCommand_CLICause_ShortDescription(
209 ModelHyperlinkNote.encodeTo("/user/" + startedBy, startedBy)));
210 }
211
212 @Override
213 public boolean equals(Object o) {
214 return o instanceof CLICause;
215 }
216
217 @Override
218 public int hashCode() {
219 return 7;
220 }
221 }
222 }
223
224