mirror of
https://github.com/ethauvin/kobalt.git
synced 2025-04-25 16:07:12 -07:00
Use commons-compress fast archive.
This commit is contained in:
parent
46f73ee5e7
commit
c195a7bdf7
5 changed files with 101 additions and 56 deletions
|
@ -6,13 +6,12 @@ import com.beust.kobalt.archive.Archives
|
||||||
import com.beust.kobalt.archive.Zip
|
import com.beust.kobalt.archive.Zip
|
||||||
import com.beust.kobalt.maven.DependencyManager
|
import com.beust.kobalt.maven.DependencyManager
|
||||||
import com.beust.kobalt.maven.aether.Scope
|
import com.beust.kobalt.maven.aether.Scope
|
||||||
import com.beust.kobalt.misc.*
|
import com.beust.kobalt.misc.KFiles
|
||||||
|
import com.beust.kobalt.misc.kobaltLog
|
||||||
import com.google.inject.Inject
|
import com.google.inject.Inject
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileInputStream
|
import java.io.FileInputStream
|
||||||
import java.io.OutputStream
|
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
import java.util.jar.JarOutputStream
|
|
||||||
import java.util.jar.Manifest
|
import java.util.jar.Manifest
|
||||||
|
|
||||||
class JarGenerator @Inject constructor(val dependencyManager: DependencyManager) : ArchiveGenerator {
|
class JarGenerator @Inject constructor(val dependencyManager: DependencyManager) : ArchiveGenerator {
|
||||||
|
@ -155,10 +154,8 @@ class JarGenerator @Inject constructor(val dependencyManager: DependencyManager)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val jarFactory = { os: OutputStream -> JarOutputStream(os, manifest) }
|
|
||||||
|
|
||||||
return Archives.generateArchive(project, context, zip.name, ".jar", includedFiles,
|
return Archives.generateArchive(project, context, zip.name, ".jar", includedFiles,
|
||||||
true /* expandJarFiles */, jarFactory)
|
true /* expandJarFiles */, manifest)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -8,10 +8,7 @@ import com.beust.kobalt.misc.JarUtils
|
||||||
import com.beust.kobalt.misc.KFiles
|
import com.beust.kobalt.misc.KFiles
|
||||||
import com.beust.kobalt.misc.kobaltLog
|
import com.beust.kobalt.misc.kobaltLog
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
|
||||||
import java.io.OutputStream
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.zip.ZipOutputStream
|
|
||||||
|
|
||||||
class Archives {
|
class Archives {
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -20,8 +17,6 @@ class Archives {
|
||||||
@ExportedProjectProperty(doc = "The name of the a jar file with a main() method", type = "String")
|
@ExportedProjectProperty(doc = "The name of the a jar file with a main() method", type = "String")
|
||||||
const val JAR_NAME_WITH_MAIN_CLASS = "jarNameWithMainClass"
|
const val JAR_NAME_WITH_MAIN_CLASS = "jarNameWithMainClass"
|
||||||
|
|
||||||
private val DEFAULT_STREAM_FACTORY = { os : OutputStream -> ZipOutputStream(os) }
|
|
||||||
|
|
||||||
fun defaultArchiveName(project: Project) = project.name + "-" + project.version
|
fun defaultArchiveName(project: Project) = project.name + "-" + project.version
|
||||||
|
|
||||||
fun generateArchive(project: Project,
|
fun generateArchive(project: Project,
|
||||||
|
@ -30,15 +25,15 @@ class Archives {
|
||||||
suffix: String,
|
suffix: String,
|
||||||
includedFiles: List<IncludedFile>,
|
includedFiles: List<IncludedFile>,
|
||||||
expandJarFiles : Boolean = false,
|
expandJarFiles : Boolean = false,
|
||||||
outputStreamFactory: (OutputStream) -> ZipOutputStream = DEFAULT_STREAM_FACTORY) : File {
|
manifest: java.util.jar.Manifest? = null) : File {
|
||||||
val fullArchiveName = context.variant.archiveName(project, archiveName, suffix)
|
val fullArchiveName = context.variant.archiveName(project, archiveName, suffix)
|
||||||
val archiveDir = File(KFiles.libsDir(project))
|
val archiveDir = File(KFiles.libsDir(project))
|
||||||
val result = File(archiveDir.path, fullArchiveName)
|
val result = File(archiveDir.path, fullArchiveName)
|
||||||
context.logger.log(project.name, 3, "Creating $result")
|
context.logger.log(project.name, 3, "Creating $result")
|
||||||
if (! Features.USE_TIMESTAMPS || isOutdated(project.directory, includedFiles, result)) {
|
if (! Features.USE_TIMESTAMPS || isOutdated(project.directory, includedFiles, result)) {
|
||||||
try {
|
try {
|
||||||
outputStreamFactory(FileOutputStream(result)).use {
|
MetaArchive(result, manifest).use { metaArchive ->
|
||||||
JarUtils.addFiles(project.directory, includedFiles, it, expandJarFiles)
|
JarUtils.addFiles(project.directory, includedFiles, metaArchive, expandJarFiles)
|
||||||
context.logger.log(project.name, 2, "Added ${includedFiles.size} files to $result")
|
context.logger.log(project.name, 2, "Added ${includedFiles.size} files to $result")
|
||||||
context.logger.log(project.name, 1, " Created $result")
|
context.logger.log(project.name, 1, " Created $result")
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
package com.beust.kobalt.archive
|
||||||
|
|
||||||
|
import com.beust.kobalt.Glob
|
||||||
|
import com.beust.kobalt.misc.KFiles
|
||||||
|
import org.apache.commons.compress.archivers.ArchiveEntry
|
||||||
|
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream
|
||||||
|
import java.io.Closeable
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileInputStream
|
||||||
|
import java.io.FileOutputStream
|
||||||
|
import java.nio.file.Files
|
||||||
|
import org.apache.commons.compress.archivers.zip.ZipFile as ApacheZipFile
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstraction of a zip/jar/war archive that automatically manages the addition of expanded jar files.
|
||||||
|
* Uses ZipArchiveOutputStream for fast inclusion of expanded jar files.
|
||||||
|
*/
|
||||||
|
class MetaArchive(outputFile: File, val manifest: java.util.jar.Manifest?) : Closeable {
|
||||||
|
private val zos = ZipArchiveOutputStream(outputFile).apply {
|
||||||
|
encoding = "UTF-8"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addFile(file: File, path: String) {
|
||||||
|
FileInputStream(file).use { inputStream ->
|
||||||
|
val entry = zos.createArchiveEntry(file, path)
|
||||||
|
maybeAddEntry(entry) {
|
||||||
|
addEntry(entry, inputStream)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addArchive(jarFile: File) {
|
||||||
|
ApacheZipFile(jarFile).use { jar ->
|
||||||
|
val jarEntries = jar.entries
|
||||||
|
for (entry in jarEntries) {
|
||||||
|
maybeAddEntry(entry) {
|
||||||
|
zos.addRawArchiveEntry(entry, jar.getRawInputStream(entry))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val DEFAULT_JAR_EXCLUDES =
|
||||||
|
Glob("META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA")
|
||||||
|
|
||||||
|
private val seen = hashSetOf<String>()
|
||||||
|
|
||||||
|
private fun okToAdd(name: String): Boolean = ! seen.contains(name)
|
||||||
|
&& ! KFiles.isExcluded(name, DEFAULT_JAR_EXCLUDES)
|
||||||
|
|
||||||
|
override fun close() {
|
||||||
|
if (manifest != null) {
|
||||||
|
val manifestFile = Files.createTempFile("aaa", "bbb").toFile()
|
||||||
|
manifest.write(FileOutputStream(manifestFile))
|
||||||
|
|
||||||
|
val entry = zos.createArchiveEntry(manifestFile, "META-INF/MANIFEST.MF")
|
||||||
|
addEntry(entry, FileInputStream(manifestFile))
|
||||||
|
}
|
||||||
|
zos.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addEntry(entry: ArchiveEntry, inputStream: FileInputStream) {
|
||||||
|
zos.putArchiveEntry(entry)
|
||||||
|
inputStream.copyTo(zos, 50 * 1024)
|
||||||
|
zos.closeArchiveEntry()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun maybeAddEntry(entry: ArchiveEntry, action:() -> Unit) {
|
||||||
|
if (okToAdd(entry.name)) {
|
||||||
|
action()
|
||||||
|
}
|
||||||
|
seen.add(entry.name)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,14 +1,16 @@
|
||||||
package com.beust.kobalt.misc
|
package com.beust.kobalt.misc
|
||||||
|
|
||||||
import com.beust.kobalt.*
|
import com.beust.kobalt.From
|
||||||
|
import com.beust.kobalt.IFileSpec
|
||||||
|
import com.beust.kobalt.IncludedFile
|
||||||
|
import com.beust.kobalt.To
|
||||||
|
import com.beust.kobalt.archive.MetaArchive
|
||||||
import com.google.common.io.CharStreams
|
import com.google.common.io.CharStreams
|
||||||
import java.io.*
|
import java.io.File
|
||||||
import java.util.jar.JarEntry
|
import java.io.FileOutputStream
|
||||||
|
import java.io.InputStreamReader
|
||||||
import java.util.jar.JarFile
|
import java.util.jar.JarFile
|
||||||
import java.util.jar.JarInputStream
|
|
||||||
import java.util.zip.ZipEntry
|
|
||||||
import java.util.zip.ZipFile
|
import java.util.zip.ZipFile
|
||||||
import java.util.zip.ZipOutputStream
|
|
||||||
|
|
||||||
class JarUtils {
|
class JarUtils {
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -19,18 +21,15 @@ class JarUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addFiles(directory: String, files: List<IncludedFile>, target: ZipOutputStream,
|
fun addFiles(directory: String, files: List<IncludedFile>, metaArchive: MetaArchive,
|
||||||
expandJarFiles: Boolean,
|
expandJarFiles: Boolean,
|
||||||
onError: (Exception) -> Unit = DEFAULT_HANDLER) {
|
onError: (Exception) -> Unit = DEFAULT_HANDLER) {
|
||||||
files.forEach {
|
files.forEach {
|
||||||
addSingleFile(directory, it, target, expandJarFiles, onError)
|
addSingleFile(directory, it, metaArchive, expandJarFiles, onError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val DEFAULT_JAR_EXCLUDES =
|
fun addSingleFile(directory: String, file: IncludedFile, metaArchive: MetaArchive,
|
||||||
Glob("META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA")
|
|
||||||
|
|
||||||
fun addSingleFile(directory: String, file: IncludedFile, outputStream: ZipOutputStream,
|
|
||||||
expandJarFiles: Boolean, onError: (Exception) -> Unit = DEFAULT_HANDLER) {
|
expandJarFiles: Boolean, onError: (Exception) -> Unit = DEFAULT_HANDLER) {
|
||||||
val foundFiles = file.allFromFiles(directory)
|
val foundFiles = file.allFromFiles(directory)
|
||||||
foundFiles.forEach { foundFile ->
|
foundFiles.forEach { foundFile ->
|
||||||
|
@ -49,42 +48,22 @@ class JarUtils {
|
||||||
|
|
||||||
// Directory
|
// Directory
|
||||||
val includedFile = IncludedFile(From(""), To(""), listOf(IFileSpec.GlobSpec("**")))
|
val includedFile = IncludedFile(From(""), To(""), listOf(IFileSpec.GlobSpec("**")))
|
||||||
addSingleFile(localFile.path, includedFile, outputStream, expandJarFiles)
|
addSingleFile(localFile.path, includedFile, metaArchive, expandJarFiles)
|
||||||
} else {
|
} else {
|
||||||
if (file.expandJarFiles && foundFile.name.endsWith(".jar") && ! file.from.contains("resources")) {
|
try {
|
||||||
kobaltLog(2, " Writing contents of jar file $foundFile")
|
if (file.expandJarFiles && foundFile.name.endsWith(".jar") && !file.from.contains("resources")) {
|
||||||
JarInputStream(FileInputStream(localFile)).use { stream ->
|
kobaltLog(2, " Writing contents of jar file $foundFile")
|
||||||
var entry = stream.nextEntry
|
metaArchive.addArchive(foundFile)
|
||||||
while (entry != null) {
|
} else {
|
||||||
if (!entry.isDirectory && !KFiles.isExcluded(entry.name, DEFAULT_JAR_EXCLUDES)) {
|
metaArchive.addFile(File(directory, fromFile.path), foundFile.path)
|
||||||
addEntry(stream, JarEntry(entry), outputStream, onError)
|
|
||||||
}
|
|
||||||
entry = stream.nextEntry
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
val entryFileName = KFiles.fixSlashes(file.to(foundFile.path))
|
|
||||||
val entry = JarEntry(entryFileName)
|
|
||||||
entry.time = localFile.lastModified()
|
|
||||||
FileInputStream(localFile).use { stream ->
|
|
||||||
addEntry(stream, entry, outputStream, onError)
|
|
||||||
}
|
}
|
||||||
|
} catch(ex: Exception) {
|
||||||
|
onError(ex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addEntry(inputStream: InputStream, entry: ZipEntry, outputStream: ZipOutputStream,
|
|
||||||
onError: (Exception) -> Unit = DEFAULT_HANDLER) {
|
|
||||||
try {
|
|
||||||
outputStream.putNextEntry(entry)
|
|
||||||
inputStream.copyTo(outputStream, 50 * 1024)
|
|
||||||
outputStream.closeEntry()
|
|
||||||
} catch(ex: Exception) {
|
|
||||||
onError(ex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun extractTextFile(zip : ZipFile, fileName: String) : String? {
|
fun extractTextFile(zip : ZipFile, fileName: String) : String? {
|
||||||
val enumEntries = zip.entries()
|
val enumEntries = zip.entries()
|
||||||
while (enumEntries.hasMoreElements()) {
|
while (enumEntries.hasMoreElements()) {
|
||||||
|
|
|
@ -88,7 +88,7 @@ class WarGenerator @Inject constructor(val dependencyManager: DependencyManager,
|
||||||
|
|
||||||
val jarFactory = { os: OutputStream -> JarOutputStream(os, manifest) }
|
val jarFactory = { os: OutputStream -> JarOutputStream(os, manifest) }
|
||||||
return Archives.generateArchive(project, context, war.name, ".war", files,
|
return Archives.generateArchive(project, context, war.name, ".war", files,
|
||||||
false /* don't expand jar files */, jarFactory)
|
false /* don't expand jar files */, manifest)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue