Skip to content
Permalink
Browse files

Fix JENKINS-20151

Added dateFormat parameter to change various CHANGES_SINCE... tokens. The format is the same as SimpleDateFormat uses.
  • Loading branch information
slide committed Oct 22, 2013
1 parent 311e53b commit 6453a56cdcc82d2d7f085e8dba9c2b7032cb112a
@@ -49,6 +49,8 @@
public String pathFormat = "\\t%p\\n";
@Parameter
public boolean showDependencies = false;
@Parameter
public String dateFormat;

@Override
public String evaluate(AbstractBuild<?, ?> build, TaskListener listener, String macroName)
@@ -96,6 +98,7 @@ public String evaluate(AbstractBuild<?, ?> build, TaskListener listener, String
// Use this object since it already formats the changes per build
final ChangesSinceLastBuildContent changes = new ChangesSinceLastBuildContent(changesFormat, pathFormat, showPaths);
changes.showDependencies = showDependencies;
changes.dateFormat = dateFormat;

Util.printf(buf, format, new Util.PrintfSpec() {
public boolean printSpec(StringBuffer buf, char formatChar) {
@@ -1,43 +1,46 @@
package hudson.plugins.emailext.plugins.content;

import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.AbstractBuild.DependencyChange;
import hudson.model.AbstractProject;
import hudson.model.TaskListener;
import hudson.plugins.emailext.plugins.EmailToken;
import hudson.plugins.emailext.Util;
import hudson.plugins.emailext.plugins.EmailToken;
import hudson.scm.ChangeLogSet;
import java.io.IOException;
import org.apache.commons.lang.StringUtils;
import org.jenkinsci.plugins.tokenmacro.DataBoundTokenMacro;
import org.jenkinsci.plugins.tokenmacro.MacroEvaluationException;

import java.io.IOException;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Map.Entry;
import org.apache.commons.lang.StringUtils;
import org.jenkinsci.plugins.tokenmacro.DataBoundTokenMacro;
import org.jenkinsci.plugins.tokenmacro.MacroEvaluationException;

@EmailToken
public class ChangesSinceLastBuildContent extends DataBoundTokenMacro {

public static final String FORMAT_DEFAULT_VALUE = "[%a] %m\\n";
public static final String PATH_FORMAT_DEFAULT_VALUE = "\\t%p\\n";
public static final String FORMAT_DEFAULT_VALUE_WITH_PATHS = "[%a] %m%p\\n";

public static final String MACRO_NAME = "CHANGES";

@Parameter
public boolean showPaths = false;
@Parameter
public String format;
@Parameter
@Parameter
public String pathFormat = PATH_FORMAT_DEFAULT_VALUE;
@Parameter
public boolean showDependencies = false;

public boolean showDependencies = false;
@Parameter
public String dateFormat;

public ChangesSinceLastBuildContent() {

}

public ChangesSinceLastBuildContent(String format, String pathFormat, boolean showPaths) {
this.format = format;
this.pathFormat = pathFormat;
@@ -53,14 +56,22 @@ public boolean acceptsMacroName(String macroName) {
public String evaluate(AbstractBuild<?, ?> build, TaskListener listener, String macroName)
throws MacroEvaluationException, IOException, InterruptedException {

if(StringUtils.isEmpty(format)) {
if (StringUtils.isEmpty(format)) {
format = showPaths ? FORMAT_DEFAULT_VALUE_WITH_PATHS : FORMAT_DEFAULT_VALUE;
}

DateFormat dateFormatter;
if (StringUtils.isEmpty(dateFormat)) {
dateFormatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT);
} else {
dateFormatter = new SimpleDateFormat(dateFormat);
}

StringBuffer buf = new StringBuffer();
for (ChangeLogSet.Entry entry : build.getChangeSet()) {
Util.printf(buf, format, new ChangesSincePrintfSpec(entry, pathFormat));
Util.printf(buf, format, new ChangesSincePrintfSpec(entry, pathFormat, dateFormatter));
}

if (showDependencies && build.getPreviousBuild() != null)
for (Entry<AbstractProject, DependencyChange> e : build
.getDependencyChanges(build.getPreviousBuild()).entrySet()) {
@@ -69,9 +80,7 @@ public String evaluate(AbstractBuild<?, ?> build, TaskListener listener, String
.append(":\n");
for (AbstractBuild<?, ?> b : e.getValue().getBuilds()) {
for (ChangeLogSet.Entry entry : b.getChangeSet()) {
Util.printf(buf, format,
new ChangesSincePrintfSpec(entry,
pathFormat));
Util.printf(buf, format, new ChangesSincePrintfSpec(entry, pathFormat, dateFormatter));
}
}
}
@@ -88,12 +97,13 @@ public boolean hasNestedContent() {
implements Util.PrintfSpec {

final private ChangeLogSet.Entry entry;

final private String pathFormatString;
final private DateFormat dateFormatter;

public ChangesSincePrintfSpec(ChangeLogSet.Entry entry, String pathFormatString) {
public ChangesSincePrintfSpec(ChangeLogSet.Entry entry, String pathFormatString, DateFormat dateFormatter) {
this.entry = entry;
this.pathFormatString = pathFormatString;
this.dateFormatter = dateFormatter;
}

public boolean printSpec(StringBuffer buf, char formatChar) {
@@ -103,8 +113,7 @@ public boolean printSpec(StringBuffer buf, char formatChar) {
return true;
case 'd': {
try {
Method getDateMethod = entry.getClass().getMethod("getDate");
buf.append(getDateMethod.invoke(entry));
buf.append(dateFormatter.format(new Date(entry.getTimestamp())));
} catch (Exception e) {
// If it is not implemented or any other problem, swallow the %d
}
@@ -136,8 +145,7 @@ public boolean printSpec(StringBuffer buf, char formatChar) {
}
case 'r': {
try {
Method getRevisionMethod = entry.getClass().getMethod("getRevision");
buf.append(getRevisionMethod.invoke(entry));
buf.append(entry.getCommitId());
} catch (Exception e) {
// If it is not implemented or any other problem, swallow the %r
}
@@ -13,6 +13,7 @@
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;

import static junit.framework.Assert.assertEquals;
import static org.mockito.Mockito.mock;
@@ -28,6 +29,7 @@
public void setup() {
changesSinceLastBuildContent = new ChangesSinceLastBuildContent();
listener = new StreamTaskListener(System.out);
Locale.setDefault(Locale.US);
}

@Test
@@ -63,7 +65,7 @@ public void testShouldPrintDate()

String content = changesSinceLastBuildContent.evaluate(currentBuild, listener, ChangesSinceLastBuildContent.MACRO_NAME);

assertEquals("DATE", content);
assertEquals("Oct 21, 2013 7:39:00 PM", content);
}

@Test
@@ -102,6 +104,19 @@ public void testWhenShowPathsIsTrueShouldPrintPath()
assertEquals("[Ash Lux] Changes for a successful build.\n" + "\tPATH1\n" + "\tPATH2\n" + "\tPATH3\n" + "\n", content);
}

@Test
public void testDateFormatString()
throws Exception {
changesSinceLastBuildContent.format = "%d";
changesSinceLastBuildContent.dateFormat = "MMM d, yyyy HH:mm:ss";

AbstractBuild currentBuild = createBuild(Result.SUCCESS, 42, "Changes for a successful build.");

String content = changesSinceLastBuildContent.evaluate(currentBuild, listener, ChangesSinceLastBuildContent.MACRO_NAME);

assertEquals("Oct 21, 2013 19:39:00", content);
}

private AbstractBuild createBuild(Result result, int buildNumber, String message) {
AbstractBuild build = mock(AbstractBuild.class);
when(build.getResult()).thenReturn(result);
@@ -157,14 +172,15 @@ public User getAuthor() {
};
}

@SuppressWarnings({"UnusedDeclaration"})
public String getRevision() {
@Override
public String getCommitId() {
return "REVISION";
}

@SuppressWarnings({"UnusedDeclaration"})
public String getDate() {
return "DATE";
@Override
public long getTimestamp() {
// 10/21/13 7:39 PM
return 1382409540000L;
}
}
}
@@ -14,6 +14,7 @@
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
@@ -29,6 +30,7 @@
public void setUp() {
content = new ChangesSinceLastSuccessfulBuildContent();
listener = new StreamTaskListener(System.out);
Locale.setDefault(Locale.US);
}

@Test
@@ -141,7 +143,7 @@ public void testShouldPrintDate()

String contentStr = content.evaluate(currentBuild, listener, ChangesSinceLastSuccessfulBuildContent.MACRO_NAME);

Assert.assertEquals("Changes for Build #41\n" + "DATE\n" + "Changes for Build #42\n" + "DATE\n", contentStr);
Assert.assertEquals("Changes for Build #41\n" + "Oct 21, 2013 7:39:00 PM\n" + "Changes for Build #42\n" + "Oct 21, 2013 7:39:00 PM\n", contentStr);
}

@Test
@@ -247,14 +249,15 @@ public User getAuthor() {
};
}

@SuppressWarnings({"UnusedDeclaration"})
public String getRevision() {
@Override
public String getCommitId() {
return "REVISION";
}

@SuppressWarnings({"UnusedDeclaration"})
public String getDate() {
return "DATE";
@Override
public long getTimestamp() {
// 10/21/13 7:39 PM
return 1382409540000L;
}
}
}
@@ -14,6 +14,7 @@
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
@@ -29,6 +30,7 @@
public void setUp() {
content = new ChangesSinceLastUnstableBuildContent();
listener = new StreamTaskListener(System.out);
Locale.setDefault(Locale.US);
}

@Test
@@ -140,7 +142,7 @@ public void testShouldPrintDate()

String contentStr = content.evaluate(currentBuild, listener, ChangesSinceLastUnstableBuildContent.MACRO_NAME);

Assert.assertEquals("Changes for Build #41\n" + "DATE\n" + "Changes for Build #42\n" + "DATE\n", contentStr);
Assert.assertEquals("Changes for Build #41\n" + "Oct 21, 2013 7:39:00 PM\n" + "Changes for Build #42\n" + "Oct 21, 2013 7:39:00 PM\n", contentStr);
}

@Test
@@ -249,14 +251,15 @@ public User getAuthor() {
};
}

@SuppressWarnings({"UnusedDeclaration"})
public String getRevision() {
@Override
public String getCommitId() {
return "REVISION";
}

@SuppressWarnings({"UnusedDeclaration"})
public String getDate() {
return "DATE";
@Override
public long getTimestamp() {
// 10/21/13 7:39 PM
return 1382409540000L;
}
}
}

0 comments on commit 6453a56

Please sign in to comment.
You can’t perform that action at this time.