ktlint
ktlint copied to clipboard
Log messages mixed with formatted code on stdout
When formatting code from stdin to stdout, all log messages should go to stderr. Only the formatted code should go to stdout.
Is there a current or planned way to accomplish this using command line flags?
(Prompted by https://github.com/lassik/emacs-format-all-the-code/issues/237)
Possibly related: #589, #1327
No there are no plans to add a new toggle. But theoretically should should be able to manage this with the logger configuration. Ktlint CLI uses logback classic as logger implementation. If you provide a logback.xml file on the classpath of Ktlint CLI this config should be picked up. You can start with something like:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="SystemErr"
class="ch.qos.logback.core.ConsoleAppender">
<target>System.err</target>
<encoder>
<pattern>[%level] %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="trace">
<appender-ref ref="SystemErr"/>
</root>
</configuration>
Please let me know if you can get it to work and provide some details back so that it can be transformed to a FAQ in the documentation. It would be supercool if you could write that documentation and raise a PR for it.
Where would you place/refer this file if you installed ktlint with something like brew install ktlint and run it with just the binary ktlint?
I have never tried. But with some googling I found that you can pass an option logback.configurationFile to the jvm (https://logback.qos.ch/manual/configuration.html#configFileProperty). So technically it should at least be possible to pass that flag to the ktlint.jar. It does not work with the self-executable jar ktlint though.
Thanks for hearing us. Unfortunately It is quite inconvenient for editor plugins to modify the classpath, and placing a file on the classpath is more complicated still. Stdin->stdout formatting, with logging to stderr, is the easiest and most reliable way to implement editor plugins. The plugin I maintain, Format-All for Emacs, calls out to 80 different formatters all using this convention. It would really help plugin authors if ktlint had robust native support for this use case.
It's been years since I wrote any Java code, but I found the following Groovy snippet to do the same thing as the above XML.
appender("SystemErr", ConsoleAppender) {
// Enable coloured output.
withJansi = true
encoder(PatternLayoutEncoder) {
pattern = "%blue(%-5level) %green(%logger{35}) - %msg %n"
}
// Redirect output to the System.err.
target = 'System.err'
}
root(DEBUG, ["SystemErr"])
Btw, one thing that you can do is to add --log-level=none which entirely disables the logging. But do note, that in case ktlint throws an exception or an error is printed, that it will be suppressed as well.
I will park the issue for now. I see no way to change this behavior in ktlint without affect other use cases.
Thank you for the tip. We adopted --log-level=none as a workaround for the time being.
Just to clarify: Adding a --log-stderr flag would also interfere with existing use cases?
Just to clarify: Adding a
--log-stderrflag would also interfere with existing use cases?
No that would not interfere. But I see no way how I can implement that in a reasonable way. Ktlint uses io.github.oshai.kotlinlogging logging implementation and not simply a println to either stdout or stderr. Not only the ktlint-cli module but every other module in ktlint uses the same logger. So the ktlint-cli module would need to dynamically change the logging configuration based on parameter which only can be interpreted at runtime. This is also done for the log level but that case is simpler than what you request.
I do think it is possible to do so. But to be honest I don't want to spend my time on it.