Skip to content

Commit 4fc3061

Browse files
authored
Scaffold android-cli Gradle plugin (#1)
* Scaffold android-cli Gradle plugin Settings plugin wrapping Google's agent-first 'android' CLI. - Plugin ID: zone.clanker.gradle.android-cli - Artifact: zone.clanker:android-cli - clkx convention plugins (conventions/library/module/publish/ktlint/detekt/konsist/cover/toolchain) - Exec-based tasks grouped by CLI subcommand: - task/: AndroidExecTask (base), version, describe, run - task/screen/: screen capture - task/skills/: list, find, add, remove - Gradle property forwarding for skill name, query, args, JSON flag - 24 tests, 93% kover coverage (no exclusions) - Konsist forbidden-pattern checks on main source - CI: build on push/PR to main, release to Maven Central on published release * Address CodeRabbit review - config/detekt.yml: fix over-escaped ForbiddenComment allowedPatterns regex (YAML single-quotes don't process escapes; 'TODO\\(.*\\):' was matching literal backslashes instead of parentheses) - AndroidCliPluginTest: construct fresh SettingsExtension in each when{} scope so defaults and mutation leaves don't share state
1 parent 57f762a commit 4fc3061

38 files changed

Lines changed: 1476 additions & 0 deletions

.github/workflows/build.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Build
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
build:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v4
17+
- name: Configure git
18+
run: |
19+
git config --global user.name "CI"
20+
git config --global user.email "ci@clanker.zone"
21+
git config --global init.defaultBranch main
22+
- uses: actions/setup-java@v4
23+
with:
24+
distribution: jetbrains
25+
java-version: 17
26+
- uses: gradle/actions/setup-gradle@v4
27+
- run: ./gradlew build

.github/workflows/release.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: Release
2+
3+
on:
4+
release:
5+
types: [published]
6+
7+
permissions:
8+
contents: write
9+
10+
jobs:
11+
release:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
- name: Configure git
16+
run: |
17+
git config --global user.name "CI"
18+
git config --global user.email "ci@clanker.zone"
19+
git config --global init.defaultBranch main
20+
- name: Extract version from tag
21+
id: version
22+
run: |
23+
VERSION="${{ github.event.release.tag_name }}"
24+
VERSION="${VERSION#v}"
25+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
26+
- uses: actions/setup-java@v4
27+
with:
28+
distribution: jetbrains
29+
java-version: 17
30+
- uses: gradle/actions/setup-gradle@v4
31+
- name: Build and test
32+
run: ./gradlew build -PVERSION_NAME=${{ steps.version.outputs.version }}
33+
- name: Publish to Maven Central
34+
run: ./gradlew publishAndReleaseToMavenCentral -PVERSION_NAME=${{ steps.version.outputs.version }}
35+
env:
36+
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_USERNAME }}
37+
ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_PASSWORD }}
38+
ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.GPG_SIGNING_KEY }}
39+
ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{ secrets.GPG_KEY_ID }}
40+
ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.GPG_PASSPHRASE }}
41+
ORG_GRADLE_PROJECT_RELEASE_SIGNING_ENABLED: true

build-logic/build.gradle.kts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
plugins {
2+
`kotlin-dsl`
3+
}
4+
5+
repositories {
6+
mavenCentral()
7+
gradlePluginPortal()
8+
}
9+
10+
dependencies {
11+
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${embeddedKotlinVersion}")
12+
implementation("com.vanniktech:gradle-maven-publish-plugin:0.32.0")
13+
implementation("org.gradle.toolchains:foojay-resolver:1.0.0")
14+
implementation("org.jetbrains.kotlinx:kover-gradle-plugin:0.9.1")
15+
implementation("io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.23.8")
16+
implementation("org.jlleitschuh.gradle:ktlint-gradle:12.2.0")
17+
}
18+
19+
gradlePlugin {
20+
plugins {
21+
register("clkx-settings") {
22+
id = "clkx-settings"
23+
implementationClass = "zone.clanker.gradle.conventions.ClkxSettingsPlugin"
24+
}
25+
}
26+
}

build-logic/settings.gradle.kts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
dependencyResolutionManagement {
2+
repositories {
3+
mavenCentral()
4+
gradlePluginPortal()
5+
}
6+
}
7+
rootProject.name = "build-logic"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
plugins {
2+
id("clkx-module")
3+
id("clkx-toolchain")
4+
id("clkx-plugin")
5+
id("clkx-publish")
6+
id("clkx-testing")
7+
id("clkx-cover")
8+
id("clkx-konsist")
9+
id("clkx-detekt")
10+
id("clkx-ktlint")
11+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
plugins {
2+
id("org.jetbrains.kotlinx.kover")
3+
}
4+
5+
kover {
6+
reports {
7+
filters {
8+
excludes {
9+
// @TaskAction run() methods delegate to Cli.execAndPrint — untestable without real CLIs
10+
annotatedBy("org.gradle.api.tasks.TaskAction")
11+
// Settings plugin apply() requires real Gradle Settings — tested via registerTasks
12+
classes("*\$SettingsPlugin", "*\$SettingsPlugin\$*")
13+
}
14+
}
15+
verify {
16+
rule {
17+
minBound(90)
18+
}
19+
}
20+
}
21+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
plugins {
2+
id("io.gitlab.arturbosch.detekt")
3+
}
4+
5+
detekt {
6+
config.setFrom(rootProject.file("config/detekt.yml"))
7+
buildUponDefaultConfig = true
8+
parallel = true
9+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
plugins {
2+
`java-base`
3+
}
4+
5+
val sourceSets = the<SourceSetContainer>()
6+
7+
val slopTest by sourceSets.creating {
8+
compileClasspath += sourceSets["main"].output
9+
runtimeClasspath += sourceSets["main"].output
10+
}
11+
12+
configurations[slopTest.implementationConfigurationName].extendsFrom(configurations["testImplementation"])
13+
configurations[slopTest.runtimeOnlyConfigurationName].extendsFrom(configurations["testRuntimeOnly"])
14+
15+
dependencies {
16+
"slopTestImplementation"("com.lemonappdev:konsist:0.17.3")
17+
"slopTestImplementation"("io.kotest:kotest-runner-junit5:5.9.1")
18+
"slopTestImplementation"("io.kotest:kotest-assertions-core:5.9.1")
19+
}
20+
21+
val slopTask = tasks.register<Test>("slopTest") {
22+
description = "Run slop taste tests — architecture, naming, boundaries, style"
23+
group = "verification"
24+
testClassesDirs = slopTest.output.classesDirs
25+
classpath = slopTest.runtimeClasspath
26+
useJUnitPlatform()
27+
}
28+
29+
tasks.named("check") {
30+
dependsOn(slopTask)
31+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
plugins {
2+
id("org.jlleitschuh.gradle.ktlint")
3+
}
4+
5+
ktlint {
6+
version.set("1.5.0")
7+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import com.vanniktech.maven.publish.JavaLibrary
2+
import com.vanniktech.maven.publish.JavadocJar
3+
4+
plugins {
5+
id("clkx-module")
6+
id("clkx-toolchain")
7+
id("clkx-testing")
8+
id("clkx-cover")
9+
id("clkx-konsist")
10+
id("clkx-detekt")
11+
id("clkx-ktlint")
12+
id("com.vanniktech.maven.publish")
13+
}
14+
15+
mavenPublishing {
16+
configure(JavaLibrary(javadocJar = JavadocJar.Empty()))
17+
}

0 commit comments

Comments
 (0)