Skip to content

Commit

Permalink
Merge pull request #1327 from paul-dingemans/589-kotling-logging
Browse files Browse the repository at this point in the history
Add kotlin-logging as logging framework
  • Loading branch information
paul-dingemans authored Jan 29, 2022
2 parents e873543 + de594ed commit c56168b
Show file tree
Hide file tree
Showing 24 changed files with 333 additions and 179 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
- Update Dokka to `1.6.0` release
- Apply ktlint experimental rules on the ktlint code base itself.
- Update shadow plugin to `7.1.1` release
- Add Kotlin-logging backed by logback as logging framework ([#589](https://github.com/pinterest/ktlint/issues/589))

### Removed

Expand Down
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ ext.deps = [
'klob' : 'com.github.shyiko.klob:klob:0.2.1',
ec4j : 'org.ec4j.core:ec4j-core:0.3.0',
'picocli' : 'info.picocli:picocli:3.9.6',
'logging' : 'io.github.microutils:kotlin-logging-jvm:2.1.21',
// Use logback-classic as the logger for kotlin-logging / slf4j as it allow changing the log level at runtime.
'logback' : 'ch.qos.logback:logback-classic:1.2.9',
// Testing libraries
'junit' : 'junit:junit:4.13.1',
'junit5Api' : 'org.junit.jupiter:junit-jupiter-api:5.8.2',
Expand Down
27 changes: 26 additions & 1 deletion gradle/verification-metadata.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@
<trusted-key id="35774b17c9836878845270f4119df80e6bf8dbc3" group="org.zeroturnaround" name="zt-exec" version="1.10"/>
<trusted-key id="3909c28792327fad38100eaf04633a577c200941" group="org.vafer" name="jdependency" version="2.1.1"/>
<trusted-key id="44fbdbbc1a00fe414f1c1873586654072ead6677" group="org.sonatype.oss" name="oss-parent" version="9"/>
<trusted-key id="475f3b8e59e6e63aa78067482c7b12f2a511e325" group="org.slf4j"/>
<trusted-key id="475f3b8e59e6e63aa78067482c7b12f2a511e325">
<trusting group="org.slf4j"/>
<trusting group="ch.qos.logback"/>
</trusted-key>
<trusted-key id="47eb6836245d2d40e89dfb4136d4e9618f3adab5" group="io.github.microutils" name="kotlin-logging-jvm" version="2.1.21"/>
<trusted-key id="4db1a49729b053caf015cee9a6adfc93ef34893e" group="org.hamcrest"/>
<trusted-key id="4f5277bf72a045dad4ae36dd9440c8d6decafa12" group="org.testng" name="testng" version="6.13.1"/>
<trusted-key id="53c935821aa6a755bd337db53595395eb3d8e1ba" group="org.apache.logging.log4j"/>
Expand Down Expand Up @@ -136,6 +140,27 @@
</trusted-keys>
</configuration>
<components>
<component group="ch.qos.logback" name="logback-classic" version="1.2.9">
<artifact name="logback-classic-1.2.9.jar">
<sha256 value="ad745cc243805800d1ebbf5b7deba03b37c95885e6bce71335a73f7d6d0f14ee" origin="Generated by Gradle"/>
</artifact>
<artifact name="logback-classic-1.2.9.pom">
<sha256 value="d04475f2e2312bec9fb5a081381ff3096de82f099ff420ba1e172a0d12feb392" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="ch.qos.logback" name="logback-core" version="1.2.9">
<artifact name="logback-core-1.2.9.jar">
<sha256 value="4a9ef7ed809b1fbc6992bf87d404087c247e7a9766e25bb84377b58ed5c9eb58" origin="Generated by Gradle"/>
</artifact>
<artifact name="logback-core-1.2.9.pom">
<sha256 value="1d8f7cee8747e06e73c5a0b61be0bc2aae95f53f7271937aae263069a42e035a" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="ch.qos.logback" name="logback-parent" version="1.2.9">
<artifact name="logback-parent-1.2.9.pom">
<sha256 value="130e446db4400d5623a46cda4942e730d1d971c49d2ca77839886848e324a53e" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.jetbrains.kotlin.jvm" name="org.jetbrains.kotlin.jvm.gradle.plugin" version="1.6.0">
<artifact name="org.jetbrains.kotlin.jvm.gradle.plugin-1.6.0.pom">
<sha256 value="15e303c11e2d46529dc4e9af77ce77a45ca07b6f5626f1e3905b253325652408" origin="Generated by Gradle because artifact wasn't signed"/>
Expand Down
2 changes: 2 additions & 0 deletions ktlint-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ plugins {
dependencies {
api deps.kotlin.compiler
api deps.ec4j
api deps.logging
api deps.logback

testImplementation deps.junit
testImplementation deps.assertj
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.pinterest.ktlint.core

import ch.qos.logback.classic.Level
import ch.qos.logback.classic.Logger
import mu.KLogger
import org.jetbrains.kotlin.utils.addToStdlib.ifTrue

public enum class LogLevel { TRACE, DEBUG, INFO }

public var logLevel: LogLevel? = null

@Deprecated("Environment variable is replace by new variables below")
private const val KTLINT_DEBUG = "KTLINT_DEBUG"

// Via command line parameters "--trace" and "--print-ast" the end user of ktlint can change the logging behavior. As
// unit tests are not invoked via the main ktlint runtime, those command line parameters can not be used to change the
// logging behavior while running the unit tests. Instead, the environment variables below can be used by ktlint
// developers to change the logging behavior. Note, when set the environment variables also affect the runtinme of
// ktlint. As of that the name of the variables start with KTLINT_UNIT_TEST to clarify the intent.
public const val KTLINT_UNIT_TEST_DUMP_AST = "KTLINT_UNIT_TEST_DUMP_AST"
public const val KTLINT_UNIT_TEST_TRACE = "KTLINT_UNIT_TEST_TRACE"
public const val KTLINT_UNIT_TEST_ON_PROPERTY = "ON"

public fun KLogger.initKtLintKLogger(): KLogger =
also { logger ->
System
.getenv(KTLINT_UNIT_TEST_TRACE)
.orEmpty()
.equals(KTLINT_UNIT_TEST_ON_PROPERTY, ignoreCase = true)
.ifTrue {
// The log level of the kotlin-logging framework can only be altered by modifying the underling logging
// library. Also note that the default SLF4J implementation does not allow the log level to be changes.
// Therefore, a fall back on the logback-core is required. See
// https://github.com/MicroUtils/kotlin-logging/issues/20
logger.trace { "Enable TRACE logging as System environment variable $KTLINT_UNIT_TEST_TRACE is set to 'on'" }
logLevel = LogLevel.TRACE
}
if (logLevel == LogLevel.TRACE) {
(logger.underlyingLogger as Logger).level = Level.TRACE
}

System
.getenv(KTLINT_DEBUG)
.orEmpty()
.takeIf { it.isNotEmpty() }
?.let {
logger.error {
"""
System environment variable $KTLINT_DEBUG is no longer used to change the logging behavior while running unit tests.
Now set one or more of environment variables below:
$KTLINT_UNIT_TEST_TRACE=[on|off]
$KTLINT_UNIT_TEST_DUMP_AST=[on|off]
""".trimIndent()
}
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package com.pinterest.ktlint.core.internal

import com.pinterest.ktlint.core.LintError
import com.pinterest.ktlint.core.initKtLintKLogger
import java.io.File
import java.io.IOException
import java.io.InputStream
import java.nio.file.Paths
import javax.xml.parsers.DocumentBuilderFactory
import javax.xml.parsers.ParserConfigurationException
import mu.KotlinLogging
import org.w3c.dom.Element
import org.xml.sax.SAXException

private val logger = KotlinLogging.logger {}.initKtLintKLogger()

/**
* Loads the baseline file if one is provided.
*
Expand All @@ -31,13 +35,13 @@ public fun loadBaseline(
baselineRules = parseBaseline(baselineFile.inputStream())
baselineGenerationNeeded = false
} catch (e: IOException) {
System.err.println("Unable to parse baseline file: $baselineFilePath")
logger.error { "Unable to parse baseline file: $baselineFilePath" }
baselineGenerationNeeded = true
} catch (e: ParserConfigurationException) {
System.err.println("Unable to parse baseline file: $baselineFilePath")
logger.error { "Unable to parse baseline file: $baselineFilePath" }
baselineGenerationNeeded = true
} catch (e: SAXException) {
System.err.println("Unable to parse baseline file: $baselineFilePath")
logger.error { "Unable to parse baseline file: $baselineFilePath" }
baselineGenerationNeeded = true
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import com.pinterest.ktlint.core.Rule
import com.pinterest.ktlint.core.api.EditorConfigProperties
import com.pinterest.ktlint.core.api.FeatureInAlphaState
import com.pinterest.ktlint.core.api.UsesEditorConfigProperties
import com.pinterest.ktlint.core.initKtLintKLogger
import java.nio.charset.StandardCharsets
import java.nio.file.FileSystem
import java.nio.file.Path
import mu.KotlinLogging
import org.ec4j.core.EditorConfigLoader
import org.ec4j.core.PropertyTypeRegistry
import org.ec4j.core.Resource
Expand All @@ -15,6 +17,8 @@ import org.ec4j.core.model.Property
import org.ec4j.core.model.PropertyType
import org.ec4j.core.model.Version

private val logger = KotlinLogging.logger {}.initKtLintKLogger()

/**
* Map contains [UsesEditorConfigProperties.EditorConfigProperty] and related
* [PropertyType.PropertyValue] entries to add/replace loaded from `.editorconfig` files values.
Expand Down Expand Up @@ -82,8 +86,6 @@ public class EditorConfigLoader(
else -> filePath
}

if (debug) println("Resolving .editorconfig files for $normalizedFilePath file path")

return propService
.queryProperties(
Resource.Resources.ofPath(normalizedFilePath, StandardCharsets.UTF_8)
Expand All @@ -99,15 +101,13 @@ public class EditorConfigLoader(
}
}
.also {
if (debug) {
val editorConfigValues = it
.map { entry ->
"${entry.key}: ${entry.value.sourceValue}"
}
logger.trace {
it
.map { entry -> "${entry.key}: ${entry.value.sourceValue}" }
.joinToString(
prefix = "Resolving .editorconfig files for $normalizedFilePath file path:\n\t",
separator = ", "
)
println("Loaded .editorconfig: [$editorConfigValues]")
}
}
}
Expand Down
1 change: 1 addition & 0 deletions ktlint-ruleset-standard/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ plugins {

dependencies {
implementation project(':ktlint-core')
implementation deps.logging

testImplementation project(':ktlint-test')
testImplementation deps.junit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,21 @@ import com.pinterest.ktlint.core.api.FeatureInAlphaState
import com.pinterest.ktlint.core.api.UsesEditorConfigProperties
import com.pinterest.ktlint.core.ast.ElementType
import com.pinterest.ktlint.core.ast.isRoot
import com.pinterest.ktlint.core.initKtLintKLogger
import com.pinterest.ktlint.ruleset.standard.ImportOrderingRule.Companion.ASCII_PATTERN
import com.pinterest.ktlint.ruleset.standard.ImportOrderingRule.Companion.IDEA_PATTERN
import com.pinterest.ktlint.ruleset.standard.internal.importordering.ImportSorter
import com.pinterest.ktlint.ruleset.standard.internal.importordering.PatternEntry
import com.pinterest.ktlint.ruleset.standard.internal.importordering.parseImportsLayout
import mu.KotlinLogging
import org.ec4j.core.model.PropertyType
import org.jetbrains.kotlin.com.intellij.lang.ASTNode
import org.jetbrains.kotlin.com.intellij.psi.PsiWhiteSpace
import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.PsiWhiteSpaceImpl
import org.jetbrains.kotlin.psi.KtImportDirective

private val logger = KotlinLogging.logger {}.initKtLintKLogger()

/**
* Import ordering is configured via EditorConfig's property `ij_kotlin_imports_layout`, so the Kotlin IDE plugin also recongizes it. Supported values:
* * "*,java.**,javax.**,kotlin.**,^" - default IntelliJ IDEA's order, see [IDEA_PATTERN]
Expand Down Expand Up @@ -85,20 +89,14 @@ public class ImportOrderingRule :
"Import layout must contain at least one entry of a wildcard symbol (*)"
)
value == "idea" -> {
println(
"[WARNING] `idea` is deprecated! Please use `*,java.**,javax.**,kotlin.**,^` instead" +
" to ensure that the Kotlin IDE plugin recognizes the value"
)
logger.warn { "`idea` is deprecated! Please use `*,java.**,javax.**,kotlin.**,^` instead to ensure that the Kotlin IDE plugin recognizes the value" }
PropertyType.PropertyValue.valid(
value,
IDEA_PATTERN
)
}
value == "ascii" -> {
println(
"[WARNING] `ascii` is deprecated! Please use `*` instead" +
" to ensure that the Kotlin IDE plugin recognizes the value"
)
logger.warn { "`ascii` is deprecated! Please use `*` instead to ensure that the Kotlin IDE plugin recognizes the value" }
PropertyType.PropertyValue.valid(
value,
ASCII_PATTERN
Expand Down Expand Up @@ -252,10 +250,7 @@ public class ImportOrderingRule :
private fun EditorConfigProperties.resolveImportsLayout(
android: Boolean
): List<PatternEntry> = if (containsKey(KTLINT_CUSTOM_IMPORTS_LAYOUT_PROPERTY_NAME)) {
println(
"[WARNING] `kotlin_imports_layout` is deprecated! Please use `ij_kotlin_imports_layout` to ensure" +
" that the Kotlin IDE plugin and ktlint use same imports layout"
)
logger.warn { "`kotlin_imports_layout` is deprecated! Please use `ij_kotlin_imports_layout` to ensure that the Kotlin IDE plugin and ktlint use same imports layout" }
getEditorConfigValue(ktlintCustomImportsLayoutProperty, android)
} else {
getEditorConfigValue(ideaImportsLayoutProperty, android)
Expand Down
Loading

0 comments on commit c56168b

Please sign in to comment.