From d9a287f710dae13fab00e64f40110ac2255638d5 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 19 Dec 2015 02:26:10 +0400 Subject: [PATCH] Timestamp work. --- .../kobalt/internal/JvmCompilerPlugin.kt | 14 ++++---- .../kotlin/com/beust/kobalt/misc/JarUtils.kt | 13 +++---- .../kotlin/com/beust/kobalt/misc/KFiles.kt | 24 +++++++++---- .../plugin/packaging/PackagingPlugin.kt | 36 +++++++++++++++---- .../com/beust/kobalt/misc/JarUtilsTest.kt | 18 ++++++++++ 5 files changed, 80 insertions(+), 25 deletions(-) create mode 100644 src/test/kotlin/com/beust/kobalt/misc/JarUtilsTest.kt diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/JvmCompilerPlugin.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/JvmCompilerPlugin.kt index d891f33c..c5f2a3f7 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/JvmCompilerPlugin.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/JvmCompilerPlugin.kt @@ -112,7 +112,7 @@ abstract class JvmCompilerPlugin @Inject constructor( it.exists() } .forEach { log(2, "Copying from $sourceDirs to $absOutputDir") - KFiles.copyRecursively(it, absOutputDir, deleteFirst = true) + KFiles.copyRecursively(it, absOutputDir, deleteFirst = false) } } else { lp(project, "No resources to copy for $sourceSet") @@ -133,7 +133,7 @@ abstract class JvmCompilerPlugin @Inject constructor( project.projectProperties.put(COMPILER_ARGS, arrayListOf(*args)) } - fun isOutOfDate(project: Project, context: KobaltContext, actionInfo: CompilerActionInfo) : Boolean { + fun isOutdated(project: Project, context: KobaltContext, actionInfo: CompilerActionInfo) : Boolean { fun stripSourceDir(sourceFile: String) : String { project.sourceDirectories.forEach { val d = KFiles.joinDir(project.directory, it) @@ -150,10 +150,10 @@ abstract class JvmCompilerPlugin @Inject constructor( fun toClassFile(sourceFile: String) = stripSuffix(sourceFile) + ".class" - val sourceFiles = actionInfo.sourceFiles.map { stripSourceDir(it) } - sourceFiles.forEach { sourceFile -> - val classFile = KFiles.joinDir(project.directory, project.classesDir(context), toClassFile(sourceFile)) - if (classFile == null || File(sourceFile).lastModified() > File(classFile).lastModified()) { + actionInfo.sourceFiles.forEach { sourceFile -> + val stripped = stripSourceDir(sourceFile) + val classFile = File(KFiles.joinDir(project.directory, project.classesDir(context), toClassFile(stripped))) + if (! classFile.exists() || File(sourceFile).lastModified() > classFile.lastModified()) { return true } } @@ -170,7 +170,7 @@ abstract class JvmCompilerPlugin @Inject constructor( sourceDirectories.add(sourceDirectory) } val info = createCompilerActionInfo(project, context, isTest = false) - if (isOutOfDate(project, context, info)) { + if (isOutdated(project, context, info)) { val compiler = ActorUtils.selectAffinityActor(project, context, context.pluginInfo.compilerContributors) if (compiler != null) { return compiler.compile(project, context, info) diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/JarUtils.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/JarUtils.kt index cd1b469a..22f1db83 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/JarUtils.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/JarUtils.kt @@ -34,7 +34,8 @@ public class JarUtils { public fun addSingleFile(directory: String, file: IncludedFile, outputStream: ZipOutputStream, expandJarFiles: Boolean, onError: (Exception) -> Unit = DEFAULT_HANDLER) { - file.allFromFiles(directory).forEach { source -> + val allFiles = file.allFromFiles(directory) + allFiles.forEach { source -> val path = source.path if (source.isDirectory) { log(2, "Writing contents of directory $source") @@ -68,8 +69,8 @@ public class JarUtils { } else { val entry = JarEntry((file.to + source.path).replace("\\", "/")) entry.time = source.lastModified() - val fromPath = (file.from + "/" + source.path).replace("\\", "/") - val entryFile = File(directory, fromPath) + val fromPath = source.path.replace("\\", "/") + val entryFile = source if (! entryFile.exists()) { throw AssertionError("File should exist: $entryFile") } @@ -155,9 +156,9 @@ class IncludedFile(val fromOriginal: From, val toOriginal: To, val specs: List { val result = arrayListOf() specs.forEach { spec -> - val path = spec.toString() - spec.toFiles(directory + "/" + from).forEach { source -> - result.add(source) + val fullDir = KFiles.joinDir(directory, from) + spec.toFiles(fullDir).forEach { source -> + result.add(if (source.isAbsolute) source else File(fullDir, source.path)) } } return result diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/KFiles.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/KFiles.kt index cc7542d0..bdde58b5 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/KFiles.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/KFiles.kt @@ -7,6 +7,7 @@ import com.beust.kobalt.api.Kobalt import com.beust.kobalt.api.Project import com.beust.kobalt.homeDir import com.beust.kobalt.internal.build.BuildFile +import com.beust.kobalt.maven.Md5 import java.io.File import java.io.IOException import java.nio.file.* @@ -160,7 +161,7 @@ class KFiles { // Until then, wipe everything first if (deleteFirst) to.deleteRecursively() // to.mkdirs() - hackCopyRecursively(from, to, replaceExisting, onError) + hackCopyRecursively(from, to, replaceExisting = replaceExisting, onError = onError) } /** Private exception class, used to terminate recursive copying */ @@ -171,6 +172,7 @@ class KFiles { */ private fun hackCopyRecursively(from: File, dst: File, replaceExisting: Boolean, + checkTimestamp: Boolean = false, onError: (File, IOException) -> OnErrorAction = { file, exception -> throw exception } ): Boolean { @@ -196,9 +198,13 @@ class KFiles { } else if (src.isDirectory) { dstFile.mkdirs() } else { - if (src.copyTo(dstFile, true) != src.length()) { - if (onError(src, IOException("src.length() != dst.length()")) == OnErrorAction.TERMINATE) - return false + if (dstFile.exists() && Md5.toMd5(src) == Md5.toMd5(dstFile)) { + log(2, " Identical files, not copying $src to $dstFile") + } else { + if (src.copyTo(dstFile, true) != src.length()) { + if (onError(src, IOException("src.length() != dst.length()")) == OnErrorAction.TERMINATE) + return false + } } } } @@ -242,8 +248,14 @@ class KFiles { log(2, "Windows detected, not overwriting $to") } else { try { - log(2, "Copy from $from to ${to!!}") - Files.copy(from, to, option) + if (from != null && to != null) { + if (!Files.exists(to) || Md5.toMd5(from.toFile()) != Md5.toMd5(to.toFile())) { + log(2, "Copy from $from to ${to}") + Files.copy(from, to, option) + } else { + log(2, " Not copying, indentical files: $from $to") + } + } } catch(ex: IOException) { // Windows is anal about this log(1, "Couldn't copy $from to $to: ${ex.message}") diff --git a/src/main/kotlin/com/beust/kobalt/plugin/packaging/PackagingPlugin.kt b/src/main/kotlin/com/beust/kobalt/plugin/packaging/PackagingPlugin.kt index c86f5ace..f1d6695b 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/packaging/PackagingPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/packaging/PackagingPlugin.kt @@ -17,6 +17,7 @@ import java.io.File import java.io.FileOutputStream import java.io.OutputStream import java.nio.file.Paths +import java.util.* import java.util.jar.JarOutputStream import java.util.zip.ZipOutputStream import javax.inject.Inject @@ -236,19 +237,42 @@ class PackagingPlugin @Inject constructor(val dependencyManager : DependencyMana val fullArchiveName = context.variant.archiveName(project, archiveName, suffix) val archiveDir = File(libsDir(project)) val result = File(archiveDir.path, fullArchiveName) - val outStream = outputStreamFactory(FileOutputStream(result)) log(2, "Creating $result") - JarUtils.addFiles(project.directory, includedFiles, outStream, expandJarFiles) - log(2, text = "Added ${includedFiles.size} files to $result") - outStream.flush() - outStream.close() - log(1, " Created $result") + if (isOutdated(project.directory, includedFiles, result)) { + val outStream = outputStreamFactory(FileOutputStream(result)) + JarUtils.addFiles(project.directory, includedFiles, outStream, expandJarFiles) + log(2, text = "Added ${includedFiles.size} files to $result") + outStream.flush() + outStream.close() + log(1, " Created $result") + } else { + log(2, " $result is up to date") + } project.projectProperties.put(JAR_NAME, result.absolutePath) return result } + private fun isOutdated(directory: String, includedFiles: List, output: File): Boolean { + if (! output.exists()) return true + + val lastModified = output.lastModified() + includedFiles.forEach { root -> + val allFiles = root.allFromFiles(directory) + allFiles.forEach { file -> + if (file.isFile) { + if (file.lastModified() > lastModified) { + log(2, " Outdated $file and $output " + + Date(file.lastModified()) + " " + Date(output.lastModified())) + return true + } + } + } + } + return false + } + fun addPackage(p: PackageConfig) { packages.add(p) } diff --git a/src/test/kotlin/com/beust/kobalt/misc/JarUtilsTest.kt b/src/test/kotlin/com/beust/kobalt/misc/JarUtilsTest.kt new file mode 100644 index 00000000..e43bd7c6 --- /dev/null +++ b/src/test/kotlin/com/beust/kobalt/misc/JarUtilsTest.kt @@ -0,0 +1,18 @@ +package com.beust.kobalt.misc + +import com.beust.kobalt.IFileSpec +import org.testng.Assert +import org.testng.annotations.Test +import javax.inject.Inject + +@Test +class JarUtilsTest @Inject constructor() { + + fun allFromFiles() { + val inf = IncludedFile(From("kobaltBuild/classes"), To(""), + listOf(IFileSpec.FileSpec("com/beust/kobalt/wrapper/Main.class"))) + val files = inf.allFromFiles("modules/wrapper") + println("Files: $files") + Assert.assertEquals(files[0].path, "modules/wrapper/kobaltBuild/classes/com/beust/kobalt/wrapper/Main.class") + } +}