From fda8c80949626293db2b7e99f2d7f00d0bc583d0 Mon Sep 17 00:00:00 2001 From: Nik Clayton Date: Sat, 25 Feb 2023 21:22:49 +0100 Subject: [PATCH] Use an explicit SCHEMA_VERSION instead of BuildConfig.VERSION_CODE (#3324) * Use an explicit SCHEMA_VERSION instead of BuildConfig.VERSION_CODE Every nightly release has a new BuildConfig.VERSION_CODE, so the previous code would not do the right thing. Require the schema version to be explicitly set. While I'm here, provide a clear set of guidelines as to what has to happen when the schema changes. * Improve documentation links --- .../keylesspalace/tusky/TuskyApplication.kt | 9 +++--- .../tusky/settings/SettingsConstants.kt | 31 +++++++++++++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/keylesspalace/tusky/TuskyApplication.kt b/app/src/main/java/com/keylesspalace/tusky/TuskyApplication.kt index 59978310d..c755b217d 100644 --- a/app/src/main/java/com/keylesspalace/tusky/TuskyApplication.kt +++ b/app/src/main/java/com/keylesspalace/tusky/TuskyApplication.kt @@ -23,6 +23,7 @@ import autodispose2.AutoDisposePlugins import com.keylesspalace.tusky.components.notifications.NotificationWorkerFactory import com.keylesspalace.tusky.di.AppInjector import com.keylesspalace.tusky.settings.PrefKeys +import com.keylesspalace.tusky.settings.SCHEMA_VERSION import com.keylesspalace.tusky.util.APP_THEME_DEFAULT import com.keylesspalace.tusky.util.LocaleManager import com.keylesspalace.tusky.util.setAppNightMode @@ -69,10 +70,10 @@ class TuskyApplication : Application(), HasAndroidInjector { AppInjector.init(this) // Migrate shared preference keys and defaults from version to version. The last - // version that did not have a SCHEMA_VERSION was 97, so that's the default. - val oldVersion = sharedPreferences.getInt(PrefKeys.SCHEMA_VERSION, 97) - if (oldVersion != BuildConfig.VERSION_CODE) { - upgradeSharedPreferences(oldVersion, BuildConfig.VERSION_CODE) + // version that did not have a SCHEMA_VERSION was 100, so that's the default. + val oldVersion = sharedPreferences.getInt(PrefKeys.SCHEMA_VERSION, 100) + if (oldVersion != SCHEMA_VERSION) { + upgradeSharedPreferences(oldVersion, SCHEMA_VERSION) } // In this case, we want to have the emoji preferences merged with the other ones diff --git a/app/src/main/java/com/keylesspalace/tusky/settings/SettingsConstants.kt b/app/src/main/java/com/keylesspalace/tusky/settings/SettingsConstants.kt index 619003219..4b4f5f18c 100644 --- a/app/src/main/java/com/keylesspalace/tusky/settings/SettingsConstants.kt +++ b/app/src/main/java/com/keylesspalace/tusky/settings/SettingsConstants.kt @@ -12,6 +12,37 @@ enum class AppTheme(val value: String) { } } +/** + * Current preferences schema version. Format is 4-digit year + 2 digit month (zero padded) + 2 + * digit day (zero padded) + 2 digit counter (zero padded). + * + * If you make an incompatible change to the preferences schema you must: + * + * - Update this value + * - Update the code in + * [TuskyApplication.upgradeSharedPreferences][com.keylesspalace.tusky.TuskyApplication.upgradeSharedPreferences] + * to migrate from the old schema version to the new schema version. + * + * An incompatible change is: + * + * - Deleting a preference. The migration should delete the old preference. + * - Changing a preference's default value (e.g., from true to false, or from one enum value to + * another). The migration should check to see if the user had set an explicit value for + * that preference ([SharedPreferences.contains][android.content.SharedPreferences.contains]); + * if they hadn't then the migration should set the *old* default value as the preference's + * value, so the app behaviour does not unexpectedly change. + * - Changing a preference's type (e.g,. from a boolean to an enum). If you do this you may want + * to give the preference a different name, but you still need to migrate the user's previous + * preference value to the new preference. + * - Renaming a preference key. The migration should copy the user's previous value for the + * preference under the old key to the value for the new, and delete the old preference. + * + * A compatible change is: + * + * - Adding a new preference that does not change the interpretation of an existing preference + */ +const val SCHEMA_VERSION = 2023021501 + object PrefKeys { // Note: not all of these keys are actually used as SharedPreferences keys but we must give // each preference a key for it to work.