diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a77195e..664b4fef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,17 @@ ### Changes +* Добавлена валидация публичного ABI публикуемых модулей: слепок каждого модуля хранится в `api/<модуль>.api`, таск `apiCheck` входит в `check`, слепки обновляются командой `./gradlew apiDump`. Объявления, помеченные `@DebugPanelInternal`, в слепок не попадают. См. [plugin development](docs/plugin_development.md). +* Добавлена валидация полноты `panel-no-op`: таск `checkNoopApi` проверяет, что модуль покрывает весь публичный API `panel-core` и плагинов. +* **Breaking changes:** Приведены в соответствие с оригиналом no-op объявления: `DebugEvent` перенесён из `com.redmadrobot.debug.core.internal` в `com.redmadrobot.debug.core`, `AboutAppAction` и `AboutAppInfo` — в `com.redmadrobot.debug.plugin.aboutapp.model`. См. [migration guide](docs/migration_guide.md). +* В `panel-no-op` добавлены отсутствовавшие `DebugPanel.isInitialized`, `AboutAppInfo.id`, `AboutAppAction.Event.debugEvent`, `ServersPlugin.getSelectedServer()` и `ServersPlugin.getDefaultServer()`; удалён `DebugPanel.showPanel(FragmentManager)`, которого нет в `panel-core`. +* Обновлён каталог версий зависимостей (2026.07.10 → 2026.07.31). +* Gradle обновлён с 9.4.1 до 9.6.1. + +## [1.3.0] (2026-07-30) + +### Changes + * **Breaking changes:** `plugin-konfeature` переведён на публичную библиотеку [`konfeature-ui`][konfeature-ui]. Собственная реализация экрана, `ViewModel`, диалога редактирования и `JsonConverter` удалены — UI, состояние и хранение переопределений теперь предоставляет `konfeature-ui`. См. [migration guide](docs/migration_guide.md). * **Breaking changes:** Удалён `KonfeatureDebugPanelInterceptor`. Вместо него используется `KonfeatureDebugPanelConfig`, который объединяет хранилище переопределений (DataStore) и интерцептор. Создайте конфиг через `KonfeatureDebugPanelConfig.create(context)`, подключите его к `Konfeature` через `applyDebugPanelConfig(config)` и передайте тот же конфиг в `KonfeaturePlugin(konfeature, config)`. * **Breaking changes:** Изменена сигнатура конструктора `KonfeaturePlugin`: параметр `debugPanelInterceptor` заменён на `config: KonfeatureDebugPanelConfig`. diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index d3f0c122..a3af5afb 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -24,7 +24,7 @@ dependencies { implementation(stack.kotlin.composeCompiler.gradlePlugin) implementation(stack.detekt.gradlePlugin) implementation(stack.android.tools.build.gradle) - + implementation(stack.kotlinx.binaryCompatibilityValidator) // Hack-around to access version catalogs inside precompiled script plugins // See: https://github.com/gradle/gradle/issues/15383#issuecomment-779893192 implementation(files(androidx.javaClass.superclass.protectionDomain.codeSource.location)) diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts index 64d47418..9e6a5d58 100644 --- a/buildSrc/settings.gradle.kts +++ b/buildSrc/settings.gradle.kts @@ -30,7 +30,7 @@ dependencyResolutionManagement { } versionCatalogs { - val version = "2026.07.10" // Keep it in sync with root settings.gradle.kts + val version = "2026.07.31" // Keep it in sync with root settings.gradle.kts create("rmr") { from("com.redmadrobot.versions:versions-redmadrobot:$version") } diff --git a/buildSrc/src/main/kotlin/convention.abi.validation.gradle.kts b/buildSrc/src/main/kotlin/convention.abi.validation.gradle.kts new file mode 100644 index 00000000..82ab61df --- /dev/null +++ b/buildSrc/src/main/kotlin/convention.abi.validation.gradle.kts @@ -0,0 +1,64 @@ +import internal.Versions +import internal.stack +import kotlinx.validation.KotlinApiBuildTask +import kotlinx.validation.KotlinApiCompareTask +import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile + +/* + * Public ABI validation for Android library modules. + * + * The reference dump lives in `/api/.api` and is verified by `check`. + * Run `./gradlew apiDump` to update dumps after an intentional API change. + * + * Note: the ABI validation built into the Kotlin Gradle plugin (`kotlin { abiValidation { } }`) + * cannot be used here. KGP registers its setup actions only from `org.jetbrains.kotlin.android`, + * and since AGP 9 provides Kotlin support itself that plugin must not be applied — so the DSL is + * present but inert. The tasks are wired manually instead; the dump format is identical, so the + * files stay valid once the built-in validation becomes usable. + */ + +val abiTools = configurations.dependencyScope("abiTools") +val abiToolsClasspath = configurations.resolvable("abiToolsClasspath") { + extendsFrom(abiTools.get()) +} + +dependencies { + add(abiTools.name, "org.ow2.asm:asm:${Versions.ASM}") + add(abiTools.name, "org.ow2.asm:asm-tree:${Versions.ASM}") + add(abiTools.name, "org.jetbrains.kotlin:kotlin-metadata-jvm:${stack.versions.kotlin.get()}") +} + +val apiFileName = "${project.name}.api" +val referenceApiDir = layout.projectDirectory.dir("api") +// Taken from the compile tasks rather than from `kotlin.target.compilations`: with AGP's built-in +// Kotlin support the compilation outputs are not populated, so the collection would come out empty. +val releaseClasses = files( + provider { tasks.named("compileReleaseKotlin").flatMap { it.destinationDirectory } }, + provider { tasks.named("compileReleaseJavaWithJavac").flatMap { it.destinationDirectory } }, +) + +val apiBuild = tasks.register("apiBuild") { + description = "Dumps the public ABI of the 'release' variant into the build directory." + runtimeClasspath.from(abiToolsClasspath) + inputClassesDirs.from(releaseClasses) + outputApiFile.set(layout.buildDirectory.file("api/$apiFileName")) + nonPublicMarkers.add("com.redmadrobot.debug.core.annotation.DebugPanelInternal") +} + +val apiCheck = tasks.register("apiCheck") { + description = "Checks that the public ABI matches the reference dump in the 'api' directory." + group = LifecycleBasePlugin.VERIFICATION_GROUP + projectApiFile.set(referenceApiDir.file(apiFileName)) + generatedApiFile.set(apiBuild.flatMap { it.outputApiFile }) +} + +tasks.register("apiDump") { + description = "Overwrites the reference ABI dump with the ABI of the current code." + group = LifecycleBasePlugin.VERIFICATION_GROUP + from(apiBuild.flatMap { it.outputApiFile }) + into(referenceApiDir) +} + +tasks.named(LifecycleBasePlugin.CHECK_TASK_NAME) { + dependsOn(apiCheck) +} diff --git a/buildSrc/src/main/kotlin/convention.debug.panel.plugin.gradle.kts b/buildSrc/src/main/kotlin/convention.debug.panel.plugin.gradle.kts index 167109f4..1bf2a789 100644 --- a/buildSrc/src/main/kotlin/convention.debug.panel.plugin.gradle.kts +++ b/buildSrc/src/main/kotlin/convention.debug.panel.plugin.gradle.kts @@ -6,6 +6,7 @@ plugins { id("convention-publish") id("convention.compose") id("convention.detekt") + id("convention.abi.validation") } android { diff --git a/buildSrc/src/main/kotlin/internal/CheckNoopApiTask.kt b/buildSrc/src/main/kotlin/internal/CheckNoopApiTask.kt new file mode 100644 index 00000000..74e311a9 --- /dev/null +++ b/buildSrc/src/main/kotlin/internal/CheckNoopApiTask.kt @@ -0,0 +1,246 @@ +package internal + +import org.gradle.api.DefaultTask +import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity +import org.gradle.api.tasks.TaskAction +import java.io.File + +/** + * Verifies that the no-op module stays a drop-in replacement for the real ones: every public + * declaration of the mirrored modules (`panel-core` and the plugins) must be repeated in the no-op + * module under the same fully qualified name and with the same members, so that swapping + * `debugImplementation` for `releaseImplementation` keeps the consumer code compiling. + * + * The comparison is made on the ABI dumps produced by `convention.abi.validation`, so any change + * of the public API fails the build until it is mirrored in the no-op module (or hidden from the + * dump by making the declaration `internal`). + * + * The panel's own machinery is not part of the contract and is skipped: declarations from the + * [INTERNAL_TYPE_PREFIXES] packages, from `internal`/`ui` packages, and every member that mentions + * such a type, is Compose-related, or is a `kotlinx.serialization` synthetic. That is exactly the + * surface a plugin implementation uses and an application does not. + */ +abstract class CheckNoopApiTask : DefaultTask() { + + /** ABI dump of the no-op module. */ + @get:InputFile + @get:PathSensitive(PathSensitivity.NONE) + abstract val noopDump: RegularFileProperty + + /** ABI dumps of the modules the no-op module must mirror. */ + @get:InputFiles + @get:PathSensitive(PathSensitivity.NONE) + abstract val mirroredDumps: ConfigurableFileCollection + + @TaskAction + fun check() { + val dumps = mirroredDumps.files.sortedBy(File::getPath) + check(dumps.isNotEmpty()) { "No ABI dumps to compare the no-op module against." } + val absentDumps = dumps.filterNot(File::isFile) + check(absentDumps.isEmpty()) { + "ABI dumps are not generated yet, run './gradlew apiDump':\n" + + absentDumps.joinToString("\n") { " $it" } + } + + val noopModule = noopDump.get().asFile.nameWithoutExtension + val expected = declarations(dumps.flatMap(::parse), dropInternal = true) + val actual = declarations(parse(noopDump.get().asFile), dropInternal = false) + + val problems = buildList { + (expected - actual.keys).values.forEach { declaration -> + add("Missing in $noopModule:\n" + render(declaration).prependIndent(" ")) + } + (actual - expected.keys).values.forEach { declaration -> + add("Not part of the mirrored public API:\n" + render(declaration).prependIndent(" ")) + } + expected.keys.intersect(actual.keys).forEach { name -> + diff(expected.getValue(name), actual.getValue(name), noopModule)?.let(::add) + } + } + if (problems.isEmpty()) return + + error( + buildString { + appendLine("$noopModule does not cover the public API of the mirrored modules.") + appendLine() + appendLine( + "Mirror the declarations below in $noopModule keeping the original package, " + + "or make them `internal` if they are not meant for library consumers. " + + "Run './gradlew apiDump' afterwards to update the ABI dumps." + ) + appendLine() + append(problems.joinToString("\n\n")) + }, + ) + } + + private companion object { + + /** + * Types that are the panel's own machinery, not part of the no-op contract: `panel-core` + * packages meant for plugin implementations, Compose, and serialization synthetics. + */ + val INTERNAL_TYPE_PREFIXES = listOf( + "com/redmadrobot/debug/core/annotation/", + "com/redmadrobot/debug/core/extension/", + "com/redmadrobot/debug/core/inapp/", + "com/redmadrobot/debug/core/plugin/", + "com/redmadrobot/debug/uikit/", + "androidx/compose/", + "kotlinx/serialization/", + ) + + /** Package segments marking declarations internal to the panel, e.g. plugin screens. */ + val INTERNAL_PACKAGE_SEGMENTS = setOf("internal", "ui") + + /** Keywords a member line starts with, right after its modifiers. */ + val MEMBER_KEYWORDS = listOf("fun ", "field ") + + /** Matches a class reference inside a JVM descriptor, e.g. `Lcom/redmadrobot/debug/Foo;`. */ + val TYPE_REGEX = Regex("""L([\w/$]+);""") + + /** Synthetic field added by the Compose compiler; the no-op module has no Compose. */ + const val STABLE_FIELD = " field \$stable " + + fun isInternal(type: String): Boolean { + return INTERNAL_TYPE_PREFIXES.any(type::startsWith) || + type.split('/').dropLast(1).any { it in INTERNAL_PACKAGE_SEGMENTS } + } + + /** Member without its modifiers, so that an override matches the declaration it overrides. */ + fun signature(member: String): String { + val keyword = MEMBER_KEYWORDS.firstOrNull { it in member } ?: return member + return member.substring(member.indexOf(keyword)) + } + + fun isInternal(member: String, dropped: Set): Boolean { + return STABLE_FIELD in member || + TYPE_REGEX.findAll(member).any { it.groupValues[1].let { type -> isInternal(type) || type in dropped } } + } + + /** + * Splits an ABI dump into declarations: a header line plus its indented members. + * Compiler-generated (`synthetic`) classes are skipped, as are the members that are not + * part of the no-op contract. + */ + fun parse(file: File): List { + return file.readLines() + .filterNot { it.isBlank() || it.startsWith("//") } + .fold(mutableListOf>()) { blocks, line -> + if (line.first().isWhitespace()) blocks.last() += line.trim() else blocks += mutableListOf(line) + blocks + } + .mapNotNull(::parseDeclaration) + } + + fun parseDeclaration(block: List): Declaration? { + val header = block.first().removeSuffix(" {") + val modifiers = header.substringBefore("class ").trim() + if ("synthetic" in modifiers.split(' ')) return null + + val declaration = header.substringAfter("class ") + val name = declaration.substringBefore(" : ") + val supertypes = declaration.substringAfter(" : ", missingDelimiterValue = "") + .split(", ") + .filter(String::isNotEmpty) + val publicSupertypes = supertypes.filterNot(::isInternal).sorted() + + return Declaration( + name = name, + header = "$modifiers class $name" + + if (publicSupertypes.isEmpty()) "" else publicSupertypes.joinToString(", ", prefix = " : "), + supertypes = supertypes, + members = block.drop(1).filterNot { isInternal(it, dropped = emptySet()) }.toSet(), + ) + } + + /** + * Members a declaration only has because it implements a panel-internal supertype, e.g. + * `Plugin.getName()`. They are a part of the plugin machinery rather than of the API the + * application calls, so the no-op module does not repeat them. Constructors are kept: + * they are not inherited. + */ + fun inheritedFromInternal(declaration: Declaration, index: Map): Set { + val inherited = mutableSetOf() + + fun collect(name: String) { + val supertype = index[name] ?: return + supertype.members + .filterNot { "fun " in it } + .mapTo(inherited, ::signature) + supertype.supertypes.forEach(::collect) + } + + declaration.supertypes.filter(::isInternal).forEach(::collect) + return inherited + } + + /** + * Indexes declarations by name, dropping the ones the no-op module does not have to + * mirror. A companion left without members (it only held a serializer, for example) is + * dropped together with the field referencing it. + */ + fun declarations(all: List, dropInternal: Boolean): Map { + val index = all.associateBy(Declaration::name) + val kept = if (dropInternal) all.filterNot { isInternal(it.name) } else all + val emptyCompanions = kept + .filter { it.name.endsWith("\$Companion") && it.members.isEmpty() } + .mapTo(mutableSetOf()) { it.name } + + return kept + .filterNot { it.name in emptyCompanions } + .associateBy( + keySelector = Declaration::name, + valueTransform = { declaration -> + val inherited = inheritedFromInternal(declaration, index) + declaration.copy( + members = declaration.members + .filterNot { signature(it) in inherited || isInternal(it, emptyCompanions) } + .toSet(), + ) + }, + ) + .toSortedMap() + } + + fun diff(expected: Declaration, actual: Declaration, noopModule: String): String? { + val missingMembers = expected.members - actual.members + val extraMembers = actual.members - expected.members + if (expected.header == actual.header && missingMembers.isEmpty() && extraMembers.isEmpty()) return null + + return buildString { + appendLine("${expected.name} differs:") + if (expected.header != actual.header) { + appendLine(" declaration:") + appendLine(" expected: ${expected.header}") + appendLine(" actual: ${actual.header}") + } + if (missingMembers.isNotEmpty()) { + appendLine(" missing in $noopModule:") + missingMembers.sorted().forEach { appendLine(" $it") } + } + if (extraMembers.isNotEmpty()) { + appendLine(" not part of the mirrored public API:") + extraMembers.sorted().forEach { appendLine(" $it") } + } + }.trimEnd() + } + + fun render(declaration: Declaration): String { + val members = declaration.members.sorted().joinToString(separator = "") { "\n\t$it" } + return "${declaration.header} {$members\n}" + } + } + + private data class Declaration( + val name: String, + val header: String, + val supertypes: List, + val members: Set, + ) +} diff --git a/buildSrc/src/main/kotlin/internal/Versions.kt b/buildSrc/src/main/kotlin/internal/Versions.kt index 8bb0c5a4..d86239f5 100644 --- a/buildSrc/src/main/kotlin/internal/Versions.kt +++ b/buildSrc/src/main/kotlin/internal/Versions.kt @@ -4,4 +4,7 @@ internal object Versions { const val MIN_SDK = 23 const val TARGET_SDK = 36 const val COMPILE_SDK = 37 + + /** Bytecode reader used by binary-compatibility-validator workers. Keep in sync with the plugin's own version. */ + const val ASM = "9.6" } diff --git a/docs/migration_guide.md b/docs/migration_guide.md index ded76ca0..a116dfb1 100644 --- a/docs/migration_guide.md +++ b/docs/migration_guide.md @@ -1,5 +1,79 @@ # Миграция +## Миграция на версию 1.4.0 + +### Приведение panel-no-op в соответствие с публичным API + +Изменения касаются только `panel-no-op` — модуля, который подключается как `releaseImplementation`. +Публичный API `panel-core` и плагинов не менялся, поэтому если в приложении нет кода, компилируемого +только для release (отдельные source set'ы, `release`-флейворы), миграция не требуется. + +Полнота no-op реализации теперь проверяется на сборке — см. [Разработка плагинов][plugin-development]. +Ранее объявления в `panel-no-op` расходились с оригиналами по пакетам и сигнатурам; расхождения +устранены, поэтому часть импортов и вызовов в release-коде нужно поправить. + +#### Пакеты объявлений + +```diff +- import com.redmadrobot.debug.core.internal.DebugEvent ++ import com.redmadrobot.debug.core.DebugEvent + +- import com.redmadrobot.debug.plugin.aboutapp.AboutAppAction ++ import com.redmadrobot.debug.plugin.aboutapp.model.AboutAppAction + +- import com.redmadrobot.debug.plugin.aboutapp.AboutAppInfo ++ import com.redmadrobot.debug.plugin.aboutapp.model.AboutAppInfo +``` + +#### AboutAppAction.Event + +Добавлен обязательный параметр `debugEvent` — событие, которое публикуется в шину при нажатии. + +```diff + AboutAppAction.Event( + title = "Сбросить кэш", ++ debugEvent = ResetCacheEvent, + ) +``` + +#### DebugPanel.showPanel(FragmentManager) + +Перегрузка удалена: в `panel-core` её нет с версии 0.9.0. + +```diff +- DebugPanel.showPanel(supportFragmentManager) ++ DebugPanel.showPanel(this) +``` + +#### ServersPlugin + +Тип `preInstalledServers` уточнён с `List` до `List`. + +```diff +- ServersPlugin(preInstalledServers = listOf(/*...*/)) ++ ServersPlugin(preInstalledServers = listOf(DebugServer(/*...*/))) +``` + +#### Объявления, добавленные в panel-no-op + +В no-op появились `DebugPanel.isInitialized`, `AboutAppInfo.id`, +`ServersPlugin.getSelectedServer()` и `ServersPlugin.getDefaultServer()` — раньше код, +использующий их, не компилировался в release-сборке. + +> `ServersPlugin.getSelectedServer()` и `ServersPlugin.getDefaultServer()` в release-сборке +> **всегда бросают** `IllegalArgumentException`: панели нет, а значит нет и выбранного сервера. +> Раньше такой вызов не компилировался, теперь он собирается и падает в рантайме. +> Если приложение берёт URL из панели, разведите источники по source set'ам или проверяйте +> `DebugPanel.isInitialized`: + +```kotlin +val baseUrl = if (DebugPanel.isInitialized) { + ServersPlugin.getSelectedServer().url +} else { + BuildConfig.BASE_URL +} +``` + ## Миграция на версию 1.3.0 ### Переход plugin-konfeature на библиотеку konfeature-ui @@ -297,4 +371,5 @@ VariablePlugin позволял изменять значения перемен [readme]: /README.md -[konfeature]: https://github.com/RedMadRobot/Konfeature \ No newline at end of file +[konfeature]: https://github.com/RedMadRobot/Konfeature +[plugin-development]: plugin_development.md \ No newline at end of file diff --git a/docs/plugin_development.md b/docs/plugin_development.md index 7287de6d..f9ba9b6d 100644 --- a/docs/plugin_development.md +++ b/docs/plugin_development.md @@ -190,6 +190,40 @@ releaseImplementation(project(":panel-no-op")) Подробнее о подходе: [No-op versions for dev tools](https://medium.com/@orhanobut/no-op-versions-for-dev-tools-b0a865934398) +Полнота no-op реализаций проверяется автоматически — см. раздел ниже. + +## Валидация публичного API + +Каждый модуль плагина хранит слепок своего публичного ABI в файле `api/<имя-модуля>.api`. +Таск `apiCheck` сравнивает текущий код со слепком и входит в `check`, поэтому несогласованное +изменение публичного API упадёт на CI. + +После намеренного изменения API обновите слепки и закоммитьте их вместе с кодом: + +```bash +./gradlew apiDump +``` + +Объявления, помеченные `@DebugPanelInternal`, в слепок не попадают. + +### Проверка покрытия no-op модуля + +Таск `checkNoopApi` (модуль `panel-no-op`, входит в `check`) сравнивает слепки и требует, чтобы +каждое публичное объявление `panel-core` и плагинов было продублировано в `panel-no-op` с тем же +полным именем и тем же набором членов. Поэтому новый публичный API уронит сборку, пока для него +не появится no-op реализация. + +Не входят в контракт и в сравнении не участвуют: + +* внутренняя механика панели — пакеты `core.annotation`, `core.extension`, `core.inapp`, + `core.plugin`, `panel-ui-kit`, а также любые пакеты с сегментом `internal` или `ui`; +* члены, которые упоминают такие типы, Compose или `kotlinx.serialization`, и члены, унаследованные + от внутренних супертипов (например, `Plugin.getName()`) — их реализуют только плагины, не приложение. + +Если объявление не предназначено для клиентского приложения, сделайте его `internal` или пометьте +`@DebugPanelInternal` — тогда оно не попадёт в слепок и не потребует no-op реализации. Списки +исключений описаны в [CheckNoopApiTask](../buildSrc/src/main/kotlin/internal/CheckNoopApiTask.kt). + ## Публикация Публикация новых плагинов проходит через создание **Pull Request** в ветку **main**. diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e6441136..b1b8ef56 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c61a118f..04c1e1e3 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,9 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip networkTimeout=10000 -validateDistributionUrl=true +retries=0 +retryBackOffMs=500 +validateDistributionUrl=false zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 1aa94a42..249efbb0 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,10 +15,12 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # -# Gradle start up script for POSIX generated by Gradle. +# gradlew start up script for POSIX generated by Gradle. # # Important for running: # @@ -27,7 +29,7 @@ # bash, then to run this script, type that shell name before the whole # command line, like: # -# ksh Gradle +# ksh gradlew # # Busybox and similar reduced shells will NOT work, because this script # requires all of these POSIX shell features: @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 25da30db..a51ec4f5 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,16 +13,18 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem -@rem Gradle startup script for Windows +@rem gradlew startup script for Windows @rem @rem ########################################################################## -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal +@rem Set local scope for the variables, and ensure extensions are enabled +setlocal EnableExtensions set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. @@ -49,7 +51,7 @@ echo. 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo location of your Java installation. 1>&2 -goto fail +"%COMSPEC%" /c exit 1 :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% @@ -63,30 +65,18 @@ echo. 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo location of your Java installation. 1>&2 -goto fail +"%COMSPEC%" /c exit 1 :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% -:mainEnd -if "%OS%"=="Windows_NT" endlocal +@rem Execute gradlew +@rem endlocal doesn't take effect until after the line is parsed and variables are expanded +@rem which allows us to clear the local environment before executing the java command +endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel -:omega +:exitWithErrorLevel +@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts +"%COMSPEC%" /c exit %ERRORLEVEL% diff --git a/panel-core/api/panel-core.api b/panel-core/api/panel-core.api new file mode 100644 index 00000000..69dee3fe --- /dev/null +++ b/panel-core/api/panel-core.api @@ -0,0 +1,55 @@ +public abstract interface class com/redmadrobot/debug/core/DebugEvent { +} + +public final class com/redmadrobot/debug/core/DebugPanel { + public static final field $stable I + public static final field INSTANCE Lcom/redmadrobot/debug/core/DebugPanel; + public final fun initialize (Landroid/app/Application;Ljava/util/List;)V + public final fun isInitialized ()Z + public final fun observeEvents ()Lkotlinx/coroutines/flow/Flow; + public final fun showPanel (Landroid/app/Activity;)V + public final fun subscribeToEvents (Landroidx/lifecycle/LifecycleOwner;Lkotlin/jvm/functions/Function1;)V +} + +public abstract interface annotation class com/redmadrobot/debug/core/annotation/DebugPanelInternal : java/lang/annotation/Annotation { +} + +public abstract interface class com/redmadrobot/debug/core/data/DebugDataProvider { + public abstract fun provideData ()Ljava/lang/Object; +} + +public final class com/redmadrobot/debug/core/extension/CoroutinesExtensionKt { + public static final fun safeLaunch (Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;)V + public static final fun safeLaunch (Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;)V +} + +public final class com/redmadrobot/debug/core/extension/PluginsExtKt { + public static final fun getPlugin (Ljava/lang/String;)Lcom/redmadrobot/debug/core/plugin/Plugin; +} + +public final class com/redmadrobot/debug/core/inapp/compose/ComposableSingletons$DebugPanelScreenKt { + public static final field INSTANCE Lcom/redmadrobot/debug/core/inapp/compose/ComposableSingletons$DebugPanelScreenKt; + public fun ()V + public final fun getLambda$-1186943481$panel_core ()Lkotlin/jvm/functions/Function2; + public final fun getLambda$1864401833$panel_core ()Lkotlin/jvm/functions/Function2; +} + +public final class com/redmadrobot/debug/core/inapp/compose/DebugPanelScreenKt { + public static final fun DebugPanelScreen (Lcom/redmadrobot/debug/uikit/theme/model/ThemeMode;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V +} + +public final class com/redmadrobot/debug/core/internal/PluginDependencyContainer$Empty : com/redmadrobot/debug/core/internal/PluginDependencyContainer { + public static final field $stable I + public static final field INSTANCE Lcom/redmadrobot/debug/core/internal/PluginDependencyContainer$Empty; +} + +public abstract class com/redmadrobot/debug/core/plugin/Plugin { + public static final field $stable I + public fun ()V + public fun content (Landroidx/compose/runtime/Composer;I)V + public final fun getContainer ()Ljava/lang/Object; + public abstract fun getName ()Ljava/lang/String; + public abstract fun getPluginContainer (Lcom/redmadrobot/debug/core/internal/CommonContainer;)Lcom/redmadrobot/debug/core/internal/PluginDependencyContainer; + public final fun pushEvent (Lcom/redmadrobot/debug/core/DebugEvent;)V +} + diff --git a/panel-core/build.gradle.kts b/panel-core/build.gradle.kts index c9ac12e8..465d8c80 100644 --- a/panel-core/build.gradle.kts +++ b/panel-core/build.gradle.kts @@ -3,6 +3,7 @@ plugins { id("convention.compose") id("convention-publish") id("convention.detekt") + id("convention.abi.validation") alias(stack.plugins.kotlin.serialization) } diff --git a/panel-no-op/api/panel-no-op.api b/panel-no-op/api/panel-no-op.api new file mode 100644 index 00000000..ddff282b --- /dev/null +++ b/panel-no-op/api/panel-no-op.api @@ -0,0 +1,121 @@ +public abstract interface class com/redmadrobot/debug/core/DebugEvent { +} + +public final class com/redmadrobot/debug/core/DebugPanel { + public static final field INSTANCE Lcom/redmadrobot/debug/core/DebugPanel; + public final fun initialize (Landroid/app/Application;Ljava/util/List;)V + public final fun isInitialized ()Z + public final fun observeEvents ()Lkotlinx/coroutines/flow/Flow; + public final fun showPanel (Landroid/app/Activity;)V + public final fun subscribeToEvents (Landroidx/lifecycle/LifecycleOwner;Lkotlin/jvm/functions/Function1;)V +} + +public abstract interface class com/redmadrobot/debug/core/data/DebugDataProvider { + public abstract fun provideData ()Ljava/lang/Object; +} + +public final class com/redmadrobot/debug/plugin/aboutapp/AboutAppPlugin { + public fun (Ljava/util/List;Ljava/util/List;)V + public synthetic fun (Ljava/util/List;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V +} + +public abstract interface class com/redmadrobot/debug/plugin/aboutapp/model/AboutAppAction { + public abstract fun getId ()Ljava/lang/String; + public abstract fun getTitle ()Ljava/lang/String; +} + +public final class com/redmadrobot/debug/plugin/aboutapp/model/AboutAppAction$Direct : com/redmadrobot/debug/plugin/aboutapp/model/AboutAppAction { + public fun (Ljava/lang/String;Lkotlin/jvm/functions/Function1;Ljava/lang/String;)V + public synthetic fun (Ljava/lang/String;Lkotlin/jvm/functions/Function1;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun getId ()Ljava/lang/String; + public final fun getOnClick ()Lkotlin/jvm/functions/Function1; + public fun getTitle ()Ljava/lang/String; +} + +public final class com/redmadrobot/debug/plugin/aboutapp/model/AboutAppAction$Event : com/redmadrobot/debug/plugin/aboutapp/model/AboutAppAction { + public fun (Ljava/lang/String;Lcom/redmadrobot/debug/core/DebugEvent;Ljava/lang/String;)V + public synthetic fun (Ljava/lang/String;Lcom/redmadrobot/debug/core/DebugEvent;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun getDebugEvent ()Lcom/redmadrobot/debug/core/DebugEvent; + public fun getId ()Ljava/lang/String; + public fun getTitle ()Ljava/lang/String; +} + +public final class com/redmadrobot/debug/plugin/aboutapp/model/AboutAppInfo { + public fun (Ljava/lang/String;Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;Ljava/lang/String;)Lcom/redmadrobot/debug/plugin/aboutapp/model/AboutAppInfo; + public static synthetic fun copy$default (Lcom/redmadrobot/debug/plugin/aboutapp/model/AboutAppInfo;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lcom/redmadrobot/debug/plugin/aboutapp/model/AboutAppInfo; + public fun equals (Ljava/lang/Object;)Z + public final fun getId ()Ljava/lang/String; + public final fun getTitle ()Ljava/lang/String; + public final fun getValue ()Ljava/lang/String; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class com/redmadrobot/debug/plugin/konfeature/KonfeatureDebugPanelConfig { + public static final field Companion Lcom/redmadrobot/debug/plugin/konfeature/KonfeatureDebugPanelConfig$Companion; + public static final field DEFAULT_PATH Ljava/lang/String; + public synthetic fun (Lcom/redmadrobot/konfeature/ui/KonfeatureDebugStore;Lcom/redmadrobot/konfeature/ui/KonfeatureDebugInterceptor;Lkotlin/jvm/internal/DefaultConstructorMarker;)V +} + +public final class com/redmadrobot/debug/plugin/konfeature/KonfeatureDebugPanelConfig$Companion { + public final fun create (Landroid/content/Context;Ljava/lang/String;Lcom/redmadrobot/konfeature/Logger;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static synthetic fun create$default (Lcom/redmadrobot/debug/plugin/konfeature/KonfeatureDebugPanelConfig$Companion;Landroid/content/Context;Ljava/lang/String;Lcom/redmadrobot/konfeature/Logger;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; +} + +public final class com/redmadrobot/debug/plugin/konfeature/KonfeatureDebugPanelConfigKt { + public static final fun applyDebugPanelConfig (Lcom/redmadrobot/konfeature/builder/KonfeatureBuilder;Lcom/redmadrobot/debug/plugin/konfeature/KonfeatureDebugPanelConfig;)Lcom/redmadrobot/konfeature/builder/KonfeatureBuilder; +} + +public final class com/redmadrobot/debug/plugin/konfeature/KonfeaturePlugin { + public fun (Lcom/redmadrobot/konfeature/Konfeature;Lcom/redmadrobot/debug/plugin/konfeature/KonfeatureDebugPanelConfig;)V +} + +public final class com/redmadrobot/debug/plugin/servers/ServerSelectedEvent : com/redmadrobot/debug/core/DebugEvent { + public fun (Lcom/redmadrobot/debug/plugin/servers/data/model/DebugServer;)V + public final fun component1 ()Lcom/redmadrobot/debug/plugin/servers/data/model/DebugServer; + public final fun copy (Lcom/redmadrobot/debug/plugin/servers/data/model/DebugServer;)Lcom/redmadrobot/debug/plugin/servers/ServerSelectedEvent; + public static synthetic fun copy$default (Lcom/redmadrobot/debug/plugin/servers/ServerSelectedEvent;Lcom/redmadrobot/debug/plugin/servers/data/model/DebugServer;ILjava/lang/Object;)Lcom/redmadrobot/debug/plugin/servers/ServerSelectedEvent; + public fun equals (Ljava/lang/Object;)Z + public final fun getDebugServer ()Lcom/redmadrobot/debug/plugin/servers/data/model/DebugServer; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class com/redmadrobot/debug/plugin/servers/ServersPlugin { + public static final field Companion Lcom/redmadrobot/debug/plugin/servers/ServersPlugin$Companion; + public fun ()V + public fun (Lcom/redmadrobot/debug/core/data/DebugDataProvider;)V + public fun (Ljava/util/List;)V + public synthetic fun (Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V +} + +public final class com/redmadrobot/debug/plugin/servers/ServersPlugin$Companion { + public final fun getDefaultServer ()Lcom/redmadrobot/debug/plugin/servers/data/model/DebugServer; + public final fun getSelectedServer ()Lcom/redmadrobot/debug/plugin/servers/data/model/DebugServer; +} + +public final class com/redmadrobot/debug/plugin/servers/data/model/DebugServer { + public fun (Ljava/lang/String;Ljava/lang/String;Z)V + public synthetic fun (Ljava/lang/String;Ljava/lang/String;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Ljava/lang/String; + public final fun component3 ()Z + public final fun copy (Ljava/lang/String;Ljava/lang/String;Z)Lcom/redmadrobot/debug/plugin/servers/data/model/DebugServer; + public static synthetic fun copy$default (Lcom/redmadrobot/debug/plugin/servers/data/model/DebugServer;Ljava/lang/String;Ljava/lang/String;ZILjava/lang/Object;)Lcom/redmadrobot/debug/plugin/servers/data/model/DebugServer; + public fun equals (Ljava/lang/Object;)Z + public final fun getName ()Ljava/lang/String; + public final fun getUrl ()Ljava/lang/String; + public fun hashCode ()I + public final fun isDefault ()Z + public fun toString ()Ljava/lang/String; +} + +public final class com/redmadrobot/debug/plugin/servers/interceptor/DebugServerInterceptor : okhttp3/Interceptor { + public fun ()V + public fun intercept (Lokhttp3/Interceptor$Chain;)Lokhttp3/Response; + public final fun modifyRequest (Lkotlin/jvm/functions/Function2;)Lcom/redmadrobot/debug/plugin/servers/interceptor/DebugServerInterceptor; +} + diff --git a/panel-no-op/build.gradle.kts b/panel-no-op/build.gradle.kts index a199b667..c5fc3f86 100644 --- a/panel-no-op/build.gradle.kts +++ b/panel-no-op/build.gradle.kts @@ -1,7 +1,10 @@ +import internal.CheckNoopApiTask + plugins { id("com.android.library") id("convention-publish") id("convention.detekt") + id("convention.abi.validation") } description = "Debug panel no-op dependency module" @@ -34,6 +37,23 @@ android { namespace = "com.redmadrobot.debug.noop" } +// Modules whose public API this module replaces in release builds: every published module except +// the panel's own UI kit, which consumers do not depend on directly. +val notMirrored = setOf(project.name, "panel-ui-kit", "sample") +val mirroredModules = rootProject.subprojects + .filter { it.subprojects.isEmpty() && it.name !in notMirrored } + +val checkNoopApi = tasks.register("checkNoopApi") { + description = "Checks that ${project.name} covers the public API of the modules it replaces." + group = LifecycleBasePlugin.VERIFICATION_GROUP + noopDump.set(layout.projectDirectory.file("api/${project.name}.api")) + mirroredDumps.from(mirroredModules.map { it.layout.projectDirectory.file("api/${it.name}.api") }) +} + +tasks.named(LifecycleBasePlugin.CHECK_TASK_NAME) { + dependsOn(checkNoopApi) +} + dependencies { implementation(stack.kotlin.stdlib) implementation(androidx.appcompat) diff --git a/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/core/DebugEvent.kt b/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/core/DebugEvent.kt index 6ab28c18..64ab3403 100644 --- a/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/core/DebugEvent.kt +++ b/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/core/DebugEvent.kt @@ -1,4 +1,4 @@ -package com.redmadrobot.debug.core.internal +package com.redmadrobot.debug.core /** * No-op declaration of [DebugEvent] for release builds. diff --git a/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/core/DebugPanel.kt b/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/core/DebugPanel.kt index 7562bfee..48a22cd3 100644 --- a/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/core/DebugPanel.kt +++ b/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/core/DebugPanel.kt @@ -2,9 +2,7 @@ package com.redmadrobot.debug.core import android.app.Activity import android.app.Application -import androidx.fragment.app.FragmentManager import androidx.lifecycle.LifecycleOwner -import com.redmadrobot.debug.core.internal.DebugEvent import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.emptyFlow @@ -15,13 +13,14 @@ import kotlinx.coroutines.flow.emptyFlow */ @Suppress("UnusedParameter", "OptionalUnit") public object DebugPanel { + /** Always `false`: there is no panel to initialize in release builds. */ + public val isInitialized: Boolean get() = false + public fun initialize(application: Application, plugins: List): Unit = Unit public fun subscribeToEvents(lifecycleOwner: LifecycleOwner, onEvent: (DebugEvent) -> Unit): Unit = Unit public fun observeEvents(): Flow = emptyFlow() - public fun showPanel(fragmentManager: FragmentManager): Unit = Unit - public fun showPanel(activity: Activity): Unit = Unit } diff --git a/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/plugin/aboutapp/AboutAppAction.kt b/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/plugin/aboutapp/AboutAppAction.kt index ed62673f..cf0a4bc3 100644 --- a/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/plugin/aboutapp/AboutAppAction.kt +++ b/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/plugin/aboutapp/AboutAppAction.kt @@ -1,6 +1,7 @@ -package com.redmadrobot.debug.plugin.aboutapp +package com.redmadrobot.debug.plugin.aboutapp.model import android.content.Context +import com.redmadrobot.debug.core.DebugEvent import java.util.UUID /** @@ -19,6 +20,7 @@ public sealed interface AboutAppAction { public class Event( override val title: String, + public val debugEvent: DebugEvent, override val id: String = UUID.randomUUID().toString(), ) : AboutAppAction } diff --git a/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/plugin/aboutapp/AboutAppInfo.kt b/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/plugin/aboutapp/AboutAppInfo.kt index d20a0c9c..431e4ea8 100644 --- a/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/plugin/aboutapp/AboutAppInfo.kt +++ b/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/plugin/aboutapp/AboutAppInfo.kt @@ -1,9 +1,13 @@ -package com.redmadrobot.debug.plugin.aboutapp +package com.redmadrobot.debug.plugin.aboutapp.model + +import java.util.UUID /** * No-op declaration of [AboutAppInfo] for release builds. */ public data class AboutAppInfo( val title: String, - val value: String -) + val value: String, +) { + val id: String = UUID.randomUUID().toString() +} diff --git a/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/plugin/aboutapp/AboutAppPlugin.kt b/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/plugin/aboutapp/AboutAppPlugin.kt index 025773c2..cfb56255 100644 --- a/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/plugin/aboutapp/AboutAppPlugin.kt +++ b/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/plugin/aboutapp/AboutAppPlugin.kt @@ -1,5 +1,8 @@ package com.redmadrobot.debug.plugin.aboutapp +import com.redmadrobot.debug.plugin.aboutapp.model.AboutAppAction +import com.redmadrobot.debug.plugin.aboutapp.model.AboutAppInfo + /** * No-op implementation of [AboutAppPlugin] for release builds. * diff --git a/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/plugin/servers/ServerSelectedEvent.kt b/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/plugin/servers/ServerSelectedEvent.kt index 344eb79b..65a919d1 100644 --- a/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/plugin/servers/ServerSelectedEvent.kt +++ b/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/plugin/servers/ServerSelectedEvent.kt @@ -1,6 +1,6 @@ package com.redmadrobot.debug.plugin.servers -import com.redmadrobot.debug.core.internal.DebugEvent +import com.redmadrobot.debug.core.DebugEvent import com.redmadrobot.debug.plugin.servers.data.model.DebugServer /** diff --git a/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/plugin/servers/ServersPlugin.kt b/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/plugin/servers/ServersPlugin.kt index 084d92ef..134bbb26 100644 --- a/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/plugin/servers/ServersPlugin.kt +++ b/panel-no-op/src/main/kotlin/com/redmadrobot/debug/noop/plugin/servers/ServersPlugin.kt @@ -2,17 +2,42 @@ package com.redmadrobot.debug.plugin.servers import com.redmadrobot.debug.core.data.DebugDataProvider import com.redmadrobot.debug.plugin.servers.data.model.DebugServer -import java.util.Collections.emptyList /** * No-op implementation of [ServersPlugin] for release builds. * * Performs no actions; only mirrors the public constructor signatures. */ +@Suppress("UnusedPrivateProperty") public class ServersPlugin( - private val preInstalledServers: List = emptyList() + private val preInstalledServers: List = emptyList(), ) { - public constructor(debugDataProvider: DebugDataProvider>) : this( - preInstalledServers = debugDataProvider.provideData() + public constructor(preInstalledServers: DebugDataProvider>) : this( + preInstalledServers = preInstalledServers.provideData() ) + + public companion object { + /** + * Always throws: no plugin is registered in release builds. + * + * Mirrors the real implementation, which throws the same exception when [ServersPlugin] + * is not registered in the panel. Guard the call with `DebugPanel.isInitialized` or use + * the application's own configuration in release builds. + * + * @throws IllegalArgumentException always + */ + public fun getSelectedServer(): DebugServer = noPlugin() + + /** + * Always throws: no plugin is registered in release builds. + * + * @throws IllegalArgumentException always + * @see getSelectedServer + */ + public fun getDefaultServer(): DebugServer = noPlugin() + + private fun noPlugin(): Nothing { + throw IllegalArgumentException("ServersPlugin is not available in release builds") + } + } } diff --git a/panel-ui-kit/api/panel-ui-kit.api b/panel-ui-kit/api/panel-ui-kit.api new file mode 100644 index 00000000..dfe44245 --- /dev/null +++ b/panel-ui-kit/api/panel-ui-kit.api @@ -0,0 +1,297 @@ +public final class com/redmadrobot/debug/uikit/components/ComposableSingletons$PanelBottomSheetKt { + public static final field INSTANCE Lcom/redmadrobot/debug/uikit/components/ComposableSingletons$PanelBottomSheetKt; + public fun ()V + public final fun getLambda$-171560508$panel_ui_kit ()Lkotlin/jvm/functions/Function2; +} + +public final class com/redmadrobot/debug/uikit/components/ComposableSingletons$PanelSearchBarKt { + public static final field INSTANCE Lcom/redmadrobot/debug/uikit/components/ComposableSingletons$PanelSearchBarKt; + public fun ()V + public final fun getLambda$1650688964$panel_ui_kit ()Lkotlin/jvm/functions/Function2; +} + +public final class com/redmadrobot/debug/uikit/components/PanelBottomSheetKt { + public static final fun PanelBottomSheet (Ljava/lang/String;Lkotlin/jvm/functions/Function0;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;II)V +} + +public final class com/redmadrobot/debug/uikit/components/PanelDialogKt { + public static final fun PanelDialog (Ljava/lang/String;Lkotlin/jvm/functions/Function0;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;II)V +} + +public final class com/redmadrobot/debug/uikit/components/PanelSearchBarKt { + public static final fun PanelSearchBar (Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;II)V +} + +public final class com/redmadrobot/debug/uikit/components/PanelStyledTextFieldKt { + public static final fun PanelStyledTextField (Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;Landroidx/compose/ui/Modifier;ZLjava/lang/String;Landroidx/compose/foundation/text/KeyboardOptions;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/material3/TextFieldColors;Landroidx/compose/runtime/Composer;II)V +} + +public final class com/redmadrobot/debug/uikit/components/PanelToggleKt { + public static final fun PanelToggle (ZLkotlin/jvm/functions/Function1;Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;II)V +} + +public final class com/redmadrobot/debug/uikit/components/ThemeSwitcherKt { + public static final fun ThemeSwitcher (Lcom/redmadrobot/debug/uikit/theme/model/ThemeMode;Lkotlin/jvm/functions/Function1;Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;II)V +} + +public final class com/redmadrobot/debug/uikit/theme/BackgroundColors { + public static final field $stable I + public synthetic fun (JJJILkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (JJJLkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1-0d7_KjU ()J + public final fun component2-0d7_KjU ()J + public final fun component3-0d7_KjU ()J + public final fun copy-ysEtTa8 (JJJ)Lcom/redmadrobot/debug/uikit/theme/BackgroundColors; + public static synthetic fun copy-ysEtTa8$default (Lcom/redmadrobot/debug/uikit/theme/BackgroundColors;JJJILjava/lang/Object;)Lcom/redmadrobot/debug/uikit/theme/BackgroundColors; + public fun equals (Ljava/lang/Object;)Z + public final fun getPrimary-0d7_KjU ()J + public final fun getSecondary-0d7_KjU ()J + public final fun getTertiary-0d7_KjU ()J + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class com/redmadrobot/debug/uikit/theme/ButtonColors { + public static final field $stable I + public synthetic fun (JJJJJJILkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (JJJJJJLkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1-0d7_KjU ()J + public final fun component2-0d7_KjU ()J + public final fun component3-0d7_KjU ()J + public final fun component4-0d7_KjU ()J + public final fun component5-0d7_KjU ()J + public final fun component6-0d7_KjU ()J + public final fun copy-tNS2XkQ (JJJJJJ)Lcom/redmadrobot/debug/uikit/theme/ButtonColors; + public static synthetic fun copy-tNS2XkQ$default (Lcom/redmadrobot/debug/uikit/theme/ButtonColors;JJJJJJILjava/lang/Object;)Lcom/redmadrobot/debug/uikit/theme/ButtonColors; + public fun equals (Ljava/lang/Object;)Z + public final fun getError-0d7_KjU ()J + public final fun getOnError-0d7_KjU ()J + public final fun getOnPrimary-0d7_KjU ()J + public final fun getOnSecondary-0d7_KjU ()J + public final fun getPrimary-0d7_KjU ()J + public final fun getSecondary-0d7_KjU ()J + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class com/redmadrobot/debug/uikit/theme/ComposableSingletons$BaseColorsKt { + public static final field INSTANCE Lcom/redmadrobot/debug/uikit/theme/ComposableSingletons$BaseColorsKt; + public fun ()V + public final fun getLambda$-288969138$panel_ui_kit ()Lkotlin/jvm/functions/Function3; + public final fun getLambda$110896553$panel_ui_kit ()Lkotlin/jvm/functions/Function2; +} + +public final class com/redmadrobot/debug/uikit/theme/ContentColors { + public static final field $stable I + public synthetic fun (JJJJJJILkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (JJJJJJLkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1-0d7_KjU ()J + public final fun component2-0d7_KjU ()J + public final fun component3-0d7_KjU ()J + public final fun component4-0d7_KjU ()J + public final fun component5-0d7_KjU ()J + public final fun component6-0d7_KjU ()J + public final fun copy-tNS2XkQ (JJJJJJ)Lcom/redmadrobot/debug/uikit/theme/ContentColors; + public static synthetic fun copy-tNS2XkQ$default (Lcom/redmadrobot/debug/uikit/theme/ContentColors;JJJJJJILjava/lang/Object;)Lcom/redmadrobot/debug/uikit/theme/ContentColors; + public fun equals (Ljava/lang/Object;)Z + public final fun getAccent-0d7_KjU ()J + public final fun getError-0d7_KjU ()J + public final fun getPrimary-0d7_KjU ()J + public final fun getSecondary-0d7_KjU ()J + public final fun getTeal-0d7_KjU ()J + public final fun getTertiary-0d7_KjU ()J + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class com/redmadrobot/debug/uikit/theme/DebugPanelColors { + public static final field $stable I + public fun ()V + public fun (Lcom/redmadrobot/debug/uikit/theme/BackgroundColors;Lcom/redmadrobot/debug/uikit/theme/ButtonColors;Lcom/redmadrobot/debug/uikit/theme/ContentColors;Lcom/redmadrobot/debug/uikit/theme/StrokeColors;Lcom/redmadrobot/debug/uikit/theme/SurfaceColors;Lcom/redmadrobot/debug/uikit/theme/SourceColors;)V + public synthetic fun (Lcom/redmadrobot/debug/uikit/theme/BackgroundColors;Lcom/redmadrobot/debug/uikit/theme/ButtonColors;Lcom/redmadrobot/debug/uikit/theme/ContentColors;Lcom/redmadrobot/debug/uikit/theme/StrokeColors;Lcom/redmadrobot/debug/uikit/theme/SurfaceColors;Lcom/redmadrobot/debug/uikit/theme/SourceColors;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Lcom/redmadrobot/debug/uikit/theme/BackgroundColors; + public final fun component2 ()Lcom/redmadrobot/debug/uikit/theme/ButtonColors; + public final fun component3 ()Lcom/redmadrobot/debug/uikit/theme/ContentColors; + public final fun component4 ()Lcom/redmadrobot/debug/uikit/theme/StrokeColors; + public final fun component5 ()Lcom/redmadrobot/debug/uikit/theme/SurfaceColors; + public final fun component6 ()Lcom/redmadrobot/debug/uikit/theme/SourceColors; + public final fun copy (Lcom/redmadrobot/debug/uikit/theme/BackgroundColors;Lcom/redmadrobot/debug/uikit/theme/ButtonColors;Lcom/redmadrobot/debug/uikit/theme/ContentColors;Lcom/redmadrobot/debug/uikit/theme/StrokeColors;Lcom/redmadrobot/debug/uikit/theme/SurfaceColors;Lcom/redmadrobot/debug/uikit/theme/SourceColors;)Lcom/redmadrobot/debug/uikit/theme/DebugPanelColors; + public static synthetic fun copy$default (Lcom/redmadrobot/debug/uikit/theme/DebugPanelColors;Lcom/redmadrobot/debug/uikit/theme/BackgroundColors;Lcom/redmadrobot/debug/uikit/theme/ButtonColors;Lcom/redmadrobot/debug/uikit/theme/ContentColors;Lcom/redmadrobot/debug/uikit/theme/StrokeColors;Lcom/redmadrobot/debug/uikit/theme/SurfaceColors;Lcom/redmadrobot/debug/uikit/theme/SourceColors;ILjava/lang/Object;)Lcom/redmadrobot/debug/uikit/theme/DebugPanelColors; + public fun equals (Ljava/lang/Object;)Z + public final fun getBackground ()Lcom/redmadrobot/debug/uikit/theme/BackgroundColors; + public final fun getButton ()Lcom/redmadrobot/debug/uikit/theme/ButtonColors; + public final fun getContent ()Lcom/redmadrobot/debug/uikit/theme/ContentColors; + public final fun getSource ()Lcom/redmadrobot/debug/uikit/theme/SourceColors; + public final fun getStroke ()Lcom/redmadrobot/debug/uikit/theme/StrokeColors; + public final fun getSurface ()Lcom/redmadrobot/debug/uikit/theme/SurfaceColors; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class com/redmadrobot/debug/uikit/theme/DebugPanelDimensions { + public static final field $stable I + public static final field INSTANCE Lcom/redmadrobot/debug/uikit/theme/DebugPanelDimensions; + public final fun getBottomBarHeight-D9Ej5fM ()F + public final fun getDotSize-D9Ej5fM ()F + public final fun getIconSizeLarge-D9Ej5fM ()F + public final fun getIconSizeMedium-D9Ej5fM ()F + public final fun getIconSizeSmall-D9Ej5fM ()F + public final fun getRowMinHeight-D9Ej5fM ()F + public final fun getTabRowHeight-D9Ej5fM ()F + public final fun getToggleHeight-D9Ej5fM ()F + public final fun getToggleWidth-D9Ej5fM ()F + public final fun getTopBarHeight-D9Ej5fM ()F +} + +public final class com/redmadrobot/debug/uikit/theme/DebugPanelShapes { + public static final field $stable I + public static final field INSTANCE Lcom/redmadrobot/debug/uikit/theme/DebugPanelShapes; + public final fun getDialog ()Landroidx/compose/foundation/shape/RoundedCornerShape; + public final fun getLarge ()Landroidx/compose/foundation/shape/RoundedCornerShape; + public final fun getMedium ()Landroidx/compose/foundation/shape/RoundedCornerShape; + public final fun getSmall ()Landroidx/compose/foundation/shape/RoundedCornerShape; +} + +public final class com/redmadrobot/debug/uikit/theme/DebugPanelTheme { + public static final field $stable I + public static final field INSTANCE Lcom/redmadrobot/debug/uikit/theme/DebugPanelTheme; + public final fun getColors (Landroidx/compose/runtime/Composer;I)Lcom/redmadrobot/debug/uikit/theme/DebugPanelColors; + public final fun getTypography (Landroidx/compose/runtime/Composer;I)Lcom/redmadrobot/debug/uikit/theme/DebugPanelTypographyTokens; + public final fun isDarkTheme (Landroidx/compose/runtime/Composer;I)Z +} + +public final class com/redmadrobot/debug/uikit/theme/DebugPanelTypographyTokens { + public static final field $stable I + public fun ()V + public fun (Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;)V + public synthetic fun (Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Landroidx/compose/ui/text/TextStyle; + public final fun component2 ()Landroidx/compose/ui/text/TextStyle; + public final fun component3 ()Landroidx/compose/ui/text/TextStyle; + public final fun component4 ()Landroidx/compose/ui/text/TextStyle; + public final fun component5 ()Landroidx/compose/ui/text/TextStyle; + public final fun component6 ()Landroidx/compose/ui/text/TextStyle; + public final fun component7 ()Landroidx/compose/ui/text/TextStyle; + public final fun component8 ()Landroidx/compose/ui/text/TextStyle; + public final fun component9 ()Landroidx/compose/ui/text/TextStyle; + public final fun copy (Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;)Lcom/redmadrobot/debug/uikit/theme/DebugPanelTypographyTokens; + public static synthetic fun copy$default (Lcom/redmadrobot/debug/uikit/theme/DebugPanelTypographyTokens;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;ILjava/lang/Object;)Lcom/redmadrobot/debug/uikit/theme/DebugPanelTypographyTokens; + public fun equals (Ljava/lang/Object;)Z + public final fun getBodyLarge ()Landroidx/compose/ui/text/TextStyle; + public final fun getBodyMedium ()Landroidx/compose/ui/text/TextStyle; + public final fun getBodySmall ()Landroidx/compose/ui/text/TextStyle; + public final fun getLabelLarge ()Landroidx/compose/ui/text/TextStyle; + public final fun getLabelMedium ()Landroidx/compose/ui/text/TextStyle; + public final fun getLabelSmall ()Landroidx/compose/ui/text/TextStyle; + public final fun getTitleLarge ()Landroidx/compose/ui/text/TextStyle; + public final fun getTitleMedium ()Landroidx/compose/ui/text/TextStyle; + public final fun getTitleSmall ()Landroidx/compose/ui/text/TextStyle; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class com/redmadrobot/debug/uikit/theme/SourceColors { + public static final field $stable I + public synthetic fun (JJJJJJILkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (JJJJJJLkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1-0d7_KjU ()J + public final fun component2-0d7_KjU ()J + public final fun component3-0d7_KjU ()J + public final fun component4-0d7_KjU ()J + public final fun component5-0d7_KjU ()J + public final fun component6-0d7_KjU ()J + public final fun copy-tNS2XkQ (JJJJJJ)Lcom/redmadrobot/debug/uikit/theme/SourceColors; + public static synthetic fun copy-tNS2XkQ$default (Lcom/redmadrobot/debug/uikit/theme/SourceColors;JJJJJJILjava/lang/Object;)Lcom/redmadrobot/debug/uikit/theme/SourceColors; + public fun equals (Ljava/lang/Object;)Z + public final fun getDebugBackground-0d7_KjU ()J + public final fun getDebugText-0d7_KjU ()J + public final fun getDefaultBackground-0d7_KjU ()J + public final fun getDefaultText-0d7_KjU ()J + public final fun getRemoteBackground-0d7_KjU ()J + public final fun getRemoteText-0d7_KjU ()J + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class com/redmadrobot/debug/uikit/theme/StrokeColors { + public static final field $stable I + public synthetic fun (JJILkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (JJLkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1-0d7_KjU ()J + public final fun component2-0d7_KjU ()J + public final fun copy--OWjLjI (JJ)Lcom/redmadrobot/debug/uikit/theme/StrokeColors; + public static synthetic fun copy--OWjLjI$default (Lcom/redmadrobot/debug/uikit/theme/StrokeColors;JJILjava/lang/Object;)Lcom/redmadrobot/debug/uikit/theme/StrokeColors; + public fun equals (Ljava/lang/Object;)Z + public final fun getPrimary-0d7_KjU ()J + public final fun getSecondary-0d7_KjU ()J + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class com/redmadrobot/debug/uikit/theme/SurfaceColors { + public static final field $stable I + public synthetic fun (JJJJJILkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (JJJJJLkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1-0d7_KjU ()J + public final fun component2-0d7_KjU ()J + public final fun component3-0d7_KjU ()J + public final fun component4-0d7_KjU ()J + public final fun component5-0d7_KjU ()J + public final fun copy-t635Npw (JJJJJ)Lcom/redmadrobot/debug/uikit/theme/SurfaceColors; + public static synthetic fun copy-t635Npw$default (Lcom/redmadrobot/debug/uikit/theme/SurfaceColors;JJJJJILjava/lang/Object;)Lcom/redmadrobot/debug/uikit/theme/SurfaceColors; + public fun equals (Ljava/lang/Object;)Z + public final fun getDialog-0d7_KjU ()J + public final fun getPrimary-0d7_KjU ()J + public final fun getSecondary-0d7_KjU ()J + public final fun getSelected-0d7_KjU ()J + public final fun getTertiary-0d7_KjU ()J + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class com/redmadrobot/debug/uikit/theme/SystemBarsColors { + public static final field $stable I + public static final field Companion Lcom/redmadrobot/debug/uikit/theme/SystemBarsColors$Companion; + public synthetic fun (JJLkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1-0d7_KjU ()J + public final fun component2-0d7_KjU ()J + public final fun copy--OWjLjI (JJ)Lcom/redmadrobot/debug/uikit/theme/SystemBarsColors; + public static synthetic fun copy--OWjLjI$default (Lcom/redmadrobot/debug/uikit/theme/SystemBarsColors;JJILjava/lang/Object;)Lcom/redmadrobot/debug/uikit/theme/SystemBarsColors; + public fun equals (Ljava/lang/Object;)Z + public final fun getNavigationBarColor-0d7_KjU ()J + public final fun getStatusBarColor-0d7_KjU ()J + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class com/redmadrobot/debug/uikit/theme/SystemBarsColors$Companion { + public final fun fromTheme (Lcom/redmadrobot/debug/uikit/theme/DebugPanelColors;)Lcom/redmadrobot/debug/uikit/theme/SystemBarsColors; +} + +public final class com/redmadrobot/debug/uikit/theme/SystemBarsEffectKt { + public static final fun SystemBarsEffect (Lcom/redmadrobot/debug/uikit/theme/SystemBarsColors;Landroidx/compose/runtime/Composer;I)V +} + +public final class com/redmadrobot/debug/uikit/theme/ThemeKt { + public static final fun DebugPanelTheme (Lcom/redmadrobot/debug/uikit/theme/model/ThemeMode;ZLkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V +} + +public final class com/redmadrobot/debug/uikit/theme/TypographyKt { + public static final fun getMonoFontFamily ()Landroidx/compose/ui/text/font/FontFamily; +} + +public final class com/redmadrobot/debug/uikit/theme/model/ThemeMode : java/lang/Enum { + public static final field Companion Lcom/redmadrobot/debug/uikit/theme/model/ThemeMode$Companion; + public static final field Dark Lcom/redmadrobot/debug/uikit/theme/model/ThemeMode; + public static final field Light Lcom/redmadrobot/debug/uikit/theme/model/ThemeMode; + public static final field System Lcom/redmadrobot/debug/uikit/theme/model/ThemeMode; + public static fun getEntries ()Lkotlin/enums/EnumEntries; + public static fun valueOf (Ljava/lang/String;)Lcom/redmadrobot/debug/uikit/theme/model/ThemeMode; + public static fun values ()[Lcom/redmadrobot/debug/uikit/theme/model/ThemeMode; +} + +public final class com/redmadrobot/debug/uikit/theme/model/ThemeMode$Companion { + public final fun getIconRes (Lcom/redmadrobot/debug/uikit/theme/model/ThemeMode;)I + public final fun getTitleRes (Lcom/redmadrobot/debug/uikit/theme/model/ThemeMode;)I +} + diff --git a/panel-ui-kit/build.gradle.kts b/panel-ui-kit/build.gradle.kts index a12e41b1..96e4a8c7 100644 --- a/panel-ui-kit/build.gradle.kts +++ b/panel-ui-kit/build.gradle.kts @@ -3,6 +3,7 @@ plugins { id("convention.compose") id("convention-publish") id("convention.detekt") + id("convention.abi.validation") } description = "Debug panel UI kit: theme, design tokens, shared components" diff --git a/plugins/plugin-about-app/api/plugin-about-app.api b/plugins/plugin-about-app/api/plugin-about-app.api new file mode 100644 index 00000000..d772e581 --- /dev/null +++ b/plugins/plugin-about-app/api/plugin-about-app.api @@ -0,0 +1,53 @@ +public final class com/redmadrobot/debug/plugin/aboutapp/AboutAppPlugin : com/redmadrobot/debug/core/plugin/Plugin { + public static final field $stable I + public fun (Ljava/util/List;Ljava/util/List;)V + public synthetic fun (Ljava/util/List;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun content (Landroidx/compose/runtime/Composer;I)V + public fun getName ()Ljava/lang/String; + public fun getPluginContainer (Lcom/redmadrobot/debug/core/internal/CommonContainer;)Lcom/redmadrobot/debug/core/internal/PluginDependencyContainer; +} + +public abstract interface class com/redmadrobot/debug/plugin/aboutapp/model/AboutAppAction { + public abstract fun getId ()Ljava/lang/String; + public abstract fun getTitle ()Ljava/lang/String; +} + +public final class com/redmadrobot/debug/plugin/aboutapp/model/AboutAppAction$Direct : com/redmadrobot/debug/plugin/aboutapp/model/AboutAppAction { + public static final field $stable I + public fun (Ljava/lang/String;Lkotlin/jvm/functions/Function1;Ljava/lang/String;)V + public synthetic fun (Ljava/lang/String;Lkotlin/jvm/functions/Function1;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun getId ()Ljava/lang/String; + public final fun getOnClick ()Lkotlin/jvm/functions/Function1; + public fun getTitle ()Ljava/lang/String; +} + +public final class com/redmadrobot/debug/plugin/aboutapp/model/AboutAppAction$Event : com/redmadrobot/debug/plugin/aboutapp/model/AboutAppAction { + public static final field $stable I + public fun (Ljava/lang/String;Lcom/redmadrobot/debug/core/DebugEvent;Ljava/lang/String;)V + public synthetic fun (Ljava/lang/String;Lcom/redmadrobot/debug/core/DebugEvent;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun getDebugEvent ()Lcom/redmadrobot/debug/core/DebugEvent; + public fun getId ()Ljava/lang/String; + public fun getTitle ()Ljava/lang/String; +} + +public final class com/redmadrobot/debug/plugin/aboutapp/model/AboutAppInfo { + public static final field $stable I + public fun (Ljava/lang/String;Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;Ljava/lang/String;)Lcom/redmadrobot/debug/plugin/aboutapp/model/AboutAppInfo; + public static synthetic fun copy$default (Lcom/redmadrobot/debug/plugin/aboutapp/model/AboutAppInfo;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lcom/redmadrobot/debug/plugin/aboutapp/model/AboutAppInfo; + public fun equals (Ljava/lang/Object;)Z + public final fun getId ()Ljava/lang/String; + public final fun getTitle ()Ljava/lang/String; + public final fun getValue ()Ljava/lang/String; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class com/redmadrobot/debug/plugin/aboutapp/ui/ComposableSingletons$AboutAppScreenKt { + public static final field INSTANCE Lcom/redmadrobot/debug/plugin/aboutapp/ui/ComposableSingletons$AboutAppScreenKt; + public fun ()V + public final fun getLambda$-1763104387$plugin_about_app ()Lkotlin/jvm/functions/Function3; +} + diff --git a/plugins/plugin-konfeature/api/plugin-konfeature.api b/plugins/plugin-konfeature/api/plugin-konfeature.api new file mode 100644 index 00000000..0518fdf3 --- /dev/null +++ b/plugins/plugin-konfeature/api/plugin-konfeature.api @@ -0,0 +1,24 @@ +public final class com/redmadrobot/debug/plugin/konfeature/KonfeatureDebugPanelConfig { + public static final field $stable I + public static final field Companion Lcom/redmadrobot/debug/plugin/konfeature/KonfeatureDebugPanelConfig$Companion; + public static final field DEFAULT_PATH Ljava/lang/String; + public synthetic fun (Lcom/redmadrobot/konfeature/ui/KonfeatureDebugStore;Lcom/redmadrobot/konfeature/ui/KonfeatureDebugInterceptor;Lkotlin/jvm/internal/DefaultConstructorMarker;)V +} + +public final class com/redmadrobot/debug/plugin/konfeature/KonfeatureDebugPanelConfig$Companion { + public final fun create (Landroid/content/Context;Ljava/lang/String;Lcom/redmadrobot/konfeature/Logger;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static synthetic fun create$default (Lcom/redmadrobot/debug/plugin/konfeature/KonfeatureDebugPanelConfig$Companion;Landroid/content/Context;Ljava/lang/String;Lcom/redmadrobot/konfeature/Logger;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; +} + +public final class com/redmadrobot/debug/plugin/konfeature/KonfeatureDebugPanelConfigKt { + public static final fun applyDebugPanelConfig (Lcom/redmadrobot/konfeature/builder/KonfeatureBuilder;Lcom/redmadrobot/debug/plugin/konfeature/KonfeatureDebugPanelConfig;)Lcom/redmadrobot/konfeature/builder/KonfeatureBuilder; +} + +public final class com/redmadrobot/debug/plugin/konfeature/KonfeaturePlugin : com/redmadrobot/debug/core/plugin/Plugin { + public static final field $stable I + public fun (Lcom/redmadrobot/konfeature/Konfeature;Lcom/redmadrobot/debug/plugin/konfeature/KonfeatureDebugPanelConfig;)V + public fun content (Landroidx/compose/runtime/Composer;I)V + public fun getName ()Ljava/lang/String; + public fun getPluginContainer (Lcom/redmadrobot/debug/core/internal/CommonContainer;)Lcom/redmadrobot/debug/core/internal/PluginDependencyContainer; +} + diff --git a/plugins/plugin-servers/api/plugin-servers.api b/plugins/plugin-servers/api/plugin-servers.api new file mode 100644 index 00000000..cc428981 --- /dev/null +++ b/plugins/plugin-servers/api/plugin-servers.api @@ -0,0 +1,81 @@ +public final class com/redmadrobot/debug/plugin/servers/ServerSelectedEvent : com/redmadrobot/debug/core/DebugEvent { + public static final field $stable I + public fun (Lcom/redmadrobot/debug/plugin/servers/data/model/DebugServer;)V + public final fun component1 ()Lcom/redmadrobot/debug/plugin/servers/data/model/DebugServer; + public final fun copy (Lcom/redmadrobot/debug/plugin/servers/data/model/DebugServer;)Lcom/redmadrobot/debug/plugin/servers/ServerSelectedEvent; + public static synthetic fun copy$default (Lcom/redmadrobot/debug/plugin/servers/ServerSelectedEvent;Lcom/redmadrobot/debug/plugin/servers/data/model/DebugServer;ILjava/lang/Object;)Lcom/redmadrobot/debug/plugin/servers/ServerSelectedEvent; + public fun equals (Ljava/lang/Object;)Z + public final fun getDebugServer ()Lcom/redmadrobot/debug/plugin/servers/data/model/DebugServer; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class com/redmadrobot/debug/plugin/servers/ServersPlugin : com/redmadrobot/debug/core/plugin/Plugin, com/redmadrobot/debug/core/internal/EditablePlugin { + public static final field $stable I + public static final field Companion Lcom/redmadrobot/debug/plugin/servers/ServersPlugin$Companion; + public fun ()V + public fun (Lcom/redmadrobot/debug/core/data/DebugDataProvider;)V + public fun (Ljava/util/List;)V + public synthetic fun (Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun content (Landroidx/compose/runtime/Composer;I)V + public fun getName ()Ljava/lang/String; + public fun getPluginContainer (Lcom/redmadrobot/debug/core/internal/CommonContainer;)Lcom/redmadrobot/debug/core/internal/PluginDependencyContainer; + public fun settingsContent (Landroidx/compose/runtime/Composer;I)V +} + +public final class com/redmadrobot/debug/plugin/servers/ServersPlugin$Companion { + public final fun getDefaultServer ()Lcom/redmadrobot/debug/plugin/servers/data/model/DebugServer; + public final fun getSelectedServer ()Lcom/redmadrobot/debug/plugin/servers/data/model/DebugServer; +} + +public final class com/redmadrobot/debug/plugin/servers/data/model/DebugServer { + public static final field $stable I + public static final field Companion Lcom/redmadrobot/debug/plugin/servers/data/model/DebugServer$Companion; + public fun (Ljava/lang/String;Ljava/lang/String;Z)V + public synthetic fun (Ljava/lang/String;Ljava/lang/String;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Ljava/lang/String; + public final fun component3 ()Z + public final fun copy (Ljava/lang/String;Ljava/lang/String;Z)Lcom/redmadrobot/debug/plugin/servers/data/model/DebugServer; + public static synthetic fun copy$default (Lcom/redmadrobot/debug/plugin/servers/data/model/DebugServer;Ljava/lang/String;Ljava/lang/String;ZILjava/lang/Object;)Lcom/redmadrobot/debug/plugin/servers/data/model/DebugServer; + public fun equals (Ljava/lang/Object;)Z + public final fun getName ()Ljava/lang/String; + public final fun getUrl ()Ljava/lang/String; + public fun hashCode ()I + public final fun isDefault ()Z + public fun toString ()Ljava/lang/String; +} + +public final synthetic class com/redmadrobot/debug/plugin/servers/data/model/DebugServer$$serializer : kotlinx/serialization/internal/GeneratedSerializer { + public static final field $stable I + public static final field INSTANCE Lcom/redmadrobot/debug/plugin/servers/data/model/DebugServer$$serializer; + public final fun childSerializers ()[Lkotlinx/serialization/KSerializer; + public final fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/redmadrobot/debug/plugin/servers/data/model/DebugServer; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public final fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public final fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/redmadrobot/debug/plugin/servers/data/model/DebugServer;)V + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V + public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; +} + +public final class com/redmadrobot/debug/plugin/servers/data/model/DebugServer$Companion { + public final fun serializer ()Lkotlinx/serialization/KSerializer; +} + +public final class com/redmadrobot/debug/plugin/servers/interceptor/DebugServerInterceptor : okhttp3/Interceptor { + public static final field $stable I + public fun ()V + public fun intercept (Lokhttp3/Interceptor$Chain;)Lokhttp3/Response; + public final fun modifyRequest (Lkotlin/jvm/functions/Function2;)Lcom/redmadrobot/debug/plugin/servers/interceptor/DebugServerInterceptor; +} + +public final class com/redmadrobot/debug/plugin/servers/ui/ComposableSingletons$ServersScreenKt { + public static final field INSTANCE Lcom/redmadrobot/debug/plugin/servers/ui/ComposableSingletons$ServersScreenKt; + public fun ()V + public final fun getLambda$-1230053063$plugin_servers ()Lkotlin/jvm/functions/Function2; + public final fun getLambda$-1902662446$plugin_servers ()Lkotlin/jvm/functions/Function3; + public final fun getLambda$-692726257$plugin_servers ()Lkotlin/jvm/functions/Function3; + public final fun getLambda$-83851575$plugin_servers ()Lkotlin/jvm/functions/Function3; + public final fun getLambda$1203279212$plugin_servers ()Lkotlin/jvm/functions/Function3; +} + diff --git a/sample/src/release/kotlin/com/redmadrobot/debug_sample/debug_data/DebugAboutAppInfoProvider.kt b/sample/src/release/kotlin/com/redmadrobot/debug_sample/debug_data/DebugAboutAppInfoProvider.kt index a6258ec1..bf80001b 100644 --- a/sample/src/release/kotlin/com/redmadrobot/debug_sample/debug_data/DebugAboutAppInfoProvider.kt +++ b/sample/src/release/kotlin/com/redmadrobot/debug_sample/debug_data/DebugAboutAppInfoProvider.kt @@ -1,6 +1,6 @@ package com.redmadrobot.debug_sample.debug_data -import com.redmadrobot.debug.plugin.aboutapp.AboutAppInfo +import com.redmadrobot.debug.plugin.aboutapp.model.AboutAppInfo class DebugAboutAppInfoProvider { companion object { diff --git a/settings.gradle.kts b/settings.gradle.kts index ca2d15ab..7ee3950e 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -31,12 +31,9 @@ dependencyResolutionManagement { } versionCatalogs { - val version = "2026.07.10" // Keep it in sync with buildSrc/settings.gradle.kts + val version = "2026.07.31" // Keep it in sync with buildSrc/settings.gradle.kts create("rmr") { from("com.redmadrobot.versions:versions-redmadrobot:$version") - version("konfeature", "1.1.0") // Remove with update version - library("konfeature-ui", "com.redmadrobot.konfeature:konfeature-ui:1.1.0") // Remove with update version - library("konfeature-ui-noop", "com.redmadrobot.konfeature:konfeature-ui-noop:1.1.0") // Remove with update version } create("androidx") { from("com.redmadrobot.versions:versions-androidx:$version")