support vendor_kernel_boot.img, also refine display info on Windows

pull/140/head
cfig 3 years ago
parent d7ea80a5c2
commit 130789c276
No known key found for this signature in database
GPG Key ID: B104C307F0FDABB7

@ -62,10 +62,11 @@ Well done you did it! The last step is to star this repo :smile
| Image Type | file names | platforms | note |
| --------------- | ----------------------------------- | ---------- | ---- |
| boot images | boot.img, vendor_boot.img, init_boot.img| all | |
| recovery images | recovery.img, recovery-two-step.img | all | |
| vbmeta images | vbmeta.img, vbmeta_system.img etc. | all | |
| dtbo images | dtbo.img | linux & mac | |
| boot | boot.img, init_boot.img | all | |
|vendor boot | vendor_boot.img, vendor_boot-debug.img, vendor_kernel_boot.img | all | |
| recovery | recovery.img, recovery-two-step.img | all | |
| vbmeta | vbmeta.img, vbmeta_system.img etc. | all | |
| dtbo | dtbo.img | linux & mac | |
| sparse images | system.img, vendor.img, product.img etc.| linux & mac | need **hacking mode**\* |
| OTA payload | payload.bin | linux & mac | |

@ -34,9 +34,9 @@ dependencies {
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("cc.cfig:io:0.2")
implementation("ch.qos.logback:logback-classic:1.2.11")
implementation("com.fasterxml.jackson.core:jackson-annotations:2.13.3")
implementation("com.fasterxml.jackson.core:jackson-databind:2.13.3")
implementation("ch.qos.logback:logback-classic:1.4.5")
implementation("com.fasterxml.jackson.core:jackson-annotations:2.14.0")
implementation("com.fasterxml.jackson.core:jackson-databind:2.14.0")
implementation("com.google.guava:guava:31.1-jre")
implementation("org.apache.commons:commons-exec:1.3")
implementation("org.apache.commons:commons-compress:1.21")
@ -45,6 +45,7 @@ dependencies {
implementation("junit:junit:4.13.2")
implementation("org.bouncycastle:bcprov-jdk15on:1.70")
implementation("de.vandermeer:asciitable:0.3.2")
implementation("com.github.freva:ascii-table:1.8.0")
implementation("com.google.protobuf:protobuf-java:3.21.1")
implementation(project(":helper"))

@ -21,6 +21,7 @@ import cfig.utils.DTC
import cfig.helper.Helper
import cfig.helper.ZipHelper
import cfig.utils.KernelExtractor
import com.github.freva.asciitable.HorizontalAlign
import org.apache.commons.exec.CommandLine
import org.apache.commons.exec.DefaultExecutor
import org.apache.commons.exec.PumpStreamHandler
@ -391,5 +392,53 @@ class Common {
10
}
}
fun table2String(prints: List<Pair<String, String>>): String {
return com.github.freva.asciitable.AsciiTable.getTable(
com.github.freva.asciitable.AsciiTable.BASIC_ASCII,
prints, mutableListOf(
com.github.freva.asciitable.Column().header("What")
.headerAlign(HorizontalAlign.CENTER)
.dataAlign(HorizontalAlign.LEFT)
.with { it.first },
com.github.freva.asciitable.Column().header("Where")
.headerAlign(HorizontalAlign.CENTER)
.dataAlign(HorizontalAlign.LEFT)
.with { it.second }))
}
fun printPackSummary(imageName: String) {
val prints: MutableList<Pair<String, String>> = mutableListOf()
val tableHeader = de.vandermeer.asciitable.AsciiTable().apply {
addRule(); addRow("What", "Where"); addRule()
}
val tab = de.vandermeer.asciitable.AsciiTable().let {
it.addRule()
if (File("$imageName.signed").exists()) {
it.addRow("re-packed $imageName", "$imageName.signed")
prints.add(Pair("re-packed $imageName", "$imageName.signed"))
} else {
it.addRow("re-packed $imageName", "$imageName.clear")
prints.add(Pair("re-packed $imageName", "$imageName.clear"))
}
it.addRule()
it
}
if (File("vbmeta.img").exists()) {
if (File("vbmeta.img.signed").exists()) {
tab.addRow("re-packed vbmeta", "vbmeta.img.signed")
prints.add(Pair("re-packed vbmeta", "vbmeta.img.signed"))
} else {
tab.addRow("re-packed vbmeta", "-")
prints.add(Pair("re-packed vbmeta", "-"))
}
tab.addRule()
}
if (EnvironmentVerifier().isWindows) {
log.info("\n" + Common.table2String(prints))
} else {
log.info("\n\t\t\tPack Summary of ${imageName}\n{}\n{}", tableHeader.render(), tab.render())
}
}
}
}

