Skip to content

Commit 77bae44

Browse files
Merge pull request #290 from nebula-plugins/modernization
Modernization, Phase 2
2 parents 7fc031e + 004865b commit 77bae44

12 files changed

+226
-171
lines changed

src/main/groovy/nebula/plugin/dependencylock/DependencyLockTaskConfigurer.groovy

Lines changed: 60 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -170,15 +170,14 @@ class DependencyLockTaskConfigurer {
170170
//TODO: address Invocation of Task.project at execution time has been deprecated.
171171
DeprecationLogger.whileDisabled {
172172
SaveLockTask globalSave = project.rootProject.tasks.findByName(SAVE_GLOBAL_LOCK_TASK_NAME) as SaveLockTask
173-
if (globalSave && globalSave.outputLock && globalSave.outputLock.exists()) {
173+
if (globalSave && globalSave.outputLock.isPresent() && globalSave.outputLock.get().asFile.exists()) {
174174
throw new GradleException('Cannot save individual locks when global lock is in place, run deleteGlobalLock task')
175175
}
176176
}
177177
}
178-
saveTask.conventionMapping.with {
179-
generatedLock = { getBuildDirLockFile(lockFilename, extension) }
180-
outputLock = { getProjectDirLockFile(lockFilename, extension) }
181-
}
178+
// Set input and output files using Property API
179+
saveTask.generatedLock.set(project.layout.buildDirectory.file(lockFilename ?: extension.lockFile.get()))
180+
saveTask.outputLock.set(project.layout.projectDirectory.file(lockFilename ?: extension.lockFile.get()))
182181
}
183182
configureCommonSaveTask(saveLockTask, lockTask, updateTask)
184183

