Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Logging levels in CLI #1976

Merged
merged 1 commit into from Jun 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 23 additions & 1 deletion core/api/core.api
Expand Up @@ -4197,10 +4197,13 @@ public final class org/jetbrains/dokka/utilities/AssociateWithNotNullKt {
}

public final class org/jetbrains/dokka/utilities/DokkaConsoleLogger : org/jetbrains/dokka/utilities/DokkaLogger {
public static final field INSTANCE Lorg/jetbrains/dokka/utilities/DokkaConsoleLogger;
public fun <init> ()V
public fun <init> (Lorg/jetbrains/dokka/utilities/LoggingLevel;Lorg/jetbrains/dokka/utilities/MessageEmitter;)V
public synthetic fun <init> (Lorg/jetbrains/dokka/utilities/LoggingLevel;Lorg/jetbrains/dokka/utilities/MessageEmitter;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun debug (Ljava/lang/String;)V
public fun error (Ljava/lang/String;)V
public fun getErrorsCount ()I
public final fun getMinLevel ()Lorg/jetbrains/dokka/utilities/LoggingLevel;
public fun getWarningsCount ()I
public fun info (Ljava/lang/String;)V
public fun progress (Ljava/lang/String;)V
Expand Down Expand Up @@ -4236,6 +4239,25 @@ public final class org/jetbrains/dokka/utilities/JsonKt {
public static final fun toJsonString (Ljava/lang/Object;)Ljava/lang/String;
}

public final class org/jetbrains/dokka/utilities/LoggingLevel : java/lang/Enum {
public static final field DEBUG Lorg/jetbrains/dokka/utilities/LoggingLevel;
public static final field ERROR Lorg/jetbrains/dokka/utilities/LoggingLevel;
public static final field INFO Lorg/jetbrains/dokka/utilities/LoggingLevel;
public static final field PROGRESS Lorg/jetbrains/dokka/utilities/LoggingLevel;
public static final field WARN Lorg/jetbrains/dokka/utilities/LoggingLevel;
public final fun getIndex ()I
public static fun valueOf (Ljava/lang/String;)Lorg/jetbrains/dokka/utilities/LoggingLevel;
public static fun values ()[Lorg/jetbrains/dokka/utilities/LoggingLevel;
}

public abstract interface class org/jetbrains/dokka/utilities/MessageEmitter : kotlin/jvm/functions/Function1 {
public static final field Companion Lorg/jetbrains/dokka/utilities/MessageEmitter$Companion;
}

public final class org/jetbrains/dokka/utilities/MessageEmitter$Companion {
public final fun getConsoleEmitter ()Lorg/jetbrains/dokka/utilities/MessageEmitter;
}

public final class org/jetbrains/dokka/utilities/ParallelCollectionOperationsKt {
public static final fun parallelForEach (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static final fun parallelMap (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
Expand Down
59 changes: 47 additions & 12 deletions core/src/main/kotlin/utilities/DokkaLogging.kt
Expand Up @@ -11,28 +11,63 @@ interface DokkaLogger {
}

fun DokkaLogger.report() {
if (DokkaConsoleLogger.warningsCount > 0 || DokkaConsoleLogger.errorsCount > 0) {
info("Generation completed with ${DokkaConsoleLogger.warningsCount} warning" +
(if(DokkaConsoleLogger.warningsCount == 1) "" else "s") +
" and ${DokkaConsoleLogger.errorsCount} error" +
if(DokkaConsoleLogger.errorsCount == 1) "" else "s"
if (warningsCount > 0 || errorsCount > 0) {
info(
"Generation completed with $warningsCount warning" +
(if (warningsCount == 1) "" else "s") +
" and $errorsCount error" +
if (errorsCount == 1) "" else "s"
)
} else {
info("generation completed successfully")
info("Generation completed successfully")
}
}

object DokkaConsoleLogger : DokkaLogger {
enum class LoggingLevel(val index: Int) {
DEBUG(0), PROGRESS(1), INFO(2), WARN(3), ERROR(4);
}

/**
* Used to decouple the transport layer from logger and make it convenient for testing
*/
fun interface MessageEmitter : (String) -> Unit {
companion object {
val consoleEmitter: MessageEmitter = MessageEmitter { message -> println(message) }
}
}

class DokkaConsoleLogger(
val minLevel: LoggingLevel = LoggingLevel.DEBUG,
private val emitter: MessageEmitter = MessageEmitter.consoleEmitter
) : DokkaLogger {
override var warningsCount: Int = 0
override var errorsCount: Int = 0

override fun debug(message: String)= println(message)
override fun debug(message: String) {
if (shouldBeDisplayed(LoggingLevel.DEBUG)) emitter(message)
}

override fun progress(message: String) = println("PROGRESS: $message")
override fun progress(message: String) {
if (shouldBeDisplayed(LoggingLevel.PROGRESS)) emitter("PROGRESS: $message")
}

override fun info(message: String) = println(message)
override fun info(message: String) {
if (shouldBeDisplayed(LoggingLevel.INFO)) emitter(message)
}

override fun warn(message: String) = println("WARN: $message").also { warningsCount++ }
override fun warn(message: String) {
if (shouldBeDisplayed(LoggingLevel.WARN)) {
emitter("WARN: $message")
}
warningsCount++
}

override fun error(message: String) {
if (shouldBeDisplayed(LoggingLevel.ERROR)) {
emitter("ERROR: $message")
}
errorsCount++
}

override fun error(message: String) = println("ERROR: $message").also { errorsCount++ }
private fun shouldBeDisplayed(messageLevel: LoggingLevel): Boolean = messageLevel.index >= minLevel.index
}
23 changes: 0 additions & 23 deletions core/test-api/api/test-api.api
Expand Up @@ -10,29 +10,6 @@ public final class org/jetbrains/dokka/testApi/context/MockContext : org/jetbrai
public fun single (Lorg/jetbrains/dokka/plugability/ExtensionPoint;)Ljava/lang/Object;
}

public final class org/jetbrains/dokka/testApi/logger/FilteringLogger : org/jetbrains/dokka/utilities/DokkaLogger {
public fun <init> (Lorg/jetbrains/dokka/testApi/logger/FilteringLogger$Level;Lorg/jetbrains/dokka/utilities/DokkaLogger;)V
public fun debug (Ljava/lang/String;)V
public fun error (Ljava/lang/String;)V
public fun getErrorsCount ()I
public fun getWarningsCount ()I
public fun info (Ljava/lang/String;)V
public fun progress (Ljava/lang/String;)V
public fun setErrorsCount (I)V
public fun setWarningsCount (I)V
public fun warn (Ljava/lang/String;)V
}

public final class org/jetbrains/dokka/testApi/logger/FilteringLogger$Level : java/lang/Enum {
public static final field Debug Lorg/jetbrains/dokka/testApi/logger/FilteringLogger$Level;
public static final field Error Lorg/jetbrains/dokka/testApi/logger/FilteringLogger$Level;
public static final field Info Lorg/jetbrains/dokka/testApi/logger/FilteringLogger$Level;
public static final field Progress Lorg/jetbrains/dokka/testApi/logger/FilteringLogger$Level;
public static final field Warn Lorg/jetbrains/dokka/testApi/logger/FilteringLogger$Level;
public static fun valueOf (Ljava/lang/String;)Lorg/jetbrains/dokka/testApi/logger/FilteringLogger$Level;
public static fun values ()[Lorg/jetbrains/dokka/testApi/logger/FilteringLogger$Level;
}

public final class org/jetbrains/dokka/testApi/logger/TestLogger : org/jetbrains/dokka/utilities/DokkaLogger {
public fun <init> (Lorg/jetbrains/dokka/utilities/DokkaLogger;)V
public fun debug (Ljava/lang/String;)V
Expand Down
3 changes: 2 additions & 1 deletion core/test-api/src/main/kotlin/testApi/context/MockContext.kt
Expand Up @@ -5,6 +5,7 @@ import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.plugability.DokkaPlugin
import org.jetbrains.dokka.plugability.ExtensionPoint
import org.jetbrains.dokka.utilities.DokkaConsoleLogger
import org.jetbrains.dokka.utilities.LoggingLevel
import kotlin.reflect.KClass
import kotlin.reflect.KMutableProperty
import kotlin.reflect.full.memberProperties
Expand All @@ -31,7 +32,7 @@ class MockContext(

override fun <T : Any, E : ExtensionPoint<T>> single(point: E): T = get(point).single()

override val logger = DokkaConsoleLogger
override val logger = DokkaConsoleLogger(LoggingLevel.DEBUG)

override val configuration: DokkaConfiguration
get() = testConfiguration ?: throw IllegalStateException("This mock context doesn't provide configuration")
Expand Down
31 changes: 0 additions & 31 deletions core/test-api/src/main/kotlin/testApi/logger/TestLogger.kt
Expand Up @@ -46,34 +46,3 @@ class TestLogger(private val logger: DokkaLogger) : DokkaLogger {
logger.error(message)
}
}

class FilteringLogger(
private val minLevel: Level,
private val downstream: DokkaLogger
) : DokkaLogger {
enum class Level { Debug, Info, Progress, Warn, Error }

override var warningsCount: Int by downstream::warningsCount

override var errorsCount by downstream::errorsCount

override fun debug(message: String) {
if (minLevel <= Level.Debug) downstream.debug(message)
}

override fun info(message: String) {
if (minLevel <= Level.Info) downstream.info(message)
}

override fun progress(message: String) {
if (minLevel <= Level.Progress) downstream.progress(message)
}

override fun warn(message: String) {
if (minLevel <= Level.Warn) downstream.warn(message)
}

override fun error(message: String) {
if (minLevel <= Level.Error) downstream.error(message)
}
}
2 changes: 2 additions & 0 deletions docs/src/doc/docs/user_guide/cli/usage.md
Expand Up @@ -41,6 +41,8 @@ Dokka supports the following command line arguments:
* `-jdkVersion` - version of JDK to use for linking to JDK JavaDoc
* `-analysisPlatform` - platform used for analysis, see the [Platforms](#platforms) section
* `-dependentSourceSets` - list of dependent source sets in format `moduleName/sourceSetName`, separated by `;`
* `-loggingLevel` - one of `DEBUG`, `PROGRESS`, `INFO`, `WARN`, `ERROR`. Defaults to `DEBUG`. Please note that this argument can't be passed in JSON.


You can also use a JSON file with Dokka configuration:
```
Expand Down
Expand Up @@ -155,6 +155,7 @@ class CliIntegrationTest : AbstractCliIntegrationTest() {
val process = ProcessBuilder(
"java", "-jar", cliJarFile.path,
"-outputDir", dokkaOutputDir.path,
"-loggingLevel", "DEBUG",
"-pluginsClasspath", basePluginJarFile.path,
"-sourceSet",
buildString {
Expand All @@ -166,6 +167,7 @@ class CliIntegrationTest : AbstractCliIntegrationTest() {

val result = process.awaitProcessResult()
assertEquals(0, result.exitCode, "Expected exitCode 0 (Success)")
assertTrue(result.output.contains("Loaded plugins: "), "Expected output to not contain info logs")

assertTrue(dokkaOutputDir.isDirectory, "Missing dokka output directory")

Expand All @@ -181,4 +183,26 @@ class CliIntegrationTest : AbstractCliIntegrationTest() {
val navigationHtml = File(dokkaOutputDir, "navigation.html")
assertTrue(navigationHtml.isFile, "Missing navigation.html")
}

@Test
fun `logging level should be respected`(){
val dokkaOutputDir = File(projectDir, "output")
assertTrue(dokkaOutputDir.mkdirs())
val process = ProcessBuilder(
"java", "-jar", cliJarFile.path,
"-outputDir", dokkaOutputDir.path,
"-loggingLevel", "WARN",
"-pluginsClasspath", basePluginJarFile.path,
"-sourceSet",
buildString {
append(" -src ${File(projectDir, "src").path}")
}
)
.redirectErrorStream(true)
.start()

val result = process.awaitProcessResult()
assertEquals(0, result.exitCode, "Expected exitCode 0 (Success)")
assertFalse(result.output.contains("Loaded plugins: "), "Expected output to not contain info logs")
}
}
Expand Up @@ -85,7 +85,7 @@ class MultiModuleTestBuilder : TestBuilder<MultiModuleTestMethods>() {
)
}

abstract class MultiModuleAbstractTest(logger: TestLogger = TestLogger(DokkaConsoleLogger)) :
abstract class MultiModuleAbstractTest(logger: TestLogger = TestLogger(DokkaConsoleLogger())) :
AbstractTest<MultiModuleTestMethods, MultiModuleTestBuilder, MultiModuleDokkaTestGenerator>(
::MultiModuleTestBuilder,
::MultiModuleDokkaTestGenerator,
Expand Down
Expand Up @@ -14,8 +14,8 @@ import org.jetbrains.dokka.base.transformers.pages.comments.CommentsToContentCon
fun testPage(callback: PageContentBuilder.DocumentableContentBuilder.() -> Unit): RawTestPage {
val content = PageContentBuilder(
EmptyCommentConverter,
KotlinSignatureProvider(EmptyCommentConverter, DokkaConsoleLogger),
DokkaConsoleLogger
KotlinSignatureProvider(EmptyCommentConverter, DokkaConsoleLogger()),
DokkaConsoleLogger()
).contentFor(
DRI.topLevel,
emptySet(),
Expand Down
Expand Up @@ -12,6 +12,7 @@ import org.jetbrains.dokka.testApi.logger.TestLogger
import org.jetbrains.dokka.testApi.testRunner.*
import org.jetbrains.dokka.utilities.DokkaConsoleLogger
import org.jetbrains.dokka.utilities.DokkaLogger
import org.jetbrains.dokka.utilities.LoggingLevel

class BaseDokkaTestGenerator(
configuration: DokkaConfiguration,
Expand Down Expand Up @@ -101,7 +102,7 @@ class BaseTestBuilder : TestBuilder<BaseTestMethods>() {
)
}

abstract class BaseAbstractTest(logger: TestLogger = TestLogger(DokkaConsoleLogger)) : AbstractTest<BaseTestMethods, BaseTestBuilder, BaseDokkaTestGenerator>(
abstract class BaseAbstractTest(logger: TestLogger = TestLogger(DokkaConsoleLogger(LoggingLevel.DEBUG))) : AbstractTest<BaseTestMethods, BaseTestBuilder, BaseDokkaTestGenerator>(
::BaseTestBuilder,
::BaseDokkaTestGenerator,
logger,
Expand Down
2 changes: 1 addition & 1 deletion plugins/base/src/test/kotlin/basic/FailOnWarningTest.kt
Expand Up @@ -116,7 +116,7 @@ class FailOnWarningTest : BaseAbstractTest() {
}

private class ZeroErrorOrWarningCountDokkaLogger(
logger: DokkaLogger = DokkaConsoleLogger
logger: DokkaLogger = DokkaConsoleLogger()
) : DokkaLogger by logger {
override var warningsCount: Int = 0
override var errorsCount: Int = 0
Expand Down
44 changes: 44 additions & 0 deletions plugins/base/src/test/kotlin/basic/LoggerTest.kt
@@ -0,0 +1,44 @@
package basic

import org.jetbrains.dokka.utilities.DokkaConsoleLogger
import org.jetbrains.dokka.utilities.LoggingLevel
import org.jetbrains.dokka.utilities.MessageEmitter
import org.junit.jupiter.api.Test
import kotlin.test.assertFalse
import kotlin.test.assertTrue

class LoggerTest {
class AccumulatingEmitter : MessageEmitter {
val messages: MutableList<String> = mutableListOf()
override fun invoke(message: String) {
messages.add(message)
}
}

@Test
fun `should display info messages if logging is info`(){
val emitter = AccumulatingEmitter()
val logger = DokkaConsoleLogger(LoggingLevel.INFO, emitter)

logger.debug("Debug!")
logger.info("Info!")

assertTrue(emitter.messages.size > 0)
assertTrue(emitter.messages.any { it == "Info!" })
assertFalse(emitter.messages.any { it == "Debug!" })
}

@Test
fun `should not display info messages if logging is warn`(){
val emitter = AccumulatingEmitter()
val logger = DokkaConsoleLogger(LoggingLevel.WARN, emitter)

logger.warn("Warning!")
logger.info("Info!")


assertTrue(emitter.messages.size > 0)
assertFalse(emitter.messages.any { it.contains("Info!") })
assertTrue(emitter.messages.any { it.contains("Warning!") })
}
}
Expand Up @@ -4,16 +4,16 @@ import matchers.content.assertNode
import matchers.content.hasExactText
import org.jetbrains.dokka.model.firstMemberOfType
import org.jetbrains.dokka.pages.*
import org.jetbrains.dokka.testApi.logger.FilteringLogger
import org.jetbrains.dokka.testApi.logger.TestLogger
import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest
import org.jetbrains.dokka.utilities.DokkaConsoleLogger
import org.jetbrains.dokka.utilities.LoggingLevel
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.MethodSource
import kotlin.reflect.KClass

class ObviousTypeSkippingTest : BaseAbstractTest(
logger = TestLogger(FilteringLogger(minLevel = FilteringLogger.Level.Warn, DokkaConsoleLogger))
logger = TestLogger(DokkaConsoleLogger(LoggingLevel.WARN))
) {

private fun source(signature: String) =
Expand Down
Expand Up @@ -75,7 +75,7 @@ class ContextModuleAndPackageDocumentationReaderTest1 : AbstractContextModuleAnd
private val context by lazy {
DokkaContext.create(
configuration = configurationBuilder.build(),
logger = TestLogger(DokkaConsoleLogger),
logger = TestLogger(DokkaConsoleLogger()),
pluginOverrides = emptyList()
)
}
Expand Down
Expand Up @@ -39,7 +39,7 @@ class ContextModuleAndPackageDocumentationReaderTest3 : AbstractContextModuleAnd
private val context by lazy {
DokkaContext.create(
configuration = configurationBuilder.build(),
logger = DokkaConsoleLogger,
logger = DokkaConsoleLogger(),
pluginOverrides = emptyList()
)
}
Expand Down
Expand Up @@ -52,14 +52,14 @@ class InvalidContentModuleAndPackageDocumentationReaderTest : AbstractContextMod
private val contextA by lazy {
DokkaContext.create(
configuration = configurationBuilderA.build(),
logger = DokkaConsoleLogger,
logger = DokkaConsoleLogger(),
pluginOverrides = emptyList()
)
}
private val contextB by lazy {
DokkaContext.create(
configuration = configurationBuilderB.build(),
logger = DokkaConsoleLogger,
logger = DokkaConsoleLogger(),
pluginOverrides = emptyList()
)
}
Expand Down