agentsclimarketplace

Gradle expert

Skill kinhluan/rules-quarkus-skills/.agent-skills/gradle-expert

Expert knowledge for Gradle Build Tool, dependency management, and Gradle-to-Bazel migration. Use for build configuration and project lifecycle questions.From its SKILL.md

Install
npx -y skills add kinhluan/rules-quarkus-skills --skill gradle-expert

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

4 things to look at

  • reads credentialsReads from 2 credential sources: `MAVEN_USER` and 1 more.
  • 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
  • runs commandsInstructs the agent to run 7 commands, including `./gradlew dependencies --configuration runtimeClasspath` and 6 more.
  • fetches URLsInstructs the agent to fetch 5 URLs, including https://docs.gradle.org/current/userguide/kotlin_dsl.html and 4 more.

SKILL.md

12.0 KB, ~3.0k tokens by cl100k_base, as published. Nobody here has run it

gradle-expert

Keyword: gradle | Platforms: gemini,claude,codex

Modern Gradle Build Tool Expert Skill - Specialized in performance, dependency management, and polyglot builds.

Core Mandates

  • DSL Proficiency: Expert in both Groovy DSL (build.gradle) and Kotlin DSL (build.gradle.kts).
  • Dependency Configurations: Distinguish between api, implementation, runtimeOnly, and testImplementation.
  • Build Performance: Leverage Build Cache, Daemon, and Parallel execution to optimize feedback loops.
  • Convention over Configuration: Prefer built-in plugins (java-library, application, maven-publish) over custom logic.

build.gradle.kts Examples

Quarkus Project

// build.gradle.kts
plugins {
    java
    id("io.quarkus") version "3.20.1"
}

repositories {
    mavenCentral()
}

val quarkusPlatformVersion: String by project  // from gradle.properties

dependencies {
    // BOM - manages all Quarkus versions
    implementation(enforcedPlatform("io.quarkus.platform:quarkus-bom:${quarkusPlatformVersion}"))

    // No versions needed - managed by BOM
    implementation("io.quarkus:quarkus-rest")
    implementation("io.quarkus:quarkus-arc")
    implementation("io.quarkus:quarkus-hibernate-orm-panache")

    // Test
    testImplementation("io.quarkus:quarkus-junit5")
    testImplementation("io.rest-assured:rest-assured")
}

java {
    sourceCompatibility = JavaVersion.VERSION_21
    targetCompatibility = JavaVersion.VERSION_21
}

tasks.withType<Test> {
    useJUnitPlatform()
    systemProperty("java.util.logging.manager", "org.jboss.logmanager.LogManager")
}

Multi-Module with Version Catalog

# gradle/libs.versions.toml
[versions]
quarkus = "3.20.1"
jackson = "2.18.2"
junit = "5.11.4"
assertj = "3.27.3"

[libraries]
quarkus-bom = { module = "io.quarkus.platform:quarkus-bom", version.ref = "quarkus" }
quarkus-rest = { module = "io.quarkus:quarkus-rest" }
quarkus-arc = { module = "io.quarkus:quarkus-arc" }
quarkus-hibernate = { module = "io.quarkus:quarkus-hibernate-orm-panache" }
quarkus-junit5 = { module = "io.quarkus:quarkus-junit5" }
jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" }
junit-bom = { module = "org.junit:junit-bom", version.ref = "junit" }
assertj = { module = "org.assertj:assertj-core", version.ref = "assertj" }

[plugins]
quarkus = { id = "io.quarkus", version.ref = "quarkus" }
// settings.gradle.kts
rootProject.name = "my-platform"
include("common", "service-user", "service-order")
// build.gradle.kts (root)
plugins {
    java
    alias(libs.plugins.quarkus) apply false
}

subprojects {
    apply(plugin = "java")

    repositories {
        mavenCentral()
    }

    dependencies {
        implementation(platform(libs.quarkus.bom))
        implementation(platform(libs.junit.bom))
    }

    java {
        toolchain {
            languageVersion.set(JavaLanguageVersion.of(21))
        }
    }
}
// service-user/build.gradle.kts
plugins {
    alias(libs.plugins.quarkus)
}

dependencies {
    implementation(project(":common"))
    implementation(libs.quarkus.rest)
    implementation(libs.quarkus.arc)
    implementation(libs.quarkus.hibernate)

    testImplementation(libs.quarkus.junit5)
    testImplementation(libs.assertj)
}

Dependency Configuration Decision Tree