@@ -191,8 +190,10 @@ class DependencyLockTaskConfigurer {
191190
saveTask.notCompatibleWithConfigurationCache("Dependency locking plugin tasks require project access. Please consider using Gradle's dependency locking mechanism")
192191
saveTask.mustRunAfter lockTask, updateTask
193192
saveTask.outputs.upToDateWhen {
194-
if (saveTask.generatedLock.exists() && saveTask.outputLock.exists()) {
195-
saveTask.generatedLock.text == saveTask.outputLock.text
193+
def generated = saveTask.generatedLock.get().asFile
194+
def output = saveTask.outputLock.get().asFile
195+
if (generated.exists() && output.exists()) {
196+
generated.text == output.text
196197
} else {
197198
false
198199
}
@@ -210,52 +211,62 @@ class DependencyLockTaskConfigurer {
210211
DeprecationLogger.whileDisabled {
211212
project.subprojects.each { Project sub ->
212213
SaveLockTask save = sub.tasks.findByName(SAVE_LOCK_TASK_NAME) as SaveLockTask
213-
if (save && save.outputLock?.exists()) {
214+
if (save && save.outputLock.isPresent() && save.outputLock.get().asFile.exists()) {
214215
throw new GradleException('Cannot save global lock, one or more individual locks are in place, run deleteLock task')
215216
}
216217
}
217218
}
218219
}
219-
globalSaveTask.conventionMapping.with {
220-
generatedLock = { getBuildDirGlobalLockFile(lockFilename, extension) }
221-
outputLock = { getProjectDirGlobalLockFile(lockFilename, extension) }
222-
}
220+
// Set input and output files using Property API
221+
globalSaveTask.generatedLock.set(project.layout.buildDirectory.file(lockFilename ?: extension.globalLockFile.get()))
222+
globalSaveTask.outputLock.set(project.layout.projectDirectory.file(lockFilename ?: extension.globalLockFile.get()))
223223
}
224224
configureCommonSaveTask(globalSaveLockTask, globalLockTask, globalUpdateLockTask)
225225

226226
globalSaveLockTask
227227
}
228228

229229
private TaskProvider<GenerateLockTask> configureGenerateLockTask(TaskProvider<GenerateLockTask> lockTask, String lockFilename, DependencyLockExtension extension, Map overrides) {
230-
setupLockConventionMapping(lockTask, extension, overrides)
230+
setupLockProperties(lockTask, extension, overrides)
231231
lockTask.configure {
232-
it.conventionMapping.with {
233-
dependenciesLock = { getBuildDirLockFile(lockFilename, extension) }
234-
configurationNames = { extension.configurationNames.get() }
235-
skippedConfigurationNames = { extension.skippedConfigurationNamesPrefixes.get() }
236-
}
232+
// Set output file
233+
it.dependenciesLock.set(project.layout.buildDirectory.file(lockFilename ?: extension.lockFile.get()))
234+
// Set configuration names
235+
it.configurationNames.set(extension.configurationNames)
236+
it.skippedConfigurationNames.set(extension.skippedConfigurationNamesPrefixes)
237+
238+
// Always regenerate lock files - dependency changes in build.gradle aren't tracked as task inputs
239+
it.outputs.upToDateWhen { false }
237240
}
238241

239242
lockTask
240243
}
241244

242-
private void setupLockConventionMapping(TaskProvider<GenerateLockTask> task, DependencyLockExtension extension, Map overrideMap) {
245+
private void setupLockProperties(TaskProvider<GenerateLockTask> task, DependencyLockExtension extension, Map overrideMap) {
243246
task.configure { generateTask ->
244247
generateTask.notCompatibleWithConfigurationCache("Dependency locking plugin tasks require project access. Please consider using Gradle's dependency locking mechanism")
245-
generateTask.conventionMapping.with {
246-
skippedDependencies = { extension.skippedDependencies.get() }
247-
includeTransitives = {
248-
project.hasProperty('dependencyLock.includeTransitives') ? Boolean.parseBoolean(project['dependencyLock.includeTransitives'] as String) : extension.includeTransitives.get()
249-
}
250-
filter = { extension.dependencyFilter }
251-
overrides = { overrideMap }
252-
}
248+
249+
// Set skipped dependencies
250+
generateTask.skippedDependencies.set(extension.skippedDependencies)
251+
252+
// Set includeTransitives with provider that checks project property first, then extension
253+
generateTask.includeTransitives.set(
254+
project.providers.gradleProperty('dependencyLock.includeTransitives')
255+
.map { it.toBoolean() }
256+
.orElse(extension.includeTransitives)
257+
)
258+
259+
// Set filter (kept as Closure for backward compatibility)
260+
generateTask.filter = extension.dependencyFilter
261+
262+
// Set overrides
263+
generateTask.overrides.set(overrideMap)
253264
}
254265
}
255266

256267
private TaskProvider<GenerateLockTask> configureGlobalLockTask(TaskProvider<GenerateLockTask> globalLockTask, String lockFilename,
257268
DependencyLockExtension extension, Map overrides) {
258-
setupLockConventionMapping(globalLockTask, extension, overrides)
269+
setupLockProperties(globalLockTask, extension, overrides)
259270
globalLockTask.configure { globalGenerateTask ->
260271
globalGenerateTask.notCompatibleWithConfigurationCache("Dependency locking plugin tasks require project access. Please consider using Gradle's dependency locking mechanism")
261272
globalGenerateTask.doFirst {
@@ -264,8 +275,14 @@ class DependencyLockTaskConfigurer {
264275
project.subprojects.each { sub -> sub.repositories.each { repo -> project.repositories.add(repo) } }
265276
}
266277
}
278+
279+
// Set output file
280+
globalGenerateTask.dependenciesLock.set(project.layout.buildDirectory.file(lockFilename ?: extension.globalLockFile.get()))
281+
282+
// TODO: Refactor this to not use conventionMapping. The global lock's configuration logic is complex
283+
// because it creates aggregate configurations at execution time. This needs a proper Property-based solution.
284+
// For now, keeping conventionMapping for this specific case to maintain functionality.
267285
globalGenerateTask.conventionMapping.with {
268-
dependenciesLock = { getBuildDirGlobalLockFile(lockFilename, extension) }
269286
configurations = {
270287
def subprojects = project.subprojects.collect { subproject ->
271288
def ext = subproject.getExtensions().findByType(DependencyLockExtension)
@@ -316,24 +333,18 @@ class DependencyLockTaskConfigurer {
316333
private TaskProvider<MigrateToCoreLocksTask> configureMigrateToCoreLocksTask(DependencyLockExtension extension) {
317334
def migrateLockedDepsToCoreLocksTask = project.tasks.register(MIGRATE_LOCKED_DEPS_TO_CORE_LOCKS_TASK_NAME, MigrateLockedDepsToCoreLocksTask)
318335
def migrateToCoreLocksTask = project.tasks.register(MIGRATE_TO_CORE_LOCKS_TASK_NAME, MigrateToCoreLocksTask)
319-
def lockFile = new File(project.projectDir, extension.lockFile.get())
320-
def dependencyLock = new File(project.projectDir, "gradle.lockfile")
321336

322337
migrateLockedDepsToCoreLocksTask.configure {
323-
it.conventionMapping.with {
324-
configurationNames = { extension.configurationNames.get() }
325-
inputLockFile = { lockFile }
326-
outputLock = { dependencyLock }
327-
}
338+
it.configurationNames.set(extension.configurationNames)
339+
it.inputLockFile.set(project.layout.projectDirectory.file(extension.lockFile))
340+
it.outputLock.set(project.layout.projectDirectory.file("gradle.lockfile"))
328341
it.notCompatibleWithConfigurationCache("Dependency locking plugin tasks require project access. Please consider using Gradle's dependency locking mechanism")
329342

330343
}
331344

332345
migrateToCoreLocksTask.configure {
333-
it.conventionMapping.with {
334-
configurationNames = { extension.configurationNames.get() }
335-
outputLock = { dependencyLock }
336-
}
346+
it.configurationNames.set(extension.configurationNames)
347+
it.outputLock.set(project.layout.projectDirectory.file("gradle.lockfile"))
337348
it.dependsOn project.tasks.named(MIGRATE_LOCKED_DEPS_TO_CORE_LOCKS_TASK_NAME)
338349
it.notCompatibleWithConfigurationCache("Dependency locking plugin tasks require project access. Please consider using Gradle's dependency locking mechanism")
339350
}
@@ -375,11 +386,18 @@ class DependencyLockTaskConfigurer {
375386
diffLockTask.configure { diffTask ->
376387
diffTask.notCompatibleWithConfigurationCache("Dependency locking plugin tasks require project access. Please consider using Gradle's dependency locking mechanism")
377388
diffTask.mustRunAfter(project.tasks.named(GENERATE_LOCK_TASK_NAME), project.tasks.named(UPDATE_LOCK_TASK_NAME))
389+
390+
// Set file properties
391+
def lockFileProvider = extension.lockFile.map { lockFileName ?: it }
378392
def existing = new File(project.projectDir, lockFileName ?: extension.lockFile.get())
379393
if (existing.exists()) {
380-
diffTask.existingLockFile = existing
394+
diffTask.existingLockFile.set(project.layout.projectDirectory.file(lockFileProvider))
381395
}
382-
diffTask.updatedLockFile = new File(project.layout.buildDirectory.getAsFile().get(), lockFileName ?: extension.lockFile.get())
396+
diffTask.updatedLockFile.set(project.layout.buildDirectory.file(lockFileProvider))
397+
398+
// Set output properties
399+
diffTask.outputDir.set(project.layout.buildDirectory.dir("dependency-lock"))
400+
diffTask.diffFile.set(diffTask.outputDir.file("lockdiff.${diffTask.diffFileExtension()}"))
383401
}
384402

385403
project.tasks.named(SAVE_LOCK_TASK_NAME).configure { save ->

src/main/groovy/nebula/plugin/dependencylock/tasks/AbstractMigrateToCoreLocksTask.groovy

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ package nebula.plugin.dependencylock.tasks
1717

1818

1919
import org.gradle.api.DefaultTask
20+
import org.gradle.api.file.RegularFileProperty
21+
import org.gradle.api.provider.SetProperty
2022
import org.gradle.api.tasks.Input
2123
import org.gradle.api.tasks.Internal
2224
import org.gradle.api.tasks.OutputDirectory
@@ -29,9 +31,9 @@ abstract class AbstractMigrateToCoreLocksTask extends DefaultTask {
2931
String group = 'Locking'
3032

3133
@OutputFile
32-
File outputLock
34+
abstract RegularFileProperty getOutputLock()
3335

3436
@Input
35-
Set<String> configurationNames
37+
abstract SetProperty<String> getConfigurationNames()
3638

3739
}

src/main/groovy/nebula/plugin/dependencylock/tasks/CommitLockTask.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ abstract class CommitLockTask extends AbstractLockTask {
5555
@Optional
5656
abstract Property<Integer> getRemoteRetries()
5757

58-
@Input
58+
@Internal
5959
abstract Property<String> getRootDirPath()
6060

6161
private final ExecOperations execOperations

src/main/groovy/nebula/plugin/dependencylock/tasks/DiffLockTask.groovy

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import groovy.json.JsonSlurper
55
import nebula.dependencies.comparison.*
66
import nebula.plugin.dependencylock.diff.DiffReportGenerator
77
import nebula.plugin.dependencylock.utils.DependencyLockingFeatureFlags
8+
import org.gradle.api.file.DirectoryProperty
9+
import org.gradle.api.file.RegularFileProperty
810
import org.gradle.api.tasks.InputFile
911
import org.gradle.api.tasks.Internal
1012
import org.gradle.api.tasks.Optional
@@ -19,23 +21,23 @@ import org.gradle.work.DisableCachingByDefault
1921
import java.nio.charset.StandardCharsets
2022

2123
@DisableCachingByDefault
22-
class DiffLockTask extends AbstractLockTask {
24+
abstract class DiffLockTask extends AbstractLockTask {
2325
@Internal
2426
String description = 'Diff existing lock and generated lock file'
2527

2628
@InputFile
2729
@Optional
2830
@PathSensitive(PathSensitivity.NONE)
29-
File existingLockFile
31+
abstract RegularFileProperty getExistingLockFile()
3032

3133
@Internal
32-
File updatedLockFile
34+
abstract RegularFileProperty getUpdatedLockFile()
3335

3436
@OutputDirectory
35-
File outputDir = new File(project.layout.buildDirectory.getAsFile().get(), "dependency-lock")
37+
abstract DirectoryProperty getOutputDir()
3638

3739
@OutputFile
38-
File diffFile = new File(outputDir, "lockdiff.${this.diffFileExtension()}")
40+
abstract RegularFileProperty getDiffFile()
3941

4042
String diffFileExtension() {
4143
DependencyLockingFeatureFlags.isPathAwareDependencyDiffEnabled() ? "json" : "txt"
@@ -45,18 +47,18 @@ class DiffLockTask extends AbstractLockTask {
4547
def diffLocks() {
4648
//TODO: address Invocation of Task.project at execution time has been deprecated.
4749
DeprecationLogger.whileDisabled {
48-
ConfigurationsSet existingLock = readLocks(existingLockFile)
49-
ConfigurationsSet newLock = readLocks(updatedLockFile)
50+
ConfigurationsSet existingLock = readLocks(existingLockFile.asFile.getOrNull())
51+
ConfigurationsSet newLock = readLocks(updatedLockFile.asFile.get())
5052
if (DependencyLockingFeatureFlags.isPathAwareDependencyDiffEnabled()) {
5153
Map<String, List<DependencyDiff>> diffByConfiguration = new DependenciesComparison().performDiffByConfiguration(existingLock, newLock)
5254
DiffReportGenerator generator = Class.forName("nebula.plugin.dependencylock.diff.PathAwareDiffReportGenerator").newInstance() as DiffReportGenerator
5355
def lockDiff = generator.generateDiffReport(project, diffByConfiguration)
54-
outputDir.mkdirs()
55-
diffFile.text = JsonOutput.prettyPrint(JsonOutput.toJson(lockDiff))
56+
outputDir.asFile.get().mkdirs()
57+
diffFile.asFile.get().text = JsonOutput.prettyPrint(JsonOutput.toJson(lockDiff))
5658
} else {
5759
if (newLock.isEmpty()) {
58-
outputDir.mkdirs()
59-
diffFile.withPrintWriter(StandardCharsets.UTF_8.displayName()) { writer ->
60+
outputDir.asFile.get().mkdirs()
61+
diffFile.asFile.get().withPrintWriter(StandardCharsets.UTF_8.displayName()) { writer ->
6062
writer.println('--no updated locks to diff--')
6163
}
6264
} else {
@@ -83,9 +85,9 @@ class DiffLockTask extends AbstractLockTask {
8385
}
8486

8587
void writeDiff(List<DependencyDiff> diff) {
86-
outputDir.mkdirs()
88+
outputDir.asFile.get().mkdirs()
8789

88-
diffFile.withPrintWriter(StandardCharsets.UTF_8.displayName()) { writer ->
90+
diffFile.asFile.get().withPrintWriter(StandardCharsets.UTF_8.displayName()) { writer ->
8991
def newDeps = diff.findAll { it.isNew() }
9092
if (!newDeps.isEmpty()) {
9193
writer.println('new:')

0 commit comments

Comments
 (0)