spring-projects / spring-boot

Spring Boot helps you to create Spring-powered, production-grade applications and services with absolute minimum fuss.
https://spring.io/projects/spring-boot
Apache License 2.0
75.47k stars 40.76k forks source link

Improve detection in AnsiOutput #4523

Closed odrotbohm closed 9 years ago

odrotbohm commented 9 years ago

AnsiOutput.detectIfEnabled(…) seems to be too strict. If running in an Eclipse environment, System.console() seems to return nulland thus ANSI coloring is not activated. However, explicitly activating AnsiOutput.setEnabled(true) explicitly produces output as expected.

bildschirmfoto 2015-11-16 um 19 48 30

Note that I have an Eclipse plugin installed to make the built in console ANSI color aware.

snicoll commented 9 years ago

For the record, Intellij has the same problem but it's overriding that property behind the scenes for you.

On Tue, Nov 17, 2015 at 10:36 AM, Oliver Gierke notifications@github.com wrote:

AnsiOutput.detectIfEnabled(…) seems to be too strict. If running in an Eclipse environment, System.console() seems to return nulland thus ANSI coloring is not activated. However, explicitly activating AnsiOutput.setEnabled(true) explicitly produces output as expected.

[image: bildschirmfoto 2015-11-16 um 19 48 30] https://cloud.githubusercontent.com/assets/128577/11207676/e82bac46-8d16-11e5-81a0-34848173595f.PNG

Note that I have an Eclipse plugin https://marketplace.eclipse.org/content/ansi-escape-console installed to make the built in console ANSI color aware.

— Reply to this email directly or view it on GitHub https://github.com/spring-projects/spring-boot/issues/4523.

odrotbohm commented 9 years ago

I guess STS could do the same for you if you explicitly run the application as Boot app explicitly. I wonder if we can rather make the detection a bit smarter. What exactly would break if the ANSI output is forwarded to a console not supporting it, i.e. if we leniently assumed it to work in the first place and only allow to explicitly turn it off?

wilkinsona commented 9 years ago

What exactly would break if the ANSI output is forwarded to a console not supporting it, i.e. if we leniently assumed it to work in the first place and only allow to explicitly turn it off?

I think you'd get all the control characters appearing as plain text, making the output very hard to read. IIRC, the detection logic deliberately errs on the side of caution to avoid this problem.

odrotbohm commented 9 years ago

I see.

@snicoll - Do you know from the top of your head, which property needs to be set? I am currently calling a method on AnsiOutput explicitly but would love to just add the property to my default execution variables for JVM runs.

snicoll commented 9 years ago

spring.output.ansi.enabled=always

odrotbohm commented 9 years ago

Nice, thanks!

philwebb commented 9 years ago

/cc @martinlippert in case STS wants to automatically add the property if the ANSI plugin is detected.

philwebb commented 9 years ago

I think we shouldn't change the default logic in Boot.

odrotbohm commented 9 years ago

I was just wondering whether the devtools could be a bit more offensive as they're running in the IDE only?

philwebb commented 9 years ago

The problem is that lots of IDE's can't display ANSI chars. If you run Eclipse without the plugin you get a bunch of unreadable chars vomited out. You really only want to enable ANSI if you are sure that your console supports it.

martinlippert commented 8 years ago

@olivergierke @philwebb I added an item to track this for STS: https://issuetracker.springsource.com/browse/STS-4286 - maybe should also include the ANSI plugin for Eclipse by default in the distribution, eh?

odrotbohm commented 8 years ago

:+1:

martinlippert commented 8 years ago

This is implemented now for the upcoming STS version 3.7.3. The ANSI color plugin is installed by default and the flag is being switched on automatically for Spring Boot apps (in case this plugin is installed correctly).

odrotbohm commented 8 years ago

My vote for employee of the month, @martinlippert!

martinlippert commented 8 years ago

@olivergierke Thanks, kudos belong to @BoykoAlex, too - he did the hard part of it

pcrocker-pivotal commented 8 years ago

For JUnit tests I still need to explicitly set spring.output.ansi.enabled=always in src/test/resources/application.properties. This works but i was wondering if there was a better way to go about this...

dlouzan commented 8 years ago

@pcrocker-pivotal I have exactly the same issue, I can manually set the spring property to have coloured unit tests (which is a burden), or I can set it in the yml file, but I don't want to set it as default in tests/resources/application.yml since a bunch of team members work in Windows and use the default cmd.exe, so for them it wouldn't work.

Any ideas?

wilkinsona commented 8 years ago

You could use a custom SpringApplicationContextLoader subclass that overrides getSpringApplication to set a default for spring.output.ansi.enabled using whatever logic's appropriate for you and your team. You'd then have to reference this loader using @ContextConfiguration(loader=YourCustomLoader.class) in place of @SpringApplicationConfiguration

dlouzan commented 8 years ago

@wilkinsona Thank you for the suggestion, I will take a look, appreciated.

There is though something I still don't understand: why, on the same terminal, executing a SpringBoot app via 'java -jar' or using the maven plugin shows coloured output (meaning the autodetection kicks in), but not when executing unit/integration tests, even with classes annotated with SpringJUnit4ClassRunner and @SpringApplicationConfiguration? Am I missing some other configuration?

Thank you and keep up the great work!

wilkinsona commented 8 years ago

@dlouzan I believe that Surefire forks a new JVM, captures its output in the parent process and then passes it onto your terminal. I would guess that this arrangement means that System.console() returns null so the process is not identified as being Ansi-capable. Unfortunately, I don't think there's anything we can do about that.

gavenkoa commented 7 years ago

For those who struggle with lacking of color it is easily can be configured in build.gradle

bootRun {
    def console = System.console() != null
    if (! console) { console = System.getenv()["TERM"].startsWith("xterm") }
    if (console) systemProperties 'spring.output.ansi.enabled': 'always'
}

You may improve detection code. I use this for running gralde from Cygwin mintty

gavenkoa commented 7 years ago

Another way to add color support outside of build.gradle (in ~/.gradle/init.d) here:

http://stackoverflow.com/questions/42370651/safely-altering-gradle-task-property-appending-to-map

The only question left for this technique is systemProperties 'spring.output.ansi.enabled': 'always' append or replace system properties. Because it can break IDE and build scripts if replace existing systemProperties.

If anybody know answer - please drop lines here or in SO.