Handle preference stores corruption by clearing them (#5086)

* Handle preference stores corruption by clearing them:
    - Use the centralised `PreferenceDataStoreFactory` instead of `preferences by`.
    - Add `DefaultPreferencesCorruptionHandlerFactory.replaceWithEmpty` to its `create(name)` method so all preference stores are cleared if they're corrupted.

* Add detekt rule to make sure we use `PreferenceDataStoreFactory` instead of `by preferencesDataStore`

* Remove `@SingleIn` annotations as the annotated class no longer have to be singletons
This commit is contained in:
Jorge Martin Espinosa 2025-08-22 08:59:06 +02:00 committed by GitHub
parent 3faaab407f
commit 8245ad8bc3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 198 additions and 138 deletions

View file

@ -0,0 +1,44 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.detektrules
import io.github.detekt.psi.fileName
import io.gitlab.arturbosch.detekt.api.CodeSmell
import io.gitlab.arturbosch.detekt.api.Config
import io.gitlab.arturbosch.detekt.api.Debt
import io.gitlab.arturbosch.detekt.api.Entity
import io.gitlab.arturbosch.detekt.api.Issue
import io.gitlab.arturbosch.detekt.api.Rule
import io.gitlab.arturbosch.detekt.api.Severity
import org.jetbrains.kotlin.psi.KtPropertyDelegate
class ByPreferencesDataStoreRule(config: Config) : Rule(config) {
override val issue: Issue = Issue(
id = "ByPreferencesDataStoreNotAllowed",
severity = Severity.Style,
description = "Avoid using `by preferencesDataStore(...)`, use `PreferenceDataStoreFactory.create(name)`instead.",
debt = Debt.FIVE_MINS,
)
override fun visitPropertyDelegate(delegate: KtPropertyDelegate) {
super.visitPropertyDelegate(delegate)
if (delegate.containingKtFile.fileName == "DefaultPreferencesDataStoreFactory.kt") {
// Skip the rule for the DefaultPreferencesDataStoreFactory implementation
return
}
if (delegate.text.startsWith("by preferencesDataStore")) {
report(CodeSmell(
issue = issue,
entity = Entity.from(delegate),
message = "Use `PreferenceDataStoreFactory.create(name)` instead of `by preferencesDataStore(...)`."
))
}
}
}

View file

@ -18,6 +18,7 @@ class ElementRuleSetProvider : RuleSetProvider {
id = ruleSetId,
rules = listOf(
RunCatchingRule(config),
ByPreferencesDataStoreRule(config),
)
)
}