Skip to content

imurphy-rh/gradle-lockfile

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

45 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

gradle-lockfile

A Gradle plugin that generates a comprehensive JSON lockfile containing all dependency coordinates, checksums, download URLs, and repository metadata needed for hermetic (offline, network-isolated) Gradle builds via Hermeto.

Plugin ID: io.github.hermetoproject.gradle-lockfile Version: 0.3.0-SNAPSHOT (lockfile schema v3)

Compatibility

Gradle Version Status Notes
7.0 - 7.1 Untested APIs present but not tested
7.2+ Supported Tested on 7.2, 7.6.4
8.x Supported Tested on 8.12
9.x Supported Tested on 9.4.1

JVM Requirements:

  • Plugin requires JDK 11+ at runtime (compiled to JVM target 11)
  • Gradle 7.2 requires JDK 8-16 to run (JDK 11 recommended)
  • Gradle 7.3+ supports JDK 17+
  • Gradle 8.5+ supports JDK 21+

Quick Start

Init script injection (recommended — no build file modification)

# 1. Generate the init script (run in the lockfile plugin's own project)
./gradlew generateInitScript

# 2. Apply to any Gradle 7.2+ project without modifying its build files
cd /path/to/target-project
./gradlew --no-parallel --init-script /path/to/hermeto-lockfile.gradle generateLockfile

All extension properties are configurable via -PlockfilePropertyName=value flags or LOCKFILE_UPPER_SNAKE environment variables. For example:

./gradlew --no-parallel --init-script hermeto-lockfile.gradle \
  -PlockfileLenientConfigResolution=true \
  -PlockfileAllowInternalRepositories=true \
  -PlockfileExtraDependencies=org.aspectj:aspectjtools:1.9.25 \
  generateLockfile

Direct plugin application

// settings.gradle.kts
pluginManagement {
    repositories { gradlePluginPortal() }
}
// build.gradle.kts
plugins {
    id("io.github.hermetoproject.gradle-lockfile") version "0.3.0"
}
lockfile {
    allowInternalRepositories.set(true)
    lenientConfigResolution.set(true)
}
./gradlew --no-parallel generateLockfile

Validation

Validated end-to-end against Spring Framework 7.x (Gradle 9.5.0, 27 subprojects):

Metric Value
Dependencies captured 1,497
Buildscript dependencies 190
Platform/BOM POMs 48
Parent POMs (inheritance chains) 206
Repositories 7
Hermetic build result ./gradlew :spring-beans:build --offline — 41s, 38 tasks, zero network access

What the lockfile captures

Data Notes
Group:Artifact:Version All configurations across all subprojects
SHA-256 checksums Computed from Gradle cache files
Download URLs HEAD-verified against declared repositories
Repository IDs Which repo serves each artifact
Classifiers -gradle813, -sources, etc.
Types jar, pom, module
Platform/BOM POMs Version-constraint-only components from dependency graph
Parent POM chains For inherited property resolution (${project.version}, etc.)
Dependency tree Optional nested children per entry
Conflict losers Artifacts that lost version negotiation
Plugin markers Gradle Plugin Portal ID→implementation mappings
Buildscript deps Separate array from main dependencies
Classifier companions Plain JAR alongside classified variants
.module metadata Gradle Module Metadata for KMP variant resolution
Extra dependencies Task-time artifacts via extraDependencies

Compared to Gradle's native lockfiles

Capability Native lockfile verification-metadata.xml This plugin
Repository URLs No No Yes
Checksums No Yes Yes
BOM/platform deps No No Yes
Single command, no build.gradle changes No No Yes (init script)
Classifier variants No Yes Yes
Dependency tree No No Yes
Parent POM chains No No Yes

Tasks

generateLockfile — resolution-api mode

Resolves artifacts through Gradle's dependency resolution API, performs parallel HEAD requests against declared Maven repositories, computes checksums from locally cached files, then writes the lockfile. source field: "resolution-api".

