Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ The project is organized in the following modules:
- `tool-googleplay` - contains a class wrapper for Google Play
- `tool-timber` - contains a class wrapper for Timber
- `tool-networkemulator-okhttp` - contains a class wrapper for NetworkEmulator
- `tool-showkase` - contains a class wrapper for Showkase
- `tool-showkase-no-op` - contains stubs for easy release implementation of the Showkase wrapper
- `sample` - a sample app for testing and developing


Expand Down Expand Up @@ -105,6 +107,8 @@ debugImplementation "com.infinum.sentinel:tool-appgallery:$sentinelVersion"
debugImplementation "com.infinum.sentinel:tool-googleplay:$sentinelVersion"
debugImplementation "com.infinum.sentinel:tool-timber:$sentinelVersion"
debugImplementation "com.infinum.sentinel:tool-networkemulator-okhttp:$sentinelVersion"
debugImplementation "com.infinum.sentinel:tool-showkase:$sentinelVersion"
releaseImplementation "com.infinum.sentinel:tool-showkase-no-op:$sentinelVersion"
```

**KotlinDSL**
Expand All @@ -118,6 +122,8 @@ debugImplementation("com.infinum.sentinel:tool-appgallery:$sentinelVersion")
debugImplementation("com.infinum.sentinel:tool-googleplay:$sentinelVersion")
debugImplementation("com.infinum.sentinel:tool-timber:$sentinelVersion")
debugImplementation("com.infinum.sentinel:tool-networkemulator-okhttp:$sentinelVersion")
debugImplementation("com.infinum.sentinel:tool-showkase:$sentinelVersion")
releaseImplementation("com.infinum.sentinel:tool-showkase-no-op:$sentinelVersion")
```

