Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deduplicate sign task inputs #10337

Merged
merged 2 commits into from
Aug 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -79,4 +79,30 @@ class SigningConfigurationsIntegrationSpec extends SigningIntegrationSpec {
and:
file("build", "libs", "sign-1.0.jar.asc").text
}

def "duplicated inputs are handled"() {
given:
buildFile << """
signing {
${signingConfiguration()}
sign configurations.archives
}

${keyInfo.addAsPropertiesScript()}

artifacts {
// depend directly on 'jar' task in addition to dependency through 'archives'
archives jar
}
"""

when:
run "buildSignatures"

then:
executedAndNotSkipped ":signArchives"

and:
file("build", "libs", "sign-1.0.jar.asc").text
}
}
Expand Up @@ -369,6 +369,7 @@ class SigningPublicationsIntegrationSpec extends SigningIntegrationSpec {

publishing.publications.mavenJava.artifacts = []
publishing.publications.mavenJava.artifact(sourceJar)
generateMetadataFileForMavenJavaPublication.enabled = false
"""

when:
Expand Down
Expand Up @@ -84,7 +84,8 @@ public Iterable<File> getInputFiles() {
public Map<String, File> getOutputFiles() {
SingleMessageLogger.nagUserOfDiscontinuedMethod("Sign.getOutputFiles()",
"Please use Sign.getSignatures() and Signature.getFile() instead.");
return signatures.stream().collect(toMap(Signature::toKey, Signature::getFile));
// will be removed in 6.0
return sanitizedSignatures().entrySet().stream().collect(toMap(Map.Entry::getKey, entry -> entry.getValue().getFile()));
}

/**
Expand Down Expand Up @@ -224,7 +225,7 @@ public void generate() {
throw new InvalidUserDataException("Cannot perform signing task \'" + getPath() + "\' because it has no configured signatory");
}

for (Signature signature : signatures) {
for (Signature signature : sanitizedSignatures().values()) {
signature.generate();
}
}
Expand All @@ -244,7 +245,14 @@ public DomainObjectSet<Signature> getSignatures() {
@Nested
@Incubating
public Map<String, Signature> getSignaturesByKey() {
return signatures.stream().collect(toMap(Signature::toKey, identity()));
return sanitizedSignatures();
}

/**
* Returns signatures mapped by their key with duplicated and non-existing inputs removed.
*/
private Map<String, Signature> sanitizedSignatures() {
return signatures.matching(signature -> signature.getToSign().exists()).stream().collect(toMap(Signature::toKey, identity(), (signature, duplicate) -> signature));
}

/**
Expand All @@ -255,10 +263,11 @@ public Map<String, Signature> getSignaturesByKey() {
*/
@Internal
public Signature getSingleSignature() {
if (signatures.size() == 1) {
return signatures.iterator().next();
Map<String, Signature> sanitizedSignatures = sanitizedSignatures();
if (sanitizedSignatures.size() == 1) {
return sanitizedSignatures.values().iterator().next();
}
throw new IllegalStateException("Expected %s to contain exactly one signature, however, it contains " + signatures.size() + " signatures.");
throw new IllegalStateException("Expected %s to contain exactly one signature, however, it contains " + sanitizedSignatures.size() + " signatures.");
}

@Inject
Expand Down
Expand Up @@ -16,15 +16,16 @@
package org.gradle.plugins.signing

class SigningTasksSpec extends SigningProjectSpec {

def setup() {
applyPlugin()
}

def "sign jar with defaults"() {
given:
useJavadocAndSourceJars()

createJarTaskOutputFile('jar', 'sourcesJar', 'javadocJar')

when:
signing {
sign jar
Expand All @@ -33,51 +34,84 @@ class SigningTasksSpec extends SigningProjectSpec {

then:
def signingTasks = [signJar, signSourcesJar, signJavadocJar]

and:
jar in signJar.dependsOn
sourcesJar in signSourcesJar.dependsOn
javadocJar in signJavadocJar.dependsOn

and:
signingTasks.every { it.singleSignature in configurations.signatures.artifacts }

and:
signingTasks.every { it.signatory == signing.signatory }
}

def "sign method return values"() {
given:
useJavadocAndSourceJars()

when:
def signJarTask = signing.sign(jar).first()

then:
signJarTask.name == "signJar"

when:
def (signSourcesJarTask, signJavadocJarTask) = signing.sign(sourcesJar, javadocJar)

then:
[signSourcesJarTask, signJavadocJarTask]*.name == ["signSourcesJar", "signJavadocJar"]
}

def "output files contain signature files"() {
def "output files contain signature files for existing files"() {
given:
useJavadocAndSourceJars()
applyPlugin()
addSigningProperties()
createJarTaskOutputFile('jar')

when:
Sign signTask = signing.sign(jar).first()

then:
File libsDir = jar.outputs.files.singleFile.parentFile
def libsDir = jar.outputs.files.singleFile.parentFile
signTask.outputFiles == ["test.jar.asc:jar.asc:asc:": new File(libsDir, "test.jar.asc")]
signTask.signaturesByKey == ["test.jar.asc:jar.asc:asc:": signTask.singleSignature]
}

def "files to sign that do not exist are ignored"() {
given:
useJavadocAndSourceJars()
applyPlugin()
addSigningProperties()

when:
Sign signTask = signing.sign(jar).first()
jar.enabled = false

then:
signTask.outputFiles == [:]
signTask.signaturesByKey == [:]
}

def "files to sign are de-duplicated"() {
given:
useJavadocAndSourceJars()
applyPlugin()
addSigningProperties()
createJarTaskOutputFile('jar')

when:
Sign signTask = signing.sign(jar).first()
signTask.sign('', jar.outputs.files.singleFile) // add jar task output again, this time directly as File

then:
signTask.signatures.size() == 2
noExceptionThrown()
signTask.signaturesByKey == ["test.jar.asc:jar.asc:asc:": signTask.singleSignature]
}

def "sign task has description"() {
given:
useJavadocAndSourceJars()
Expand All @@ -91,4 +125,14 @@ class SigningTasksSpec extends SigningProjectSpec {
signJar.description == "Signs the archive produced by the 'jar' task."
signSourcesJar.description == "Signs the archive produced by the 'sourcesJar' task."
}

private createJarTaskOutputFile(String... tasksToSimulate) {
for (def task : tasksToSimulate) {
def jarFile = tasks.getByName(task).outputs.files.singleFile
File libsDir = jarFile.parentFile
libsDir.mkdirs()
jarFile.createNewFile()
}

}
}