diff --git a/src/main/kotlin/com/beust/kobalt/misc/RunCommand.kt b/src/main/kotlin/com/beust/kobalt/misc/RunCommand.kt index 185a5e3d..8711ec90 100644 --- a/src/main/kotlin/com/beust/kobalt/misc/RunCommand.kt +++ b/src/main/kotlin/com/beust/kobalt/misc/RunCommand.kt @@ -17,6 +17,18 @@ open class RunCommand(val command: String) { var directory = File(".") var env = hashMapOf() + /** + * 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. + * This field is used to specify how errors are caught. + */ + var useErrorStreamAsErrorIndicator = true + + fun useErrorStreamAsErrorIndicator(f: Boolean) : RunCommand { + useErrorStreamAsErrorIndicator = f + return this + } + fun run(args: List, errorCallback: Function1, Unit> = defaultError, successCallback: Function1, Unit> = defaultSuccess) : Int { @@ -35,12 +47,16 @@ open class RunCommand(val command: String) { } } val callSucceeded = process.waitFor(30, TimeUnit.SECONDS) - val hasErrors = process.errorStream.available() > 0 -// val callSucceeded = if (passed == 0) true else false - if (callSucceeded && ! hasErrors) { + val hasErrorStream = process.errorStream.available() > 0 + var hasErrors = ! callSucceeded + if (useErrorStreamAsErrorIndicator && ! hasErrors) { + hasErrors = hasErrors && hasErrorStream + } + + if (! hasErrors) { successCallback(fromStream(process.inputStream)) } else { - val stream = if (hasErrors) process.errorStream + val stream = if (hasErrorStream) process.errorStream else if (process.inputStream.available() > 0) process.inputStream else null val errorString = diff --git a/src/main/kotlin/com/beust/kobalt/plugin/android/AndroidPlugin.kt b/src/main/kotlin/com/beust/kobalt/plugin/android/AndroidPlugin.kt index b176509e..6289b628 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/android/AndroidPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/android/AndroidPlugin.kt @@ -61,6 +61,8 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler) runTask = { taskGenerateDex(project) }) addVariantTasks(project, "signApk", runAfter = listOf("generateDex"), runBefore = listOf("assemble"), runTask = { taskSignApk(project) }) + addVariantTasks(project, "install", runAfter = listOf("signApk"), + runTask = { taskInstall(project) }) } context.pluginInfo.classpathContributors.add(this) @@ -104,6 +106,8 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler) private fun aapt(project: Project) = "${androidHome(project)}/build-tools/${buildToolsVersion(project)}/aapt" + private fun adb(project: Project) = "${androidHome(project)}/platform-tools/adb" + private fun temporaryApk(project: Project, flavor: String) = KFiles.joinFileAndMakeDir(intermediates(project), "res", "resources-$flavor.ap_") @@ -123,9 +127,11 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler) } inner class AaptCommand(project: Project, aapt: String, val aaptCommand: String, + useErrorStream: Boolean = false, cwd: File = File(project.directory)) : AndroidCommand(project, aapt) { init { directory = cwd + useErrorStreamAsErrorIndicator = useErrorStream } override fun call(args: List) = super.run(arrayListOf(aaptCommand) + args) @@ -205,7 +211,7 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler) val variantDir = context.variant.toIntermediateDir() val rDirectory = KFiles.joinAndMakeDir(generated, "source", "r", variantDir).toString() - AaptCommand(project, aapt, "package").call(listOf( + AaptCommand(project, aapt, "package", false).call(listOf( "-f", "--no-crunch", "-I", androidJar.toString(), @@ -369,6 +375,16 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler) return TaskResult() } + @Task(name = "install", description = "Install the apk file", runAfter = arrayOf(TASK_GENERATE_DEX), + runBefore = arrayOf("assemble")) + fun taskInstall(project: Project): TaskResult { + val apk = apk(project, context.variant.shortArchiveName) + RunCommand(adb(project)).useErrorStreamAsErrorIndicator(false).run(args = listOf( + "install", "-r", + apk)) + return TaskResult() + } + private val classpathEntries = HashMultimap.create() // IClasspathContributor