agentsclimarketplace

Gradle expert

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

πŸ€– Complete AI expert ecosystem for Modern Java, Quarkus & Bazel development β˜•οΈβš‘οΈ Coverage for Vert.x, GraalVM, Maven/Gradle migration, and more πŸš€

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.

One thing to look at

  • 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.

What its author says it does

Copied from the file, not written here

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

SKILL.md

12.0 KB, 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.

Keep looking

Skills are one crate of 328,083. 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.