Gradle Lint 插件簡介
1. 概述
在本文中,我們將探討gradle-lint
插件。
首先,我們將看看何時使用它。然後,我們將逐步介紹插件配置選項。接下來,我們將使用它的一些預定義規則。最後,我們將產生 lint 報告。
2. 什麼是 Gradle Lint 插件?
Gradle Lint 插件有助於檢查 Gradle 設定檔。它在我們的程式碼庫中強制執行建置腳本結構。該插件可以使 Gradle Wrapper 版本保持最新,防止跨建置檔案的不良做法,並刪除未使用的依賴項。
實際上,我們使用預先定義的規則或編寫自訂規則。然後,我們配置插件將它們視為違規或忽略它們。 linter 在大多數 Gradle 任務結束時運行。
預設情況下,它不會直接修改程式碼,而是顯示警告。這很有幫助,因為其他 Gradle 任務不會因為該插件而失敗。此外,這些警告不會遺失,因為它們在日誌末尾可見。
此外, [gradle-lint](https://github.com/nebula-plugins/gradle-lint-plugin)
提供了一個fixGradleLint
命令來自動修復大多數 lint 違規。
在內部,Gradle Lint 外掛程式利用Groovy AST和Gradle 模型來應用 lint 規則。這表明該插件與 Groovy AST 緊密耦合。因此,**該插件不支援 Kotlin 建置腳本。**
3. 設定
有三種方法可以設定 Gradle Lint 插件:在build.gradle,
初始化腳本或腳本插件。讓我們逐一探討。
3.1.使用build.gradle
讓我們將[gradle-lint](https://mvnrepository.com/artifact/com.netflix.nebula/gradle-lint-plugin)
插件加入到我們的build.gradle
中:
plugins {
id "nebula.lint" version "17.8.0"
}
使用多模組專案時,應將此插件應用於根專案。由於我們將使用多模組項目,因此我們將插件應用到根項目:
allprojects {
apply plugin :"nebula.lint"
gradleLint {
rules = [] // we'll add rules here
}
}
稍後,我們將在gradleLint.rules
數組中新增 lint 規則。
3.2.使用初始化腳本
除了build.gradle
之外,我們還可以使用init 腳本來設定我們的插件:
import com.netflix.nebula.lint.plugin.GradleLintPlugin
initscript {
repositories { mavenCentral() }
dependencies {
classpath 'com.netflix.nebula:gradle-lint-plugin:17.8.0'
}
}
allprojects {
apply plugin: GradleLintPlugin
gradleLint {
rules=[]
}
}
這個lint.gradle
腳本與我們之前的設定相同。要應用它,我們將–init-script
標誌傳遞給我們的任務:
./gradlew build --init-script lint.gradle
一個有趣的用例是根據任務運行的環境傳遞不同的初始化腳本。缺點是我們總是必須傳遞–init-script
標誌。
3.3.使用腳本插件
讓我們將腳本插件直接套用到我們的build.gradle
:
plugins{
id "nebula.lint" version "17.8.0"
}
apply from: "gradle-lint-intro.gradle"
gradle-lint-intro.gradle
內容將被注入,就好像它是建置腳本的一部分一樣:
allprojects {
apply plugin: "nebula.lint"
gradleLint {
rules= []
}
}
在本文中,我們將在build.gradle
腳本中保留gradle-lint
配置。
4. 配置
讓我們回顧一下grade-lint
插件中可用的不同配置選項。
4.1.執行
執行 Gradle Lint 插件的命令是./gradlew lintGradle
。我們可以單獨呼叫它,也可以在其他任務期間呼叫它。
預設情況下,外掛程式會在所有任務結束時自動運行,除了dependencyInsight
任務 - help
、 tasks
、 dependencies
、 components
、 model
、 projects
、 wrapper,
和properties
:
./gradlew build
此build
任務透過呼叫./gradlew lintGradle.
linter 將違規行為顯示為警告。
此外,我們可以透過應用skipForTask
方法來阻止linter在特定任務中執行:
gradleLint {
skipForTask('build')
}
在這裡,我們阻止插件在建置任務期間運行。
如果我們想停用所有任務的插件,我們可以使用alwaysRun
標誌:
gradleLint {
alwaysRun = false
}
當我們想要在特定時間點單獨呼叫./gradlew lintGradle
時,這特別有用。
需要注意的是,單獨呼叫插件會將 lint 違規標記為錯誤,而不是警告。
4.2.規則定義
Gradle Lint 外掛程式可讓我們配置兩組規則:違規規則(透過rules
和critcalRules
選項)和忽略規則(使用excludedRules
、 ignore
和fixme
屬性)。讓我們來探索一下它們。
首先, rules
屬性採用一系列 lint 規則。當滿足規則定義的違規行為時,linter 會發出警告。但如果 Gradle Lint 插件單獨運行,這些警告會使建置失敗。
接下來,讓我們探討criticalRules
選項。當我們希望規則違規觸發任務失敗時,我們為gradleLint.criticalRules
屬性新增一條規則。該插件提供了一個特定的criticalLintGradle
任務來僅檢查關鍵規則:
./gradlew criticalLintGradle -PgradleLint.criticalRules=undeclared-dependency
此處, -PgradleLint.criticalRules
選項將undeclared-dependency
規則新增至criticalRules
。然後, criticalLintGradle
任務僅檢查criticalRules
中定義的規則。
繼續, excludedRules
選項採用要忽略的規則清單。當我們想要忽略群組規則中的特定規則時,它會派上用場:
gradleLint {
rules= ['all-dependency']
excludedRules= ['undeclared-dependency']
}
我們已從先前的全依賴群組規則中排除了undeclared-dependency
規則。組規則允許我們立即應用一組規則。
最後,我們可以透過將建置檔案的某些部分包裝在ignore
屬性中來防止linter掃描它們:
dependencies {
testImplementation('junit:junit:4.13.1')
gradleLint.ignore('dependency-parentheses') {
implementation("software.amazon.awssdk:sts")
}
}
我們有意保護[aws-sts](https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-sts)
免受dependency-parenthesis
規則的影響。當我們執行 linter 時它不會被列出:
warning dependency-parentheses parentheses are unnecessary for dependencies
gradle-lint-intro/build.gradle:11
testImplementation('junit:junit:4.13.1')
dependency-parentheses
警告不要在 Gradle 依賴項宣告中不必要地使用括號。
此外,如果我們想暫時忽略一條規則,我們可以將ignore
替換為fixme
屬性:
gradleLint.fixme('2029-04-23', 'dependency-parentheses') {
implementation('software.amazon.awssdk:sts')
}
此處, [aws-sts](https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-sts)
依賴項將在 2029 年 4 月 23 日之後觸發未使用依賴項違規。
需要注意的是, ignore
和fixme
屬性僅對已解析的依賴項有效。它們不適用於建立文件中的包裝聲明:
dependencies {
gradleLint.ignore('unused-dependency') {
implementation "software.amazon.awssdk:sts"
}
}
我們有意保護[aws-sts](https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-sts)
免受未使用的依賴關係規則的影響。我們不會直接在程式碼中使用它。但由於某些原因, AWS WebIdentityTokenCredentialsProvider
需要它。不幸的是,linter 不會捕捉這一點,因為它不會評估未解決的依賴關係。
4.3.覆蓋配置屬性
Gradle Lint 允許我們覆寫命令列中的一些設定屬性。我們透過使用-PgradleLint
選項後跟任何有效的文件配置選項來完成此操作。
讓我們將unused-dependency
規則加入到初始的空rules
陣列中:
gradleLint {
rules= ['unused-dependency']
}
接下來,讓我們透過命令列排除它來防止 linter 應用它:
./gradlew lintGradle -PgradleLint.excludedRules=unused-dependency
這相當於在設定檔中設定excludedRules=[“unused-dependency”]
。
我們可以將此模式用於所有其他屬性,特別是在 CI 環境中執行時。多個值應以逗號分隔。
5. 內建規則
**Gradle Lint 插件有幾個內建的 lint 規則**。讓我們來探討其中的一些。
5.1.最小依賴版本規則
首先,讓我們來看看minimum-dependency-version
規則。它顯示版本嚴格低於預定義版本的依賴項的違規情況:
gradleLint {
rules= ['minimum-dependency-version']
}
我們需要在minVersions
屬性中提供以逗號分隔的最小依賴版本清單。但是,截至撰寫本文時, [GradleLintExtension](https://github.com/nebula-plugins/gradle-lint-plugin/blob/280804cbbdcce703284921b34fe8719a0a84f661/src/main/groovy/com/netflix/nebula/lint/plugin/GradleLintExtension.groovy#L23)
沒有[minVersions](https://github.com/nebula-plugins/gradle-lint-plugin/blob/280804cbbdcce703284921b34fe8719a0a84f661/src/main/groovy/com/netflix/nebula/lint/plugin/GradleLintExtension.groovy#L23)
屬性。因此,我們透過命令列來設定它:
./gradlew lintGradle -PgradleLint.minVersions=junit:junit:5.0.0
在這裡,linter 警告不要使用低於5.0.0
的junit
版本:
> Task :lintGradle FAILED
This project contains lint violations. A complete listing of the violations follows.
Because none were serious, the build's overall status was unaffected.
warning minimum-dependency-version junit:junit is below the minimum version of 5.0.0 (no auto-fix available). See https://github.com/nebula-plugins/gradle-lint-plugin/wiki/Minimum-Dependency-Version-Rule for more details
? 1 problem (0 errors, 1 warning)
To apply fixes automatically, run fixGradleLint, review, and commit the changes.
運行./gradlew fixGradleLint
可以有效地將junit
版本更新到5.0.0.
5.2.未聲明的依賴規則
接下來,我們將了解[undeclared-dependency](https://github.com/nebula-plugins/gradle-lint-plugin/blob/main/src/main/groovy/com/netflix/nebula/lint/rule/dependency/UndeclaredDependencyRule.groovy)
規則。它確保我們已經明確地聲明了在程式碼中直接使用的傳遞依賴項:
gradleLint {
rules= ['undeclared-dependency']
}
現在,讓我們執行lintGradle
任務:
> Task :lintGradle FAILED
This project contains lint violations. A complete listing of the violations follows.
Because none were serious, the build's overall status was unaffected.
warning undeclared-dependency one or more classes in org.hamcrest:hamcrest-core:1.3 are required by your code directly
warning undeclared-dependency one or more classes in org.apache.httpcomponents:httpcore:4.4.13 are required by your code directly
? 2 problems (0 errors, 2 warnings)
To apply fixes automatically, run fixGradleLint, review, and commit the changes.
我們可以看到我們的程式碼直接需要兩個依賴項。在我們執行fixlintGradle
任務後,linter 新增它們:
> Task :fixLintGradle
This project contains lint violations. A complete listing of my attempt to fix them follows. Please review and commit the changes.
fixed undeclared-dependency one or more classes in org.hamcrest:hamcrest-core:1.3 are required by your code directly
fixed undeclared-dependency one or more classes in org.apache.httpcomponents:httpcore:4.4.13 are required by your code directly
Corrected 2 lint problems
此外,截至撰寫本文時,**無法向外掛程式提供自訂規則**。另一種方法是分叉庫並直接添加自訂規則。
最後,我們在使用過時的規則時應該小心。 archaic-wrapper
規則已於 2018 年刪除。文件的某些部分尚未更新。
6. 產生報告
現在,讓我們使用generateGradleLintReport
任務來產生報表:
./gradlew generateGradleLintReport
預設情況下,報告格式為 HTML。該插件將所有報告文件放置在build/reports/gradleLint
資料夾中.
我們的 HTML 報告將命名為gradle-5.html
,其中gradle-5
是我們的根項目名稱。
其他可用選項是xml
和text:
gradleLint {
reportFormat = 'text'
reportOnlyFixableViolations = true
}
我們使用reportFormat
屬性直接以純文字輸出報告。此外,由於啟動了reportOnlyFixableViolations
標誌,我們的報告僅包含可修復的違規行為.
七、結論
在本文中,我們探索了[gradle-lint](https://github.com/nebula-plugins/gradle-lint-plugin)
插件。首先,我們看到了它的實用性。然後,我們列出了不同的配置選項。接下來,我們使用了一些預先定義的規則。最後,我們產生了 lint 報表。
與往常一樣,本文的程式碼可以在 GitHub 上取得。