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

fix: SpotBugsTask was not cacheable #258

Merged
merged 1 commit into from
May 20, 2020
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* Copyright 2019 SpotBugs team
*
* <p>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
*
* <p>http://www.apache.org/licenses/LICENSE-2.0
*
* <p>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.github.spotbugs.snom

import org.gradle.testkit.runner.BuildResult
import org.gradle.testkit.runner.GradleRunner
import org.gradle.util.GradleVersion
import spock.lang.Specification

import java.nio.file.Files

class CacheabilityFunctionalTest extends Specification {


/**
* Verifies the cacheability of {@link SpotBugsTask} by invoking the same code
* in two different, uniquely-named folders.
*
* Thanks to the presence of sysprop {@code org.gradle.caching.debug=true}, the
* build cache key for the task is echoed to stdout.
*
* If we compare these keys for both builds and they are equal, we can now trust the
* task is cacheable.
*
*/
def 'spotbugsMain task is cacheable'() {
given:
def buildDir1 = Files.createTempDirectory(null).toFile()
def buildDir2 = Files.createTempDirectory(null).toFile()

def version = System.getProperty('snom.test.functional.gradle', GradleVersion.current().version)

initializeBuildFile(buildDir1)
initializeBuildFile(buildDir2)

when:
BuildResult result1 =
GradleRunner.create()
.withProjectDir(buildDir1)
.withArguments(':spotbugsMain')
.withPluginClasspath()
.forwardOutput()
.withGradleVersion(version)
.build()
def hashKeyLine1 = getHashKeyLine(result1)

then:
hashKeyLine1

when:
BuildResult result2 =
GradleRunner.create()
.withProjectDir(buildDir2)
.withArguments(':spotbugsMain')
.withPluginClasspath()
.forwardOutput()
.withGradleVersion(version)
.build()
def hashKeyLine2 = getHashKeyLine(result2)

then:
hashKeyLine2
hashKeyLine1 == hashKeyLine2
}

private static String getHashKeyLine(BuildResult result) {
return result.output.find('Build cache key for task \':spotbugsMain\' is .*')
}

private static void initializeBuildFile(File buildDir) {
File buildFile = new File(buildDir, 'build.gradle')
File propertiesFile = new File(buildDir, 'gradle.properties')

buildFile << '''
|plugins {
| id 'java'
| id 'com.github.spotbugs'
|}
|
|version = 1.0
|
|repositories {
| mavenCentral()
|}
|'''.stripMargin()

File sourceDir = buildDir.toPath().resolve('src').resolve('main').resolve('java').toFile()
sourceDir.mkdirs()
File sourceFile = new File(sourceDir, 'Foo.java')
sourceFile << '''
|public class Foo {
| public static void main(String... args) {
| System.out.println("Hello, SpotBugs!");
| }
|}
|'''.stripMargin()

propertiesFile << '''
|org.gradle.caching = true
|org.gradle.caching.debug = true
|'''.stripMargin()
}
}
9 changes: 8 additions & 1 deletion src/main/groovy/com/github/spotbugs/snom/SpotBugsTask.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import org.gradle.api.file.FileCollection;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.provider.ListProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.InputFiles;
Expand Down Expand Up @@ -82,6 +83,8 @@ import javax.inject.Inject
*
* <p>See also <a href="https://spotbugs.readthedocs.io/en/stable/running.html">SpotBugs Manual about configuration</a>.</p>
*/

@CacheableTask
class SpotBugsTask extends DefaultTask implements VerificationTask {
private static final String FEATURE_FLAG_WORKER_API = "com.github.spotbugs.snom.worker";
private final Logger log = LoggerFactory.getLogger(SpotBugsTask);
Expand Down Expand Up @@ -174,8 +177,12 @@ class SpotBugsTask extends DefaultTask implements VerificationTask {
/**
* Property to specify the name of project. Some reporting formats use this property.
* Default value is {@code "${project.name} (${task.name})"}.
* <br>
* Note that this property, if treated as a task input, can break cacheability.<br>
* As such, it has been marked {@link Internal} to exclude it from task up-to-date and
* cacheability checks.
*/
@Input
@Internal
KengoTODA marked this conversation as resolved.
Show resolved Hide resolved
@NonNull
final Property<String> projectName;
/**
Expand Down