The task:

  1. Collects repositories declared in the project (project-declared repos first, Maven Central and Plugin Portal as fallbacks).
  2. Resolves all configurations across rootProject.allprojects (main and buildscript).
  3. buildSrc auto-scan — parses buildSrc/build.gradle[.kts] for additional coordinates.
  4. Lenient resolution — retries failed configurations with artifactView { lenient(true) } when lenientConfigResolution = true.
  5. Extra dependencies — resolves extraDependencies GAV coordinates from cache.
  6. Platform/BOM capture — walks resolutionResult.allComponents for constraint-only components; adds their POMs.
  7. Resolves conflict losers when includeConflictLosers = true.
  8. Classifier companion probing — probes for plain JARs alongside classified variants.
  9. Module metadata probing — probes for .module and .pom files per unique GAV.
  10. Parent POM chain walking — walks <parent> elements in all collected POMs; adds parent POMs from cache for inherited property resolution.
  11. Parallel HEAD requests to verify download URLs.
  12. Checksum computation from cached files.
  13. Writes lockfile.

generateLockfileFromVerification — verification-metadata mode

Uses an existing gradle/verification-metadata.xml as the source of checksums instead of re-resolving. Includes tamper detection: re-checksums cached artifacts against the XML values. source field: "verification-metadata".

generateInitScript

Generates a Groovy init script that applies the plugin to any Gradle 7.2+ project without modifying build files. Template-based with @@PLUGIN_VERSION@@ injection.

Extension Properties

Configure inside a lockfile { } block or via -P flags / env vars:

Property Type Default Description
outputFile String "gradle-lockfile.json" Output path relative to root project dir
checksumAlgorithm String "SHA-256" Hash algorithm
maxHeadConcurrency Int 10 Max parallel HEAD requests
maxArtifacts Int 10_000 Abort if artifact count exceeds this
maxRepositories Int 20 Abort if repository count exceeds this
allowHttpRepositories Boolean false Allow non-HTTPS repository URLs
allowInternalRepositories Boolean false Allow non-public/internal URLs
includeConflictLosers Boolean true Include version-conflict losers
includeDependencyTree Boolean true Populate children on each entry
maxConflictLosersToResolve Int 50 Cap on conflict losers resolved
maxGraphNodes Int 10_000 Cap on dependency graph nodes
verificationMetadataFile String "gradle/verification-metadata.xml" Input for verification mode
excludePatterns List<String> ["io.github.hermetoproject:gradle-lockfile-plugin"] Glob patterns to exclude
repositoryPriority List<String> [] URL substrings to prioritize during resolution
includeClassifierCompanions Boolean true Probe for plain JAR alongside classified variants
includeModuleMetadata Boolean true Probe for .module and .pom metadata files
detectChecksumMismatches Boolean false Compare cache size vs remote Content-Length
lenientConfigResolution Boolean false Retry failed configs with lenient artifact view
maxPluginMarkerProbes Int 500 Cap on plugin marker HEAD requests
extraDependencies List<String> [] GAV coordinates for task-time artifacts

Scope Values

Scope Meaning
compileClasspath, runtimeClasspath, etc. Standard Gradle configuration
buildscript, buildSrc Build infrastructure dependencies
companion Plain JAR probed alongside a classified variant
metadata .module or .pom metadata file
platform BOM/platform component (version constraints only)
parent-pom Parent POM from Maven inheritance chain
extra Manually specified via extraDependencies
conflict-loser Artifact that lost version negotiation

Gradle 9.5+ Multi-Project Builds

Gradle 9.5 enforces exclusive locks for cross-project configuration resolution during parallel execution. Use --no-parallel when generating lockfiles for multi-project builds. The plugin warns if parallel execution is detected.

Known Limitations

  1. Transitive BOM imports — BOMs imported via <dependencyManagement><scope>import</scope> in other POMs are not captured if not in the Gradle cache. These are resolved by Gradle at the constraint level without downloading the POM files.

  2. Task-time resolution — Dependencies resolved by plugins at task execution time (e.g., aspectjtools by the freefair aspectj plugin) require manual extraDependencies configuration. This is a workaround for Gradle's lack of a task-time resolution capture API.

  3. Configuration cache — Not compatible with Gradle's configuration cache. Designed for one-shot lockfile generation, not cached incremental builds.

  4. Kotlin implementation — Currently implemented in Kotlin. A Java 21 port is planned for consistency with the Maven lockfile plugin ecosystem.

Building

./gradlew build            # compile + unit tests
./gradlew test             # unit tests only
./gradlew functionalTest   # functional (integration) tests

Toolchain: JDK 25 for compilation, JVM 11 bytecode target.

License

Apache License 2.0

About

Gradle lockfile plugin for hermetic builds — generates lockfiles compatible with hermeto's Gradle backend

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors