diff --git a/core/src/main/java/hudson/TcpSlaveAgentListener.java b/core/src/main/java/hudson/TcpSlaveAgentListener.java index f526f4c2625e109ee733be949794eb5dd54a3d49..c991ddd331fe3b04cbf9f3f84f879aec20dd693a 100644 --- a/core/src/main/java/hudson/TcpSlaveAgentListener.java +++ b/core/src/main/java/hudson/TcpSlaveAgentListener.java @@ -212,7 +212,7 @@ public final class TcpSlaveAgentListener extends Thread { return; } - String nodeName = in.readUTF(); + final String nodeName = in.readUTF(); SlaveComputer computer = (SlaveComputer) Hudson.getInstance().getComputer(nodeName); if(computer==null) { error(out, "No such slave: "+nodeName); @@ -241,7 +241,7 @@ public final class TcpSlaveAgentListener extends Thread { e.printStackTrace(); } if(cause!=null) - LOGGER.log(Level.WARNING, "Connection #"+id+" terminated",cause); + LOGGER.log(Level.WARNING, "Connection #"+id+" for + " + nodeName + " terminated",cause); try { ConnectionHandler.this.s.close(); } catch (IOException e) { @@ -254,7 +254,7 @@ public final class TcpSlaveAgentListener extends Thread { logw.println("Failed to establish the connection with the slave"); throw e; } catch (IOException e) { - logw.println("Failed to establish the connection with the slave"); + logw.println("Failed to establish the connection with the slave " + nodeName); e.printStackTrace(logw); throw e; } diff --git a/core/src/main/java/hudson/cli/SetBuildDescriptionCommand.java b/core/src/main/java/hudson/cli/SetBuildDescriptionCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..8429fe73f168ec25aef843dfad0f220a28104972 --- /dev/null +++ b/core/src/main/java/hudson/cli/SetBuildDescriptionCommand.java @@ -0,0 +1,48 @@ +package hudson.cli; + +import hudson.Extension; +import hudson.model.AbstractProject; +import hudson.model.Run; +import hudson.remoting.Callable; + +import java.io.IOException; +import java.io.Serializable; + +import org.apache.commons.io.IOUtils; +import org.kohsuke.args4j.Argument; + +@Extension +public class SetBuildDescriptionCommand extends CLICommand implements Serializable { + + @Override + public String getShortDescription() { + return "Sets the description of a build"; + } + + @Argument(metaVar="JOB",usage="Name of the job to build",required=true,index=0) + public transient AbstractProject job; + + @Argument(metaVar="BUILD#",usage="Number of the build",required=true,index=1) + public int number; + + @Argument(metaVar="DESCRIPTION",required=true,usage="Description to be set. '=' to read from stdin.", index=2) + public String description; + + protected int run() throws Exception { + Run run = job.getBuildByNumber(number); + run.checkPermission(Run.UPDATE); + + if ("=".equals(description)) { + description = channel.call(new Callable() { + public String call() throws IOException { + return IOUtils.toString(System.in); + } + }); + } + + run.setDescription(description); + + return 0; + } + +} diff --git a/core/src/main/java/hudson/model/Cause.java b/core/src/main/java/hudson/model/Cause.java index d296f27dffc29d2e9f871cbf4e03384098d7a21d..eb5f85461a6787d23d868ce0854d462b8c68727c 100644 --- a/core/src/main/java/hudson/model/Cause.java +++ b/core/src/main/java/hudson/model/Cause.java @@ -190,7 +190,8 @@ public abstract class Cause { @Exported(visibility=3) public String getUserName() { - return authenticationName; + User u = User.get(authenticationName, false); + return u != null ? u.getDisplayName() : authenticationName; } @Override diff --git a/core/src/main/java/hudson/model/ListView.java b/core/src/main/java/hudson/model/ListView.java index e3174b39e29ffe2d18b78caeafa911b36add23a7..02658d760bc08755a06c63918d6524dd779265d5 100644 --- a/core/src/main/java/hudson/model/ListView.java +++ b/core/src/main/java/hudson/model/ListView.java @@ -166,25 +166,17 @@ public class ListView extends View implements Saveable { jobFilters = new DescribableList>(this,r); } - /** - * Returns the transient {@link Action}s associated with the top page. - * - * @see Hudson#getActions() - */ - @Override - public List getActions() { - return Hudson.getInstance().getActions(); - } - /** * Used to determine if we want to display the Add button. */ public boolean hasJobFilterExtensions() { return !ViewJobFilter.all().isEmpty(); } + public Iterable getJobFilters() { return jobFilters; } + public Iterable getColumns() { return columns; } diff --git a/core/src/main/java/hudson/model/Run.java b/core/src/main/java/hudson/model/Run.java index 722cf0ea85ec6afd379d1fa6cae460b97ff3767a..f2514b93e07f06c2a80352e20296933ba4a36353 100644 --- a/core/src/main/java/hudson/model/Run.java +++ b/core/src/main/java/hudson/model/Run.java @@ -61,6 +61,8 @@ import hudson.util.ProcessTree; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FilterOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -94,6 +96,7 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.input.NullInputStream; +import org.apache.commons.io.IOUtils; import org.apache.commons.jelly.XMLOutput; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; @@ -1072,8 +1075,19 @@ public abstract class Run ,RunT extends Run,RunT extends Run createFor(View v); + + /** + * Returns all the registered {@link TransientViewActionFactory}s. + */ + public static ExtensionList all() { + return Hudson.getInstance().getExtensionList(TransientViewActionFactory.class); + } + + /** + * Creates {@link Action)s for a view, using all registered {@link TransientViewActionFactory}s. + */ + public static List createAllFor(View v) { + List result = new ArrayList(); + for (TransientViewActionFactory f: all()) { + result.addAll(f.createFor(v)); + } + return result; + } + +} diff --git a/core/src/main/java/hudson/model/View.java b/core/src/main/java/hudson/model/View.java index 919848d54695638a5efb3e762a86622ae7b6463a..d8e9a136ee9629e802d40b2dca4694a155168927 100644 --- a/core/src/main/java/hudson/model/View.java +++ b/core/src/main/java/hudson/model/View.java @@ -108,6 +108,8 @@ public abstract class View extends AbstractModelObject implements AccessControll * If true, only show relevant queue items */ protected boolean filterQueue; + + protected transient List transientActions; protected View(String name) { this.name = name; @@ -313,7 +315,22 @@ public abstract class View extends AbstractModelObject implements AccessControll * @see Hudson#getActions() */ public List getActions() { - return Hudson.getInstance().getActions(); + List result = new ArrayList(); + result.addAll(Hudson.getInstance().getActions()); + synchronized (this) { + if (transientActions == null) { + transientActions = TransientViewActionFactory.createAllFor(this); + } + result.addAll(transientActions); + } + return result; + } + + public Object getDynamic(String token) { + for (Action a : getActions()) + if(a.getUrlName().equals(token)) + return a; + return null; } /** diff --git a/core/src/main/java/hudson/tasks/junit/History.java b/core/src/main/java/hudson/tasks/junit/History.java index 58430e415830a7a3ebc0125c423d14b5ad8bb236..29e00f73b269e5ef1d29822aa40cf69ace1799a5 100644 --- a/core/src/main/java/hudson/tasks/junit/History.java +++ b/core/src/main/java/hudson/tasks/junit/History.java @@ -25,9 +25,20 @@ package hudson.tasks.junit; import hudson.model.AbstractBuild; import hudson.model.Hudson; -import hudson.tasks.test.TestResult; import hudson.tasks.test.TestObject; -import hudson.util.*; +import hudson.tasks.test.TestResult; +import hudson.util.ChartUtil; +import hudson.util.ColorPalette; +import hudson.util.DataSetBuilder; +import hudson.util.Graph; +import hudson.util.ShiftedCategoryAxis; +import hudson.util.StackedAreaRenderer2; + +import java.awt.Color; +import java.awt.Paint; +import java.util.ArrayList; +import java.util.List; + import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.CategoryAxis; @@ -38,10 +49,8 @@ import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.renderer.category.StackedAreaRenderer; import org.jfree.data.category.CategoryDataset; import org.jfree.ui.RectangleInsets; - -import java.awt.*; -import java.util.ArrayList; -import java.util.List; +import org.kohsuke.stapler.Stapler; +import org.kohsuke.stapler.StaplerRequest; /** * History of {@link hudson.tasks.test.TestObject} over time. @@ -66,16 +75,21 @@ public class History { return false; } + public List getList(int start, int end) { + List list = new ArrayList(); + end = Math.min(end, testObject.getOwner().getParent().getBuilds().size()); + for (AbstractBuild b: testObject.getOwner().getParent().getBuilds().subList(start, end)) { + if (b.isBuilding()) continue; + TestResult o = testObject.getResultInBuild(b); + if (o != null) { + list.add(o); + } + } + return list; + } + public List getList() { - List list = new ArrayList(); - for (AbstractBuild b: testObject.getOwner().getParent().getBuilds()) { - if (b.isBuilding()) continue; - TestResult o = testObject.getResultInBuild(b); - if (o != null) { - list.add(o); - } - } - return list; + return getList(0, testObject.getOwner().getParent().getBuilds().size()); } /** @@ -83,9 +97,20 @@ public class History { */ public Graph getDurationGraph() { return new GraphImpl("seconds") { + protected DataSetBuilder createDataSet() { DataSetBuilder data = new DataSetBuilder(); - for (hudson.tasks.test.TestResult o: getList()) { + + List list; + try { + list = getList( + Integer.parseInt(Stapler.getCurrentRequest().getParameter("start")), + Integer.parseInt(Stapler.getCurrentRequest().getParameter("end"))); + } catch (NumberFormatException e) { + list = getList(); + } + + for (hudson.tasks.test.TestResult o: list) { data.add(((double) o.getDuration()) / (1000), "", new ChartLabel(o) { @Override public Color getColor() { @@ -100,6 +125,7 @@ public class History { } return data; } + }; } @@ -111,7 +137,16 @@ public class History { protected DataSetBuilder createDataSet() { DataSetBuilder data = new DataSetBuilder(); - for (TestResult o: getList()) { + List list; + try { + list = getList( + Integer.parseInt(Stapler.getCurrentRequest().getParameter("start")), + Integer.parseInt(Stapler.getCurrentRequest().getParameter("end"))); + } catch (NumberFormatException e) { + list = getList(); + } + + for (TestResult o: list) { data.add(o.getPassCount(), "2Passed", new ChartLabel(o)); data.add(o.getFailCount(), "1Failed", new ChartLabel(o)); data.add(o.getSkipCount(), "0Skipped", new ChartLabel(o)); @@ -125,7 +160,7 @@ public class History { private final String yLabel; protected GraphImpl(String yLabel) { - super(testObject.getOwner().getTimestamp(),600,300); + super(-1,600,300); // cannot use timestamp, since ranges may change this.yLabel = yLabel; } diff --git a/core/src/main/java/hudson/tasks/test/TestObject.java b/core/src/main/java/hudson/tasks/test/TestObject.java index 529a437c552180c2e40187ac6d70d91807a3436d..31a5efffb2dcd9dc736648a37f6791fb99313255 100644 --- a/core/src/main/java/hudson/tasks/test/TestObject.java +++ b/core/src/main/java/hudson/tasks/test/TestObject.java @@ -33,6 +33,8 @@ import hudson.tasks.junit.TestResultAction; import org.kohsuke.stapler.*; import org.kohsuke.stapler.export.ExportedBean; +import com.google.common.collect.MapMaker; + import javax.servlet.ServletException; import java.io.IOException; import java.util.*; @@ -339,7 +341,7 @@ public abstract class TestObject extends hudson.tasks.junit.TestObject { UNIQUIFIED_NAMES.put(this, uniquified); return uniquified; } - private static final Map UNIQUIFIED_NAMES = new WeakHashMap(); + private static final Map UNIQUIFIED_NAMES = new MapMaker().weakKeys().makeMap(); /** * Replaces URL-unsafe characters. diff --git a/core/src/main/resources/hudson/model/Job/index.jelly b/core/src/main/resources/hudson/model/Job/index.jelly index 1d42e0409c1aeb271fac53ce87a8338a1f998830..5c922ba4ecf48a681a7b606240eed4fb8350c4b3 100644 --- a/core/src/main/resources/hudson/model/Job/index.jelly +++ b/core/src/main/resources/hudson/model/Job/index.jelly @@ -29,7 +29,8 @@ THE SOFTWARE.

${it.pronoun} ${it.displayName}

- + +
${%This project is currently disabled} @@ -38,7 +39,17 @@ THE SOFTWARE.
-
+ + +
+
+ + + +
+
+
+ diff --git a/core/src/main/resources/hudson/tasks/junit/CaseResult/list.jelly b/core/src/main/resources/hudson/tasks/junit/CaseResult/list.jelly index d70f52078ca5cf044a436887c7eb2424ea2f9954..61a7ca127ab90c6fb12900ff47bc59bd6676aba7 100644 --- a/core/src/main/resources/hudson/tasks/junit/CaseResult/list.jelly +++ b/core/src/main/resources/hudson/tasks/junit/CaseResult/list.jelly @@ -35,7 +35,7 @@ THE SOFTWARE. ${%Test Result} - + diff --git a/core/src/main/resources/hudson/tasks/junit/ClassResult/list.jelly b/core/src/main/resources/hudson/tasks/junit/ClassResult/list.jelly index 5c161fd595ae38591b82c499ca0b8cfcbe0f7b12..85fea87f984cf44540eec85fda648aaaaa204c58 100644 --- a/core/src/main/resources/hudson/tasks/junit/ClassResult/list.jelly +++ b/core/src/main/resources/hudson/tasks/junit/ClassResult/list.jelly @@ -34,7 +34,7 @@ THE SOFTWARE. ${%Total} - + diff --git a/core/src/main/resources/hudson/tasks/junit/History/index.jelly b/core/src/main/resources/hudson/tasks/junit/History/index.jelly index 85ab8bbfb8a18fd2d3f1a19f94e92e347d89c93f..16a6386d0e1e398920409841a9f4226e01eec917 100644 --- a/core/src/main/resources/hudson/tasks/junit/History/index.jelly +++ b/core/src/main/resources/hudson/tasks/junit/History/index.jelly @@ -25,18 +25,20 @@ THE SOFTWARE. - + + +