Skip to content

Conversation

@jglick
Copy link
Member

@jglick jglick commented Nov 5, 2018

Supersedes #128, #129, and #130. Fixes JENKINS-11752, JENKINS-39536, and JENKINS-54133. May help with JENKINS-34019 (not tested).

@dblock + @dwnusbaum

@dwnusbaum dwnusbaum self-requested a review November 5, 2018 22:49

<properties>
<jenkins.version>2.121.2</jenkins.version>
<jenkins.version>2.145</jenkins.version> <!-- to pick up https://github.com/jenkinsci/jenkins/pull/3662 -->
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently I should have offered jenkinsci/jenkins#3662 up for backport. At the time it did not seem like a major fix. But in fact this patch will not work without it for freestyle builds or per-step logs (still works for Pipeline whole-build logs): you get a Class for the context and there is no way to look for ColorizedAction.

Copy link
Member

@dwnusbaum dwnusbaum Nov 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since that fix is not in any LTS line yet, I think it would be good to release what we currently have in master for anyone using JEP-210 in recent LTS lines, and then we can release this afterwards as a complete fix for future LTS lines. EDIT: Done with the recently released 0.5.3.


/**
* Marker for the fact that a build used colorization.
* Note that the specific log span(s) are ignored.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternately, could go the route of jenkinsci/timestamper-plugin#25 and just have a global option to turn on ANSI coloring (with a specified colormap), and deprecate the step & build wrapper altogether. This would be more in line with how Blue Ocean works: it just assumes that if it sees these escape sequences, it should render them.

System.out.print(html);
assertThat(html.replaceAll("<span style=\"display: none\">.+?</span>", ""),
allOf(
containsString("[<b><span style=\"color: #1E90FF;\">INFO</span></b>]"),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checks the subtle case that INFO is wrapped in two tags.

Copy link
Member

@dwnusbaum dwnusbaum Nov 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A little awkward how some of the hidden ANSI escape sequences end up nested in other tags, but it works 🤷‍♂️ . i.e. I expected the inner span with style="display: none" to come after the </b> tag when displaying [INFO] in a colorized Maven build, but that's not the case:

[
<span style="display: none">\u001B[1;34m</span> 
<b>
  <span style="color: #1E90FF;">
    INFO
    <!-- Seems weird that this is nested, but it doesn't really matter -->
    <span style="display: none">\u001B[m</span>
  </span>
</b>
]

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I decided it was not worth the bother to fix.

assertThat(html.replaceAll("<span style=\"display: none\">.+?</span>", ""),
allOf(
containsString("[<b><span style=\"color: #1E90FF;\">INFO</span></b>]"),
containsString("<b>--------------&lt; </b><span style=\"color: #00CDCD;\">org.jenkins-ci.plugins:build-token-root</span><b> &gt;---------------</b>")));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sure regular HTML escaping is not messed up, and verifies multiple color sequences in the course of a line.

I have interactively run Maven builds in this branch and it all looks right.

import org.jvnet.hudson.test.LoggerRule;

/**
* Checks which kinds of console notes are successfully pregenerated for use in a remoted filter.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No longer relevant.

story.j.assertLogContains("TERM=xterm", run);
assertTrue("Failed to match color attribute in following HTML log output:\n" + html,
html.matches("(?s).*<span style=\"color: #CD0000;\">red</span>.*"));
html.replaceAll("<span style=\"display: none\">.+?</span>", "").matches("(?s).*<span style=\"color: #CD0000;\">red</span>.*"));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unlike a ConsoleLogFilter, MarkupText offers no way to delete any of the plain text (in this case the ANSI escapes). You can only suppress its display. A bit nasty but seems to work.

}

protected String annotate(String text, AnsiColorMap colorMap) throws IOException {
private String annotate(String text, AnsiColorMap colorMap) throws IOException {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverting this bit from #130.

if (action != null) {
return new ColorConsoleAnnotator(action.colorMapName, ((Run) context).getCharset().name());
}
} else if (Jenkins.get().getPlugin("workflow-api") != null && context instanceof FlowNode) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did not try to verify behavior when the plugin is not in fact installed. Generally speaking, optional deps are dangerous. I would rather just make it a hard dep.

Copy link
Member

@dwnusbaum dwnusbaum Nov 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that making it a normal dependency would be safer, but I did some testing with the plugins not installed and things seem to work fine. New freestyle builds are still colored correctly, and executing Jenkins.get().getPlugin("workflow-api") in the script console returns null, so the short-circuiting behavior here looks fine to me.

class EmitterImpl implements AnsiAttributeElement.Emitter {
CountingOutputStream incoming;
int adjustment;
int lastPoint = -1; // multiple HTML tags may be emitted for one control sequence
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The triumph of test-driven development over comprehensibility.

@dwnusbaum dwnusbaum mentioned this pull request Nov 6, 2018
@dblock
Copy link
Member

dblock commented Nov 7, 2018

@dwnusbaum Can you code review/merge this please? I'm going to try to do less work here ;)

Copy link
Member

@dwnusbaum dwnusbaum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes look good to me, and I didn't find any issues in my interactive testing.

if (action != null) {
return new ColorConsoleAnnotator(action.colorMapName, ((Run) context).getCharset().name());
}
} else if (Jenkins.get().getPlugin("workflow-api") != null && context instanceof FlowNode) {
Copy link
Member

@dwnusbaum dwnusbaum Nov 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that making it a normal dependency would be safer, but I did some testing with the plugins not installed and things seem to work fine. New freestyle builds are still colored correctly, and executing Jenkins.get().getPlugin("workflow-api") in the script console returns null, so the short-circuiting behavior here looks fine to me.

System.out.print(html);
assertThat(html.replaceAll("<span style=\"display: none\">.+?</span>", ""),
allOf(
containsString("[<b><span style=\"color: #1E90FF;\">INFO</span></b>]"),
Copy link
Member

@dwnusbaum dwnusbaum Nov 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A little awkward how some of the hidden ANSI escape sequences end up nested in other tags, but it works 🤷‍♂️ . i.e. I expected the inner span with style="display: none" to come after the </b> tag when displaying [INFO] in a colorized Maven build, but that's not the case:

[
<span style="display: none">\u001B[1;34m</span> 
<b>
  <span style="color: #1E90FF;">
    INFO
    <!-- Seems weird that this is nested, but it doesn't really matter -->
    <span style="display: none">\u001B[m</span>
  </span>
</b>
]

@dblock dblock merged commit 829e6e6 into jenkinsci:master Nov 8, 2018
@dblock
Copy link
Member

dblock commented Nov 8, 2018

I hit merge.

@reinholdfuereder
Copy link

Thanks for the improvements/fixes: besides the aforementioned Jenkins issues I think this also really solves JENKINS-41200, JENKINS-46324 and JENKINS-43107

@cmurphy208
Copy link

@jglick Does this cover the pipeline.log file that contains all the output during a pipeline?

Is there a way to completely strip the ansi codes for this pipeline.log file? (or replace them with html tags)?

@jglick
Copy link
Member Author

jglick commented Apr 14, 2020

Does this cover the pipeline.log file that contains all the output during a pipeline?

Not sure what exactly you are asking.

Is there a way to completely strip the ansi codes for this pipeline.log file?

Only by displaying the …/console link the Jenkins GUI.

@cmurphy208
Copy link

cmurphy208 commented Apr 14, 2020

Just to clarify for all other parties:
I was talking about the pipeline/build log accessible via blue ocean UI (i.e. the pop-out button above the comment section). It appears that this was out of the scope of this change according @jglick
I intend to file a blue-ocean plugin bug on his suggestion.
@jglick can you advice the preferred way to have a discussion with your team in the future?

@jglick
Copy link
Member Author

jglick commented Apr 14, 2020

Yes Blue Ocean has its own handling of ANSI escapes which was never compatible with the ConsoleNotes formerly used in this plugin—one of the motivations for getting rid of the notes. If Blue Ocean does not process escapes in the full log view, that is a Blue Ocean issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants