mirror of
https://github.com/ethauvin/kobalt.git
synced 2025-04-27 08:38:13 -07:00
Checkpoint.
This commit is contained in:
parent
e93f4ba85f
commit
8882c1cae5
4 changed files with 143 additions and 75 deletions
|
@ -6,65 +6,28 @@ import java.io.InputStream
|
||||||
import java.io.InputStreamReader
|
import java.io.InputStreamReader
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
open class RunCommand(val command: String) {
|
class RunCommandInfo {
|
||||||
val DEFAULT_SUCCESS = { output: List<String> -> }
|
lateinit var command: String
|
||||||
// val DEFAULT_SUCCESS_VERBOSE = { output: List<String> -> log(2, "Success:\n " + output.joinToString("\n"))}
|
var args : List<String> = arrayListOf()
|
||||||
val defaultSuccess = DEFAULT_SUCCESS
|
var directory : File = File("")
|
||||||
val DEFAULT_ERROR = {
|
var env : Map<String, String> = hashMapOf()
|
||||||
output: List<String> -> error(output.joinToString("\n "))
|
|
||||||
}
|
|
||||||
|
|
||||||
var directory = File(".")
|
|
||||||
var env = hashMapOf<String, String>()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some commands fail but return 0, so the only way to find out if they failed is to look
|
* Some commands fail but return 0, so the only way to find out if they failed is to look
|
||||||
* at the error stream. However, some commands succeed but output text on the error stream.
|
* at the error stream. However, some commands succeed but output text on the error stream.
|
||||||
* This field is used to specify how errors are caught.
|
* This field is used to specify how errors are caught.
|
||||||
*/
|
*/
|
||||||
var useErrorStreamAsErrorIndicator = true
|
var useErrorStreamAsErrorIndicator : Boolean = true
|
||||||
var useInputStreamAsErrorIndicator = false
|
var useInputStreamAsErrorIndicator : Boolean = false
|
||||||
|
|
||||||
fun useErrorStreamAsErrorIndicator(f: Boolean) : RunCommand {
|
var errorCallback: Function1<List<String>, Unit> = RunCommand.DEFAULT_ERROR
|
||||||
useErrorStreamAsErrorIndicator = f
|
var successCallback: Function1<List<String>, Unit> = RunCommand.DEFAULT_SUCCESS
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun run(args: List<String>,
|
var isSuccess: (Boolean, List<String>, List<String>) -> Boolean = {
|
||||||
errorCallback: Function1<List<String>, Unit> = DEFAULT_ERROR,
|
isSuccess: Boolean,
|
||||||
successCallback: Function1<List<String>, Unit> = defaultSuccess) : Int {
|
input: List<String>,
|
||||||
val allArgs = arrayListOf<String>()
|
error: List<String> ->
|
||||||
allArgs.add(command)
|
var hasErrors = ! isSuccess
|
||||||
allArgs.addAll(args)
|
|
||||||
|
|
||||||
val pb = ProcessBuilder(allArgs)
|
|
||||||
pb.directory(directory)
|
|
||||||
log(2, "Running command in directory ${directory.absolutePath}" +
|
|
||||||
"\n " + allArgs.joinToString(" ").replace("\\", "/"))
|
|
||||||
val process = pb.start()
|
|
||||||
pb.environment().let { pbEnv ->
|
|
||||||
env.forEach {
|
|
||||||
pbEnv.put(it.key, it.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val callSucceeded = process.waitFor(30, TimeUnit.SECONDS)
|
|
||||||
val input = if (process.inputStream.available() > 0) fromStream(process.inputStream)
|
|
||||||
else listOf()
|
|
||||||
val error = if (process.errorStream.available() > 0) fromStream(process.errorStream)
|
|
||||||
else listOf()
|
|
||||||
val isSuccess = isSuccess(callSucceeded, input, error)
|
|
||||||
|
|
||||||
if (isSuccess) {
|
|
||||||
successCallback(fromStream(process.inputStream))
|
|
||||||
} else {
|
|
||||||
errorCallback(error + input)
|
|
||||||
}
|
|
||||||
|
|
||||||
return if (isSuccess) 0 else 1
|
|
||||||
}
|
|
||||||
|
|
||||||
open protected fun isSuccess(callSucceeded: Boolean, input: List<String>, error: List<String>) : Boolean {
|
|
||||||
var hasErrors = ! callSucceeded
|
|
||||||
if (useErrorStreamAsErrorIndicator && ! hasErrors) {
|
if (useErrorStreamAsErrorIndicator && ! hasErrors) {
|
||||||
hasErrors = hasErrors || error.size > 0
|
hasErrors = hasErrors || error.size > 0
|
||||||
}
|
}
|
||||||
|
@ -72,9 +35,83 @@ open class RunCommand(val command: String) {
|
||||||
hasErrors = hasErrors || input.size > 0
|
hasErrors = hasErrors || input.size > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
! hasErrors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun runCommand(init: RunCommandInfo.() -> Unit) = RunCommand(RunCommandInfo().apply { init() }).invoke()
|
||||||
|
|
||||||
|
open class RunCommand(val info: RunCommandInfo) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val DEFAULT_SUCCESS = { output: List<String> -> }
|
||||||
|
// val DEFAULT_SUCCESS_VERBOSE = { output: List<String> -> log(2, "Success:\n " + output.joinToString("\n"))}
|
||||||
|
// val defaultSuccess = DEFAULT_SUCCESS
|
||||||
|
val DEFAULT_ERROR = {
|
||||||
|
output: List<String> ->
|
||||||
|
error(output.joinToString("\n "))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fun useErrorStreamAsErrorIndicator(f: Boolean) : RunCommand {
|
||||||
|
// useErrorStreamAsErrorIndicator = f
|
||||||
|
// return this
|
||||||
|
// }
|
||||||
|
|
||||||
|
fun invoke() : Int {
|
||||||
|
val allArgs = arrayListOf<String>()
|
||||||
|
allArgs.add(info.command)
|
||||||
|
allArgs.addAll(info.args)
|
||||||
|
|
||||||
|
val pb = ProcessBuilder(allArgs)
|
||||||
|
pb.directory(info.directory)
|
||||||
|
log(2, "Running command in directory ${info.directory.absolutePath}" +
|
||||||
|
"\n " + allArgs.joinToString(" ").replace("\\", "/"))
|
||||||
|
val process = pb.start()
|
||||||
|
pb.environment().let { pbEnv ->
|
||||||
|
info.env.forEach {
|
||||||
|
pbEnv.put(it.key, it.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the command and collect the return code and streams
|
||||||
|
val returnCode = process.waitFor(30, TimeUnit.SECONDS)
|
||||||
|
val input = if (process.inputStream.available() > 0) fromStream(process.inputStream)
|
||||||
|
else listOf()
|
||||||
|
val error = if (process.errorStream.available() > 0) fromStream(process.errorStream)
|
||||||
|
else listOf()
|
||||||
|
|
||||||
|
// Check to see if the command succeeded
|
||||||
|
val isSuccess = isSuccess(returnCode, input, error)
|
||||||
|
|
||||||
|
if (isSuccess) {
|
||||||
|
info.successCallback(input)
|
||||||
|
} else {
|
||||||
|
info.errorCallback(error + input)
|
||||||
|
}
|
||||||
|
|
||||||
|
return if (isSuccess) 0 else 1
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subclasses can override this method to do their own error handling, since commands can
|
||||||
|
* have various ways to signal errors.
|
||||||
|
*/
|
||||||
|
open protected fun isSuccess(isSuccess: Boolean, input: List<String>, error: List<String>) : Boolean {
|
||||||
|
var hasErrors = ! isSuccess
|
||||||
|
if (info.useErrorStreamAsErrorIndicator && ! hasErrors) {
|
||||||
|
hasErrors = hasErrors || error.size > 0
|
||||||
|
}
|
||||||
|
if (info.useInputStreamAsErrorIndicator && ! hasErrors) {
|
||||||
|
hasErrors = hasErrors || input.size > 0
|
||||||
|
}
|
||||||
|
|
||||||
return ! hasErrors
|
return ! hasErrors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turn the given InputStream into a list of strings.
|
||||||
|
*/
|
||||||
private fun fromStream(ins: InputStream) : List<String> {
|
private fun fromStream(ins: InputStream) : List<String> {
|
||||||
val result = arrayListOf<String>()
|
val result = arrayListOf<String>()
|
||||||
val br = BufferedReader(InputStreamReader(ins))
|
val br = BufferedReader(InputStreamReader(ins))
|
||||||
|
|
|
@ -1,24 +1,54 @@
|
||||||
package com.beust.kobalt.plugin.android
|
package com.beust.kobalt.plugin.android
|
||||||
|
|
||||||
import com.beust.kobalt.api.Project
|
import com.beust.kobalt.api.Project
|
||||||
import com.beust.kobalt.misc.RunCommand
|
|
||||||
import com.beust.kobalt.misc.log
|
import com.beust.kobalt.misc.log
|
||||||
|
import com.beust.kobalt.misc.runCommand
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
open class AndroidCommand(project: Project, androidHome: String, command: String, cwd: File = File(project.directory))
|
open class AndroidCommand(project: Project, val androidHome: String, val command: String,
|
||||||
: RunCommand(command) {
|
val directory: File = File(project.directory),
|
||||||
init {
|
val useErrorStreamAsErrorIndicator : Boolean = true,
|
||||||
env.put("ANDROID_HOME", androidHome)
|
val args: List<String>)
|
||||||
directory = cwd
|
// : RunCommand(command, directory = cwd, args = args
|
||||||
}
|
// ,
|
||||||
|
// successCallback = { output ->
|
||||||
|
// log(1, "$command succeeded:")
|
||||||
|
// output.forEach {
|
||||||
|
// log(1, " $it")
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
{
|
||||||
|
|
||||||
open fun call(args: List<String>) = run(args,
|
|
||||||
|
// val SUCCESS_CALLBACK : (List<String>) -> Unit = { output ->
|
||||||
|
// log(1, "$command succeeded:")
|
||||||
|
// output.forEach {
|
||||||
|
// log(1, " $it")
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// val ERROR_CALLBACK : (List<String>) -> Unit = { output ->
|
||||||
|
// with(StringBuilder()) {
|
||||||
|
// append("Error running $command:")
|
||||||
|
// output.forEach {
|
||||||
|
// append(" $it")
|
||||||
|
// }
|
||||||
|
// error(this.toString())
|
||||||
|
// }
|
||||||
|
// }nComman
|
||||||
|
|
||||||
|
open fun call(theseArgs: List<String>) : Int {
|
||||||
|
val rc = runCommand {
|
||||||
|
args = theseArgs
|
||||||
|
useErrorStreamAsErrorIndicator = useErrorStreamAsErrorIndicator
|
||||||
|
directory = directory
|
||||||
|
env = hashMapOf("ANDROID_HOME" to androidHome)
|
||||||
successCallback = { output ->
|
successCallback = { output ->
|
||||||
log(1, "$command succeeded:")
|
log(1, "$command succeeded:")
|
||||||
output.forEach {
|
output.forEach {
|
||||||
log(1, " $it")
|
log(1, " $it")
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
errorCallback = { output ->
|
errorCallback = { output ->
|
||||||
with(StringBuilder()) {
|
with(StringBuilder()) {
|
||||||
append("Error running $command:")
|
append("Error running $command:")
|
||||||
|
@ -27,7 +57,10 @@ open class AndroidCommand(project: Project, androidHome: String, command: String
|
||||||
}
|
}
|
||||||
error(this.toString())
|
error(this.toString())
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
}
|
||||||
|
return rc
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -107,15 +107,12 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler, v
|
||||||
* aapt returns 0 even if it fails, so in order to detect whether it failed, we are checking
|
* aapt returns 0 even if it fails, so in order to detect whether it failed, we are checking
|
||||||
* if its error stream contains anything.
|
* if its error stream contains anything.
|
||||||
*/
|
*/
|
||||||
inner class AaptCommand(project: Project, aapt: String, val aaptCommand: String,
|
inner class AaptCommand(project: Project, aapt: String, val aaptCommand: String, cwd: File = File("."),
|
||||||
cwd: File = File(".")) : AndroidCommand(project, androidHome(project), aapt) {
|
args: List<String>)
|
||||||
init {
|
: AndroidCommand(project, androidHome(project), aapt,
|
||||||
directory = cwd
|
directory = cwd,
|
||||||
useErrorStreamAsErrorIndicator = true
|
useErrorStreamAsErrorIndicator = true,
|
||||||
}
|
args = arrayListOf(aaptCommand) + args)
|
||||||
|
|
||||||
override fun call(args: List<String>) = super.run(arrayListOf(aaptCommand) + args)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun generateR(project: Project, generated: String, aapt: String) : Boolean {
|
private fun generateR(project: Project, generated: String, aapt: String) : Boolean {
|
||||||
val compileSdkVersion = compileSdkVersion(project)
|
val compileSdkVersion = compileSdkVersion(project)
|
||||||
|
@ -132,7 +129,7 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler, v
|
||||||
val variantDir = context.variant.toIntermediateDir()
|
val variantDir = context.variant.toIntermediateDir()
|
||||||
|
|
||||||
val rDirectory = KFiles.joinAndMakeDir(generated, "source", "r", variantDir).toString()
|
val rDirectory = KFiles.joinAndMakeDir(generated, "source", "r", variantDir).toString()
|
||||||
val result = AaptCommand(project, aapt, "package").call(listOf(
|
val result = AaptCommand(project, aapt, "package", args = listOf(
|
||||||
"-f",
|
"-f",
|
||||||
"--no-crunch",
|
"--no-crunch",
|
||||||
"-I", androidJar.toString(),
|
"-I", androidJar.toString(),
|
||||||
|
@ -358,7 +355,7 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler, v
|
||||||
* adb has weird ways of signaling errors, that's the best I've found so far.
|
* adb has weird ways of signaling errors, that's the best I've found so far.
|
||||||
*/
|
*/
|
||||||
class AdbInstall : RunCommand(adb(project)) {
|
class AdbInstall : RunCommand(adb(project)) {
|
||||||
override fun isSuccess(callSucceeded: Boolean, input: List<String>, error: List<String>)
|
override fun isSuccess(isSuccess: Boolean, input: List<String>, error: List<String>)
|
||||||
= input.filter { it.contains("Success")}.size > 0
|
= input.filter { it.contains("Success")}.size > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,9 +55,10 @@ class RetrolambdaPlugin @Inject constructor(val dependencyManager: DependencyMan
|
||||||
"-Dretrolambda.bytecodeVersion=${config.byteCodeVersion}",
|
"-Dretrolambda.bytecodeVersion=${config.byteCodeVersion}",
|
||||||
"-jar", JAR.jarFile.get().path)
|
"-jar", JAR.jarFile.get().path)
|
||||||
|
|
||||||
val result = RunCommand("java").apply {
|
val result = RunCommand("java",
|
||||||
directory = File(project.directory)
|
directory = File(project.directory),
|
||||||
}.run(args)
|
args = args)
|
||||||
|
.run()
|
||||||
TaskResult(result == 0)
|
TaskResult(result == 0)
|
||||||
} else {
|
} else {
|
||||||
TaskResult()
|
TaskResult()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue