1
0
Fork 0
mirror of https://github.com/ethauvin/kobalt.git synced 2025-04-26 08:27:12 -07:00

Streamlined the file management for AndroidPlugin.

This commit is contained in:
Cedric Beust 2015-11-06 04:23:11 -08:00
parent 8f53eb6e95
commit 309209f776
3 changed files with 68 additions and 51 deletions

View file

@ -55,7 +55,33 @@ public class KFiles {
public val TEST_CLASSES_DIR : String = "test-classes"
public fun joinDir(vararg ts: String): String = ts.toArrayList().joinToString(File.separator)
/**
* Join the paths elements with the file separator.
*/
fun joinDir(paths: List<String>): String = paths.joinToString(File.separator)
/**
* Join the paths elements with the file separator.
*/
fun joinDir(vararg ts: String): String = ts.toArrayList().joinToString(File.separator)
/**
* The paths elements are expected to be a directory. Make that directory and join the
* elements with the file separator.
*/
fun joinAndMakeDir(paths: List<String>) = joinDir(paths).apply { File(this).mkdirs() }
/**
* The paths elements are expected to be a directory. Make that directory and join the
* elements with the file separator.
*/
fun joinAndMakeDir(vararg ts: String) = joinAndMakeDir(ts.toList())
/**
* The paths elements are expected to be a file. Make that parent directory of that file and join the
* elements with the file separator.
*/
fun joinFileAndMakeDir(vararg ts: String) = joinDir(joinAndMakeDir(ts.slice(0..ts.size - 2)), ts[ts.size - 1])
fun makeDir(dir: String, s: String? = null) =
(if (s != null) File(dir, s) else File(dir)).apply { mkdirs() }
@ -148,20 +174,6 @@ public class KFiles {
}
}
// public fun copy(from: InputStream, to: OutputStream, bufSize: Int): Long {
// val buf = ByteArray(bufSize)
// var total: Long = 0
// while (true) {
// val r = from.read(buf, 0, buf.size())
// if (r == -1) {
// break
// }
// to.write(buf, 0, r)
// total += r.toLong()
// }
// return total
// }
public fun createTempFile(suffix : String = "", deleteOnExit: Boolean = false) : File =
File.createTempFile("kobalt", suffix, File(SystemProperties.tmpDir)).let {
if (deleteOnExit) it.deleteOnExit()

View file

@ -6,10 +6,13 @@ import java.io.InputStream
import java.io.InputStreamReader
open class RunCommand(val command: String) {
val defaultSuccess = { output: List<String> -> log(1, "Success:\n " + output.joinToString("\n"))}
val defaultError = { output: List<String> -> log(1, "Error:\n " + output.joinToString("\n"))}
val defaultSuccess = { output: List<String> -> log(2, "Success:\n " + output.joinToString("\n"))}
val defaultError = {
output: List<String> -> error("Error:\n " + output.joinToString("\n"))
}
var directory = File(".")
var env = hashMapOf<String, String>()
fun run(args: List<String>, error: Function1<List<String>, Unit>? = defaultError,
success: Function1<List<String>, Unit>? = defaultSuccess) : Int {
@ -19,9 +22,13 @@ open class RunCommand(val command: String) {
val pb = ProcessBuilder(allArgs)
pb.directory(directory)
log(2, "Running command: " + allArgs.joinToString(" "))
log(2, "Running command: " + allArgs.joinToString(" ") + "\n Current directory: $directory")
val process = pb.start()
pb.environment().put("ANDROID_HOME", "/Users/beust/android/adt-bundle-mac-x86_64-20140702/sdk")
pb.environment().let { pbEnv ->
env.forEach {
pbEnv.put(it.key, it.value)
}
}
val errorCode = process.waitFor()
if (errorCode != 0 && error != null) {
error(fromStream(process.errorStream))

View file

@ -62,14 +62,6 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler) :
override fun accept(project: Project) = configurations.containsKey(project.name!!)
fun dirGet(dir: Path, vararg others: String) : String {
val result = Paths.get(dir.toString(), *others)
with(result.toFile()) {
mkdirs()
}
return result.toString()
}
val flavor = "debug"
fun compileSdkVersion(project: Project) = configurations[project.name!!]?.compileSdkVersion
@ -96,18 +88,16 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler) :
fun androidJar(project: Project) : Path =
Paths.get(androidHome(project), "platforms", "android-${compileSdkVersion(project)}", "android.jar")
fun generated(project: Project) = Paths.get(project.directory, "app", "build", "generated")
private fun generated(project: Project) = Paths.get(project.buildDirectory, "app", "build", "generated")
private fun intermediates(project: Project) = Paths.get(project.buildDirectory, "app", "build", "intermediates")
private fun aapt(project: Project) = "${androidHome(project)}/build-tools/${buildToolsVersion(project)}/aapt"
private fun temporaryApk(project: Project, flavor: String) = apk(project, flavor, "ap_")
private fun temporaryApk(project: Project, flavor: String)
= KFiles.joinFileAndMakeDir(project.buildDirectory!!, "intermediates", "res", "resources-$flavor.ap_")
private fun apk(project: Project, flavor: String, suffix: String) : String {
val outputDir = dirGet(intermediates(project), "resources", "resources-$flavor")
return Paths.get(outputDir, "resources-$flavor.$suffix").toString()
}
private fun intermediates(project: Project) = Paths.get(project.directory, "app", "build", "intermediates")
private fun apk(project: Project, flavor: String)
= KFiles.joinFileAndMakeDir(project.buildDirectory!!, "outputs", "apk" ,"app-$flavor.apk")
@Task(name = "generateR", description = "Generate the R.java file",
runBefore = arrayOf("compile"), runAfter = arrayOf("clean"))
@ -119,8 +109,14 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler) :
return TaskResult()
}
class AaptCommand(project: Project, aapt: String, val aaptCommand: String,
cwd: File = File(project.directory)) : RunCommand(aapt) {
open class AndroidCommand(androidHome: String, command: String) : RunCommand(command) {
init {
env.put("ANDROID_HOME", androidHome)
}
}
inner class AaptCommand(project: Project, aapt: String, val aaptCommand: String,
cwd: File = File(project.directory)) : AndroidCommand(androidHome(project), aapt) {
init {
directory = cwd
}
@ -134,7 +130,7 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler) :
val manifestDir = Paths.get(project.directory, "app", "src", "main").toString()
val manifest = Paths.get(manifestDir, "AndroidManifest.xml")
val crunchedPngDir = dirGet(intermediates(project), "res", flavor)
val crunchedPngDir = KFiles.joinAndMakeDir(intermediates(project).toString(), "res", flavor)
AaptCommand(project, aapt, "crunch").call(listOf(
"-v",
@ -149,14 +145,16 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler) :
"-M", manifest.toString(),
"-S", crunchedPngDir,
"-S", "app/src/main/res",
"-A", dirGet(intermediates(project), "assets", flavor), // where to find more assets
// where to find more assets
"-A", KFiles.joinAndMakeDir(intermediates(project).toString(), "assets", flavor),
"-m", // create directory
"-J", dirGet(generated, "sources", "r", flavor).toString(), // where all gets generated
// where all gets generated
"-J", KFiles.joinAndMakeDir(generated.toString(), "sources", "r", flavor).toString(),
"-F", temporaryApk(project, flavor),
"--debug-mode",
"-0", "apk",
"--custom-package", applicationId,
"--output-text-symbols", dirGet(intermediates(project), "symbol", flavor))
"--output-text-symbols", KFiles.joinAndMakeDir(intermediates(project).toString(), "symbol", flavor))
)
val rDirectory = KFiles.joinDir(generated.toFile().path, "sources", "r", flavor,
@ -202,21 +200,21 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler) :
val buildToolsDir = buildToolsVersion(project)
val dx = "${androidHome(project)}/build-tools/$buildToolsDir/dx"
val buildDir = context.pluginProperties.get("java", JvmCompilerPlugin.BUILD_DIR)
val libsDir = context.pluginProperties.get("packaging", PackagingPlugin.LIBS_DIR)
File(libsDir!!.toString()).mkdirs()
val libsDir = (context.pluginProperties.get("packaging", PackagingPlugin.LIBS_DIR) as File).path
File(libsDir.toString()).mkdirs()
val classesDex = "classes.dex"
val outClassesDex = KFiles.joinDir(libsDir.toString(), classesDex)
val relClassesDex = File(outClassesDex).parentFile
RunCommand(dx).run(listOf("--dex", "--output", outClassesDex,
buildDir!!.toString()))
val classesDexDir = KFiles.joinAndMakeDir(libsDir, "intermediates", "dex", flavor)
val outClassesDex = KFiles.joinDir(classesDexDir, classesDex)
RunCommand(dx).run(listOf("--dex", "--output", outClassesDex, buildDir!!.toString()))
//
// Add classes.dex to existing .ap_
//
AaptCommand(project, aapt(project), "add", relClassesDex).call(listOf(
"-v", temporaryApk(project, flavor), classesDex
))
AaptCommand(project, aapt(project), "add").apply {
directory = File(outClassesDex).parentFile
}.call(listOf("-v", KFiles.joinDir("../../../../..", temporaryApk(project, flavor)), classesDex))
return TaskResult()
}
@ -230,7 +228,7 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler) :
@Task(name = "signApk", description = "Sign the apk file", runAfter = arrayOf(TASK_GENERATE),
runBefore = arrayOf("assemble"))
fun signApk(project: Project) : TaskResult {
val apk = apk(project, flavor, "apk")
val apk = apk(project, flavor)
val temporaryApk = temporaryApk(project, flavor)
RunCommand("jarsigner").run(listOf(
"-keystore", homeDir(".android", "debug.keystore"),