/hudson-core/src/main/java/hudson/matrix/MatrixConfiguration.java

http://github.com/hudson/hudson · Java · 336 lines · 180 code · 44 blank · 112 comment · 7 complexity · 37cb1bfff84f99b380a21dc40c28a485 MD5 · raw file

  1. /*
  2. * The MIT License
  3. *
  4. * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Tom Huybrechts
  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.matrix;
  25. import hudson.Util;
  26. import hudson.security.ACL;
  27. import hudson.util.DescribableList;
  28. import hudson.model.AbstractBuild;
  29. import hudson.model.Cause;
  30. import hudson.model.CauseAction;
  31. import hudson.model.DependencyGraph;
  32. import hudson.model.Descriptor;
  33. import hudson.model.Hudson;
  34. import hudson.model.Item;
  35. import hudson.model.ItemGroup;
  36. import hudson.model.JDK;
  37. import hudson.model.Label;
  38. import hudson.model.ParametersAction;
  39. import hudson.model.Project;
  40. import hudson.model.SCMedItem;
  41. import hudson.model.Queue.NonBlockingTask;
  42. import hudson.model.Cause.LegacyCodeCause;
  43. import hudson.scm.SCM;
  44. import hudson.tasks.BuildWrapper;
  45. import hudson.tasks.Builder;
  46. import hudson.tasks.LogRotator;
  47. import hudson.tasks.Publisher;
  48. import java.io.IOException;
  49. import java.util.List;
  50. import java.util.Map;
  51. /**
  52. * One configuration of {@link MatrixProject}.
  53. *
  54. * @author Kohsuke Kawaguchi
  55. */
  56. public class MatrixConfiguration extends Project<MatrixConfiguration,MatrixRun> implements SCMedItem, NonBlockingTask {
  57. /**
  58. * The actual value combination.
  59. */
  60. private transient /*final*/ Combination combination;
  61. /**
  62. * Hash value of {@link #combination}. Cached for efficiency.
  63. */
  64. private transient String digestName;
  65. public MatrixConfiguration(MatrixProject parent, Combination c) {
  66. super(parent,c.toString());
  67. setCombination(c);
  68. updateTransientActions();
  69. }
  70. @Override
  71. public void onLoad(ItemGroup<? extends Item> parent, String name) throws IOException {
  72. // directory name is not a name for us --- it's taken from the combination name
  73. super.onLoad(parent, combination.toString());
  74. }
  75. /**
  76. * Used during loading to set the combination back.
  77. */
  78. /*package*/ void setCombination(Combination c) {
  79. this.combination = c;
  80. this.digestName = c.digest().substring(0,8);
  81. }
  82. /**
  83. * Build numbers are always synchronized with the parent.
  84. *
  85. * <p>
  86. * Computing this is bit tricky. Several considerations:
  87. *
  88. * <ol>
  89. * <li>A new configuration build #N is started while the parent build #N is building,
  90. * and when that happens we want to return N.
  91. * <li>But the configuration build #N is done before the parent build #N finishes,
  92. * and when that happens we want to return N+1 because that's going to be the next one.
  93. * <li>Configuration builds might skip some numbers if the parent build is aborted
  94. * before this configuration is built.
  95. * <li>If nothing is building right now and the last build of the parent is #N,
  96. * then we want to return N+1.
  97. * </ol>
  98. */
  99. @Override
  100. public int getNextBuildNumber() {
  101. AbstractBuild lb = getParent().getLastBuild();
  102. if(lb==null) return 0;
  103. int n=lb.getNumber();
  104. if(!lb.isBuilding()) n++;
  105. lb = getLastBuild();
  106. if(lb!=null)
  107. n = Math.max(n,lb.getNumber()+1);
  108. return n;
  109. }
  110. @Override
  111. public int assignBuildNumber() throws IOException {
  112. int nb = getNextBuildNumber();
  113. MatrixRun r = getLastBuild();
  114. if(r!=null && r.getNumber()>=nb) // make sure we don't schedule the same build twice
  115. throw new IllegalStateException("Build #"+nb+" is already completed");
  116. return nb;
  117. }
  118. @Override
  119. public String getDisplayName() {
  120. return combination.toCompactString(getParent().getAxes());
  121. }
  122. @Override
  123. public MatrixProject getParent() {
  124. return (MatrixProject)super.getParent();
  125. }
  126. /**
  127. * Get the actual combination of the axes values for this {@link MatrixConfiguration}
  128. */
  129. public Combination getCombination() {
  130. return combination;
  131. }
  132. /**
  133. * Since {@link MatrixConfiguration} is always invoked from {@link MatrixRun}
  134. * once and just once, there's no point in having a quiet period.
  135. */
  136. @Override
  137. public int getQuietPeriod() {
  138. return 0;
  139. }
  140. /**
  141. * Inherit the value from the parent.
  142. */
  143. @Override
  144. public int getScmCheckoutRetryCount() {
  145. return getParent().getScmCheckoutRetryCount();
  146. }
  147. @Override
  148. public boolean isConfigurable() {
  149. return false;
  150. }
  151. @Override
  152. protected Class<MatrixRun> getBuildClass() {
  153. return MatrixRun.class;
  154. }
  155. @Override
  156. protected MatrixRun newBuild() throws IOException {
  157. // for every MatrixRun there should be a parent MatrixBuild
  158. MatrixBuild lb = getParent().getLastBuild();
  159. MatrixRun lastBuild = new MatrixRun(this, lb.getTimestamp());
  160. lastBuild.number = lb.getNumber();
  161. builds.put(lastBuild);
  162. return lastBuild;
  163. }
  164. @Override
  165. protected void buildDependencyGraph(DependencyGraph graph) {
  166. }
  167. @Override
  168. public MatrixConfiguration asProject() {
  169. return this;
  170. }
  171. @Override
  172. public Label getAssignedLabel() {
  173. // combine all the label axes by &&.
  174. String expr = Util.join(combination.values(getParent().getAxes().subList(LabelAxis.class)), "&&");
  175. return Hudson.getInstance().getLabel(Util.fixEmpty(expr));
  176. }
  177. @Override
  178. public String getPronoun() {
  179. return Messages.MatrixConfiguration_Pronoun();
  180. }
  181. @Override
  182. public JDK getJDK() {
  183. return Hudson.getInstance().getJDK(combination.get("jdk"));
  184. }
  185. //
  186. // inherit build setting from the parent project
  187. //
  188. @Override
  189. public List<Builder> getBuilders() {
  190. return getParent().getBuilders();
  191. }
  192. @Override
  193. public Map<Descriptor<Publisher>, Publisher> getPublishers() {
  194. return getParent().getPublishers();
  195. }
  196. @Override
  197. public DescribableList<Builder, Descriptor<Builder>> getBuildersList() {
  198. return getParent().getBuildersList();
  199. }
  200. @Override
  201. public DescribableList<Publisher, Descriptor<Publisher>> getPublishersList() {
  202. return getParent().getPublishersList();
  203. }
  204. @Override
  205. public Map<Descriptor<BuildWrapper>, BuildWrapper> getBuildWrappers() {
  206. return getParent().getBuildWrappers();
  207. }
  208. /**
  209. * @since 2.1.0
  210. */
  211. @Override
  212. public DescribableList<BuildWrapper, Descriptor<BuildWrapper>> getBuildWrappersList() {
  213. return getParent().getBuildWrappersList();
  214. }
  215. @Override
  216. public Publisher getPublisher(Descriptor<Publisher> descriptor) {
  217. return getParent().getPublisher(descriptor);
  218. }
  219. @Override
  220. public LogRotator getLogRotator() {
  221. LogRotator lr = getParent().getLogRotator();
  222. return new LinkedLogRotator(lr != null ? lr.getArtifactDaysToKeep() : -1,
  223. lr != null ? lr.getArtifactNumToKeep() : -1);
  224. }
  225. @Override
  226. public SCM getScm() {
  227. return getParent().getScm();
  228. }
  229. /*package*/ String getDigestName() {
  230. return digestName;
  231. }
  232. /**
  233. * JDK cannot be set on {@link MatrixConfiguration} because
  234. * it's controlled by {@link MatrixProject}.
  235. * @deprecated
  236. * Not supported.
  237. */
  238. @Override
  239. public void setJDK(JDK jdk) throws IOException {
  240. throw new UnsupportedOperationException();
  241. }
  242. /**
  243. * @deprecated
  244. * Value is controlled by {@link MatrixProject}.
  245. */
  246. @Override
  247. public void setLogRotator(LogRotator logRotator) {
  248. //TODO fins the reason
  249. //throw new UnsupportedOperationException();
  250. }
  251. /**
  252. * Returns true if this configuration is a configuration
  253. * currently in use today (as opposed to the ones that are
  254. * there only to keep the past record.)
  255. *
  256. * @see MatrixProject#getActiveConfigurations()
  257. */
  258. public boolean isActiveConfiguration() {
  259. return getParent().getActiveConfigurations().contains(this);
  260. }
  261. /**
  262. * @since 2.1.0
  263. */
  264. @Override
  265. public ACL getACL() {
  266. return getParent().getACL();
  267. }
  268. /**
  269. * On Cygwin, path names cannot be longer than 256 chars.
  270. * See http://cygwin.com/ml/cygwin/2005-04/msg00395.html and
  271. * http://www.nabble.com/Windows-Filename-too-long-errors-t3161089.html for
  272. * the background of this issue. Setting this flag to true would
  273. * cause Hudson to use cryptic but short path name, giving more room for
  274. * jobs to use longer path names.
  275. */
  276. public static boolean useShortWorkspaceName = Boolean.getBoolean(MatrixConfiguration.class.getName()+".useShortWorkspaceName");
  277. /**
  278. * @deprecated
  279. * Use {@link #scheduleBuild(ParametersAction, Cause)}. Since 1.283
  280. */
  281. public boolean scheduleBuild(ParametersAction parameters) {
  282. return scheduleBuild(parameters, new LegacyCodeCause());
  283. }
  284. /**
  285. *
  286. * @param parameters
  287. * Can be null.
  288. */
  289. public boolean scheduleBuild(ParametersAction parameters, Cause c) {
  290. return Hudson.getInstance().getQueue().schedule(this, getQuietPeriod(), parameters, new CauseAction(c))!=null;
  291. }
  292. }