diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1b16c34..4e1cc9d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -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 diff --git a/src/main/groovy/nebula/plugin/info/reporting/InfoJarPropertiesFilePlugin.groovy b/src/main/groovy/nebula/plugin/info/reporting/InfoJarPropertiesFilePlugin.groovy index 76a2e41..53ea965 100644 --- a/src/main/groovy/nebula/plugin/info/reporting/InfoJarPropertiesFilePlugin.groovy +++ b/src/main/groovy/nebula/plugin/info/reporting/InfoJarPropertiesFilePlugin.groovy @@ -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 /** @@ -34,9 +35,26 @@ class InfoJarPropertiesFilePlugin implements Plugin, 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) } } } diff --git a/src/main/groovy/nebula/plugin/info/reporting/InfoPropertiesFile.groovy b/src/main/groovy/nebula/plugin/info/reporting/InfoPropertiesFile.groovy index c0d5a4b..cee00e0 100644 --- a/src/main/groovy/nebula/plugin/info/reporting/InfoPropertiesFile.groovy +++ b/src/main/groovy/nebula/plugin/info/reporting/InfoPropertiesFile.groovy @@ -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 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) } } diff --git a/src/main/groovy/nebula/plugin/info/reporting/PropertiesWriter.groovy b/src/main/groovy/nebula/plugin/info/reporting/PropertiesWriter.groovy new file mode 100644 index 0000000..b48d439 --- /dev/null +++ b/src/main/groovy/nebula/plugin/info/reporting/PropertiesWriter.groovy @@ -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 attrs = basePlugin.buildManifest() + + String manifestStr = attrs.collect { "${it.key}=${it.value}"}.join('\n') + location.text = manifestStr + } +} diff --git a/src/test/groovy/nebula/plugin/info/reporting/InfoPropertiesFilePluginLauncherSpec.groovy b/src/test/groovy/nebula/plugin/info/reporting/InfoPropertiesFilePluginLauncherSpec.groovy new file mode 100644 index 0000000..ca20f6c --- /dev/null +++ b/src/test/groovy/nebula/plugin/info/reporting/InfoPropertiesFilePluginLauncherSpec.groovy @@ -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 + } +} diff --git a/src/test/groovy/nebula/plugin/info/reporting/InfoPropertiesFilePluginSpec.groovy b/src/test/groovy/nebula/plugin/info/reporting/InfoPropertiesFilePluginSpec.groovy index 8b5662d..e47d1ea 100644 --- a/src/test/groovy/nebula/plugin/info/reporting/InfoPropertiesFilePluginSpec.groovy +++ b/src/test/groovy/nebula/plugin/info/reporting/InfoPropertiesFilePluginSpec.groovy @@ -39,7 +39,7 @@ class InfoPropertiesFilePluginSpec extends ProjectSpec { manifestTask.getPropertiesFile().parentFile.mkdirs() when: - manifestTask.writeOut() + manifestTask.write() then: def result = new Properties()