diff --git a/CHANGELOG.md b/CHANGELOG.md
index 01cbe00..14cc672 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,7 @@
* Your contribution here.
* [#107](https://github.com/jenkinsci/ansicolor-plugin/pull/107): Removing startup banner - [@jglick](https://github.com/jglick).
+* [#128](https://github.com/jenkinsci/ansicolor-plugin/pull/128): Restoring limited compatibility for coloration generated remotely by Pipeline builds on agents - [@jglick](https://github.com/jglick).
0.5.2 (08/17/2017)
============
diff --git a/pom.xml b/pom.xml
index a3682a8..0a18745 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,8 @@
org.jenkins-ci.plugins
plugin
- 2.25
+ 3.25
+
ansicolor
@@ -45,23 +46,51 @@
- 1.642.3
+ 2.121.2
+ 8
org.jenkins-ci.plugins.workflow
workflow-step-api
- 2.12
+ 2.15
true
org.jenkins-ci.plugins.workflow
- workflow-aggregator
- 2.5
+ workflow-cps
+ 2.59
+ test
+
+
+ org.jenkins-ci.plugins.workflow
+ workflow-job
+ 2.26
+ test
+
+
+ org.jenkins-ci.plugins.workflow
+ workflow-durable-task-step
+ 2.25
+ test
+
+
+ org.jenkins-ci.plugins.workflow
+ workflow-basic-steps
+ 2.12
test
+
+
+
+ org.jenkins-ci.plugins
+ structs
+ 1.17
+
+
+
diff --git a/src/main/java/hudson/plugins/ansicolor/AnsiColorConsoleLogFilter.java b/src/main/java/hudson/plugins/ansicolor/AnsiColorConsoleLogFilter.java
index 4c1b912..e318629 100644
--- a/src/main/java/hudson/plugins/ansicolor/AnsiColorConsoleLogFilter.java
+++ b/src/main/java/hudson/plugins/ansicolor/AnsiColorConsoleLogFilter.java
@@ -3,12 +3,16 @@
import hudson.console.ConsoleLogFilter;
import hudson.console.LineTransformationOutputStream;
import hudson.model.AbstractBuild;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
+import jenkins.util.JenkinsJVM;
/**
* {@link ConsoleLogFilter} that adds a {@link SimpleHtmlNote} to each line.
@@ -20,10 +24,40 @@ public final class AnsiColorConsoleLogFilter extends ConsoleLogFilter implements
private static final Logger LOG = Logger.getLogger(AnsiColorConsoleLogFilter.class.getName());
private AnsiColorMap colorMap;
+ private final Map notes;
public AnsiColorConsoleLogFilter(AnsiColorMap colorMap) {
super();
this.colorMap = colorMap;
+ this.notes = new HashMap<>();
+ // some cases of AnsiHtmlOutputStream.setForegroundColor:
+ for (AnsiColorMap.Color color : AnsiColorMap.Color.values()) {
+ pregenerateNote(new AnsiAttributeElement(AnsiAttributeElement.AnsiAttrType.FG, "span", "style=\"color: " + colorMap.getNormal(color.ordinal()) + ";\""));
+ }
+ // TODO other cases, and other methods
+ LOG.log(Level.FINE, "Notes pregenerated for {0}", notes.keySet());
+ }
+
+ private void pregenerateNote(AnsiAttributeElement element) {
+ element.emitOpen(html -> pregenerateNote(html));
+ element.emitClose(html -> pregenerateNote(html));
+ }
+
+ private void pregenerateNote(String html) {
+ if (!notes.containsKey(html)) {
+ JenkinsJVM.checkJenkinsJVM();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ try {
+ new SimpleHtmlNote(html).encodeTo(baos);
+ } catch (IOException x) { // should be impossible
+ throw new RuntimeException(x);
+ }
+ notes.put(html, baos.toByteArray());
+ }
+ }
+
+ private Object readResolve() { // handle old program.dat
+ return notes == null ? new AnsiColorConsoleLogFilter(colorMap) : this;
}
@SuppressWarnings("rawtypes")
@@ -39,7 +73,12 @@ public OutputStream decorateLogger(AbstractBuild build, final OutputStream logge
@Override
public void emitHtml(String html) {
try {
- new SimpleHtmlNote(html).encodeTo(logger);
+ byte[] pregenerated = notes.get(html);
+ if (pregenerated != null) {
+ logger.write(pregenerated);
+ } else {
+ new SimpleHtmlNote(html).encodeTo(logger);
+ }
} catch (IOException e) {
LOG.log(Level.WARNING, "Failed to add HTML markup '" + html + "'", e);
}
diff --git a/src/test/java/hudson/plugins/ansicolor/AnsiColorBuildWrapperTest.java b/src/test/java/hudson/plugins/ansicolor/AnsiColorBuildWrapperTest.java
index 13851ae..06fabf7 100644
--- a/src/test/java/hudson/plugins/ansicolor/AnsiColorBuildWrapperTest.java
+++ b/src/test/java/hudson/plugins/ansicolor/AnsiColorBuildWrapperTest.java
@@ -1,11 +1,12 @@
package hudson.plugins.ansicolor;
import hudson.Functions;
+import hudson.console.ConsoleNote;
import java.io.StringWriter;
+import java.util.logging.Level;
import static org.hamcrest.CoreMatchers.instanceOf;
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
-import org.jenkinsci.plugins.workflow.job.WorkflowRun;
import org.junit.Test;
import static org.junit.Assert.*;
import org.junit.Assume;
@@ -13,6 +14,8 @@
import org.junit.Rule;
import org.junit.runners.model.Statement;
import org.jvnet.hudson.test.BuildWatcher;
+import org.jvnet.hudson.test.Issue;
+import org.jvnet.hudson.test.LoggerRule;
import org.jvnet.hudson.test.RestartableJenkinsRule;
public class AnsiColorBuildWrapperTest {
@@ -42,7 +45,10 @@ public void testDecorateLogger() {
public static BuildWatcher buildWatcher = new BuildWatcher();
@Rule
public RestartableJenkinsRule story = new RestartableJenkinsRule();
+ @Rule
+ public LoggerRule logging = new LoggerRule().recordPackage(ConsoleNote.class, Level.FINE);
+ @Issue("JENKINS-54133")
@Test
public void testWorkflowWrap() throws Exception {
story.addStep(new Statement() {
@@ -50,9 +56,10 @@ public void testWorkflowWrap() throws Exception {
@Override
public void evaluate() throws Throwable {
Assume.assumeTrue(!Functions.isWindows());
+ story.j.createSlave();
WorkflowJob p = story.j.jenkins.createProject(WorkflowJob.class, "p");
p.setDefinition(new CpsFlowDefinition(
- "node {\n"
+ "node('!master') {\n"
+ " wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 1, 'defaultBg': 2]) {\n"
+ " sh(\"\"\"#!/bin/bash\n"
+ " printf 'The following word is supposed to be \\\\e[31mred\\\\e[0m\\\\n'\"\"\"\n"