Now you can sync your project.
Expand Down Expand Up @@ -202,6 +208,36 @@ Depending of what you include as module dependencies, very specific tools are pr
- `GooglePlayTool` - a wrapper class that opens Google Play of a published application or a web page
of the application if Google Play is not found
- `NetworkEmulatorTool` - a wrapper class that opens [NetworkEmulator](https://github.com/infinum/android-sentinel/tree/master/tool-networkemulator-okhttp). Enables user to modify network conditions.
- `ShowkaseTool` - a wrapper class that opens [Showkase](https://github.com/airbnb/Showkase), Airbnb's
Compose component browser. Requires additional setup, see [Showkase](#showkase) below.

##### Showkase

Unlike the other wrappers, Showkase needs build configuration in your project, because its
annotation processor has to run over your own sources. The short version:

```groovy
debugImplementation "com.infinum.sentinel:tool-showkase:$sentinelVersion"
releaseImplementation "com.infinum.sentinel:tool-showkase-no-op:$sentinelVersion"
debugImplementation "com.airbnb.android:showkase:1.0.5"
kspDebug "com.airbnb.android:showkase-processor:1.0.5"
```

Use a variant-scoped `ksp` configuration such as `kspDebug`, never the project-wide `ksp`
configuration: that one applies the processor to every variant, production included.

Register the tool with your app's `@ShowkaseRoot` module:

```kotlin
Sentinel.watch(
setOf(
ShowkaseTool(MyRootModule::class),
),
)
```

[tool-showkase/README.md](tool-showkase/README.md) covers the full setup, flavored projects,
minified builds and troubleshooting.


#### Source abstractions
Expand Down
8 changes: 6 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ tasks.register("lintAll") {
":tool-dbinspector:lintRelease",
":tool-leakcanary:lintRelease",
":tool-appgallery:lintRelease",
":tool-googleplay:lintRelease"
":tool-googleplay:lintRelease",
":tool-showkase:lintRelease",
":tool-showkase-no-op:lintRelease"
)
group = "Verification"
description = "Run Detekt on all modules"
Expand All @@ -88,7 +90,9 @@ tasks.register("detektAll") {
":tool-dbinspector:detekt",
":tool-leakcanary:detekt",
":tool-appgallery:detekt",
":tool-googleplay:detekt"
":tool-googleplay:detekt",
":tool-showkase:detekt",
":tool-showkase-no-op:detekt"
)
group = "Verification"
description = "Run Detekt on all modules"
Expand Down
23 changes: 20 additions & 3 deletions deploy.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,17 @@ tasks.register("deployToolNetworkEmulatorOkhttp") {
description = "Deploy Tool NetworkEmulator OkHttp modules to Maven Central repository"
}

tasks.register("deployToolShowkase") {
dependsOn(
":tool-showkase:clean",
":tool-showkase-no-op:clean",
":tool-showkase:publishMavenPublicationToMavenCentralRepository",
":tool-showkase-no-op:publishMavenPublicationToMavenCentralRepository"
)
group = "Deploy"
description = "Deploy Tool Showkase modules to Maven Central repository"
}

tasks.register("deploySentinelAll") {
dependsOn(
"deploySentinel",
Expand All @@ -108,7 +119,8 @@ tasks.register("deployToolsAll") {
"deployToolAppGallery",
"deployToolGooglePlay",
"deployToolTimber",
"deployToolNetworkEmulatorOkhttp"
"deployToolNetworkEmulatorOkhttp",
"deployToolShowkase"
)
group = "Deploy"
description = "Deploy all tools modules to repositories"
Expand All @@ -125,7 +137,8 @@ tasks.register("deployAll") {
"deployToolAppGallery",
"deployToolGooglePlay",
"deployToolTimber",
"deployToolNetworkEmulatorOkhttp"
"deployToolNetworkEmulatorOkhttp",
"deployToolShowkase"
)
group = "Deploy"
description = "Deploy all modules to Maven Central repository"
Expand All @@ -144,6 +157,8 @@ tasks.register("deployDebug") {
":tool-timber:clean",
":tool-networkemulator-okhttp:clean",
":tool-networkemulator-okhttp-no-op:clean",
":tool-showkase:clean",
":tool-showkase-no-op:clean",
":sentinel:publishMavenPublicationToMavenLocal",
":sentinel-no-op:publishMavenPublicationToMavenLocal",
":tool-chucker:publishMavenPublicationToMavenLocal",
Expand All @@ -154,7 +169,9 @@ tasks.register("deployDebug") {
":tool-googleplay:publishMavenPublicationToMavenLocal",
":tool-timber:publishMavenPublicationToMavenLocal",
":tool-networkemulator-okhttp:publishMavenPublicationToMavenLocal",
":tool-networkemulator-okhttp-no-op:publishMavenPublicationToMavenLocal"
":tool-networkemulator-okhttp-no-op:publishMavenPublicationToMavenLocal",
":tool-showkase:publishMavenPublicationToMavenLocal",
":tool-showkase-no-op:publishMavenPublicationToMavenLocal"
)
group = "Deploy"
description = "Deploy all modules to Maven Local repository for debugging"
Expand Down
12 changes: 12 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ appcompat = "1.8.0"
binaryCompatibility = "0.18.1"
chucker = "4.3.1"
collar = "2.1.0"
compose = "1.12.0"
core = "1.19.0"
coroutines = "1.11.0"
crypto = "1.1.0"
Expand Down Expand Up @@ -37,6 +38,7 @@ robolectricShadow = "4.16.1"
room = "2.8.4"
roomTest = "2.8.4"
sentinel = "2.0.0"
showkase = "1.0.5"
startup = "1.2.0"
timber = "5.0.1"
workmanager = "2.11.2"
Expand All @@ -53,6 +55,8 @@ toolgoogleplay = { module = "com.infinum.sentinel:tool-googleplay", version.ref
tooltimber = { module = "com.infinum.sentinel:tool-timber", version.ref = "sentinel" }
toolnetworkemulatorokhttp = { module = "com.infinum.sentinel:tool-networkemulator-okhttp", version.ref = "sentinel" }
toolnetworkemulatorokhttpnoop = { module = "com.infinum.sentinel:tool-networkemulator-okhttp-no-op", version.ref = "sentinel" }
toolshowkase = { module = "com.infinum.sentinel:tool-showkase", version.ref = "sentinel" }
toolshowkasenoop = { module = "com.infinum.sentinel:tool-showkase-no-op", version.ref = "sentinel" }
Comment on lines +58 to +59

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add those to bundles section of version catalog? so we don't forget



tools-gradle = { module = "com.android.tools.build:gradle", version.ref = "gradle" }
Expand Down Expand Up @@ -117,6 +121,13 @@ robolectric-shadowapi = { module = "org.robolectric:shadowapi", version.ref = "r

okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }

showkase = { module = "com.airbnb.android:showkase", version.ref = "showkase" }
showkase-annotation = { module = "com.airbnb.android:showkase-annotation", version.ref = "showkase" }
showkase-processor = { module = "com.airbnb.android:showkase-processor", version.ref = "showkase" }

compose-runtime = { module = "androidx.compose.runtime:runtime", version.ref = "compose" }
compose-material = { module = "androidx.compose.material:material", version.ref = "compose" }

[bundles]
androidx = [
"androidx-core",
Expand Down Expand Up @@ -150,4 +161,5 @@ tools = [
[plugins]
gradle-maven-publish = { id = "com.vanniktech.maven.publish", version.ref = "gradle-maven-publish" }
kotlin-binary-compatibility = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version.ref = "binaryCompatibility" }
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
17 changes: 17 additions & 0 deletions sample/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ val releaseConfig = extra["releaseConfig"] as Map<String, Any>
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
alias(libs.plugins.kotlin.compose)
alias(libs.plugins.ksp)
}

android {
Expand Down Expand Up @@ -93,4 +95,19 @@ dependencies {
debugImplementation(project(":tool-networkemulator-okhttp"))
releaseImplementation(project(":tool-networkemulator-okhttp-no-op"))
debugImplementation(project(":tool-timber"))

debugImplementation(project(":tool-showkase"))
releaseImplementation(project(":tool-showkase-no-op"))

debugImplementation(libs.showkase)
debugImplementation(libs.compose.runtime)
debugImplementation(libs.compose.material)

// The Compose compiler plugin applies to every variant and refuses to run without the
// runtime on the compile classpath, even though release has no composables
releaseCompileOnly(libs.compose.runtime)

// Variant-scoped on purpose. The project-wide `ksp` configuration would run the
// processor for release, where the browser runtime does not exist.
kspDebug(libs.showkase.processor)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.infinum.sentinel.sample

import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import com.airbnb.android.showkase.annotation.ShowkaseComposable

@ShowkaseComposable(name = "Primary button", group = "Buttons")
@Composable
fun PrimaryButtonSample() {
Button(onClick = {}) {
Text(text = "Show Sentinel")
}
}

@ShowkaseComposable(name = "Title", group = "Text")
@Composable
fun TitleTextSample() {
Text(text = "Sentinel sample", style = MaterialTheme.typography.h6)
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.infinum.sentinel.ui.tools.DbInspectorTool
import com.infinum.sentinel.ui.tools.GooglePlayTool
import com.infinum.sentinel.ui.tools.LeakCanaryTool
import com.infinum.sentinel.ui.tools.NetworkEmulatorTool
import com.infinum.sentinel.ui.tools.ShowkaseTool
import com.infinum.sentinel.ui.tools.TimberTool
import java.security.cert.CertificateFactory
import java.security.cert.X509Certificate
Expand All @@ -35,6 +36,7 @@ class SampleApplication : Application() {
tools.add(AppGalleryTool(appId = "102016595"))
tools.add(GooglePlayTool())
tools.add(TimberTool(allowedTags = listOf("Main")))
tools.add(ShowkaseTool(SampleShowkaseRootModule::class))
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
tools.add(CertificateTool(userCertificates = loadDebugCertificates()))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.infinum.sentinel.sample

import com.airbnb.android.showkase.annotation.ShowkaseRoot
import com.airbnb.android.showkase.annotation.ShowkaseRootModule

@ShowkaseRoot
class SampleShowkaseRootModule : ShowkaseRootModule
2 changes: 2 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ include(":tool-googleplay")
include(":tool-appgallery")
include(":tool-networkemulator-okhttp")
include(":tool-networkemulator-okhttp-no-op")
include(":tool-showkase")
include(":tool-showkase-no-op")
include(":tool-timber")

gradle.startParameter.excludedTaskNames.add(":buildSrc:testClasses")
1 change: 1 addition & 0 deletions tool-showkase-no-op/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
12 changes: 12 additions & 0 deletions tool-showkase-no-op/api/tool-showkase-no-op.api
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
public final class com/infinum/sentinel/ui/tools/ShowkaseTool : com/infinum/sentinel/Sentinel$Tool {
public fun <init> (Lkotlin/reflect/KClass;)V
public final fun copy (Lkotlin/reflect/KClass;)Lcom/infinum/sentinel/ui/tools/ShowkaseTool;
public static synthetic fun copy$default (Lcom/infinum/sentinel/ui/tools/ShowkaseTool;Lkotlin/reflect/KClass;ILjava/lang/Object;)Lcom/infinum/sentinel/ui/tools/ShowkaseTool;
public fun equals (Ljava/lang/Object;)Z
public fun hashCode ()I
public fun icon ()Ljava/lang/Integer;
public fun listener ()Landroid/view/View$OnClickListener;
public fun name ()I
public fun toString ()Ljava/lang/String;
}

79 changes: 79 additions & 0 deletions tool-showkase-no-op/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
@Suppress("UNCHECKED_CAST")
val buildConfig = extra["buildConfig"] as Map<String, Any>
@Suppress("UNCHECKED_CAST")
val releaseConfig = extra["releaseConfig"] as Map<String, Any>

plugins {
id("com.android.library")
id("org.jetbrains.kotlin.android")
alias(libs.plugins.gradle.maven.publish)
}

android {
buildFeatures {
buildConfig = false
}

compileSdk = buildConfig["compileSdk"] as Int
buildToolsVersion = buildConfig["buildTools"] as String

defaultConfig {
minSdk = buildConfig["minSdk"] as Int
}

buildTypes {
debug {
isMinifyEnabled = false
}
release {
isMinifyEnabled = true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.txt")
}
}

namespace = "com.infinum.sentinel.tool.showkase"
resourcePrefix = "sentinel_"

kotlin {
jvmToolchain(11)

compilerOptions {
freeCompilerArgs.addAll(
listOf(
"-Xexplicit-api=strict",
"-Xjvm-default=all"
)
)
}
}

java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(11))
}
}

}

tasks.named("dokkaGenerate") {
mustRunAfter(":tool-showkase-no-op:generateReleaseRFile")
}

dependencies {
implementation(libs.kotlin.core)
// Sentinel is provided by the app. Production variants use sentinel-no-op, and declaring the
// real library as api here would drag it into those builds.
compileOnly(libs.library)
// Kotlin-only artifact, no Compose. Keeps the app's @ShowkaseRoot class resolvable in production.
api(libs.showkase.annotation)
}

val groupId: String by project

mavenPublishing {
coordinates(
groupId = groupId,
artifactId = "tool-showkase-no-op",
version = releaseConfig["version"] as String
)
}
4 changes: 4 additions & 0 deletions tool-showkase-no-op/proguard-rules.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Showkase No-op - ProGuard Rules

# Keep the public API class - no-op implementations should be preserved
-keep public class com.infinum.sentinel.ui.tools.ShowkaseTool { *; }
Loading