@ -19,14 +19,13 @@ import cfig.Avb
import cfig.bootimg.Common
import cfig.bootimg.Common.Companion.deleleIfExists
import cfig.bootimg.Signer
import cfig.bootimg.v3.BootV3
import cfig.bootimg.v3.VendorBoot
import cfig.helper.Helper
import cfig.helper.Dumpling
import cfig.helper.Helper
import cfig.packable.VBMetaParser
import cfig.utils.EnvironmentVerifier
import cfig.utils.DTC
import cfig.utils.EnvironmentVerifier
import com.fasterxml.jackson.databind.ObjectMapper
import com.github.freva.asciitable.HorizontalAlign
import de.vandermeer.asciitable.AsciiTable
import org.apache.commons.exec.CommandLine
import org.apache.commons.exec.DefaultExecutor
@ -240,7 +239,8 @@ data class BootV2(
return this
}
fun printSummary(): BootV2 {
fun printUnpackSummary(): BootV2 {
val prints: MutableList<Pair<String, String>> = mutableListOf()
val tableHeader = AsciiTable().apply {
addRule()
addRow("What", "Where")
@ -249,6 +249,7 @@ data class BootV2(
val tab = AsciiTable().let {
it.addRule()
it.addRow("image info", workDir + info.output.removeSuffix(".img") + ".json")
prints.add(Pair("image info", workDir + info.output.removeSuffix(".img") + ".json"))
if (this.info.verify.startsWith("VB2.0")) {
it.addRule()
val verifyStatus = if (this.info.verify.contains("PASS")) {
@ -258,11 +259,13 @@ data class BootV2(
}
Avb.getJsonFileName(info.output).let { jsonFile ->
it.addRow("AVB info [$verifyStatus]", jsonFile)
prints.add(Pair("AVB info [$verifyStatus]", jsonFile))
if (File(jsonFile).exists()) {
mapper.readValue(File(jsonFile), AVBInfo::class.java).let { ai ->
val inspectRet = Avb.inspectKey(ai)
if (inspectRet != "NONE") {
it.addRow("\\-- signing key", inspectRet)
prints.add(Pair("\\-- signing key", inspectRet))
}
}
}
@ -271,27 +274,33 @@ data class BootV2(
//kernel
it.addRule()
it.addRow("kernel", this.kernel.file)
prints.add(Pair("kernel", this.kernel.file.toString()))
File(Helper.prop("kernelVersionFile")).let { kernelVersionFile ->
if (kernelVersionFile.exists()) {
it.addRow("\\-- version " + kernelVersionFile.readLines().toString(), kernelVersionFile.path)
prints.add(Pair("\\-- version " + kernelVersionFile.readLines().toString(), kernelVersionFile.path))
}
}
File(Helper.prop("kernelConfigFile")).let { kernelConfigFile ->
if (kernelConfigFile.exists()) {
it.addRow("\\-- config", kernelConfigFile.path)
prints.add(Pair("\\-- config", kernelConfigFile.path))
}
}
//ramdisk
if (this.ramdisk.size > 0) {
it.addRule()
it.addRow("ramdisk", this.ramdisk.file)
prints.add(Pair("ramdisk", this.ramdisk.file.toString()))
it.addRow("\\-- extracted ramdisk rootfs", "${workDir}root")
prints.add(Pair("\\-- extracted ramdisk rootfs", "${workDir}root"))
}
//second
this.secondBootloader?.let { theSecondBootloader ->
if (theSecondBootloader.size > 0) {
it.addRule()
it.addRow("second bootloader", theSecondBootloader.file)
prints.add(Pair("second bootloader", theSecondBootloader.file.toString()))
}
}
//dtbo
@ -299,6 +308,7 @@ data class BootV2(
if (theDtbo.size > 0) {
it.addRule()
it.addRow("recovery dtbo", theDtbo.file)
prints.add(Pair("recovery dtbo", theDtbo.file.toString()))
}
}
//dtb
@ -306,8 +316,10 @@ data class BootV2(
if (theDtb.size > 0) {
it.addRule()
it.addRow("dtb", theDtb.file)
prints.add(Pair("dtb", theDtb.file.toString()))
if (File(theDtb.file + ".${dtsSuffix}").exists()) {
it.addRow("\\-- decompiled dts", theDtb.file + ".${dtsSuffix}")
prints.add(Pair("\\-- decompiled dts", theDtb.file + ".${dtsSuffix}"))
}
}
}
@ -319,16 +331,31 @@ data class BootV2(
if (File("vbmeta.img").exists()) {
it.addRule()
it.addRow("vbmeta.img", Avb.getJsonFileName("vbmeta.img"))
prints.add(Pair("vbmeta.img", Avb.getJsonFileName("vbmeta.img")))
it.addRule()
"\n" + it.render()
} else {
""
}
}
log.info(
"\n\t\t\tUnpack Summary of ${info.output}\n{}\n{}{}",
tableHeader.render(), tab.render(), tabVBMeta
)
if (EnvironmentVerifier().isWindows) {
log.info("\n" +
com.github.freva.asciitable.AsciiTable.getTable(
com.github.freva.asciitable.AsciiTable.BASIC_ASCII,
prints, mutableListOf(
com.github.freva.asciitable.Column().header("What")
.dataAlign(HorizontalAlign.LEFT)
.with { it.first },
com.github.freva.asciitable.Column().header("Where").with { it.second })
))
} else {
log.info(
"\n\t\t\tUnpack Summary of ${info.output}\n{}\n{}{}",
tableHeader.render(), tab.render(), tabVBMeta
)
}
return this
}
@ -535,7 +562,7 @@ data class BootV2(
}
fun printPackSummary(): BootV2 {
VendorBoot.printPackSummary(info.output)
Common.printPackSummary(info.output)
return this
}

@ -19,9 +19,8 @@ import cfig.Avb
import cfig.bootimg.Common
import cfig.bootimg.Common.Companion.deleleIfExists
import cfig.bootimg.Signer
import cfig.bootimg.v3.VendorBoot
import cfig.helper.Helper
import cfig.helper.Dumpling
import cfig.helper.Helper
import cfig.packable.VBMetaParser
import cfig.utils.EnvironmentVerifier
import com.fasterxml.jackson.databind.ObjectMapper
@ -540,7 +539,7 @@ data class BootV2Dialects(
}
fun printPackSummary(): BootV2Dialects {
VendorBoot.printPackSummary(info.output)
Common.printPackSummary(info.output)
return this
}

@ -18,6 +18,7 @@ import avb.AVBInfo
import avb.alg.Algorithms
import avb.blob.AuxBlob
import cfig.Avb
import cfig.bootimg.Common
import cfig.utils.EnvironmentVerifier
import cfig.bootimg.Common.Companion.deleleIfExists
import cfig.bootimg.Common.Companion.getPaddingSize
@ -308,7 +309,8 @@ data class BootV3(
return this
}
fun printSummary(): BootV3 {
fun printUnpackSummary(): BootV3 {
val prints: MutableList<Pair<String, String>> = mutableListOf()
val workDir = Helper.prop("workDir")
val tableHeader = AsciiTable().apply {
addRule()
@ -318,32 +320,43 @@ data class BootV3(
val tab = AsciiTable().let {
it.addRule()
it.addRow("image info", workDir + info.output.removeSuffix(".img") + ".json")
prints.add(Pair("image info", workDir + info.output.removeSuffix(".img") + ".json"))
it.addRule()
if (this.kernel.size > 0) {
it.addRow("kernel", this.kernel.file)
prints.add(Pair("kernel", this.kernel.file))
File(Helper.prop("kernelVersionFile")).let { kernelVersionFile ->
if (kernelVersionFile.exists()) {
it.addRow("\\-- version " + kernelVersionFile.readLines().toString(), kernelVersionFile.path)
prints.add(Pair("\\-- version " + kernelVersionFile.readLines().toString(), kernelVersionFile.path))
}
}
File(Helper.prop("kernelConfigFile")).let { kernelConfigFile ->
if (kernelConfigFile.exists()) {
it.addRow("\\-- config", kernelConfigFile.path)
prints.add(Pair("\\-- config", kernelConfigFile.path))
}
}
it.addRule()
}
if (this.ramdisk.size > 0) {
//fancy
it.addRow("ramdisk", this.ramdisk.file)
it.addRow("\\-- extracted ramdisk rootfs", "${workDir}root")
it.addRule()
//basic
prints.add(Pair("ramdisk", this.ramdisk.file))
prints.add(Pair("\\-- extracted ramdisk rootfs", "${workDir}root"))
}
if (this.info.signatureSize > 0) {
it.addRow("GKI signature 1.0", this.bootSignature.file)
prints.add(Pair("GKI signature 1.0", this.bootSignature.file))
File(Avb.getJsonFileName(this.bootSignature.file)).let { jsFile ->
it.addRow("\\-- decoded boot signature", if (jsFile.exists()) jsFile.path else "N/A")
prints.add(Pair("\\-- decoded boot signature", if (jsFile.exists()) jsFile.path else "N/A"))
if (jsFile.exists()) {
it.addRow("\\------ signing key", Avb.inspectKey(mapper.readValue(jsFile, AVBInfo::class.java)))
prints.add(Pair("\\------ signing key", Avb.inspectKey(mapper.readValue(jsFile, AVBInfo::class.java))))
}
}
it.addRule()
@ -355,6 +368,10 @@ data class BootV3(
it.addRow("GKI signature 2.0", this.bootSignature.file)
it.addRow("\\-- boot", jsonFile.path)
it.addRow("\\------ signing key", Avb.inspectKey(mapper.readValue(jsonFile, AVBInfo::class.java)))
//basic
prints.add(Pair("GKI signature 2.0", this.bootSignature.file))
prints.add(Pair("\\-- boot", jsonFile.path))
prints.add(Pair("\\------ signing key", Avb.inspectKey(mapper.readValue(jsonFile, AVBInfo::class.java))))
}
}
File(Avb.getJsonFileName("sig.kernel")).let { jsonFile ->
@ -363,15 +380,20 @@ data class BootV3(
it.addRow("\\-- kernel", jsonFile.path)
it.addRow("\\------ signing key", Avb.inspectKey(readBackAvb))
it.addRule()
//basic
prints.add(Pair("\\-- kernel", jsonFile.path))
prints.add(Pair("\\------ signing key", Avb.inspectKey(readBackAvb)))
}
}
//AVB info
Avb.getJsonFileName(info.output).let { jsonFile ->
it.addRow("AVB info", if (File(jsonFile).exists()) jsonFile else "NONE")
prints.add(Pair("AVB info", if (File(jsonFile).exists()) jsonFile else "NONE"))
if (File(jsonFile).exists()) {
mapper.readValue(File(jsonFile), AVBInfo::class.java).let { ai ->
it.addRow("\\------ signing key", Avb.inspectKey(ai))
prints.add(Pair("\\------ signing key", Avb.inspectKey(ai)))
}
}
}
@ -384,19 +406,25 @@ data class BootV3(
it.addRow("vbmeta.img", Avb.getJsonFileName("vbmeta.img"))
it.addRule()
"\n" + it.render()
//basic
prints.add(Pair("vbmeta.img", Avb.getJsonFileName("vbmeta.img")))
} else {
""
}
}
log.info(
"\n\t\t\tUnpack Summary of ${info.output}\n{}\n{}{}",
tableHeader.render(), tab.render(), tabVBMeta
)
if (EnvironmentVerifier().isWindows) {
log.info("\n" + Common.table2String(prints))
} else {
log.info(
"\n\t\t\tUnpack Summary of ${info.output}\n{}\n{}{}",
tableHeader.render(), tab.render(), tabVBMeta
)
}
return this
}
fun printPackSummary(): BootV3 {
VendorBoot.printPackSummary(info.output)
Common.printPackSummary(info.output)
return this
}

@ -17,13 +17,14 @@ package cfig.bootimg.v3
import avb.AVBInfo
import cc.cfig.io.Struct
import cfig.Avb
import cfig.utils.EnvironmentVerifier
import cfig.bootimg.Common
import cfig.bootimg.Common.Companion.deleleIfExists
import cfig.bootimg.Signer
import cfig.helper.Helper
import cfig.helper.Dumpling
import cfig.helper.Helper
import cfig.packable.VBMetaParser
import cfig.utils.DTC
import cfig.utils.EnvironmentVerifier
import com.fasterxml.jackson.databind.ObjectMapper
import de.vandermeer.asciitable.AsciiTable
import org.apache.commons.exec.CommandLine
@ -211,34 +212,6 @@ data class VendorBoot(
ret.info.imageSize = File(fileName).length()
return ret
}
fun printPackSummary(imageName: String) {
val tableHeader = AsciiTable().apply {
addRule()
addRow("What", "Where")
addRule()
}
val tab = AsciiTable().let {
it.addRule()
if (File("$imageName.signed").exists()) {
it.addRow("re-packed $imageName", "$imageName.signed")
} else {
it.addRow("re-packed $imageName", "$imageName.clear")
}
it.addRule()
it
}
if (File("vbmeta.img").exists()) {
if (File("vbmeta.img.signed").exists()) {
tab.addRow("re-packed vbmeta", "vbmeta.img.signed")
} else {
tab.addRow("re-packed vbmeta", "-")
}
tab.addRule()
}
log.info("\n\t\t\tPack Summary of ${imageName}\n{}\n{}", tableHeader.render(), tab.render())
}
}
fun pack(): VendorBoot {
@ -402,6 +375,7 @@ data class VendorBoot(
}
fun printUnpackSummary(): VendorBoot {
val prints: MutableList<Pair<String, String>> = mutableListOf()
val tableHeader = AsciiTable().apply {
addRule()
addRow("What", "Where")
@ -410,34 +384,47 @@ data class VendorBoot(
val tab = AsciiTable().let {
it.addRule()
it.addRow("image info", workDir + info.output.removeSuffix(".img") + ".json")
prints.add(Pair("image info", workDir + info.output.removeSuffix(".img") + ".json"))
it.addRule()
it.addRow("ramdisk", this.ramdisk.file)
prints.add(Pair("ramdisk", this.ramdisk.file))
if (this.ramdisk_table.size > 0) {
this.ramdisk_table.ramdidks.forEachIndexed { index, entry ->
//fancy ascii
it.addRow("-- ${entry.type} ramdisk[${index + 1}/${this.ramdisk_table.ramdidks.size}]", entry.file)
it.addRow("------- extracted rootfs", "${workDir}root.${index + 1}")
//basic ascii
prints.add(Pair(" -- ${entry.type} ramdisk[${index + 1}/${this.ramdisk_table.ramdidks.size}]", entry.file))
prints.add(Pair(" ------- extracted rootfs", "${workDir}root.${index + 1}"))
}
} else {
it.addRow("\\-- extracted ramdisk rootfs", "${workDir}root")
prints.add(Pair("\\-- extracted ramdisk rootfs", "${workDir}root"))
}
it.addRule()
it.addRow("dtb", this.dtb.file)
prints.add(Pair("dtb", this.dtb.file))
if (File(this.dtb.file + ".${dtsSuffix}").exists()) {
it.addRow("\\-- decompiled dts", dtb.file + ".${dtsSuffix}")
prints.add(Pair("\\-- decompiled dts", dtb.file + ".${dtsSuffix}"))
}
if (this.bootconfig.size > 0) {
it.addRule()
it.addRow("bootconfig", this.bootconfig.file)
prints.add(Pair("bootconfig", this.bootconfig.file))
}
it.addRule()
Avb.getJsonFileName(info.output).let { jsonFile ->
if (File(jsonFile).exists()) {
it.addRow("AVB info", jsonFile)
prints.add(Pair("AVB info", jsonFile))
mapper.readValue(File(jsonFile), AVBInfo::class.java).let { ai ->
it.addRow("\\-- signing key", Avb.inspectKey(ai))
prints.add(Pair(" \\-- signing key", Avb.inspectKey(ai)))
}
} else {
it.addRow("AVB info", "none")
prints.add(Pair("AVB info", "none"))
}
it.addRule()
}
@ -447,18 +434,23 @@ data class VendorBoot(
if (File("vbmeta.img").exists()) {
it.addRule()
it.addRow("vbmeta.img", Avb.getJsonFileName("vbmeta.img"))
prints.add(Pair("vbmeta.img", Avb.getJsonFileName("vbmeta.img")))
it.addRule()
"\n" + it.render()
} else {
""
}
}
log.info("\n\t\t\tUnpack Summary of ${info.output}\n{}\n{}{}", tableHeader.render(), tab.render(), tabVBMeta)
if (EnvironmentVerifier().isWindows) {
log.info("\n" + Common.table2String(prints))
} else {
log.info("\n\t\t\tUnpack Summary of ${info.output}\n{}\n{}{}", tableHeader.render(), tab.render(), tabVBMeta)
}
return this
}
fun printPackSummary(): VendorBoot {
printPackSummary(info.output)
Common.printPackSummary(info.output)
return this
}

@ -45,7 +45,7 @@ class BootImgParser : IPackable {
.parse(fileName)
.extractImages()
.extractVBMeta()
.printSummary()
.printUnpackSummary()
log.debug(b2.toString())
}
in 3..4 -> {
@ -53,7 +53,7 @@ class BootImgParser : IPackable {
.parse(fileName)
.extractImages()
.extractVBMeta()
.printSummary()
.printUnpackSummary()
log.debug(b3.toString())
}
else -> {

@ -24,7 +24,7 @@ class VendorBootParser : IPackable {
override val loopNo: Int = 0
private val log = LoggerFactory.getLogger(VendorBootParser::class.java)
override fun capabilities(): List<String> {
return listOf("^vendor_boot(-debug)?\\.img$")
return listOf("^vendor_boot(-debug)?\\.img$", "^vendor_kernel_boot\\.img$")
}
override fun unpack(fileName: String) {

@ -5,9 +5,8 @@ import cc.cfig.io.Struct
import cfig.Avb
import cfig.bootimg.Common
import cfig.bootimg.Signer
import cfig.bootimg.v3.VendorBoot
import cfig.helper.Helper
import cfig.helper.Dumpling
import cfig.helper.Helper
import cfig.packable.VBMetaParser
import cfig.utils.DTC
import com.fasterxml.jackson.databind.ObjectMapper
@ -254,7 +253,7 @@ class Dtbo(
}
fun printPackSummary(): Dtbo {
VendorBoot.printPackSummary(info.output)
Common.printPackSummary(info.output)
return this
}
}

@ -45,7 +45,7 @@ class EnvironmentVerifier {
val hasGzip: Boolean
get(): Boolean {
try {
Runtime.getRuntime().exec("gzip -V")
Runtime.getRuntime().exec(arrayOf("gzip", "-V"), null, null)
log.debug("gzip available")
} catch (e: Exception) {
log.warn("gzip unavailable")
@ -54,21 +54,6 @@ class EnvironmentVerifier {
return true
}
val hasLz4: Boolean
get() : Boolean {
try {
Runtime.getRuntime().exec("lz4 --version")
log.debug("lz4 available")
} catch (e: Exception) {
log.warn("lz4 not installed")
if (isMacOS) {
log.warn("For Mac OS: \n\n\tbrew install lz4\n")
}
return false
}
return true
}
val has7z: Boolean
get(): Boolean {
try {
@ -107,6 +92,8 @@ class EnvironmentVerifier {
val isWindows: Boolean
get() = System.getProperty("os.name").contains("Windows")
var lz4prog: String = "lz4"
private fun getJavaVersion(): Int {
return System.getProperty("java.version").let { version ->
if (version.startsWith("1.")) {
@ -123,8 +110,8 @@ class EnvironmentVerifier {
}
init {
if (getJavaVersion() < 9) {
log.error("Java 9+ is required, while it's " + System.getProperty("java.version"))
if (getJavaVersion() < 11) {
log.error("Java 11+ is required, while it's " + System.getProperty("java.version"))
exitProcess(1)
} else {
log.debug("Java version " + System.getProperty("java.version"))

@ -15,6 +15,7 @@
package cfig.utils
import cfig.helper.Helper
import cfig.helper.ZipHelper
import org.apache.commons.exec.CommandLine
import org.apache.commons.exec.DefaultExecutor
import org.slf4j.Logger
@ -26,7 +27,7 @@ class KernelExtractor {
fun envCheck(): Boolean {
val envv = EnvironmentVerifier()
return envv.hasLz4 && envv.hasXz && envv.hasGzip
return ZipHelper.hasLz4 && envv.hasXz && envv.hasGzip
}
fun run(fileName: String, workDir: File? = null): List<String> {

@ -18,12 +18,6 @@ import org.junit.Test
class EnvironmentVerifierTest {
private val envv = EnvironmentVerifier()
@Test
fun getHasLz4() {
val hasLz4 = envv.hasLz4
println("hasLz4 = $hasLz4")
}
@Test
fun getHasDtc() {
val hasDtc = envv.hasDtc

@ -53,6 +53,17 @@ class ZipHelper {
companion object {
private val log = LoggerFactory.getLogger("ZipHelper")
val isMacOS: Boolean
get() = System.getProperty("os.name").contains("Mac")
val isLinux: Boolean
get() = System.getProperty("os.name").contains("Linux")
val isWindows: Boolean
get() = System.getProperty("os.name").contains("Windows")
private var lz4prog = ""
/*
unzip(): unzip fileName to outDir
*/
@ -317,9 +328,39 @@ class ZipHelper {
log.info("decompress(xz) done: $compressedFile -> $decompressedFile")
}
private fun getLz4Prog(): String {
if (lz4prog.isBlank()) {
lz4prog = "lz4"
if (isWindows) {
try {
Runtime.getRuntime().exec(arrayOf("tools/bin/lz4.exe", "--version"), null, null)
lz4prog = "tools/bin/lz4.exe"
} catch (e: Exception) {
log.warn("lz4 not installed")
}
}
}
return lz4prog
}
val hasLz4: Boolean
get() : Boolean {
try {
Runtime.getRuntime().exec(arrayOf(getLz4Prog(), "--version"), null, null)
log.debug("lz4 available")
} catch (e: Exception) {
log.warn("lz4 not installed")
if (isMacOS) {
log.warn("For Mac OS: \n\n\tbrew install lz4\n")
}
return false
}
return true
}
fun isLz4(compressedFile: String): Boolean {
return try {
"lz4 -t $compressedFile".check_call()
"${getLz4Prog()} -t $compressedFile".check_call()
true
} catch (e: Exception) {
false
@ -327,7 +368,7 @@ class ZipHelper {
}
fun lz4cat(lz4File: String, outFile: String) {
"lz4 -d -fv $lz4File $outFile".check_call()
"${getLz4Prog()} -d -fv $lz4File $outFile".check_call()
}
fun lz4(lz4File: String, inputStream: InputStream) {
@ -335,8 +376,8 @@ class ZipHelper {
val baosE = ByteArrayOutputStream()
DefaultExecutor().let { exec ->
exec.streamHandler = PumpStreamHandler(fos, baosE, inputStream)
val cmd = CommandLine.parse("lz4 -l -12")
if ("lz4 --version".check_output().contains("r\\d+,".toRegex())) {
val cmd = CommandLine.parse("${getLz4Prog()} -l -12")
if ("${getLz4Prog()} --version".check_output().contains("r\\d+,".toRegex())) {
log.warn("lz4 version obsolete, needs update")
} else {
cmd.addArgument("--favor-decSpeed")

Loading…
Cancel
Save