Skip to content

Commit

Permalink
Merge pull request #59 from chali/ImproveJarCachingWithPropertiesFile…
Browse files Browse the repository at this point in the history
…Metadata

Metadata properties file content is ignored for up-to-date checks of jar tasks
  • Loading branch information
chali authored Feb 15, 2020
2 parents e655cc4 + cf6cc1b commit 786f9f1
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 15 deletions.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ import nebula.plugin.info.InfoBrokerPlugin
import nebula.plugin.info.InfoReporterPlugin
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.internal.file.copy.CopySpecWrapper
import org.gradle.api.Task
import org.gradle.api.file.CopySpec
import org.gradle.api.tasks.bundling.Jar

/**
Expand All @@ -34,9 +35,26 @@ class InfoJarPropertiesFilePlugin implements Plugin<Project>, InfoReporterPlugin
InfoPropertiesFilePlugin propFilePlugin = project.plugins.apply(InfoPropertiesFilePlugin) as InfoPropertiesFilePlugin
InfoPropertiesFile manifestTask = propFilePlugin.getManifestTask()

//we cannot use the right module name because touching manifest task to early causes incorrect name computation
//temp.properties is renamed later when placed into jar
File propertiesFile = new File(project.buildDir, "properties_for_jar/temp.properties")
Task prepareFile = project.tasks.create("createPropertiesFileForJar") { Task task ->
task.outputs.file(propertiesFile)
task.doLast {
//Task action is intentionally creating empty file.
propertiesFile.text = ""
}
}

project.tasks.withType(Jar) { Jar jarTask ->
jarTask.from(manifestTask.outputs) { CopySpecWrapper copySpecWrapper ->
copySpecWrapper.into "META-INF"
//we link the output file from the task to the spec to add it into jar, but the file is empty, it will
//help to ignore changes in its content for caching
jarTask.metaInf { CopySpec spec ->
spec.from(prepareFile.outputs).rename("temp.properties", manifestTask.propertiesFile.name)
}
jarTask.doFirst {
//when we are after all caching decisions we fill the file with all the data
new PropertiesWriter().writeProperties(propertiesFile, project)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,7 @@ class InfoPropertiesFile extends ConventionTask {
File propertiesFile

@TaskAction
void writeOut() {
InfoBrokerPlugin basePlugin = project.plugins.getPlugin(InfoBrokerPlugin) as InfoBrokerPlugin

// Gather all values, in contrast to buildNonChangingManifest
Map<String, String> attrs = basePlugin.buildManifest()

logger.info("Writing manifest values to ${getPropertiesFile()}")

String manifestStr = attrs.collect { "${it.key}=${it.value}"}.join('\n')
getPropertiesFile().text = manifestStr
void write() {
new PropertiesWriter().writeProperties(getPropertiesFile(), project)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package nebula.plugin.info.reporting

import nebula.plugin.info.InfoBrokerPlugin
import org.gradle.api.Project

class PropertiesWriter {

void writeProperties(File location, Project project) {
InfoBrokerPlugin basePlugin = project.plugins.getPlugin(InfoBrokerPlugin) as InfoBrokerPlugin

// Gather all values, in contrast to buildNonChangingManifest
Map<String, String> attrs = basePlugin.buildManifest()

String manifestStr = attrs.collect { "${it.key}=${it.value}"}.join('\n')
location.text = manifestStr
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package nebula.plugin.info.reporting

import nebula.plugin.info.InfoBrokerPlugin
import nebula.plugin.info.basic.BasicInfoPlugin
import nebula.test.IntegrationSpec

import java.util.jar.JarFile


class InfoPropertiesFilePluginLauncherSpec extends IntegrationSpec {
def 'jar task is marked UP-TO-DATE if ran before successfully and metadata changes are ignored'() {
writeHelloWorld('nebula.test')
buildFile << """
${applyPlugin(InfoBrokerPlugin)}
${applyPlugin(BasicInfoPlugin)}
${applyPlugin(InfoJarPropertiesFilePlugin)}
apply plugin: 'java'
status = 'release'
""".stripIndent()

when:
// Make sure we have some history already in place
def result = runTasksSuccessfully('jar')
runTasksSuccessfully('clean')

result = runTasks('jar')

then:
File jarFile = new File(projectDir, "build/libs/${moduleName}.jar")
jarFile.exists()
Properties metadata = getPropertiesFromJar(jarFile)
metadata['Built-Status'] == 'release'
!result.wasUpToDate(':jar')

when: 'Nothing has changed'
def secondResult = runTasksSuccessfully('jar')

then:
secondResult.wasUpToDate(':jar')

when: 'A manifest field was changed'
buildFile << """
status = 'integration'
""".stripIndent()
def thirdResult = runTasksSuccessfully('jar')

then:
File reusedJar = new File(projectDir, "build/libs/${moduleName}.jar")
reusedJar.exists()
Properties staleMetadata = getPropertiesFromJar(reusedJar)
//metadata change is ignored and cache is reused
staleMetadata['Built-Status'] == 'release'
thirdResult.wasUpToDate(':jar')
}

Properties getPropertiesFromJar(File jar) {
def file = new JarFile(jar)
def propertiesEntry = file.getEntry("META-INF/${moduleName}.properties")
def result = new Properties()
result.load(file.getInputStream(propertiesEntry))
result.each {
println it
}
return result
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class InfoPropertiesFilePluginSpec extends ProjectSpec {
manifestTask.getPropertiesFile().parentFile.mkdirs()

when:
manifestTask.writeOut()
manifestTask.write()

then:
def result = new Properties()
Expand Down

0 comments on commit 786f9f1

Please sign in to comment.