Skip to content

Commit

Permalink
SaveLockTask: avoid using project object when using doFirst
Browse files Browse the repository at this point in the history
  • Loading branch information
rpalcolea committed Nov 10, 2023
1 parent 515be7e commit cd596ba
Show file tree
Hide file tree
Showing 16 changed files with 427 additions and 275 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import nebula.plugin.dependencylock.tasks.GenerateGlobalLockTask
import nebula.plugin.dependencylock.tasks.GenerateLockTask
import nebula.plugin.dependencylock.tasks.MigrateLockedDepsToCoreLocksTask
import nebula.plugin.dependencylock.tasks.MigrateToCoreLocksTask
import nebula.plugin.dependencylock.tasks.SaveGlobalLockTask
import nebula.plugin.dependencylock.tasks.SaveLockTask
import nebula.plugin.dependencylock.tasks.UpdateLockTask
import nebula.plugin.dependencylock.tasks.UpdateGlobalLockTask
Expand Down Expand Up @@ -74,7 +75,7 @@ class DependencyLockTaskConfigurer {
TaskProvider<UpdateLockTask> updateLockTask = project.tasks.register(UPDATE_LOCK_TASK_NAME, UpdateLockTask)
configureGenerateLockTask(updateLockTask, lockFilename, extension, overrides)

TaskProvider<SaveLockTask> saveTask = configureSaveTask(lockFilename, genLockTask, updateLockTask, extension)
TaskProvider<SaveLockTask> saveTask = configureSaveTask(lockFilename, globalLockFilename, genLockTask, updateLockTask, extension)
createDeleteLock(saveTask)

configureMigrateToCoreLocksTask(extension)
Expand All @@ -92,7 +93,7 @@ class DependencyLockTaskConfigurer {
globalUpdateLock = project.tasks.register(UPDATE_GLOBAL_LOCK_TASK_NAME, UpdateGlobalLockTask)
configureGlobalLockTask(globalUpdateLock, globalLockFilename, extension, overrides)

globalSave = configureGlobalSaveTask(globalLockFilename, globalLockTask, globalUpdateLock, extension)
globalSave = configureGlobalSaveTask(lockFilename, globalLockFilename, globalLockTask, globalUpdateLock, extension)

createDeleteGlobalLock(globalSave)
}
Expand All @@ -103,6 +104,10 @@ class DependencyLockTaskConfigurer {
}

private File getProjectDirLockFile(String lockFilename, DependencyLockExtension extension) {
getProjectDirLockFile(project, lockFilename, extension)
}

private File getProjectDirLockFile(Project project, String lockFilename, DependencyLockExtension extension) {
new File(project.projectDir, lockFilename ?: extension.lockFile.get())
}

Expand All @@ -111,11 +116,11 @@ class DependencyLockTaskConfigurer {
}

private File getProjectDirGlobalLockFile(String lockFilename, DependencyLockExtension extension) {
new File(project.projectDir, lockFilename ?: extension.globalLockFile.get())
new File(project.rootProject.projectDir, lockFilename ?: extension.globalLockFile.get())
}

private File getBuildDirGlobalLockFile(String lockFilename, DependencyLockExtension extension) {
new File(project.layout.buildDirectory.getAsFile().get(), lockFilename ?: extension.globalLockFile.get())
new File(project.rootProject.layout.buildDirectory.getAsFile().get(), lockFilename ?: extension.globalLockFile.get())
}

private void configureCommitTask(String clLockFileName, String globalLockFileName, TaskProvider<SaveLockTask> saveTask, DependencyLockExtension lockExtension,
Expand Down Expand Up @@ -154,39 +159,27 @@ class DependencyLockTaskConfigurer {
return patterns
}

private TaskProvider<SaveLockTask> configureSaveTask(String lockFilename, TaskProvider<GenerateLockTask> lockTask,
private TaskProvider<SaveLockTask> configureSaveTask(String lockFilename, String globalLockFilename, TaskProvider<GenerateLockTask> lockTask,
TaskProvider<UpdateLockTask> updateTask, DependencyLockExtension extension) {
TaskProvider<SaveLockTask> saveLockTask = project.tasks.register(SAVE_LOCK_TASK_NAME, SaveLockTask)

saveLockTask.configure { saveTask ->
saveTask.doFirst {
SaveLockTask globalSave = project.rootProject.tasks.findByName(SAVE_GLOBAL_LOCK_TASK_NAME) as SaveLockTask
if (globalSave?.outputLock?.isPresent() && globalSave?.outputLock?.get()?.exists()) {
throw new GradleException('Cannot save individual locks when global lock is in place, run deleteGlobalLock task')
}
}
projectHasGlobalLockFile.set(getProjectDirGlobalLockFile(globalLockFilename, extension).exists())
generatedLock.set(getBuildDirLockFile(lockFilename, extension))
outputLock.set(getProjectDirLockFile(lockFilename, extension))
saveTask.mustRunAfter lockTask, updateTask
}
saveLockTask
}

private TaskProvider<SaveLockTask> configureGlobalSaveTask(String lockFilename, TaskProvider<GenerateLockTask> globalLockTask,
private TaskProvider<SaveLockTask> configureGlobalSaveTask(String lockFilename, String globalLockFileName, TaskProvider<GenerateLockTask> globalLockTask,
TaskProvider<UpdateLockTask> globalUpdateLockTask, DependencyLockExtension extension) {
TaskProvider<SaveLockTask> globalSaveLockTask = project.tasks.register(SAVE_GLOBAL_LOCK_TASK_NAME, SaveLockTask)
TaskProvider<SaveLockTask> globalSaveLockTask = project.tasks.register(SAVE_GLOBAL_LOCK_TASK_NAME, SaveGlobalLockTask)

globalSaveLockTask.configure { globalSaveTask ->
globalSaveTask.doFirst {
project.subprojects.each { Project sub ->
SaveLockTask save = sub.tasks.findByName(SAVE_LOCK_TASK_NAME) as SaveLockTask
if (save && save.outputLock.isPresent() && save.outputLock?.get()?.exists()) {
throw new GradleException('Cannot save global lock, one or more individual locks are in place, run deleteLock task')
}
}
}
generatedLock.set(getBuildDirGlobalLockFile(lockFilename, extension))
outputLock.set(getProjectDirGlobalLockFile(lockFilename, extension))
anySubprojectHasLockFile.set(project.subprojects.any { getProjectDirLockFile(it, lockFilename, extension).exists() })
generatedLock.set(getBuildDirGlobalLockFile(globalLockFileName, extension))
outputLock.set(getProjectDirGlobalLockFile(globalLockFileName, extension))
mustRunAfter globalLockTask, globalUpdateLockTask
}
globalSaveLockTask
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright 2014-2019 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package nebula.plugin.dependencylock.tasks

import org.gradle.api.provider.Property
import org.gradle.api.specs.Spec
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
import org.gradle.work.DisableCachingByDefault

@DisableCachingByDefault
abstract class AbstractSaveLockTask extends AbstractLockTask {
@Internal
String description = 'Move the generated lock file into the project directory'

@InputFile
@PathSensitive(PathSensitivity.NONE)
abstract Property<File> getGeneratedLock()

@OutputFile
abstract Property<File> getOutputLock()

AbstractSaveLockTask() {
outputs.upToDateWhen(new Spec<AbstractSaveLockTask>() {
@Override
boolean isSatisfiedBy(AbstractSaveLockTask task) {
if (task.generatedLock.isPresent() && task.generatedLock.get().exists() && task.outputLock.isPresent() && task.outputLock.get().exists()) {
task.generatedLock.get().text == task.outputLock.get().text
} else {
false
}
}
})
}

abstract void verifyIfCanSaveLock()

@TaskAction
void saveLock() {
verifyIfCanSaveLock()
getOutputLock().get().text = generatedLock.get().text
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2014-2019 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package nebula.plugin.dependencylock.tasks

import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.work.DisableCachingByDefault

@DisableCachingByDefault
abstract class SaveGlobalLockTask extends AbstractSaveLockTask {

@Input
abstract Property<Boolean> getAnySubprojectHasLockFile()

@Override
void verifyIfCanSaveLock() {
if (anySubprojectHasLockFile.isPresent() && anySubprojectHasLockFile.get()) {
throw new IllegalStateException("Cannot save global lock, one or more individual locks are in place, run deleteLock task")
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,37 +16,20 @@
package nebula.plugin.dependencylock.tasks

import org.gradle.api.provider.Property
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.Input
import org.gradle.work.DisableCachingByDefault

@DisableCachingByDefault
abstract class SaveLockTask extends AbstractLockTask {
@Internal
String description = 'Move the generated lock file into the project directory'
abstract class SaveLockTask extends AbstractSaveLockTask {

SaveLockTask() {
outputs.upToDateWhen {
if (generatedLock.isPresent() && generatedLock.get().exists() && outputLock.isPresent() && outputLock.get().exists()) {
generatedLock.get().text == outputLock.get().text
} else {
false
}
@Input
abstract Property<Boolean> getProjectHasGlobalLockFile()

@Override
void verifyIfCanSaveLock() {
if (projectHasGlobalLockFile.isPresent() && projectHasGlobalLockFile.get()) {
throw new IllegalStateException("Cannot save individual locks when global lock is in place, run deleteGlobalLock task.")
}
}
@InputFile
@PathSensitive(PathSensitivity.NONE)
abstract Property<File> getGeneratedLock()

@OutputFile
abstract Property<File> getOutputLock()

@TaskAction
void saveLock() {
getOutputLock().get().text = generatedLock.get().text
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package nebula.plugin

import nebula.test.IntegrationTestKitSpec

abstract class BaseIntegrationTestKitSpec extends IntegrationTestKitSpec {
def setup() {

}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package nebula.plugin.dependencylock

import nebula.plugin.BaseIntegrationTestKitSpec
import nebula.plugin.dependencylock.utils.GradleVersionUtils
import nebula.test.IntegrationTestKitSpec
import nebula.test.dependencies.DependencyGraphBuilder
Expand All @@ -9,7 +10,7 @@ import org.gradle.util.GradleVersion
import org.junit.Rule
import org.junit.contrib.java.lang.system.ProvideSystemProperty

class AbstractDependencyLockPluginSpec extends IntegrationTestKitSpec {
abstract class AbstractDependencyLockPluginSpec extends BaseIntegrationTestKitSpec {
def expectedLocks = [
'annotationProcessor',
'compileClasspath',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
*/
package nebula.plugin.dependencylock

import nebula.plugin.BaseIntegrationTestKitSpec
import nebula.plugin.dependencyverifier.DependencyResolutionVerifierKt
import nebula.test.IntegrationTestKitSpec
import nebula.test.dependencies.DependencyGraphBuilder
Expand All @@ -27,7 +28,7 @@ import java.util.jar.JarOutputStream
import java.util.jar.Manifest

@Subject(DependencyResolutionVerifierKt)
class DependencyLockAlignmentLauncherSpec extends IntegrationTestKitSpec {
class DependencyLockAlignmentLauncherSpec extends BaseIntegrationTestKitSpec {
def setup() {
definePluginOutsideOfPluginBlock = true
keepFiles = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
*/
package nebula.plugin.dependencylock

import nebula.plugin.BaseIntegrationTestKitSpec
import nebula.plugin.dependencylock.dependencyfixture.Fixture
import nebula.test.IntegrationSpec
import org.ajoberstar.grgit.Grgit

import java.nio.file.Files

class DependencyLockCommitLauncherSpec extends IntegrationSpec {
class DependencyLockCommitLauncherSpec extends BaseIntegrationTestKitSpec {

protected Grgit git
protected Grgit originGit
Expand All @@ -35,28 +35,29 @@ class DependencyLockCommitLauncherSpec extends IntegrationSpec {
origin.mkdirs()

['build.gradle', 'settings.gradle'].each {
Files.move(new File(projectDir, it).toPath(), new File(origin, it).toPath())
def file = new File(projectDir, it)
if(!file.exists()) {
file.createNewFile()
}
Files.move(file.toPath(), new File(origin, it).toPath())
}

originGit = Grgit.init(dir: origin)

originGit.add(patterns: ['build.gradle', 'settings.gradle', '.gitignore', 'gradle.properties'] as Set)
originGit.add(patterns: ['build.gradle', 'settings.gradle', '.gitignore'] as Set)
originGit.commit(message: 'Initial checkout')

git = Grgit.clone(dir: projectDir, uri: origin.absolutePath) as Grgit

new File(projectDir, '.gitignore') << '''.gradle-test-kit/
.gradle/
new File(projectDir, '.gitignore') << '''.gradle-test-kit
.gradle
build/
gradle.properties'''.stripIndent()

// Enable configuration cache :)
new File(projectDir, 'gradle.properties') << '''org.gradle.configuration-cache=true'''.stripIndent()
def gradleProperties = new File(projectDir, "gradle.properties")
gradleProperties.createNewFile()
gradleProperties << "systemProp.nebula.features.coreLockingSupport=false"


// Enable configuration cache :)
gradleProperties << '''org.gradle.configuration-cache=true'''.stripIndent()
git.add(patterns: ['build.gradle', 'settings.gradle', '.gitignore'])
git.commit(message: 'Setup')
git.push()
}
Expand All @@ -74,7 +75,7 @@ gradle.properties'''.stripIndent()
buildFile << DependencyLockLauncherSpec.BUILD_GRADLE

when:
runTasksSuccessfully('generateLock', 'saveLock', 'commitLock')
runTasks('generateLock', 'saveLock', 'commitLock')

then:
def lockFile = new File(projectDir, 'dependencies.lock')
Expand All @@ -89,6 +90,9 @@ gradle.properties'''.stripIndent()
sub2.mkdirs()

buildFile << """\
plugins {
id 'com.netflix.nebula.dependency-lock'
}
subprojects {
apply plugin: 'java'
apply plugin: 'com.netflix.nebula.dependency-lock'
Expand All @@ -115,7 +119,7 @@ gradle.properties'''.stripIndent()


when:
runTasksSuccessfully('generateLock', 'saveLock', 'commitLock')
runTasks('generateLock', 'saveLock', 'commitLock')

then:
new File(projectDir, 'sub1/dependencies.lock').exists()
Expand All @@ -129,7 +133,9 @@ gradle.properties'''.stripIndent()
sub2.mkdirs()

buildFile << """\
apply plugin: 'com.netflix.nebula.dependency-lock'
plugins {
id 'com.netflix.nebula.dependency-lock'
}
subprojects {
apply plugin: 'java'
apply plugin: 'com.netflix.nebula.dependency-lock'
Expand All @@ -155,7 +161,7 @@ gradle.properties'''.stripIndent()
'''.stripIndent()

when:
runTasksSuccessfully('generateGlobalLock', 'saveGlobalLock', 'commitLock', '--info')
runTasks('generateGlobalLock', 'saveGlobalLock', 'commitLock', '--info')

then:
new File(projectDir, 'global.lock').exists()
Expand Down
Loading

0 comments on commit cd596ba

Please sign in to comment.