Does the consuming module need this at compile time?
  YES → Does the consuming module also see this in ITS public API?
    YES → api (leaks to consumers' compile classpath)
    NO  → implementation (hidden from consumers)
  NO → Is it needed at runtime only?
    YES → runtimeOnly (e.g., JDBC drivers, SLF4J bindings)
    NO  → Is it only for tests?
      YES → testImplementation
      NO  → compileOnly (e.g., annotation processors, provided-like)

Do vs Don't

// BAD - using 'api' everywhere leaks dependencies, slows compilation
dependencies {
    api("com.google.guava:guava:33.4.0-jre")         // Leaked!
    api("io.quarkus:quarkus-hibernate-orm-panache")    // Leaked!
}

// GOOD - only 'api' what consumers actually need in their code
dependencies {
    api("com.example:shared-dto:1.0")                 // Consumers use these types
    implementation("com.google.guava:guava:33.4.0-jre")  // Internal only
    implementation("io.quarkus:quarkus-hibernate-orm-panache")
}

Version Conflict Resolution Workflow

Step 1: Identify the conflict

# Show dependency tree for a specific configuration
./gradlew dependencies --configuration runtimeClasspath

# Filter for a specific module
./gradlew dependencyInsight --dependency jackson-databind --configuration runtimeClasspath

# Output:
# com.fasterxml.jackson.core:jackson-databind:2.18.2
#    variant "compile" [
#       Requested: 2.14.0  ← conflict
#       Selected:  2.18.2  ← Gradle picked highest
#    ]

Step 2: Understand Gradle's resolution strategy

Gradle uses highest version wins by default. This is usually safe but can break binary compatibility.

Step 3: Resolve

// Option A: Force a specific version (use sparingly)
configurations.all {
    resolutionStrategy {
        force("com.fasterxml.jackson.core:jackson-databind:2.18.2")
    }
}

// Option B: Use a BOM/platform (preferred)
dependencies {
    implementation(platform("com.fasterxml.jackson:jackson-bom:2.18.2"))
    // All Jackson modules now use 2.18.2
}

// Option C: Exclude transitive dependency
dependencies {
    implementation("some-lib:some-lib:1.0") {
        exclude(group = "com.fasterxml.jackson.core", module = "jackson-databind")
    }
}

// Option D: Fail on conflict (strict mode for CI)
configurations.all {
    resolutionStrategy {
        failOnVersionConflict()
    }
}

Resolution Priority

PriorityStrategyWhen to use
1stBOM / platform()When a BOM exists (jackson-bom, netty-bom, quarkus-bom)
2ndVersion CatalogCentralize versions in libs.versions.toml
3rdexclude()When one lib brings a known bad transitive
4thforce()Last resort - overrides everything, can mask issues

Common Errors & Fixes

"Could not resolve all dependencies"

// Cause: Missing repository or wrong coordinates
repositories {
    mavenCentral()
    // Add private repo if needed:
    maven {
        url = uri("https://nexus.example.com/repository/maven-releases/")
        credentials {
            username = providers.environmentVariable("MAVEN_USER").orNull
            password = providers.environmentVariable("MAVEN_TOKEN").orNull
        }
    }
}

"Execution failed: A valid toolchain could not be found"

// Fix: Specify Java toolchain
java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(21))
    }
}

// Or in gradle.properties:
// org.gradle.java.home=/path/to/jdk21

Build cache not working

# gradle.properties
org.gradle.caching=true
org.gradle.parallel=true
org.gradle.daemon=true
org.gradle.jvmargs=-Xmx4g -XX:+HeapDumpOnOutOfMemoryError
// settings.gradle.kts - remote cache
buildCache {
    local {
        isEnabled = true
    }
    remote<HttpBuildCache> {
        url = uri("https://cache.example.com/cache/")
        isPush = System.getenv("CI") != null  // Only push from CI
    }
}

"Cannot change dependencies after configuration resolution"

// BAD - resolving a configuration during configuration phase
val runtimeJars = configurations.runtimeClasspath.get().files  // Triggers resolution!

// GOOD - defer to execution phase
tasks.register("listDeps") {
    val runtimeCp = configurations.runtimeClasspath
    doLast {
        runtimeCp.get().files.forEach { println(it) }
    }
}

Slow builds diagnostic

# Generate build scan (interactive report)
./gradlew build --scan

# Profile locally
./gradlew build --profile
# Opens report in build/reports/profile/

# Check configuration cache compatibility
./gradlew build --configuration-cache

Slow builds optimization checklist

CheckAction
Daemon enabled?org.gradle.daemon=true in gradle.properties
Parallel builds?org.gradle.parallel=true
Build cache?org.gradle.caching=true
Configuration cache?--configuration-cache (Gradle 8.1+)
Unnecessary api deps?Switch to implementation to reduce recompilation
allprojects{} / subprojects{} blocks?Migrate to convention plugins
Task Configuration Avoidance?Use tasks.register not tasks.create

Gradle-to-Bazel Migration

Configuration Mapping Table

GradleBazelNotes
apiexports = [...]Visible to transitive consumers
implementationdeps = [...]Hidden from consumers
runtimeOnlyruntime_deps = [...]Not on compile classpath
compileOnlydeps = [...] + neverlink = TrueCompile but not package
testImplementationtest target depsSeparate test target
project(":sub")"//sub:target"Bazel label
./gradlew buildbazel build //...Build all
./gradlew testbazel test //...Test all
Version Catalogrules_jvm_externalDifferent mechanism

Exporting Dependencies for Bazel

# Generate dependency list from Gradle
./gradlew dependencies --configuration runtimeClasspath \
  | grep '\\---' | sed 's/.*--- //' | sort -u

# Then translate to rules_jvm_external format in MODULE.bazel

Advanced Patterns

  • Build Scan: Using Gradle Build Scans for debugging performance and dependency issues.
  • Custom Tasks: Writing idiomatic tasks using the Task Configuration Avoidance API.
  • Version Catalogs: Managing versions and libraries centrally via libs.versions.toml.

Expert Tips

  • Avoid using the deprecated compile configuration; use implementation or api.
  • Use ./gradlew dependencies --configuration runtimeClasspath to visualize the dependency graph.
  • Prefer Kotlin DSL for better IDE support and type safety in complex builds.
  • Use gradle wrapper --gradle-version=8.12 to pin Gradle version for reproducibility.
  • Always use tasks.register (lazy) over tasks.create (eager) for Task Configuration Avoidance.
  • Use ./gradlew build --dry-run to preview task execution order without running anything.

🌐 Gradle Knowledge Sources

Directive: Use web_fetch to find Kotlin DSL syntax, version catalog patterns, or Gradle-to-Bazel migration strategies if a build configuration is complex.

References

Skill Interoperability

The gradle-expert 🐘 skill provides expertise in modern build DSLs and performance, supporting:

  • rules-quarkus 🔧: Facilitates the migration of Gradle-based projects to Bazel.

What ships with it: 1 file

914 B alongside SKILL.md

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.