diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f6479eb..7e7edca9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,23 @@ ### Changes -- *No changes* +* **Breaking changes:** Удалён `plugin-flipper`. Вместо него используйте плагин Konfeature. См. гайд по миграции: [migration guide](docs/migration_guide.md). +* **Breaking changes:** Удалён `DebugStage` из `plugin-servers`. Вместо него используйте `DebugServer`. См. [migration guide](docs/migration_guide.md). +* **Breaking changes:** Удалён `plugin-accounts`. Плагин для работы с тестовыми аккаунтами полностью удалён. См. [migration guide](docs/migration_guide.md). +* **Breaking changes:** Удалён `plugin-app-settings`. Плагин для просмотра и редактирования `SharedPreferences` полностью удалён. См. [migration guide](docs/migration_guide.md). +* **Breaking changes:** Удалён `DebugPanelConfig` и shaker mode. Параметр `config` убран из `DebugPanel.initialize()`. Открытие панели по встряхиванию устройства больше не поддерживается. См. [migration guide](docs/migration_guide.md). +* **Breaking changes:** Повышен `minSdk` с 21 до 23. Библиотека больше не поддерживает Android 5.0–5.1 (API 21–22). +* **Breaking changes:** Java compatibility повышена с 11 до 17. Требуется JDK 17+. +* **Breaking changes:** Gradle обновлён с 8.11 до 9.1. +* **Breaking changes:** Обновлён каталог версий зависимостей (2025.03.10 → 2026.02.23). Подробнее [здесь](https://github.com/RedMadRobot/gradle-version-catalogs/releases/tag/2026.02.23). +* Повышены `compileSdk` и `targetSdk` с 35 до 36. +* Удалён модуль `panel-common`. Зависимости перенесены в `panel-core` и отдельные плагины. +* Дебаг-панель теперь открывается как полноэкранная `Activity` вместо bottom sheet. +* Хранение серверов переведено с Room на DataStore. +* Добавлен статический анализатор detekt. +* Добавлен `plugin-about-app` для отображения информации о приложении в дебаг-панели. +* Добавлена возможность поиска тогглов по ключу в `plugin-konfeature`. +* Исправлена утечка памяти в `DebugPanelBroadcastReceiver`. ## [0.9.3] (2025-04-24) @@ -50,9 +66,9 @@ * Исправлен краш на SDK 34 (#7) * Исправлен краш при доступе к БД (#5) * Обновлены зависимости: - * Kotlin 1.6.20 → 1.9.23 - * Room 2.4.0 → 2.6.1 - * KotlinX Coroutines 1.3.9 → 1.8.0 + * Kotlin 1.6.20 → 1.9.23 + * Room 2.4.0 → 2.6.1 + * KotlinX Coroutines 1.3.9 → 1.8.0 * Удалено использование синтетиков * Обновлено окружение сборки проекта diff --git a/README.md b/README.md index cbf248a5..41645c89 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,20 @@ # Debug-panel -[![Maven Central Version](https://img.shields.io/maven-central/v/com.redmadrobot.debug/panel-core?style=flat-square)](https://central.sonatype.com/search?namespace=com.redmadrobot.debug) - -Бибилиотека для отладки приложений. - -> [!WARNING] -> -> Библиотека находится в стадии разработки. +Библиотека для отладки приложений. ---- +[![Maven Central Version](https://img.shields.io/maven-central/v/com.redmadrobot.debug/panel-core?style=flat-square)](https://central.sonatype.com/search?namespace=com.redmadrobot.debug) +[![License](https://img.shields.io/github/license/RedMadRobot/debug-panel-android?style=flat-square)][license] +[![Android](https://img.shields.io/badge/Android-3DDC84?style=flat-square&logo=android&logoColor=white)](#) -**[Changelog][changelog]** | **[Документация по разработке плагинов][plugin-development-doc]** | **[Миграция на новые версии][migration-guide]** +**[Changelog][changelog]** | **[Миграция на новые версии][migration-guide]** -Тебе надоело каждый раз вручную вбивать логин и пароль тестового пользователя или пересобирать приложение для того чтобы поменять сервер в настройках? Эта библиотека разрабатывается с идеей решить эти и другие проблемы, и сделать процесс отладки приложения более удобным. +Тебе надоело пересобирать приложение для того чтобы поменять сервер в настройках или переключить feature toggle? Эта библиотека разрабатывается с идеей решить эти и другие проблемы, и сделать процесс отладки приложения более удобным. В данный момент библиотека предоставляет следующий функционал: -1. **Добавление, редактирование и выбор юзера.** -2. **Добавление, редактирование и выбор сервера.** -3. **Просмотр и редактирование SharedPreferences.** -4. **Управление Feature toggle на основе Flipper.** -5. **Управление remote config на основе Konfeature.** +1. **Добавление, редактирование и выбор сервера.** +2. **Управление feature-toggles и remote config на основе Konfeature.** +3. **Отображение информации о приложении.** Библиотека разрабатывается используя подход работы с плагинами, когда каждый функционал подключается отдельным модулем в зависимостях. @@ -30,11 +24,11 @@ 1. Подключить `Core` модуль для работы самой панели: -```groovy +```kotlin dependencies { - //core модуль панели - debugImplementation 'com.redmadrobot.debug:panel-core:${debug_panel_version}' + // Core модуль панели + debugImplementation("com.redmadrobot.debug:panel-core:${debug_panel_version}") } ``` @@ -42,34 +36,26 @@ dependencies { 2. Подключить необходимые плагины -```groovy +```kotlin dependencies { - //Плагин для работы с аккаунтами - debugImplementation 'com.redmadrobot.debug:plugin-accounts:${debug_panel_version}' + // Плагин для работы с серверами + debugImplementation("com.redmadrobot.debug:plugin-servers:${debug_panel_version}") - //Плагин для работы с серверами - debugImplementation 'com.redmadrobot.debug:plugin-servers:${debug_panel_version}' + // Плагин для работы с remote config на основе Konfeature + debugImplementation("com.redmadrobot.debug:plugin-konfeature:${debug_panel_version}") + // Так же необходимо подключить саму библиотеку konfeature + debugImplementation("com.redmadrobot.konfeature:konfeature:${konfeature_version}") - //Плагин для работы с SharedPreferences - debugImplementation 'com.redmadrobot.debug:plugin-app-settings:${debug_panel_version}' - - //Плагин для работы с Feature Toggle на основе Flipper - debugImplementation 'com.redmadrobot.debug:plugin-flipper:${debug_panel_version}' - //Так же необходимо подключить саму библеотеку flipper - debugImplementation "com.redmadrobot:flipper:${flipper_version}" - - //Плагин для работы с remote config на основе Konfeature - debugImplementation 'com.redmadrobot.debug:plugin-konfeature:${debug_panel_version}' - //Так же необходимо подключить саму библиотеку konfeature - debugImplementation "com.redmadrobot.konfeature:konfeature:${konfeature_version}" + // Плагин для отображения информации о приложении + debugImplementation("com.redmadrobot.debug:plugin-about-app:${debug_panel_version}") } ``` 3. Для того чтобы библиотека не попала в релизную сборку необходимо подключить `no-op` версию библиотеки -```groovy - releaseImplementation 'com.redmadrobot.debug:panel-no-op:${debug_panel_version}' +```kotlin + releaseImplementation("com.redmadrobot.debug:panel-no-op:${debug_panel_version}") ``` ## Использование библиотеки в коде @@ -81,16 +67,13 @@ class App : Application() { override fun onCreate() { super.onCreate() - - DebugPanel.initialize( + + DebugPanel.initialize( application = this, - config = DebugPanelConfig(shakerMode = false), plugins = listOf( - AccountsPlugin(/*arguments*/), ServersPlugin(/*arguments*/), - AppSettingsPlugin(/*arguments*/), - FlipperPlugin(/*arguments*/), KonfeaturePlugin(/*arguments*/), + AboutAppPlugin(/*arguments*/), ) ) } @@ -101,7 +84,7 @@ class App : Application() { ```kotlin fun openDebugPanel() { - DebugPanel.showPanel(supportFragmentManager) + DebugPanel.showPanel(activity) } ``` @@ -109,73 +92,8 @@ fun openDebugPanel() { ![Режим редактирования](assets/debug_notification.png) -## Конфигурация - -Для дополнительной конфигурации **DebugPanel**, нужно добавить свою версию `DebugPanelConfig` класса при инициализации панели. - -```kotlin - DebugPanel.initialize( - application = this, - config = DebugPanelConfig(), - plugins = listOf(/*plugins*/) -) -``` - -### Доступные возможности для конфигурации - -`shakerMode: Boolean` - Открытие **DebugPanel** при встряхивании устройства. - ## Работа с плагинами -### AccountsPlugin -Используется для работы тестовыми аккаунтами. - -Можно задать список предустановленных аккаунтов - -```kotlin -AccountsPlugin( - preInstalledAccounts = listOf( - DebugAccount( - login = "user_login", - password = "user_password", - pin = "pin" //необязательное поле - ) - ) -) -``` - -Чтобы реагировать на смену пользователя вы можете подписаться на события `DebugPanel` внутри любого `LifecycleOwner` - -```kotlin -DebugPanel.subscribeToEvents(lifecycleOwner = this) { event -> - when (event) { - is AccountSelectedEvent -> { - val account = event.debugAccount - //Реализация перелогина - } - } -} -``` - -Так же вы можете использовать интерфейс `DebugAuthenticator` чтобы реализовать логику перелогина в отдельном классе который можно передать в плагин. - -```kotlin -class UserAuthenticator : DebugAuthenticator { - override fun onAccountSelected(account: DebugAccount) { - //Реализация перелогина - } -} -``` - -```kotlin -AccountsPlugin( - preInstalledAccounts = listOf(), - debugAuthenticator = UserAuthenticator() -) -``` - -Метод `onAccountSelected` будет вызываться при каждом выборе аккаунта - ### ServersPlugin Используется для работы с тестовыми серверами @@ -246,57 +164,6 @@ val selectedServer = getPlugin().getSelectedServer() -### AppSettingsPlugin - -Используется для просмотра и редактирования `SharedPreferences` в проекте - -Для подключения плагина, необходимо передать в него список `SharedPreferences` с которыми хотите работать: - -```kotlin - AppSettingsPlugin( - sharedPreferences = listOf( - primarySharedPreferences, - secondarySharedPreferences - ) - ) -``` - -### FlipperPlugin - -Используется для просмотра и редактирования Flipper feature toggle'ов в проекте - -Для подключения плагина, необходимо передать в него map id поддерживаемых фичей и их значений - -```kotlin -FlipperPlugin( - featureStateMap = mapOf( - "Toggle Id" to FlipperValue() - ) -) -``` - -Для изменения значений в рамках проекта необходимо использовать метод FlipperPlugin.observeChangedToggles(): - -```kotlin -FlipperPlugin - .observeChangedToggles() // Пришлёт map размером = [0, yourFeatures.size] - .onEach { changedToggles -> // Первый раз пришлёт сохранённые значения - this.yourDebugPanelChangedToggles = changedToggles - } - .flowOn(Dispatchers.Main) - .launchIn(debugScope) -``` - -В FlipperConfig должно быть что-то наподобие - -```kotlin -override fun getValue(feature: Feature): FlipperValue { - return yourDebugPanelChangedToggles[feature.id] - ?: localConfig[feature.id] - ?: FlipperValue.BooleanValue(false) -} -``` - ### Konfeature Plugin В основе плагина лежит библиотека [Konfeature][konfeature], которая позволяет: @@ -328,6 +195,31 @@ KonfeaturePlugin( - настроить работу с remote config через реализацию интерфейса `FeatureSource` - `addSource(featureSource)` - настроить логирование - `setLogger(logger)` +### AboutApp Plugin + +Используется для отображения информации о приложении: версии, номера билда и других произвольных данных. + +Для подключения плагина необходимо передать список `AboutAppInfo`. Требуется хотя бы один элемент: + +```kotlin +AboutAppPlugin( + aboutAppInfo = listOf( + AboutAppInfo( + title = "Версия", + value = BuildConfig.VERSION_NAME + ), + AboutAppInfo( + title = "Номер билда", + value = BuildConfig.VERSION_CODE.toString() + ) + ) +) +``` + +Каждый `AboutAppInfo` содержит: +- `title` — название поля (например, «Версия») +- `value` — значение поля (например, «1.0.0») + # Безопасность! Для того чтобы тестовые данные не попали в релизные сборки рекомендуется не задавать их явно в Application классе, а использовать реализации DebugDataProvider, которые можно разнести по разным buildType. Для release версии следует сделать пустую реализацию. @@ -361,10 +253,6 @@ ServersPlugin( ) ``` -## License - -[MIT][license] - [plugin-development-doc]:docs/plugin_development.md [changelog]: ./CHANGELOG.md [migration-guide]: docs/migration_guide.md diff --git a/docs/migration_guide.md b/docs/migration_guide.md index 2aa307e7..e86c56a1 100644 --- a/docs/migration_guide.md +++ b/docs/migration_guide.md @@ -1,5 +1,202 @@ # Миграция +## Миграция на версию 1.0.0 + +### Миграция с FlipperPlugin на KonfeaturePlugin + +`KonfeaturePlugin` является функциональным расширением `FlipperPlugin`. +Поддерживает больше типов значений (Boolean, String, Long, Double), отображает источник каждого значения (Default / Interceptor / Source), позволяет сбрасывать значения по отдельности. + +#### Gradle + +```diff +- debugImplementation("com.redmadrobot.debug-panel:plugin-flipper:") +- implementation("com.redmadrobot:flipper:") + ++ debugImplementation("com.redmadrobot.debug-panel:plugin-konfeature:") ++ implementation("com.redmadrobot:konfeature:") +``` + +#### Инициализация + +```diff +- FlipperPlugin( +- featureStateMap = mapOf( +- "my_toggle" to FlipperValue.Enabled, +- ) +- ) + ++ val debugPanelInterceptor = KonfeatureDebugPanelInterceptor(context) ++ val konfeatureInstance = konfeature { ++ addInterceptor(debugPanelInterceptor) ++ } ++ KonfeaturePlugin( ++ debugPanelInterceptor = debugPanelInterceptor, ++ konfeature = konfeatureInstance, ++ ) +``` + +#### Наблюдение за изменёнными значениями + +```diff +- FlipperPlugin.observeChangedToggles() +- .onEach { changes -> /* handle Map */ } +- .launchIn(scope) + ++ // В Konfeature значения читаются напрямую через FeatureConfigSpec: ++ val myToggle: Boolean by myFeatureConfig.myToggle +``` + +#### Несколько источников (`addSource`) + +```diff +- FlipperPlugin.addSource("remote", mapOf("my_toggle" to FlipperValue.Enabled)) + ++ // В Konfeature источники объявляются через FeatureSource и передаются в builder: ++ konfeature { addSource(remoteSource) } +``` + +### Удаление plugin-accounts + +`AccountsPlugin` полностью удалён из библиотеки. Классы `AccountsPlugin`, `DebugAccount`, `DebugAuthenticator`, `AccountSelectedEvent` больше не доступны. + +#### Gradle + +```diff + dependencies { +- debugImplementation("com.redmadrobot.debug:plugin-accounts:") + } +``` + +#### Инициализация + +```diff + DebugPanel.initialize( + application = this, + plugins = listOf( +- AccountsPlugin( +- preInstalledAccounts = listOf( +- DebugAccount(login = "user", password = "pass") +- ), +- debugAuthenticator = UserAuthenticator() +- ), + ServersPlugin(/*...*/), + ) + ) +``` + +#### Подписка на события + +```diff + DebugPanel.subscribeToEvents(lifecycleOwner = this) { event -> + when (event) { +- is AccountSelectedEvent -> { /* ... */ } + is ServerSelectedEvent -> { /* ... */ } + } + } +``` + +### Удаление plugin-app-settings + +`AppSettingsPlugin` полностью удалён из библиотеки. Класс `AppSettingsPlugin` больше не доступен. + +#### Gradle + +```diff + dependencies { +- debugImplementation("com.redmadrobot.debug:plugin-app-settings:") + } +``` + +#### Инициализация + +```diff + DebugPanel.initialize( + application = this, + plugins = listOf( +- AppSettingsPlugin( +- sharedPreferences = listOf(primarySharedPreferences) +- ), + ServersPlugin(/*...*/), + ) + ) +``` + +### Удаление DebugPanelConfig и shaker mode + +Класс `DebugPanelConfig` удалён. Параметр `config` убран из `DebugPanel.initialize()`. Открытие панели по встряхиванию устройства больше не поддерживается. + +```diff + DebugPanel.initialize( + application = this, +- config = DebugPanelConfig(shakerMode = false), + plugins = listOf(/*...*/) + ) +``` + +### Миграция с DebugStage на DebugServer + +`DebugStage` удалён из `plugin-servers`. +Концепция «стейджей» с маппингом нескольких хостов больше не поддерживается — используйте `DebugServer` с единственным URL. + +#### Инициализация плагина + +```diff +- ServersPlugin( +- preInstalledServers = listOf( +- DebugServer(name = "Production", url = "https://prod.example.com"), +- DebugStage( +- name = "Staging", +- hosts = mapOf( +- "main" to "https://staging.example.com", +- "s3" to "https://s3.staging.example.com", +- ), +- isDefault = true +- ), +- ) +- ) + ++ ServersPlugin( ++ preInstalledServers = listOf( ++ DebugServer(name = "Production", url = "https://prod.example.com"), ++ DebugServer(name = "Staging", url = "https://staging.example.com", isDefault = true), ++ ) ++ ) +``` + +#### OkHttp interceptor + +```diff +- import com.redmadrobot.debug.plugin.servers.interceptor.DebugStageInterceptor ++ import com.redmadrobot.debug.plugin.servers.interceptor.DebugServerInterceptor + + OkHttpClient.Builder() +- .addInterceptor(DebugStageInterceptor("main")) ++ .addInterceptor(DebugServerInterceptor()) + .build() +``` + +```diff +- DebugStageInterceptor("main").modifyRequest { request, stage -> +- if (stage.name == "Staging") request.newBuilder().addHeader("Authorization", "token").build() +- else request +- } + ++ DebugServerInterceptor().modifyRequest { request, server -> ++ if (server.name == "Staging") request.newBuilder().addHeader("Authorization", "token").build() ++ else request ++ } +``` + +#### Удалённые API + +```diff +- ServersPlugin.getSelectedStage() +- ServersPlugin.getDefaultStage() +``` + +Если необходимо получить текущий выбранный сервер программно, используйте `ServersPlugin.getSelectedServer()`. + ## Миграция на версию 0.9.0 ### Изменения Maven-координатов библиотек