Skip to content

Modernization, Phase 5: Configuration cache compatibility for core lock tasks#293

Merged
OdysseusLives merged 10 commits intomainfrom
modernization
Feb 10, 2026
Merged

Modernization, Phase 5: Configuration cache compatibility for core lock tasks#293
OdysseusLives merged 10 commits intomainfrom
modernization

Conversation

@OdysseusLives
Copy link
Copy Markdown
Member

@OdysseusLives OdysseusLives commented Feb 7, 2026

Purpose

Make the dependency-lock plugin compatible with Gradle's configuration cache where feasible by:

  • Eliminating execution-time project access in favor of values captured at configuration time (Property API, Resolution APIs).
  • Adopting Gradle's official Resolution APIs (ResolvedComponentResult, ResolvedArtifactResult) instead of Configuration objects for lock generation, per Gradle guidance.
  • Keeping a clear split between a config-cache–compatible path (regular locks) and a legacy path (global lock) that remains opt-in incompatible until a later phase.

Most-used lock tasks (generateLock, updateLock, saveLock, diffLock, commitLock) are configuration-cache compatible.
Global lock and migration tasks remain optionally incompatible by design.
The dependency resolution verifier is unchanged.

Changes by commit

  • 5.1 — SaveLockTask: globalLockFile, remove doFirst/project access, remove notCompatibleWithConfigurationCache() from SaveLockTask and Delete tasks.
  • 5.2 — DiffLockTask: remove marker for default path; note PathAwareDiff limitation.
  • 5.3 — GenerateLockTask/UpdateLockTask: Resolution API properties, lockFromResolutionResults() (using new API) vs lock(Collection<Configuration>) (using old API), wire in configurer, wireTaskProperties() in specs, empty-config handling.
  • 5.4 — Separate global vs regular paths: includeTransitives via conventionMapping for global lock, unique aggregate config names, setupLockProperties skip for global lock, LockTaskSpec wiring, GlobalLockDeprecations trait.
  • 5.5 — PathAwareDiffReportGenerator: DiffReportGenerator takes resolution result map; PathAwareDiffReportGenerator and DiffLockTask use resolutionResults; no execution-time project/Configuration access.
  • Test isolation — GlobalLockWithForceLauncherSpec: cleanup, no file pollution.
  • Config-cache tests — DependencyLockConfigurationAvoidanceSpec: comprehensive config-cache tests for regular and global lock tasks.

Breaking changes

None for normal plugin usage. Build scripts that only apply the plugin and use standard tasks are unchanged.

Internal / integration:

  • DiffReportGenerator: Implementations must now accept a Map<String, Provider<ResolvedComponentResult>> (resolution results) instead of Project. Only PathAwareDiffReportGenerator is updated; custom implementations would need to follow the new signature.
  • Global lock: Still uses the old API and notCompatibleWithConfigurationCache(). Tests that run with --configuration-cache and exercise global lock use disableConfigurationCache() where required.

…ible

Changes:
- Remove notCompatibleWithConfigurationCache() marker from SaveLockTask
- Add globalLockFile property to capture global lock path at config time
- Check for global lock conflict at execution time without project reference
- Removed doFirst block that accessed project.rootProject at execution time
- Remove notCompatibleWithConfigurationCache() from Delete tasks

SaveLockTask now uses only Property API and has zero project references.
…ible

Changes:
- Remove notCompatibleWithConfigurationCache() marker from DiffLockTask
- Add note about PathAwareDiffReportGenerator limitation (opt-in feature)

DiffLockTask's default diff path uses only Property API and is configuration cache compatible. The experimental path-aware diff feature (enabled via nebula.features.pathAwareDependencyDiff) requires future work.
…figuration cache compatible

- Add Resolution API properties (resolutionResults, peerProjectCoordinates) to capture dependency graphs using Gradle's official APIs instead of Configuration objects
- Refactor GenerateLockFromConfigurations to support:
  * NEW API: lock(Map<String, Provider<ResolvedComponentResult>>, List<String>) for config cache
  * OLD API: lock(Collection<Configuration>) for global lock (will be fixed in later phase)
- Update @TaskAction methods to use captured properties instead of project access
- Wire properties in DependencyLockTaskConfigurer using zip() for proper provider timing
- Add wireTaskProperties() helpers to GenerateLockTaskSpec and UpdateLockTaskSpec
- Handle projects with no configurations (create empty lock file instead of throwing exception)
…uration paths

This commit implements clean separation between NEW API (config cache compatible) and OLD API (global lock legacy) code paths.

Changes:
- Add includeTransitives to conventionMapping for global lock tasks
- Use unique aggregate configuration names to avoid conflicts
- Modify setupLockProperties to skip resolutionResults for global lock (skipResolutionResults parameter)
- Fix Property API syntax in UpdateLockTaskSpec (use .set() instead of direct assignment)
- Update LockTaskSpec.wireTaskProperties() to use proper lockableConfigurations() filtering logic
- Add deprecation suppression to global lock integration tests

This allows global lock to use OLD API (conventionMapping.configurations) while regular locks use NEW API (Resolution APIs). Both code paths coexist cleanly via resolutionResults.isPresent() check.

Test changes:
- Centralize global lock deprecation suppression using trait
  - Create GlobalLockDeprecations trait that provides a factory method for the JUnit rule that suppresses 'Invocation of Task.project at execution time' deprecation warnings from global lock tasks
  - Global lock tasks intentionally use the OLD API (conventionMapping) which is not configuration cache compatible. This trait centralizes the documentation and logic in one place while working properly with Spock tests (which require @rule to be declared on the spec class itself).
Fix test pollution issue where the test would pass in isolation but fail when run as part of the full test suite.

Changes:
- Changed keepFiles from true to false to avoid file pollution between tests
- Added cleanup() method to explicitly delete lock files after each test
- Removed duplicate disableConfigurationCache() call in test method (already in setup())

This ensures each test starts with a clean slate and doesn't interfere with subsequent tests.
…tible

Refactor PathAwareDiffReportGenerator to use Resolution APIs instead of Project.

Changes:
- Refactor DiffReportGenerator interface to accept ResolvedComponentResult map
- Update PathAwareDiffReportGenerator implementation to use resolution results
- Add resolutionResults property to DiffLockTask
- Wire resolution results at configuration time in DependencyLockTaskConfigurer
- Remove execution-time project access from PathAwareDiff code path
…onfig cache tests

Validate configuration cache compatibility for all regular and global lock tasks.
@OdysseusLives OdysseusLives merged commit 1861d2a into main Feb 10, 2026
3 checks passed
@OdysseusLives OdysseusLives deleted the modernization branch February 10, 2026 18:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant