`targetExclude("**/build/**")` makes configuration cache store and reuse walk the entire project directory
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 43/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
調査の方向性
Start with FormatExtension.java around lines 314 and 329, then trace target subtraction and the lineEndingsPolicy input around lines 1096 and 1114. Read GitAttributesLineEndings.java around line 92 and inspect the supplied configuration cache stack trace to understand when the file tree is traversed. Done means string targetExclude("**/build/**") avoids walking and fingerprinting unrelated project files during configuration cache store and reuse while preserving the exclusion behavior; the issue provides TestKit timing comparisons to reproduce and assess the change.
索引モデルが issue の本文から書いたものです。
説明
Summary
A targetExclude string pattern that starts with ** makes configuration-cache store and reuse scale with the total number of files under the project directory. This happens even when target is already scoped to a few subfolders, as recommended in #2717 and #833.
spotless {
kotlin {
ktlint()
target(
"build-logic/**/*.kt",
"build-logic/**/*.kts",
"settings-logic/**/*.kt",
"settings-logic/**/*.kts",
)
targetExclude("**/build/**")
}
}
Measured with TestKit, Gradle 9.8.1, project dir containing ~100k unrelated files, spotlessKotlinCheck --dry-run:
| Configuration | CC store | CC reuse |
|---|---|---|
target(...) only |
~70 ms | ~50 ms |
target(...) + targetExclude("**/build/**") |
~1000 ms | ~1250 ms |
target(fileTree(".") { include(...); exclude("**/build/**") }) |
~90 ms | ~45 ms |
With --no-configuration-cache all three configurations take under 100 ms at configuration time. In a real repo the walk covers .git, .gradle and every module's build output, so the cost grows with the size of the repo.
Root cause
- A string
targetExcludebecomesproject.fileTree(projectDir).include("**/build/**")(FormatExtension.java:314). Gradle cannot prune a leading**, and the exclude branch returns before the default.git/.gradle/ build-dir excludes are added (L329). So resolving this tree means walking the whole project directory. - The task target is
target.minus(targetExclude)(L1096). - With the default
GIT_ATTRIBUTES_FAST_ALLSAME, thelineEndingsPolicytask input isLazyAllTheSame(L1114). When the configuration cache serializes that input,LazyForwardingEquality.writeObjectcallscalculateState(), which runstoFormat.get().iterator()(GitAttributesLineEndings.java:92) just to get the first file. Iterating theSubtractingFileCollectionresolvesright.getFiles(), which walks the whole tree. - Because this happens during configuration, Gradle records the collection as a configuration input (
ConfigurationCacheFingerprintWriter.fileCollectionObserved) and snapshots the whole tree. On every later build the fingerprint check snapshots it again, so CC reuse is slow too.
Relevant stack excerpt from the store phase:
at org.gradle.internal.cc.impl.fingerprint.ConfigurationCacheFingerprintWriter.fileCollectionObserved
at org.gradle.api.internal.file.collections.DefaultConfigurableFileTree.getFiles
...
at com.diffplug.spotless.extra.GitAttributesLineEndings$LazyAllTheSame.calculateState
at com.diffplug.spotless.LazyForwardingEquality.state
at com.diffplug.spotless.LazyForwardingEquality.writeObject
at org.gradle.internal.serialize.codecs.core.jos.JavaObjectSerializationCodec$WriteObjectEncoding.encode
at org.gradle.internal.serialize.codecs.core.ProviderCodec.encode
at org.gradle.internal.serialize.codecs.core.TaskNodeCodec.writeTask
Replacing minus with filter { !targetExclude.contains(it) } is not enough: it only brings store to ~350 ms and reuse to ~640 ms. DefaultConfigurableFileTree.contains() also reports fileCollectionObserved during configuration, so the whole exclude tree still gets fingerprinted.
Related to
- #833
- #2717
- 主要言語
- Java
- スター
- 5.7k
- フォーク
- 562
- 平均マージ
- 3日 2時間
- マージ済み PR(30日)
- 30
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
diffplug/spotless のほかの issue
-
Expose `maxLineLength` on the `googleJavaFormat` step (configurable upstream since gjf 1.37.0)対応中かも @xzxiaoshan が 3 日前に担当しました。 オープン
難易度 3/5 1〜2日 初心者へのやさしさ 28/100
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 28/100
メンテナーはふだん 1 日以内に返信
-
難易度 3/5 1〜2日 初心者へのやさしさ 68/100
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 35/100
メンテナーはふだん 1 日以内に返信
-
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
diffplug/spotless#3067 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
diffplug/spotless の issue をすべて見る
似ている issue
-
protobuf
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
FasterXML/jackson-dataformats-binary#874 ·
メンテナーはふだん 1 日以内に返信
-
難易度 1/5 1時間未満 初心者へのやさしさ 75/100
-
[Bug][Connector-V2][JDBC] Turkish locale bypasses the SQL set-operator and complex-clause guards, rewriting the user's query対応中かも @SEPURI-SAI-KRISHNA が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
メンテナーはふだん 3 日以内に返信
-
[Bug report] Lance REST catalog-level DropNamespace drops non-lakehouse catalogs対応中かも @nevzheng が今日担当しました。 オープンbug
難易度 2/5 1〜3時間 初心者へのやさしさ 73/100
メンテナーはふだん 1 日以内に返信
-
[BUG] jackson3 JacksonJsonpMapper(ObjectMapper) fails to deserialize `_source` with "Trailing token" error対応中かも @junyeokk が今日担当しました。 オープンbug untriaged
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
opensearch-project/opensearch-java#2236 ·
メンテナーはふだん 1 日以内に返信