Skip to content

Commit

Permalink
Merge pull request #1752 from Adyen/chore/logging-lint-rule
Browse files Browse the repository at this point in the history
Add logging lint rule
  • Loading branch information
OscarSpruit authored Aug 16, 2024
2 parents 2cb5670 + d02a310 commit c69e1a7
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

package com.adyen.checkout.core.internal.util

import android.annotation.SuppressLint
import android.os.Build
import android.util.Log
import com.adyen.checkout.core.AdyenLogLevel
Expand Down Expand Up @@ -59,6 +60,7 @@ internal class LogcatLogger : AdyenLogger {
}
}

@SuppressLint("NotAdyenLog")
private fun logToLogcat(
priority: Int,
tag: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ internal class LintIssueRegistry : IssueRegistry() {
override val api: Int = CURRENT_API

override val issues: List<Issue> = listOf(
NOT_ADYEN_LOG_ISSUE,
OBJECT_IN_PUBLIC_SEALED_CLASS_ISSUE,
)
}
47 changes: 47 additions & 0 deletions lint/src/main/java/com/adyen/checkout/lint/NotAdyenLog.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2024 Adyen N.V.
*
* This file is open source and available under the MIT license. See the LICENSE file for more info.
*
* Created by oscars on 14/8/2024.
*/

package com.adyen.checkout.lint

import com.android.tools.lint.detector.api.Category
import com.android.tools.lint.detector.api.Detector
import com.android.tools.lint.detector.api.Implementation
import com.android.tools.lint.detector.api.Issue
import com.android.tools.lint.detector.api.JavaContext
import com.android.tools.lint.detector.api.Scope
import com.android.tools.lint.detector.api.Severity
import com.intellij.psi.PsiMethod
import org.jetbrains.uast.UCallExpression

internal val NOT_ADYEN_LOG_ISSUE = Issue.create(
id = "NotAdyenLog",
briefDescription = "Log used instead of adyenLog",
explanation = "adyenLog should be used, so we have control over the logs.",
implementation = Implementation(NotAdyenLogDetector::class.java, Scope.JAVA_FILE_SCOPE),
category = Category.MESSAGES,
priority = 5,
severity = Severity.ERROR,
)

internal class NotAdyenLogDetector : Detector(), Detector.UastScanner {

override fun getApplicableMethodNames(): List<String> = listOf(
"v", "d", "i", "w", "e", "wtf",
)

override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
if (context.evaluator.isMemberInClass(method, "android.util.Log")) {
context.report(
NOT_ADYEN_LOG_ISSUE,
node,
context.getLocation(node),
"Log used instead of adyenLog",
)
}
}
}
76 changes: 76 additions & 0 deletions lint/src/test/java/com/adyen/checkout/lint/NotAdyenLogTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.adyen.checkout.lint

import com.android.tools.lint.checks.infrastructure.LintDetectorTest.kotlin
import com.android.tools.lint.checks.infrastructure.TestLintTask.lint
import org.junit.Test

internal class NotAdyenLogTest {

@Test
fun whenAndroidLogIsUsed_thenIssueIsDetected() {
lint()
.files(
ANDROID_LOG_STUB,
kotlin(
"""
package test
import android.util.Log
fun androidLog() {
Log.v("tag", "message")
Log.d("tag", "message")
Log.i("tag", "message")
Log.w("tag", "message")
Log.e("tag", "message")
Log.wtf("tag", "message")
}
""",
).indented(),
)
.issues(NOT_ADYEN_LOG_ISSUE)
.allowMissingSdk()
.run()
.expect(
"""
src/test/test.kt:6: Error: Log used instead of adyenLog [NotAdyenLog]
Log.v("tag", "message")
~~~~~~~~~~~~~~~~~~~~~~~
src/test/test.kt:7: Error: Log used instead of adyenLog [NotAdyenLog]
Log.d("tag", "message")
~~~~~~~~~~~~~~~~~~~~~~~
src/test/test.kt:8: Error: Log used instead of adyenLog [NotAdyenLog]
Log.i("tag", "message")
~~~~~~~~~~~~~~~~~~~~~~~
src/test/test.kt:9: Error: Log used instead of adyenLog [NotAdyenLog]
Log.w("tag", "message")
~~~~~~~~~~~~~~~~~~~~~~~
src/test/test.kt:10: Error: Log used instead of adyenLog [NotAdyenLog]
Log.e("tag", "message")
~~~~~~~~~~~~~~~~~~~~~~~
src/test/test.kt:11: Error: Log used instead of adyenLog [NotAdyenLog]
Log.wtf("tag", "message")
~~~~~~~~~~~~~~~~~~~~~~~~~
6 errors, 0 warnings
"""
)
}

companion object {

private val ANDROID_LOG_STUB = kotlin(
"""
package android.util
object Log {
fun v(tag: String, msg: String, tr: Throwable? = null) {}
fun d(tag: String, msg: String, tr: Throwable? = null) {}
fun i(tag: String, msg: String, tr: Throwable? = null) {}
fun w(tag: String, msg: String, tr: Throwable? = null) {}
fun e(tag: String, msg: String, tr: Throwable? = null) {}
fun wtf(tag: String, msg: String, tr: Throwable? = null) {}
}
""",
).indented()
}
}

0 comments on commit c69e1a7

Please sign in to comment.