본인 프로젝트에 맞는 Lint 구성을 직접 코딩해서 만들 수 있다!
우선 새로운 프로젝트 또는 기존 프로젝트의 모듈로 Custom lint 를 만들어보자.
(참고로 module 명은 lint 로 설정함)
1. lint module 의 build.gradle 구성
dependency 에 com.android.tools.lint 에서 제공하는 lint-api, lint-checks 를 추가한다.
compile 시에만 참고할 수 있도록 compileOnly 로 추가해주었다.
dependencies {
compileOnly "com.android.tools.lint:lint-api:$lint_version"
compileOnly "com.android.tools.lint:lint-checks:$lint_version"
}
// build.gradle
apply plugin: 'java-library'
apply plugin: 'kotlin'
apply plugin: 'com.android.lint'
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
dependencies {
def lint_version = '27.0.0'
// kotlin
compileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
// lint
compileOnly "com.android.tools.lint:lint-api:$lint_version"
compileOnly "com.android.tools.lint:lint-checks:$lint_version"
// test
testImplementation 'junit:junit:4.13'
testImplementation "com.android.tools.lint:lint-tests:$lint_version"
}
2. IssueRegistry 구현
IssueRegistry 는 안드로이드 프로젝트에서 수행 할 검사 목록을 제공하는 레지스트리이다.
일단은 간단하게 구성만 갖춘 후 build.gradle 에 적용까지 해본다.
class LintIssueRegistry : IssueRegistry() {
// lint api 버전 설정
override val api = CURRENT_API
// 검사를 수행 할 이슈 등록
override val issues = listOf()
}
lint 검사를 수행할 수 있도록 build.gradle 에 IssueRegistry 를 등록한다.
dependencies { ... }
jar {
manifest {
attributes("Lint-Registry-v2": "com.sample.lint.LintIssueRegistry")
}
}
3. Issue 생성
DataBinding 사용을 권장하며 setContentView() 사용 시 warning 을 띄워주는 목적의 이슈를 만들어본다.
Issue.create() 로 생성가능하며 아래 모든 내용을 필수로 채워주어야한다.
- id : Issue 의 고유 식별 문자
- briefDescription : Issue 요약 설명으로 길지 않게 작성한다
- explanation : Issue 에 대한 구체적인 설명과 권장 사항을 작성한다
- category : lint Ctegory 기준에 맞게 작성한다
- priority : Issue 의 우선순위이며 1~10 사이의 정수를 적는다
- severity : Issue 심각도 레벨을 지정한다
- implementation : 해당 detector 를 구현하고 검사 수행 할 scope 도 설정해준다
(아래 나올 detector 에 companion object 에 포함할 예정이다)
val ISSUE = Issue.create(
id = SetContentViewDetector::class.java.simpleName,
briefDescription = "Prohibits usages of SetContentView()",
explanation = "Prohibits usages of SetContentView(), use DataBindingUtil.setContentView() instead",
category = Category.CORRECTNESS,
priority = 5,
severity = Severity.WARNING,
implementation = Implementation(SetContentViewDetector::class.java, Scope.JAVA_FILE_SCOPE))
4. Detector 구현
- 수행 할 검사의 이슈를 만드는 클래스로 기본적으로 Detector 를 상속받아 구현한다
- 추가로 implement 할 인터페이스는 아래 2가지이다
- XmlScanner : xml 파일을 검사
- SourceCodeScanner : 소스코드 파일을 검사
- setContentView 라는 메소드를 사용했을 경우 보고할 예정이라 getApplicableMethodNames() 를 override 하여 리스트에 setContentView 를 넣어준다
- visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod)
- 위 getApplicableMethodNames() 에서 반환된 메서드의 이름이 검출되면 호출된다
- JavaContext : 분석한 소스코드 파일에 대한 정보
- UCallExpression : 호출된 메소드의 노드 정보
- PsiMethod : 호출된 메소드를 표현
class SetContentViewDetector : Detector(), SourceCodeScanner {
companion object {
val ISSUE = Issue.create(
id = SetContentViewDetector::class.java.simpleName,
briefDescription = "Prohibits usages of SetContentView()",
explanation = "Prohibits usages of SetContentView(), use DataBindingUtil.setContentView() instead",
category = Category.CORRECTNESS,
priority = 5,
severity = Severity.WARNING,
implementation = Implementation(SetContentViewDetector::class.java, Scope.JAVA_FILE_SCOPE))
}
// 반환된 리스트의 메소드명을 소스코드에서 검출
override fun getApplicableMethodNames(): List<String>? {
return listOf("setContentView")
}
// getApplicableMethodNames() 에서 반환된 메서드의 이름이 검출되면 호출됨
override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
if (context.evaluator.isMemberInClass(method, "androidx.databinding.DataBindingUtil")) {
return
}
context.report(ISSUE, node, context.getLocation(node), "Use DataBindingUtil.setContentView() instead.")
}
}
5. Issue 등록
class LintIssueRegistry : IssueRegistry() {
// lint api 버전
override val api = CURRENT_API
// issue 등록
override val issues = listOf(SetContentViewDetector.ISSUE)
}
6. lint module 사용하기
사용하고자하는 프로젝트에 lint module 을 추가한다.
// module 수준의 build.gradle
dependencies {
lintChecks project(':lint')
}
// settings.gradle
include ':lint'
sync gradle 후 setContentView() 를 사용한 곳에 가면 아래와 같은 warning 을 확인할 수 있다.
Issue 생성 시 작성했던 briefDescription, explanation, id 도 확인할 수 있다.
참고)
Google Custom Lint : https://github.com/googlesamples/android-custom-lint-rules
'Android개발' 카테고리의 다른 글
Migrating build.gradle from Groovy to Kotlin (0) | 2020.09.25 |
---|---|
Android Lint #1 - 기본 (0) | 2020.07.02 |
App Startup time (1) | 2020.06.25 |
App Startup (0) | 2020.06.25 |
Elevation (0) | 2020.03.18 |
댓글