Skip to content

Commit

Permalink
Merge pull request #52 from infinum/fix/lint-update
Browse files Browse the repository at this point in the history
Fix/lint update
  • Loading branch information
bojankoma authored Aug 21, 2021
2 parents 9205d5e + 1004954 commit 5a73832
Show file tree
Hide file tree
Showing 23 changed files with 207 additions and 94 deletions.
8 changes: 8 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
Change Log
==========

## Version 1.3.0

_2021-08-23_

* Add custom Lint checks.
* Fix R8 collisions on obfuscated class names.

## Version 1.2.9

_2021-08-21_
Expand Down
19 changes: 13 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ The project is organized in the following modules:
- `ui` - contains a single screen UI that provides visual tracking of sent events
- `ui-no-op` - contains a stub for easy release implementation of UI package
- `generator` - contains a generator code for provided tracking plan
- `lint` - contains custom Lint checks
- `sample` - a sample app for testing the Gradle plugin

## Usage
Expand All @@ -30,7 +31,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath "com.infinum.collar:collar-plugin:1.2.9"
classpath "com.infinum.collar:collar-plugin:1.3.0"
}
}
```
Expand All @@ -41,7 +42,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath("com.infinum.collar:collar-plugin:1.2.9")
classpath("com.infinum.collar:collar-plugin:1.3.0")
}
}
```
Expand Down Expand Up @@ -243,6 +244,12 @@ javaCompileOptions {
}
```

## Lint checks

_Collar_ plugin provides it's own custom Lint checks. These can be disabled, suppressed or fixed like any other Lint registered issues.
Checks:
- `MissingScreenNameAnnotation` - All Activities and Fragments require a valid screen name annotation on the class. You must annotate an Activity or Fragment with @ScreenName with a valid value parameter or set enabled parameter to false.

## Debug UI

![UI](ui.png)![ui-dark](ui-dark.png)
Expand All @@ -253,13 +260,13 @@ You can search, filter and clear all sent analytics.
In your app `build.gradle` or `build.gradle.kts` add:
**Groovy**
```gradle
debugImplementation "com.infinum.collar:collar-ui:1.2.9"
releaseImplementation "com.infinum.collar:collar-ui-no-op:1.2.9"
debugImplementation "com.infinum.collar:collar-ui:1.3.0"
releaseImplementation "com.infinum.collar:collar-ui-no-op:1.3.0"
```
**KotlinDSL**
```kotlin
debugImplementation("com.infinum.collar:collar-ui:1.2.9")
releaseImplementation("com.infinum.collar:collar-ui-no-op:1.2.9")
debugImplementation("com.infinum.collar:collar-ui:1.3.0")
releaseImplementation("com.infinum.collar:collar-ui-no-op:1.3.0")
```

In order to start tracking with UI you must use _LiveCollector_ as in this example:
Expand Down
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ task lintAll(dependsOn: [

task detektAll(dependsOn: [
':annotations:detekt',
':lint:detekt',
':core:detekt',
':ui:detekt',
':ui-no-op:detekt',
Expand All @@ -68,6 +69,7 @@ task detektAll(dependsOn: [

task ktlintAll(dependsOn: [
':annotations:ktlintCheck',
':lint:ktlintCheck',
':core:ktlintCheck',
':ui:ktlintCheck',
':ui-no-op:ktlintCheck',
Expand All @@ -81,6 +83,7 @@ task ktlintAll(dependsOn: [

task cpdAll(dependsOn: [
':annotations:cpdCheck',
':lint:cpdCheck',
':core:cpdCheck',
':ui:cpdCheck',
':ui-no-op:cpdCheck',
Expand Down
4 changes: 2 additions & 2 deletions config.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ext {
]
releaseConfig = [
"group" : "com.infinum.collar",
"version" : "1.2.9",
"versionCode": 1 * 100 * 100 + 2 * 100 + 9
"version" : "1.3.0",
"versionCode": 1 * 100 * 100 + 3 * 100 + 0
]
}
1 change: 1 addition & 0 deletions core/proguard-rules.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
-keeppackagenames
-keep public class com.infinum.collar.* {
public protected *;
}
11 changes: 11 additions & 0 deletions deploy.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ task deployAnnotations(dependsOn: [
description = "Deploy module to repositories"
}

task deployLint(dependsOn: [
':lint:clean',
':lint:publishReleasePublicationToSonatypeRepository'
]) {
group = "Deploy"
description = "Deploy module to repositories"
}

task deployCore(dependsOn: [
':core:clean',
':core:publishReleasePublicationToSonatypeRepository'
Expand Down Expand Up @@ -56,6 +64,7 @@ task deployPlugin(dependsOn: [

task deployStage1(dependsOn: [
'deployAnnotations',
'deployLint',
'deployGenerator'
]) {
group = "Deploy"
Expand All @@ -81,13 +90,15 @@ task deployStage3(dependsOn: [

task deployDebug(dependsOn: [
':annotations:clean',
':lint:clean',
':core:clean',
':ui:clean',
':ui-no-op:clean',
':processor:clean',
':generator:clean',
':plugin:clean',
':annotations:publishReleasePublicationToMavenLocal',
':lint:publishReleasePublicationToMavenLocal',
':core:publishReleasePublicationToMavenLocal',
':ui:publishReleasePublicationToMavenLocal',
':ui-no-op:publishReleasePublicationToMavenLocal',
Expand Down
6 changes: 5 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[versions]
collar = "1.2.9"
collar = "1.3.0"
gradle = "7.0.1"
lint = "30.0.1"
kotlin = "1.5.21"
coroutines = "1.5.1"
serialization = "1.2.2"
Expand Down Expand Up @@ -33,6 +34,9 @@ libraryui = { module = "com.infinum.collar:collar-ui", version.ref = "collar" }
libraryuinoop = { module = "com.infinum.collar:collar-ui-no-op", version.ref = "collar" }

tools-gradle = { module = "com.android.tools.build:gradle", version.ref = "gradle" }
tools-lintapi = { module = "com.android.tools.lint:lint-api", version.ref = "lint" }
tools-lintchecks = { module = "com.android.tools.lint:lint-tests", version.ref = "lint" }
tools-linttests = { module = "com.android.tools.lint:lint-checks", version.ref = "lint" }

kotlin-gradle = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }
kotlin-core = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8", version.ref = "kotlin" }
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
25 changes: 23 additions & 2 deletions lint/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ plugins {
id "java-library"
id "org.jetbrains.kotlin.jvm"
}

kotlin {
explicitApi()
}

java {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
Expand All @@ -18,14 +23,30 @@ compileTestKotlin {
}
}

test {
useJUnitPlatform()
}

sourceSets.each {
it.java.srcDirs += "src/$it.name/kotlin"
}

dependencies {
compileOnly libs.kotlin.core
compileOnly "com.android.tools.lint:lint-api:27.1.3"
compileOnly libs.tools.lintapi
compileOnly libs.tools.lintchecks

testImplementation 'junit:junit:4.13.2'
testImplementation "org.junit.jupiter:junit-jupiter-api:5.7.2"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.7.2"
testImplementation libs.tools.lintapi
testImplementation libs.tools.lintchecks
testImplementation libs.tools.linttests
}

jar {
manifest {
attributes("Lint-Registry-v2": "com.infinum.collar.lint.registries.ScreenNameRegistry")
attributes("Lint-Registry-v2": "com.infinum.collar.lint.CollarIssueRegistry")
}
}

Expand Down
10 changes: 0 additions & 10 deletions lint/publish.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,6 @@ afterEvaluate {
url = "https://github.com/infinum/android-collar"
}
}
pom.withXml {
def root = asNode()
def dependenciesNode = root.appendNode("dependencies")
configurations.implementation.allDependencies.each {
def dependencyNode = dependenciesNode.appendNode("dependency")
dependencyNode.appendNode("groupId", it.group)
dependencyNode.appendNode("artifactId", it.name)
dependencyNode.appendNode("version", it.version)
}
}
signing {
sign publishing.publications.release
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.infinum.collar.lint

import com.android.tools.lint.client.api.IssueRegistry
import com.android.tools.lint.client.api.Vendor
import com.android.tools.lint.detector.api.CURRENT_API
import com.android.tools.lint.detector.api.Issue

@Suppress("UnstableApiUsage")
public class CollarIssueRegistry : IssueRegistry() {

override val vendor: Vendor = Vendor(
vendorName = "Infinum Inc.",
identifier = "com.infinum.collar:collar-lint:{version}",
feedbackUrl = "https://github.com/infinum/android-collar/issues"
)

override val issues: List<Issue> = IssueFactory.issues()

override val api: Int = CURRENT_API
}
35 changes: 35 additions & 0 deletions lint/src/main/kotlin/com/infinum/collar/lint/IssueFactory.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.infinum.collar.lint

import com.android.tools.lint.detector.api.Category
import com.android.tools.lint.detector.api.Implementation
import com.android.tools.lint.detector.api.Issue
import com.android.tools.lint.detector.api.Scope
import com.android.tools.lint.detector.api.Severity
import com.infinum.collar.lint.detectors.MissingScreenNameAnnotationDetector
import java.util.EnumSet

@Suppress("UnstableApiUsage")
internal object IssueFactory {

fun issues(): List<Issue> = listOf(
MISSING_SCREEN_NAME_ANNOTATION
)

val MISSING_SCREEN_NAME_ANNOTATION: Issue = Issue.create(
id = "MissingScreenNameAnnotation",
briefDescription = "Missing screen name annotation.",
explanation = "All Activities and Fragments require a valid screen name annotation on the class." +
"\nYou must annotate an Activity or Fragment with @ScreenName with a valid value parameter " +
"or set enabled parameter to false.",
category = Category.CORRECTNESS,
priority = 5,
severity = Severity.WARNING,
implementation = Implementation(
MissingScreenNameAnnotationDetector::class.java,
EnumSet.of(
Scope.JAVA_FILE,
Scope.TEST_SOURCES
)
)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,16 @@ package com.infinum.collar.lint.detectors
import com.android.tools.lint.detector.api.Detector
import com.android.tools.lint.detector.api.JavaContext
import com.android.tools.lint.detector.api.SourceCodeScanner
import com.infinum.collar.lint.issues.Issues
import com.infinum.collar.lint.IssueFactory
import org.jetbrains.uast.UClass

@Suppress("UnstableApiUsage")
class ScreenNameDetector : Detector(), SourceCodeScanner {
internal class MissingScreenNameAnnotationDetector : Detector(), SourceCodeScanner {

companion object {
private val SUPPORTED_CLASSES = listOf(
"android.app.Activity",
"androidx.activity.ComponentActivity",
"androidx.core.app.ComponentActivity",
"androidx.appcompat.app.AppCompatActivity",
"androidx.fragment.app.FragmentActivity",
"android.support.v7.app.AppCompatActivity",
"android.support.v4.app.FragmentActivity",
"android.app.Fragment",
"androidx.fragment.app.Fragment",
"android.support.v4.app.Fragment"
)
Expand All @@ -27,19 +22,22 @@ class ScreenNameDetector : Detector(), SourceCodeScanner {
override fun applicableSuperClasses(): List<String> = SUPPORTED_CLASSES

override fun visitClass(context: JavaContext, declaration: UClass) {
if (!context.project.reportIssues) {
return
if (context.project.reportIssues) {
visitExtendedClass(context, declaration)
}
}

SUPPORTED_CLASSES.forEach {
if (context.evaluator.extendsClass(declaration, it, false)) {
if (!declaration.hasAnnotation(ANNOTATION_SCREEN_NAME)) {
private fun visitExtendedClass(context: JavaContext, declaration: UClass) {
loop@ for (className in SUPPORTED_CLASSES) {
if (context.evaluator.extendsClass(declaration, className, false)) {
if (declaration.hasAnnotation(ANNOTATION_SCREEN_NAME).not()) {
context.report(
Issues.ISSUE_SCREEN_NAME,
IssueFactory.MISSING_SCREEN_NAME_ANNOTATION,
declaration,
context.getNameLocation(declaration),
"Missing ScreenName annotation."
"Missing screen name annotation."
)
break@loop
}
}
}
Expand Down
24 changes: 0 additions & 24 deletions lint/src/main/kotlin/com/infinum/collar/lint/issues/Issues.kt

This file was deleted.

Loading

0 comments on commit 5a73832

Please sign in to comment.