Skip to content

Commit

Permalink
Add a marker task for writing just product dependencies locks (#1178)
Browse files Browse the repository at this point in the history
* Add a marker task for writing just product dependencies locks

In some circumstances, it is useful to do just one type of lock
writing at a time, without running everything that keys off of
--write-locks. This is less common for product-dependencies.lock
updates, which are now usually slower than other types, but this
still comes in useful in certain situations.

Adds a marker task named `writeProductDependenciesLocks`, matching
the convention of `writeVersionsLocks` in gradle-consistent-versions.
This modifies the behavior of the existing createManifest tasks.

Co-authored-by: Alex Landau <[email protected]>
Co-authored-by: svc-changelog <[email protected]>
Co-authored-by: Eric Sword <[email protected]>
  • Loading branch information
4 people authored Nov 10, 2021
1 parent 80d1287 commit 9e5f82c
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 6 deletions.
7 changes: 7 additions & 0 deletions changelog/@unreleased/pr-1178.v2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
type: improvement
improvement:
description: Add a new `writeProductDependenciesLocks` task that allows writing
out the `product-dependencies.lock` files without running `--write-locks` and
possibly triggering undesirable code paths from other gradle plugins.
links:
- https://github.com/palantir/sls-packaging/pull/1178
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.invocation.Gradle;
import org.gradle.api.provider.MapProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.provider.SetProperty;
Expand Down Expand Up @@ -139,7 +140,7 @@ private void requireAbsentLockfile() {
return;
}

if (getProject().getGradle().getStartParameter().isWriteDependencyLocks()) {
if (shouldWriteLocks(getProject())) {
lockfile.delete();
getLogger().lifecycle("Deleted {}", relativePath);
} else {
Expand All @@ -153,14 +154,23 @@ private File getLockfile() {
return getProject().file(ProductDependencyLockFile.LOCK_FILE);
}

public static boolean shouldWriteLocks(Project project) {
String taskName = project.getPath().equals(":")
? ":writeProductDependenciesLocks"
: project.getPath() + ":writeProductDependenciesLocks";
Gradle gradle = project.getGradle();
return gradle.getStartParameter().isWriteDependencyLocks()
|| gradle.getTaskGraph().hasTask(taskName);
}

private void ensureLockfileIsUpToDate(List<ProductDependency> productDeps) throws IOException {
File lockfile = getLockfile();
Path relativePath = getProject().getRootDir().toPath().relativize(lockfile.toPath());
String upToDateContents = ProductDependencyLockFile.asString(
productDeps, getInRepoProductIds().get());
boolean lockfileExists = lockfile.exists();

if (getProject().getGradle().getStartParameter().isWriteDependencyLocks()) {
if (shouldWriteLocks(getProject())) {
Files.writeString(lockfile.toPath(), upToDateContents);

if (!lockfileExists) {
Expand Down Expand Up @@ -244,7 +254,7 @@ public static TaskProvider<CreateManifestTask> createManifestTask(Project projec
task.getOutputs().upToDateWhen(new Spec<Task>() {
@Override
public boolean isSatisfiedBy(Task _task) {
return !project.getGradle().getStartParameter().isWriteDependencyLocks();
return !shouldWriteLocks(project);
}
});

Expand All @@ -257,6 +267,11 @@ public boolean isSatisfiedBy(Task _task) {
.configure(task -> task.dependsOn(createManifest));
});

project.getTasks()
.register("writeProductDependenciesLocks", WriteProductDependenciesLocksMarkerTask.class, task -> {
task.dependsOn(createManifest);
});

// We want `./gradlew --write-locks` to magically fix up the product-dependencies.lock file
// We can't do this at configuration time because it would mess up gradle-consistent-versions.
StartParameter startParam = project.getGradle().getStartParameter();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* (c) Copyright 2021 Palantir Technologies Inc. All rights reserved.
*
* 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 com.palantir.gradle.dist.tasks;

import org.gradle.api.DefaultTask;
import org.gradle.api.GradleException;
import org.gradle.api.tasks.TaskAction;

public class WriteProductDependenciesLocksMarkerTask extends DefaultTask {
@TaskAction
public final void checkWriteLocksShouldBeRunning() {
// Check that our task name matcher for writeProductDependenciesLocks is actually matching up the Gradle one;
// if this task is running but we didn't actually write locks, error out.
if (!CreateManifestTask.shouldWriteLocks(getProject())) {
throw new GradleException("This `writeProductDependenciesLocks` marker task has been run, but the "
+ "product-dependencies.lock files did not actually get written out at configuration time. Either "
+ "there is another task dependency on this task, which is not supported "
+ "(`writeProductDependenciesLocks` must be run as a gradle task from the command line - not as a "
+ "dependent task), or this is a bug and should be reported to the owners of the "
+ "gradle-sls-packaging plugin.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import org.gradle.testkit.runner.BuildResult
import java.util.jar.Attributes
import java.util.jar.JarOutputStream
import java.util.jar.Manifest
import spock.lang.Unroll

import java.util.zip.ZipFile
import org.gradle.testkit.runner.TaskOutcome
import org.junit.Assert
Expand Down Expand Up @@ -847,7 +849,8 @@ class JavaServiceDistributionPluginTests extends GradleIntegrationSpec {
launcherStatic.classpath.any { it.contains('/lib/mockito-core-2.7.22.jar') }
}

def 'docker can resolve inter-project product dependencies'() {
@Unroll
def 'docker can resolve inter-project product dependencies (#writeLocksTask)'() {
buildFile << """
buildscript {
repositories {
Expand Down Expand Up @@ -889,14 +892,17 @@ class JavaServiceDistributionPluginTests extends GradleIntegrationSpec {
}
""".stripIndent())
runTasks("--write-locks")
runTasks(writeLocksTask)
// We're just using generateDockerCompose as it conveniently resolves the 'docker' configuration for us
// Which in turn, conveniently depends on all subprojects' `productDependencies` configurations
file("docker-compose.yml.template").text = ''

expect:
runTasks("generateDockerCompose")

where:
writeLocksTask << ['--write-locks', 'writeProductDependenciesLocks']
}

def 'uses the runtimeClasspath in manifest jar'() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package com.palantir.gradle.dist.tasks
import com.palantir.gradle.dist.ObjectMappers
import com.palantir.gradle.dist.pdeps.ResolveProductDependenciesIntegrationSpec
import nebula.test.IntegrationSpec
import spock.lang.Unroll

class CreateManifestTaskIntegrationSpec extends IntegrationSpec {

Expand Down Expand Up @@ -179,6 +180,28 @@ class CreateManifestTaskIntegrationSpec extends IntegrationSpec {
]
}

@Unroll
def 'writes locks when #writeLocksTask is on the command line'() {
buildFile << """
distribution {
${ResolveProductDependenciesIntegrationSpec.PDEP}
}
""".stripIndent()

when:
def buildResult = runTasksSuccessfully(writeLocksTask)

then:
buildResult.wasExecuted(':createManifest')
file('product-dependencies.lock').text == """\
# Run ./gradlew --write-locks to regenerate this file
group1:name1 (1.0.0, 1.3.x)
""".stripIndent()

where:
writeLocksTask << ['--write-locks', 'writeProductDependenciesLocks', 'wPDL']
}

def "check depends on createManifest"() {
when:
def result = runTasks(':check')
Expand Down
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ distribution {
}
```

sls-packaging also maintains a lockfile, `product-dependencies.lock`, which should be checked in to Git. This file is an accurate reflection of all the inferred and explicitly defined product dependencies. Run **`./gradlew --write-locks`** to update it. e.g.
sls-packaging also maintains a lockfile, `product-dependencies.lock`, which should be checked in to Git. This file is an accurate reflection of all the inferred and explicitly defined product dependencies. Run **`./gradlew --write-locks`** or **`./gradlew writeProductDependenciesLocks`** to update it. e.g.

```
# Run ./gradlew --write-locks to regenerate this file
Expand Down

0 comments on commit 9e5f82c

Please sign in to comment.