Skip to content

Commit 93073ca

Browse files
authored
Update docs for stabilityConfigurationFiles (#140)
* Add optional and improve conditional logics * Update docs for stabilityConfigurationFiles
1 parent d2c7fbe commit 93073ca

File tree

5 files changed

+80
-9
lines changed

5 files changed

+80
-9
lines changed

README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,46 @@ composeStabilityAnalyzer {
878878
}
879879
```
880880

881+
#### `stabilityConfigurationFiles` Option
882+
883+
You can provide stability configuration files to tell `stabilityCheck` which types should be treated as stable, even if the compiler marks them as unstable. This matches the [Compose compiler's stability configuration file](https://developer.android.com/develop/ui/compose/performance/stability/fix#configuration-file) format, so you can reuse the same file for both the compiler and stability validation.
884+
885+
This is useful when:
886+
- Third-party library types don't have `@Stable` or `@Immutable` annotations
887+
- Code-generated types are effectively stable but the compiler can't infer it
888+
- You want the stability check to respect the same overrides as the Compose compiler
889+
890+
```kotlin
891+
composeStabilityAnalyzer {
892+
stabilityValidation {
893+
// Use the same stability configuration file as the Compose compiler
894+
stabilityConfigurationFiles.add(
895+
rootProject.layout.projectDirectory.file("stability_config.conf")
896+
)
897+
}
898+
}
899+
```
900+
901+
**Example `stability_config.conf`:**
902+
903+
```
904+
// Types from third-party libraries
905+
com.google.firebase.auth.FirebaseUser
906+
com.squareup.moshi.JsonAdapter
907+
908+
// All types in a package
909+
com.example.generated.*
910+
911+
// All types in a package and its sub-packages
912+
com.example.models.**
913+
```
914+
915+
The file supports `*` (single-level wildcard) and `**` (multi-level wildcard) patterns. Lines starting with `//` are treated as comments.
916+
917+
When `stabilityConfigurationFiles` is set, the `stabilityCheck` task treats any parameter type matching these patterns as stable. This means:
918+
- New composables with all parameters matching these patterns won't be flagged
919+
- Parameter stability changes from UNSTABLE to a matching type won't be reported as regressions
920+
881921
**Why ignore packages/classes**
882922

883923
If you don't want to track:

compose-stability-analyzer-idea/src/main/resources/icons/stability.svg

Lines changed: 1 addition & 1 deletion
Loading

docs/gradle-plugin/stability-validation.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,13 @@ composeStabilityAnalyzer {
126126

127127
// Allow checks without a baseline file (default: false)
128128
allowMissingBaseline.set(false)
129+
130+
// Add stability configuration file
131+
// Matches compose's identical property
132+
// (see https://developer.android.com/develop/ui/compose/performance/stability/fix#configuration-file)
133+
stabilityConfigurationFiles.add(
134+
rootProject.layout.projectDirectory.file("stability_config.conf")
135+
)
129136
}
130137
}
131138
```
@@ -158,6 +165,33 @@ composeStabilityAnalyzer {
158165
}
159166
```
160167

168+
### `stabilityConfigurationFiles`
169+
170+
You can provide stability configuration files to tell `stabilityCheck` which types should be treated as stable, even if the compiler marks them as unstable. This uses the same format as the [Compose compiler's stability configuration file](https://developer.android.com/develop/ui/compose/performance/stability/fix#configuration-file), so you can reuse the same file for both the compiler and stability validation.
171+
172+
```kotlin
173+
composeStabilityAnalyzer {
174+
stabilityValidation {
175+
stabilityConfigurationFiles.add(
176+
rootProject.layout.projectDirectory.file("stability_config.conf")
177+
)
178+
}
179+
}
180+
```
181+
182+
The configuration file contains fully-qualified type names, one per line. Lines starting with `//` are treated as comments. Wildcard patterns are supported: `*` matches a single package segment and `**` matches across package boundaries.
183+
184+
```
185+
// stability_config.conf
186+
com.google.firebase.auth.FirebaseUser
187+
com.example.generated.*
188+
com.example.models.**
189+
```
190+
191+
When these files are configured, the `stabilityCheck` task treats any parameter type matching these patterns as stable. This affects the comparison in two ways: new composables whose parameters all match these patterns won't be flagged, and parameter stability regressions to a matching type won't be reported.
192+
193+
This is particularly useful when your project already uses a stability configuration file for the Compose compiler. By pointing `stabilityConfigurationFiles` to the same file, the stability validation respects the same overrides, keeping the two in sync.
194+
161195
## Excluding Composables
162196

163197
Some composables shouldn't be included in stability validation: preview composables that only exist for Android Studio previews, debug-only screens, or experimental features still under active development. Use the `@IgnoreStabilityReport` annotation to exclude them.

docs/stability-concepts.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ com.example.ThirdPartyModel
151151
com.google.firebase.auth.FirebaseUser
152152
```
153153

154+
The same configuration file can also be used with the [Stability Validation](gradle-plugin/stability-validation.md#stabilityconfigurationfiles) Gradle task. By pointing `stabilityConfigurationFiles` to this file, the `stabilityCheck` task respects the same overrides as the Compose compiler, so types you've declared stable won't be flagged as regressions.
155+
154156
## Cross-Module Stability
155157

156158
Types from other modules that were **not compiled with the Compose compiler** are treated as unstable by default. This is a conservative decision, because the Compose compiler in your module can't inspect the source code of external modules, so it can't verify stability.

stability-gradle/src/main/kotlin/com/skydoves/compose/stability/gradle/StabilityCheckTask.kt

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ public abstract class StabilityCheckTask : DefaultTask() {
9696
public abstract val allowMissingBaseline: Property<Boolean>
9797

9898
@get:InputFiles
99+
@get:Optional
99100
@get:PathSensitive(PathSensitivity.RELATIVE)
100101
public abstract val stabilityConfigurationFiles: ListProperty<RegularFile>
101102

@@ -152,15 +153,9 @@ public abstract class StabilityCheckTask : DefaultTask() {
152153
val currentStability = parseStabilityFromCompiler(inputFile)
153154
val referenceStability = parseStabilityFile(referenceFile)
154155

155-
val stabilityConfigurationMatchers = stabilityConfigurationFiles.get()
156+
val stabilityConfigurationMatchers = stabilityConfigurationFiles.getOrElse(emptyList())
156157
.flatMap { configRegularFile ->
157-
val file = configRegularFile.asFile
158-
159-
if (!file.exists()) {
160-
return@flatMap emptyList()
161-
}
162-
163-
StabilityConfigParser.fromFile(file.path).stableTypeMatchers
158+
StabilityConfigParser.fromFile(configRegularFile.asFile.path).stableTypeMatchers
164159
}
165160

166161
val differences =

0 commit comments

Comments
 (0)