diff --git a/build.gradle b/build.gradle index f448b8d..3f5d908 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ buildscript { - ext.kotlin_version = '1.3.31' + ext.kotlin_version = '1.3.60' ext.dokka_version = '0.9.17' - ext.jacoco_version = '0.8.3' + ext.jacoco_version = '0.8.5' repositories { mavenLocal() google() @@ -12,16 +12,16 @@ buildscript { maven { url "https://dl.bintray.com/salomonbrys/gradle-plugins" } } dependencies { - classpath 'com.android.tools.build:gradle:3.4.1' + classpath 'com.android.tools.build:gradle:3.5.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath "org.jetbrains.kotlin:kotlin-frontend-plugin:0.0.37" + classpath "org.jetbrains.kotlin:kotlin-frontend-plugin:0.0.45" classpath "com.github.salomonbrys.gradle.kotlin.js:kotlin-js-gradle-utils:1.0.0" classpath "org.jetbrains.dokka:dokka-gradle-plugin:$dokka_version" } } plugins { - id "io.gitlab.arturbosch.detekt" version "1.0.0-RC12" + id "io.gitlab.arturbosch.detekt" version "1.1.1" id 'nl.fabianm.kotlin.plugin.generated' version '1.3.2' } diff --git a/common/android/build.gradle b/common/android/build.gradle index b2878af..8c69a5c 100644 --- a/common/android/build.gradle +++ b/common/android/build.gradle @@ -4,7 +4,6 @@ plugins { id 'io.gitlab.arturbosch.detekt' id 'org.jetbrains.dokka' id 'jacoco' - id 'nl.fabianm.kotlin.plugin.generated' } jacoco { @@ -16,7 +15,7 @@ tasks.withType(Test) { } android { - compileSdkVersion 28 + compileSdkVersion 29 defaultConfig { minSdkVersion 15 } @@ -53,15 +52,19 @@ kotlin { dependencies { implementation project(':common') implementation "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version" + implementation "org.mockito:mockito-core:3.1.0" } } } } task jacocoTestReportAndroid(type: JacocoReport) { - classDirectories = files("$buildDir/intermediates/packaged-classes/debug") - sourceDirectories = files("src/androidMain/kotlin") - executionData = fileTree(dir: "$buildDir/jacoco", include: "*.exec") + def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*', 'android/**/*.*'] + def debugTree = fileTree(dir: "$buildDir/tmp/kotlin-classes/debug", excludes: fileFilter) + + classDirectories.from(files(debugTree)) + sourceDirectories.from(files("src/androidMain/kotlin")) + executionData.from(fileTree(dir: "$buildDir/jacoco", include: "*.exec")) reports { xml.enabled = true @@ -93,12 +96,12 @@ task dokkaAndroid(type: org.jetbrains.dokka.gradle.DokkaTask) { } task dokkaJavadocAndroidJar(type: Jar, dependsOn: dokkaAndroid) { - classifier = 'javadoc' + classifier('javadoc') from "$buildDir/javadoc/android" } task androidSourcesJar(type: Jar) { - classifier = 'sources' + classifier('sources') from kotlin.sourceSets.androidMain.kotlin.srcDirs } diff --git a/common/android/src/androidMain/kotlin/com/toxicbakery/logging/LogCatDelegate.kt b/common/android/src/androidMain/kotlin/com/toxicbakery/logging/LogCatDelegate.kt new file mode 100644 index 0000000..96e9b25 --- /dev/null +++ b/common/android/src/androidMain/kotlin/com/toxicbakery/logging/LogCatDelegate.kt @@ -0,0 +1,32 @@ +package com.toxicbakery.logging + +import android.util.Log + +/** + * Default Android delegate for logging. + */ +object LogCatDelegate : LogDelegate { + + override fun writeLog(level: Int, tag: String, msg: String) { + when (level) { + Arbor.DEBUG -> Log.d(tag, msg) + Arbor.ERROR -> Log.e(tag, msg) + Arbor.INFO -> Log.i(tag, msg) + Arbor.VERBOSE -> Log.v(tag, msg) + Arbor.WARNING -> Log.w(tag, msg) + Arbor.WTF -> Log.wtf(tag, msg) + } + } + + override fun writeLog(level: Int, tag: String, msg: String, throwable: Throwable) { + when (level) { + Arbor.DEBUG -> Log.d(tag, msg, throwable) + Arbor.ERROR -> Log.e(tag, msg, throwable) + Arbor.INFO -> Log.i(tag, msg, throwable) + Arbor.VERBOSE -> Log.v(tag, msg, throwable) + Arbor.WARNING -> Log.w(tag, msg, throwable) + Arbor.WTF -> Log.wtf(tag, msg, throwable) + } + } + +} diff --git a/common/android/src/androidMain/kotlin/com/toxicbakery/logging/LogCatSeedling.kt b/common/android/src/androidMain/kotlin/com/toxicbakery/logging/LogCatSeedling.kt index 500d61c..a6ee2d1 100644 --- a/common/android/src/androidMain/kotlin/com/toxicbakery/logging/LogCatSeedling.kt +++ b/common/android/src/androidMain/kotlin/com/toxicbakery/logging/LogCatSeedling.kt @@ -1,7 +1,6 @@ package com.toxicbakery.logging import android.os.Build -import android.util.Log import kotlin.math.min /** @@ -11,7 +10,8 @@ import kotlin.math.min * the calling code. */ class LogCatSeedling( - private val treatAsAndroidN: Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N + private val treatAsAndroidN: Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N, + private val logDelegate: LogDelegate = LogCatDelegate ) : ISeedling { private val String.asAndroidTag: String @@ -49,7 +49,6 @@ class LogCatSeedling( throwable: Throwable?, args: Array? ) { - require(level >= Arbor.DEBUG && level <= Arbor.WTF) log( level = level, tag = tag.asAndroidTag, @@ -64,17 +63,18 @@ class LogCatSeedling( msg: String, throwable: Throwable? ) = if (throwable == null) { - if (msg.length <= MAX_ANDROID_MSG) writeLog(level, tag, msg) - else msg.splitAndLog(level) - } else msg.splitAndLog(level, throwable) + if (msg.length <= MAX_ANDROID_MSG) logDelegate.writeLog(level, tag, msg) + else msg.splitAndLog(tag, level) + } else msg.splitAndLog(tag, level, throwable) private fun String.splitAndLog( + tag: String, level: Int, throwable: Throwable? = null ) = logCatSplit() .forEachIndexed { idx, messageChunk -> - if (idx != 0 || throwable == null) writeLog(level, tag, messageChunk) - else writeLog(level, tag, messageChunk, throwable) + if (idx != 0 || throwable == null) logDelegate.writeLog(level, tag, messageChunk) + else logDelegate.writeLog(level, tag, messageChunk, throwable) } companion object { @@ -90,35 +90,10 @@ class LogCatSeedling( */ internal const val MAX_ANDROID_MSG = 4023 - @JvmStatic - internal fun writeLog(level: Int, tag: String, msg: String) { - require(level >= Arbor.DEBUG && level <= Arbor.WTF) - when (level) { - Arbor.DEBUG -> Log.d(tag, msg) - Arbor.ERROR -> Log.e(tag, msg) - Arbor.INFO -> Log.i(tag, msg) - Arbor.VERBOSE -> Log.v(tag, msg) - Arbor.WARNING -> Log.w(tag, msg) - Arbor.WTF -> Log.wtf(tag, msg) - } - } - - @JvmStatic - internal fun writeLog(level: Int, tag: String, msg: String, throwable: Throwable) { - require(level >= Arbor.DEBUG && level <= Arbor.WTF) - when (level) { - Arbor.DEBUG -> Log.d(tag, msg, throwable) - Arbor.ERROR -> Log.e(tag, msg, throwable) - Arbor.INFO -> Log.i(tag, msg, throwable) - Arbor.VERBOSE -> Log.v(tag, msg, throwable) - Arbor.WARNING -> Log.w(tag, msg, throwable) - Arbor.WTF -> Log.wtf(tag, msg, throwable) - } - } - /** * Split a log message at the [MAX_ANDROID_MSG] length limit. */ + @Suppress("LongMethod") @JvmStatic internal fun String.logCatSplit(): List = mutableListOf().also { output -> var leftIndex = 0 diff --git a/common/android/src/androidMain/kotlin/com/toxicbakery/logging/LogDelegate.kt b/common/android/src/androidMain/kotlin/com/toxicbakery/logging/LogDelegate.kt new file mode 100644 index 0000000..155b75b --- /dev/null +++ b/common/android/src/androidMain/kotlin/com/toxicbakery/logging/LogDelegate.kt @@ -0,0 +1,18 @@ +package com.toxicbakery.logging + +/** + * Delegate for printing Android logs. This is useful for injecting a new output such as to a file. + */ +interface LogDelegate { + + /** + * Write a log with a given level, tag, and message. + */ + fun writeLog(level: Int, tag: String, msg: String) + + /** + * Write a log with a given level, tag, message, and a printed throwable exception. + */ + fun writeLog(level: Int, tag: String, msg: String, throwable: Throwable) + +} diff --git a/common/android/src/androidTest/kotlin/com/toxicbakery/logging/LogCatDelegateTest.kt b/common/android/src/androidTest/kotlin/com/toxicbakery/logging/LogCatDelegateTest.kt new file mode 100644 index 0000000..fb80b08 --- /dev/null +++ b/common/android/src/androidTest/kotlin/com/toxicbakery/logging/LogCatDelegateTest.kt @@ -0,0 +1,34 @@ +package com.toxicbakery.logging + +import org.junit.Test + +class LogCatDelegateTest { + + @Test + fun writeLog() { + LogCatDelegate.writeLog(Arbor.DEBUG, "tag", "msg") + LogCatDelegate.writeLog(Arbor.ERROR, "tag", "msg") + LogCatDelegate.writeLog(Arbor.INFO, "tag", "msg") + LogCatDelegate.writeLog(Arbor.VERBOSE, "tag", "msg") + LogCatDelegate.writeLog(Arbor.WARNING, "tag", "msg") + LogCatDelegate.writeLog(Arbor.WTF, "tag", "msg") + + LogCatDelegate.writeLog(Arbor.DEBUG, "tag", "msg", Exception()) + LogCatDelegate.writeLog(Arbor.ERROR, "tag", "msg", Exception()) + LogCatDelegate.writeLog(Arbor.INFO, "tag", "msg", Exception()) + LogCatDelegate.writeLog(Arbor.VERBOSE, "tag", "msg", Exception()) + LogCatDelegate.writeLog(Arbor.WARNING, "tag", "msg", Exception()) + LogCatDelegate.writeLog(Arbor.WTF, "tag", "msg", Exception()) + } + + @Test + fun invalidLevel_withoutException() { + LogCatDelegate.writeLog(0, "tag", "msg") + } + + @Test + fun invalidLevel_withException() { + LogCatDelegate.writeLog(0, "tag", "msg", Exception()) + } + +} diff --git a/common/android/src/androidTest/kotlin/com/toxicbakery/logging/LogCatSeedlingTest.kt b/common/android/src/androidTest/kotlin/com/toxicbakery/logging/LogCatSeedlingTest.kt index cc3894a..de603eb 100644 --- a/common/android/src/androidTest/kotlin/com/toxicbakery/logging/LogCatSeedlingTest.kt +++ b/common/android/src/androidTest/kotlin/com/toxicbakery/logging/LogCatSeedlingTest.kt @@ -1,118 +1,95 @@ package com.toxicbakery.logging +import org.junit.Before import org.junit.Test +import org.mockito.Mockito +import org.mockito.Mockito.verify class LogCatSeedlingTest { + private lateinit var mockedDelegate: LogDelegate + + @Before + fun setup() { + mockedDelegate = Mockito.mock(LogDelegate::class.java) + } + @Test fun log_asN() { - val seedling = LogCatSeedling() - seedling.log(Arbor.DEBUG, seedling.tag, "msg", null, null) - seedling.log(Arbor.ERROR, seedling.tag, "msg", null, null) - seedling.log(Arbor.INFO, seedling.tag, "msg", null, null) - seedling.log(Arbor.VERBOSE, seedling.tag, "msg", null, null) - seedling.log(Arbor.WARNING, seedling.tag, "msg", null, null) - seedling.log(Arbor.WTF, seedling.tag, "msg", null, null) + val seedling = LogCatSeedling( + treatAsAndroidN = true, + logDelegate = mockedDelegate + ) + val tag = (1..100).joinToString { "a" } + seedling.log(Arbor.DEBUG, tag, "msg", null, null) + verify(mockedDelegate).writeLog(Arbor.DEBUG, tag, "msg") } @Test fun log_asPreN() { val seedling = LogCatSeedling( - treatAsAndroidN = false + treatAsAndroidN = false, + logDelegate = mockedDelegate ) - seedling.log(Arbor.DEBUG, seedling.tag, "msg", null, null) - seedling.log(Arbor.ERROR, seedling.tag, "msg", null, null) - seedling.log(Arbor.INFO, seedling.tag, "msg", null, null) - seedling.log(Arbor.VERBOSE, seedling.tag, "msg", null, null) - seedling.log(Arbor.WARNING, seedling.tag, "msg", null, null) - seedling.log(Arbor.WTF, seedling.tag, "msg", null, null) + val tag = (1..100).joinToString { "a" } + seedling.log(Arbor.DEBUG, tag, "msg", null, null) + verify(mockedDelegate).writeLog(Arbor.DEBUG, tag.substring(0, 23), "msg") } @Test fun log_withThrowable() { - val seedling = LogCatSeedling() - seedling.log(Arbor.DEBUG, "tag", "msg", Exception(), null) - seedling.log(Arbor.ERROR, "tag", "msg", Exception(), null) - seedling.log(Arbor.INFO, "tag", "msg", Exception(), null) - seedling.log(Arbor.VERBOSE, "tag", "msg", Exception(), null) - seedling.log(Arbor.WARNING, "tag", "msg", Exception(), null) - seedling.log(Arbor.WTF, "tag", "msg", Exception(), null) + val seedling = LogCatSeedling(logDelegate = mockedDelegate) + val exception = Exception() + seedling.log(Arbor.DEBUG, "tag", "msg", exception, null) + verify(mockedDelegate).writeLog(Arbor.DEBUG, "tag", "msg", exception) } @Test fun log_withArgs() { - val seedling = LogCatSeedling() - seedling.log( - Arbor.DEBUG, - seedling.tag, - "msg %s", - null, - arrayOf("replacement") - ) - } - - @Test - fun log_withExcessiveTag_asN() { - val seedling = LogCatSeedling() - seedling.log( - Arbor.DEBUG, - (1..100).joinToString { "tag" }, - "msg", - null, - null - ) + val seedling = LogCatSeedling(logDelegate = mockedDelegate) + seedling.log(Arbor.DEBUG, seedling.tag, "msg %s", null, arrayOf("replacement")) + verify(mockedDelegate).writeLog(Arbor.DEBUG, seedling.tag, "msg replacement") } @Test - fun log_withExcessiveTag_asPreN() { - val seedling = LogCatSeedling( - treatAsAndroidN = false - ) - seedling.log( - Arbor.DEBUG, - (1..100).joinToString { "tag" }, - "msg", - null, - null - ) + fun log_withShortTag_asN() { + val seedling = LogCatSeedling(logDelegate = mockedDelegate) + seedling.log(Arbor.DEBUG, "tag", "msg", null, null) + verify(mockedDelegate).writeLog(Arbor.DEBUG, "tag", "msg") } @Test fun log_withShortTag_asPreN() { val seedling = LogCatSeedling( - treatAsAndroidN = false - ) - seedling.log( - Arbor.DEBUG, - "tag", - "msg", - null, - null + treatAsAndroidN = false, + logDelegate = mockedDelegate ) + seedling.log(Arbor.DEBUG, "tag", "msg", null, null) + verify(mockedDelegate).writeLog(Arbor.DEBUG, "tag", "msg") } @Test fun log_withLongMessage() { - val seedling = LogCatSeedling() - seedling.log( - Arbor.DEBUG, - seedling.tag, - (1..5000).joinToString { "msg" }, - null, - null - ) + val seedling = LogCatSeedling(logDelegate = mockedDelegate) + val msg = (1..155).joinToString { ALPHABET } + seedling.log(Arbor.DEBUG, seedling.tag, msg, null, null) + val verify = verify(mockedDelegate) + verify.writeLog(Arbor.DEBUG, seedling.tag, msg.substring(0, 4023)) + verify.writeLog(Arbor.DEBUG, seedling.tag, msg.substring(4023)) } @Test fun log_withLongMessageAndNewLines() { - val seedling = LogCatSeedling() - seedling.log( - Arbor.DEBUG, - seedling.tag, - (1..5000).joinToString { "msg\n" }, - null, - null - ) + val seedling = LogCatSeedling(logDelegate = mockedDelegate) + val msg = (1..155).joinToString { "$ALPHABET\n" } + seedling.log(Arbor.DEBUG, seedling.tag, msg, null, null) + val verify = verify(mockedDelegate) + verify.writeLog(Arbor.DEBUG, seedling.tag, (1..138).joinToString { "$ALPHABET\n" }.trim()) + verify.writeLog(Arbor.DEBUG, seedling.tag, (1..17).joinToString { "$ALPHABET\n" }) + } + + companion object { + private const val ALPHABET = "abcdefghijklmnopqrstuvwxyz" } } \ No newline at end of file diff --git a/common/android/src/commonMain/.gitignore b/common/android/src/commonMain/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/common/build.gradle b/common/build.gradle index 298edb3..87cf89f 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -1,7 +1,6 @@ plugins { id 'kotlin-multiplatform' id 'maven-publish' - id 'com.github.salomonbrys.gradle.kotlin.js.mpp-tests.node' id 'signing' id 'org.jetbrains.dokka' id 'io.gitlab.arturbosch.detekt' @@ -12,9 +11,6 @@ jacoco { toolVersion = jacoco_version } -// workaround for https://youtrack.jetbrains.com/issue/KT-27170 -configurations.create("compileClasspath") - kotlin { targets { fromPreset(presets.jvm, 'jvm') { @@ -24,11 +20,6 @@ kotlin { } fromPreset(presets.js, 'js') { tasks[compilations.main.compileKotlinTaskName].kotlinOptions.moduleKind = "umd" - kotlinJsNodeTests { - thisTarget(js) { - engine = mocha - } - } mavenPublication { artifactId = 'arbor-js' } @@ -71,14 +62,19 @@ kotlin { } task jacocoTestReportJvm(type: JacocoReport) { - classDirectories = files( - "$buildDir/classes/kotlin/common/main", - "$buildDir/classes/kotlin/jvm/main") - sourceDirectories = files( + def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*', 'android/**/*.*'] + def commonTree = fileTree(dir: "$buildDir/classes/kotlin/common/main", excludes: fileFilter) + def jvmTree = fileTree(dir: "$buildDir/classes/kotlin/jvm/main", excludes: fileFilter) + + classDirectories.from(files( + commonTree, + jvmTree + )) + sourceDirectories.from(files( "src/commonMain/kotlin", - "src/jvmMain/kotlin") - //noinspection ChangeToOperator - executionData = files("$buildDir/jacoco/jvmTest.exec") + "src/jvmMain/kotlin" + )) + executionData.from(files("$buildDir/jacoco/jvmTest.exec")) reports { xml.enabled = true @@ -87,18 +83,26 @@ task jacocoTestReportJvm(type: JacocoReport) { } task jacocoTestReportUnified(type: JacocoReport, dependsOn: ':common:android:build') { - classDirectories = files( - "$buildDir/classes/kotlin/common/main", - "$buildDir/classes/kotlin/jvm/main", - "android/build/intermediates/packaged-classes/debug") - sourceDirectories = files( + def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*', 'android/**/*.*'] + def commonTree = fileTree(dir: "$buildDir/classes/kotlin/common/main", excludes: fileFilter) + def jvmTree = fileTree(dir: "$buildDir/classes/kotlin/jvm/main", excludes: fileFilter) + def androidTree = fileTree(dir: "android/build/tmp/kotlin-classes/debug", excludes: fileFilter) + + classDirectories.from(files( + commonTree, + jvmTree, + androidTree + )) + sourceDirectories.from(files( "src/commonMain/kotlin", "src/jvmMain/kotlin", - "android/src/androidMain/kotlin") + "android/src/androidMain/kotlin" + )) //noinspection ChangeToOperator - executionData = files( - "$buildDir/jacoco/jvmTest.exec") - .plus(fileTree(dir: "android/build/jacoco", include: "*.exec")) + executionData.from(files( + "$buildDir/jacoco/jvmTest.exec", + fileTree(dir: "android/build/jacoco", include: "*.exec") + )) reports { xml.enabled = true @@ -315,7 +319,10 @@ signing { sign publishing.publications } -build.dependsOn ':common:android:build', ':common:android:test', 'jacocoTestReportJvm', 'jacocoTestReportUnified' +build.dependsOn ':common:android:build' +build.dependsOn ':common:android:test' +build.dependsOn 'jacocoTestReportJvm' +build.dependsOn 'jacocoTestReportUnified' publish.dependsOn build publishToMavenLocal.dependsOn build diff --git a/common/src/commonMain/kotlin/com/toxicbakery/logging/Branch.kt b/common/src/commonMain/kotlin/com/toxicbakery/logging/Branch.kt index 94d1f2c..15314f9 100644 --- a/common/src/commonMain/kotlin/com/toxicbakery/logging/Branch.kt +++ b/common/src/commonMain/kotlin/com/toxicbakery/logging/Branch.kt @@ -6,12 +6,14 @@ package com.toxicbakery.logging @Suppress("TooManyFunctions") class Branch internal constructor(private val tag: String = "") { + private val tagIsBlank: Boolean = tag.isBlank() + /** * Log a debug message. */ fun d(msg: String) = Arbor.forest .forEach { seedling -> - seedling.log(Arbor.DEBUG, if (tag.isBlank()) seedling.tag else tag, msg) + seedling.log(Arbor.DEBUG, if (tagIsBlank) seedling.tag else tag, msg) } /** @@ -19,7 +21,7 @@ class Branch internal constructor(private val tag: String = "") { */ fun d(throwable: Throwable, msg: String = "") = Arbor.forest .forEach { seedling -> - seedling.log(Arbor.DEBUG, if (tag.isBlank()) seedling.tag else tag, msg, throwable) + seedling.log(Arbor.DEBUG, if (tagIsBlank) seedling.tag else tag, msg, throwable) } /** @@ -27,7 +29,7 @@ class Branch internal constructor(private val tag: String = "") { */ fun d(msg: String, args: Array?) = Arbor.forest .forEach { seedling -> - seedling.log(Arbor.DEBUG, if (tag.isBlank()) seedling.tag else tag, msg, null, args) + seedling.log(Arbor.DEBUG, if (tagIsBlank) seedling.tag else tag, msg, null, args) } /** @@ -35,7 +37,7 @@ class Branch internal constructor(private val tag: String = "") { */ fun d(throwable: Throwable, msg: String, args: Array?) = Arbor.forest .forEach { seedling -> - seedling.log(Arbor.DEBUG, if (tag.isBlank()) seedling.tag else tag, msg, throwable, args) + seedling.log(Arbor.DEBUG, if (tagIsBlank) seedling.tag else tag, msg, throwable, args) } /** @@ -43,7 +45,7 @@ class Branch internal constructor(private val tag: String = "") { */ fun v(msg: String) = Arbor.forest .forEach { seedling -> - seedling.log(Arbor.VERBOSE, if (tag.isBlank()) seedling.tag else tag, msg) + seedling.log(Arbor.VERBOSE, if (tagIsBlank) seedling.tag else tag, msg) } /** @@ -51,7 +53,7 @@ class Branch internal constructor(private val tag: String = "") { */ fun v(throwable: Throwable, msg: String = "") = Arbor.forest .forEach { seedling -> - seedling.log(Arbor.VERBOSE, if (tag.isBlank()) seedling.tag else tag, msg, throwable) + seedling.log(Arbor.VERBOSE, if (tagIsBlank) seedling.tag else tag, msg, throwable) } /** @@ -59,7 +61,7 @@ class Branch internal constructor(private val tag: String = "") { */ fun v(msg: String, args: Array?) = Arbor.forest .forEach { seedling -> - seedling.log(Arbor.VERBOSE, if (tag.isBlank()) seedling.tag else tag, msg, null, args) + seedling.log(Arbor.VERBOSE, if (tagIsBlank) seedling.tag else tag, msg, null, args) } /** @@ -67,7 +69,7 @@ class Branch internal constructor(private val tag: String = "") { */ fun v(throwable: Throwable, msg: String, args: Array?) = Arbor.forest .forEach { seedling -> - seedling.log(Arbor.VERBOSE, if (tag.isBlank()) seedling.tag else tag, msg, throwable, args) + seedling.log(Arbor.VERBOSE, if (tagIsBlank) seedling.tag else tag, msg, throwable, args) } /** @@ -75,7 +77,7 @@ class Branch internal constructor(private val tag: String = "") { */ fun i(msg: String) = Arbor.forest .forEach { seedling -> - seedling.log(Arbor.INFO, if (tag.isBlank()) seedling.tag else tag, msg) + seedling.log(Arbor.INFO, if (tagIsBlank) seedling.tag else tag, msg) } /** @@ -83,7 +85,7 @@ class Branch internal constructor(private val tag: String = "") { */ fun i(throwable: Throwable, msg: String = "") = Arbor.forest .forEach { seedling -> - seedling.log(Arbor.INFO, if (tag.isBlank()) seedling.tag else tag, msg, throwable) + seedling.log(Arbor.INFO, if (tagIsBlank) seedling.tag else tag, msg, throwable) } /** @@ -91,7 +93,7 @@ class Branch internal constructor(private val tag: String = "") { */ fun i(msg: String, args: Array?) = Arbor.forest .forEach { seedling -> - seedling.log(Arbor.INFO, if (tag.isBlank()) seedling.tag else tag, msg, null, args) + seedling.log(Arbor.INFO, if (tagIsBlank) seedling.tag else tag, msg, null, args) } /** @@ -99,7 +101,7 @@ class Branch internal constructor(private val tag: String = "") { */ fun i(throwable: Throwable, msg: String, args: Array?) = Arbor.forest .forEach { seedling -> - seedling.log(Arbor.INFO, if (tag.isBlank()) seedling.tag else tag, msg, throwable, args) + seedling.log(Arbor.INFO, if (tagIsBlank) seedling.tag else tag, msg, throwable, args) } /** @@ -107,7 +109,7 @@ class Branch internal constructor(private val tag: String = "") { */ fun w(msg: String) = Arbor.forest .forEach { seedling -> - seedling.log(Arbor.WARNING, if (tag.isBlank()) seedling.tag else tag, msg) + seedling.log(Arbor.WARNING, if (tagIsBlank) seedling.tag else tag, msg) } /** @@ -115,7 +117,7 @@ class Branch internal constructor(private val tag: String = "") { */ fun w(throwable: Throwable, msg: String = "") = Arbor.forest .forEach { seedling -> - seedling.log(Arbor.WARNING, if (tag.isBlank()) seedling.tag else tag, msg, throwable) + seedling.log(Arbor.WARNING, if (tagIsBlank) seedling.tag else tag, msg, throwable) } /** @@ -123,7 +125,7 @@ class Branch internal constructor(private val tag: String = "") { */ fun w(msg: String, args: Array?) = Arbor.forest .forEach { seedling -> - seedling.log(Arbor.WARNING, if (tag.isBlank()) seedling.tag else tag, msg, null, args) + seedling.log(Arbor.WARNING, if (tagIsBlank) seedling.tag else tag, msg, null, args) } /** @@ -131,7 +133,7 @@ class Branch internal constructor(private val tag: String = "") { */ fun w(throwable: Throwable, msg: String, args: Array?) = Arbor.forest .forEach { seedling -> - seedling.log(Arbor.WARNING, if (tag.isBlank()) seedling.tag else tag, msg, throwable, args) + seedling.log(Arbor.WARNING, if (tagIsBlank) seedling.tag else tag, msg, throwable, args) } /** @@ -139,7 +141,7 @@ class Branch internal constructor(private val tag: String = "") { */ fun e(msg: String) = Arbor.forest .forEach { seedling -> - seedling.log(Arbor.ERROR, if (tag.isBlank()) seedling.tag else tag, msg) + seedling.log(Arbor.ERROR, if (tagIsBlank) seedling.tag else tag, msg) } /** @@ -147,7 +149,7 @@ class Branch internal constructor(private val tag: String = "") { */ fun e(throwable: Throwable, msg: String = "") = Arbor.forest .forEach { seedling -> - seedling.log(Arbor.ERROR, if (tag.isBlank()) seedling.tag else tag, msg, throwable) + seedling.log(Arbor.ERROR, if (tagIsBlank) seedling.tag else tag, msg, throwable) } /** @@ -155,7 +157,7 @@ class Branch internal constructor(private val tag: String = "") { */ fun e(msg: String, args: Array?) = Arbor.forest .forEach { seedling -> - seedling.log(Arbor.ERROR, if (tag.isBlank()) seedling.tag else tag, msg, null, args) + seedling.log(Arbor.ERROR, if (tagIsBlank) seedling.tag else tag, msg, null, args) } /** @@ -163,7 +165,7 @@ class Branch internal constructor(private val tag: String = "") { */ fun e(throwable: Throwable, msg: String, args: Array?) = Arbor.forest .forEach { seedling -> - seedling.log(Arbor.ERROR, if (tag.isBlank()) seedling.tag else tag, msg, throwable, args) + seedling.log(Arbor.ERROR, if (tagIsBlank) seedling.tag else tag, msg, throwable, args) } /** @@ -171,7 +173,7 @@ class Branch internal constructor(private val tag: String = "") { */ fun wtf(msg: String) = Arbor.forest .forEach { seedling -> - seedling.log(Arbor.WTF, if (tag.isBlank()) seedling.tag else tag, msg) + seedling.log(Arbor.WTF, if (tagIsBlank) seedling.tag else tag, msg) } /** @@ -179,7 +181,7 @@ class Branch internal constructor(private val tag: String = "") { */ fun wtf(throwable: Throwable, msg: String = "") = Arbor.forest .forEach { seedling -> - seedling.log(Arbor.WTF, if (tag.isBlank()) seedling.tag else tag, msg, throwable) + seedling.log(Arbor.WTF, if (tagIsBlank) seedling.tag else tag, msg, throwable) } /** @@ -187,7 +189,7 @@ class Branch internal constructor(private val tag: String = "") { */ fun wtf(msg: String, args: Array?) = Arbor.forest .forEach { seedling -> - seedling.log(Arbor.WTF, if (tag.isBlank()) seedling.tag else tag, msg, null, args) + seedling.log(Arbor.WTF, if (tagIsBlank) seedling.tag else tag, msg, null, args) } /** @@ -195,7 +197,7 @@ class Branch internal constructor(private val tag: String = "") { */ fun wtf(throwable: Throwable, msg: String, args: Array?) = Arbor.forest .forEach { seedling -> - seedling.log(Arbor.WTF, if (tag.isBlank()) seedling.tag else tag, msg, throwable, args) + seedling.log(Arbor.WTF, if (tagIsBlank) seedling.tag else tag, msg, throwable, args) } } diff --git a/common/src/jvmMain/kotlin/com/toxicbakery/logging/Seedling.kt b/common/src/jvmMain/kotlin/com/toxicbakery/logging/Seedling.kt index 3b023e8..268828f 100644 --- a/common/src/jvmMain/kotlin/com/toxicbakery/logging/Seedling.kt +++ b/common/src/jvmMain/kotlin/com/toxicbakery/logging/Seedling.kt @@ -1,8 +1,15 @@ package com.toxicbakery.logging import java.io.PrintStream -import java.util.* +/** + * Basic logger that prints [Error] and [WTF] messages to the [System.err] stream. All other logs are printed to the + * [System.out] stream. Messages are line printed in the format of `TAG: Message`. + * + * ``` + * Arbor.sow(Seedling()) + * ``` + */ class Seedling @JvmOverloads constructor( private val printStreamErr: PrintStream = System.err, private val printStreamOut: PrintStream = System.out, @@ -39,13 +46,13 @@ class Seedling @JvmOverloads constructor( else taggedMessage.format(*args) } .withThrowable(throwable) - .let { message -> - when (level) { - Arbor.ERROR, - Arbor.WTF -> printStreamErr.println(message) - else -> printStreamOut.println(message) - } - } + .let { message -> logMessage(message, level) } + } + + private fun logMessage(message: String, level: Int) = when (level) { + Arbor.ERROR, + Arbor.WTF -> printStreamErr.println(message) + else -> printStreamOut.println(message) } private fun String.withMessage(msg: String): String = diff --git a/examples/android/build.gradle b/examples/android/build.gradle index 7ddc225..c623b7e 100644 --- a/examples/android/build.gradle +++ b/examples/android/build.gradle @@ -2,12 +2,12 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' android { - compileSdkVersion 28 + compileSdkVersion 29 defaultConfig { applicationId "com.example.arborsample" minSdkVersion 15 - targetSdkVersion 28 + targetSdkVersion 29 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" @@ -27,13 +27,14 @@ repositories { } dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'com.android.support:appcompat-v7:28.0.0' - implementation 'com.android.support.constraint:constraint-layout:1.1.3' + implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation "io.reactivex.rxjava3:rxjava:3.0.0-RC5" implementation project(':common:android') + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' } diff --git a/examples/android/src/main/AndroidManifest.xml b/examples/android/src/main/AndroidManifest.xml index 4ca726b..59f6add 100644 --- a/examples/android/src/main/AndroidManifest.xml +++ b/examples/android/src/main/AndroidManifest.xml @@ -1,15 +1,16 @@ + xmlns:tools="http://schemas.android.com/tools" package="com.example.arborsample"> + android:theme="@style/AppTheme" + tools:ignore="GoogleAppIndexingWarning"> diff --git a/examples/android/src/main/java/com/example/arborsample/MainActivity.java b/examples/android/src/main/java/com/example/arborsample/MainActivity.java index 5f03974..127a536 100644 --- a/examples/android/src/main/java/com/example/arborsample/MainActivity.java +++ b/examples/android/src/main/java/com/example/arborsample/MainActivity.java @@ -1,7 +1,7 @@ package com.example.arborsample; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatActivity; import com.toxicbakery.logging.Arbor; public class MainActivity extends AppCompatActivity { diff --git a/examples/android/src/main/res/layout/activity_main.xml b/examples/android/src/main/res/layout/activity_main.xml index 980638c..716af5a 100644 --- a/examples/android/src/main/res/layout/activity_main.xml +++ b/examples/android/src/main/res/layout/activity_main.xml @@ -1,5 +1,5 @@ - - \ No newline at end of file + \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index f4d7b2b..3e87759 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Thu Nov 21 21:59:32 CST 2019 +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-bin.zip -zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME diff --git a/settings.gradle b/settings.gradle index 96a8b8d..e36def7 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,6 +1,9 @@ enableFeaturePreview('GRADLE_METADATA') -include ':common:android', ':common', ':examples:android', ':examples:java' +include ':common:android' +include ':common' +include ':examples:android' +include ':examples:java' project(':examples:android').name = 'android-example' project(':examples:java').name = 'java-example'