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

Merge branch 'master' of github.com:cbeust/kobalt

This commit is contained in:
Cedric Beust 2015-10-30 10:18:30 -07:00
commit 5d9fa17087
8 changed files with 112 additions and 21 deletions

View file

@ -0,0 +1,11 @@
package com.beust.kobalt.api
import com.beust.kobalt.maven.IClasspathDependency
/**
* Implement this interface in order to add your own entries to the classpath. A list of contributors
* can be found on the `KobaltContext`.
*/
interface IClasspathContributor {
fun entriesFor(project: Project) : Collection<IClasspathDependency>
}

View file

@ -2,8 +2,10 @@ package com.beust.kobalt.api
import com.beust.kobalt.Args import com.beust.kobalt.Args
import com.beust.kobalt.Plugins import com.beust.kobalt.Plugins
import java.util.*
public class KobaltContext(val args: Args) { public class KobaltContext(val args: Args) {
fun findPlugin(name: String) = Plugins.findPlugin(name) fun findPlugin(name: String) = Plugins.findPlugin(name)
val classpathContributors: ArrayList<IClasspathContributor> = arrayListOf()
} }

View file

@ -1,6 +1,7 @@
package com.beust.kobalt.internal package com.beust.kobalt.internal
import com.beust.kobalt.api.BasePlugin import com.beust.kobalt.api.BasePlugin
import com.beust.kobalt.api.KobaltContext
import com.beust.kobalt.api.Project import com.beust.kobalt.api.Project
import com.beust.kobalt.api.annotation.Directive import com.beust.kobalt.api.annotation.Directive
import com.beust.kobalt.api.annotation.Task import com.beust.kobalt.api.annotation.Task
@ -37,20 +38,43 @@ abstract class JvmCompilerPlugin @Inject constructor(
} }
} }
private fun runClasspathContributors(context: KobaltContext?, project: Project) :
Collection<IClasspathDependency> {
val result = arrayListOf<IClasspathDependency>()
context!!.classpathContributors.forEach {
result.addAll(it.entriesFor(project))
}
return result
}
} }
/** /**
* Log with a project. * Log with a project.
*/ */
protected fun lp(project: Project, s: String) { protected fun lp(project: Project, s: String) {
log(2, "${project.name}: ${s}") log(2, "${project.name}: $s")
} }
fun calculateClasspath(vararg allDependencies : List<IClasspathDependency>): List<IClasspathDependency> { var context: KobaltContext? = null
override fun apply(project: Project, context: KobaltContext) {
this.context = context
}
/**
* @return the classpath for this project, including the IClasspathContributors.
*/
fun calculateClasspath(project: Project?, vararg allDependencies: List<IClasspathDependency>):
List<IClasspathDependency> {
var result = arrayListOf<IClasspathDependency>() var result = arrayListOf<IClasspathDependency>()
allDependencies.forEach { dependencies -> allDependencies.forEach { dependencies ->
result.addAll(dependencyManager.transitiveClosure(dependencies)) result.addAll(dependencyManager.transitiveClosure(dependencies))
} }
if (project != null) {
result.addAll(runClasspathContributors(context, project))
}
return result return result
} }
@ -61,7 +85,7 @@ abstract class JvmCompilerPlugin @Inject constructor(
with(project) { with(project) {
arrayListOf(compileDependencies, compileProvidedDependencies, testDependencies, arrayListOf(compileDependencies, compileProvidedDependencies, testDependencies,
testProvidedDependencies).forEach { testProvidedDependencies).forEach {
result.addAll(calculateClasspath(it)) result.addAll(calculateClasspath(project, it))
} }
} }
return dependencyManager.reorderDependencies(result) return dependencyManager.reorderDependencies(result)
@ -105,18 +129,18 @@ abstract class JvmCompilerPlugin @Inject constructor(
sourceDirs.addAll(project.sourceDirectoriesTest.filter { it.contains("resources") }) sourceDirs.addAll(project.sourceDirectoriesTest.filter { it.contains("resources") })
outputDir = KFiles.TEST_CLASSES_DIR outputDir = KFiles.TEST_CLASSES_DIR
} else { } else {
throw IllegalArgumentException("Custom source sets not supported yet: ${sourceSet}") throw IllegalArgumentException("Custom source sets not supported yet: $sourceSet")
} }
if (sourceDirs.size > 0) { if (sourceDirs.size > 0) {
lp(project, "Copying ${sourceSet} resources") lp(project, "Copying $sourceSet resources")
val absOutputDir = File(KFiles.joinDir(project.directory, project.buildDirectory!!, outputDir)) val absOutputDir = File(KFiles.joinDir(project.directory, project.buildDirectory!!, outputDir))
sourceDirs.map { File(it) }.filter { it.exists() } .forEach { sourceDirs.map { File(it) }.filter { it.exists() } .forEach {
log(2, "Copying from ${sourceDirs} to ${absOutputDir}") log(2, "Copying from $sourceDirs to $absOutputDir")
KFiles.copyRecursively(it, absOutputDir) KFiles.copyRecursively(it, absOutputDir)
} }
} else { } else {
lp(project, "No resources to copy for ${sourceSet}") lp(project, "No resources to copy for $sourceSet")
} }
} }
} }

View file

@ -1,18 +1,19 @@
package com.beust.kobalt.plugin.android package com.beust.kobalt.plugin.android
import com.beust.kobalt.api.BasePlugin import com.beust.kobalt.api.*
import com.beust.kobalt.api.Kobalt
import com.beust.kobalt.api.KobaltContext
import com.beust.kobalt.api.Project
import com.beust.kobalt.api.annotation.Directive import com.beust.kobalt.api.annotation.Directive
import com.beust.kobalt.api.annotation.Task import com.beust.kobalt.api.annotation.Task
import com.beust.kobalt.internal.TaskResult import com.beust.kobalt.internal.TaskResult
import com.beust.kobalt.maven.FileDependency import com.beust.kobalt.maven.FileDependency
import com.beust.kobalt.maven.IClasspathDependency import com.beust.kobalt.maven.IClasspathDependency
import com.beust.kobalt.maven.MavenId
import com.beust.kobalt.misc.KFiles import com.beust.kobalt.misc.KFiles
import com.beust.kobalt.misc.RunCommand import com.beust.kobalt.misc.RunCommand
import com.beust.kobalt.misc.log import com.beust.kobalt.misc.log
import com.beust.kobalt.plugin.java.JavaCompiler import com.beust.kobalt.plugin.java.JavaCompiler
import com.beust.kobalt.plugin.packaging.JarUtils
import com.google.common.collect.ArrayListMultimap
import com.google.common.collect.HashMultimap
import com.google.inject.Inject import com.google.inject.Inject
import com.google.inject.Singleton import com.google.inject.Singleton
import java.io.File import java.io.File
@ -32,7 +33,7 @@ fun Project.android(init: AndroidConfiguration.() -> Unit) : AndroidConfiguratio
} }
@Singleton @Singleton
public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler) : BasePlugin() { public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler) : BasePlugin(), IClasspathContributor {
val ANDROID_HOME = "/Users/beust/android/adt-bundle-mac-x86_64-20140702/sdk" val ANDROID_HOME = "/Users/beust/android/adt-bundle-mac-x86_64-20140702/sdk"
override val name = "android" override val name = "android"
@ -41,6 +42,7 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler) :
if (accept(project)) { if (accept(project)) {
project.compileDependencies.add(FileDependency(androidJar(project).toString())) project.compileDependencies.add(FileDependency(androidJar(project).toString()))
} }
context.classpathContributors.add(this)
} }
val configurations = hashMapOf<String, AndroidConfiguration>() val configurations = hashMapOf<String, AndroidConfiguration>()
@ -49,7 +51,7 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler) :
configurations.put(p.name!!, configuration) configurations.put(p.name!!, configuration)
} }
override fun accept(p: Project) = configurations.containsKeyRaw(p.name) override fun accept(project: Project) = configurations.containsKey(project.name!!)
fun dirGet(dir: Path, vararg others: String) : String { fun dirGet(dir: Path, vararg others: String) : String {
val result = Paths.get(dir.toString(), *others) val result = Paths.get(dir.toString(), *others)
@ -60,8 +62,8 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler) :
return result.toString() return result.toString()
} }
fun compileSdkVersion(project: Project) = configurations.get(project.name!!)?.compileSdkVersion fun compileSdkVersion(project: Project) = configurations[project.name!!]?.compileSdkVersion
fun buildToolsVersion(project: Project) = configurations.get(project.name!!)?.buildToolsVersion fun buildToolsVersion(project: Project) = configurations[project.name!!]?.buildToolsVersion
fun androidJar(project: Project) : Path = fun androidJar(project: Project) : Path =
Paths.get(ANDROID_HOME, "platforms", "android-${compileSdkVersion(project)}", "android.jar") Paths.get(ANDROID_HOME, "platforms", "android-${compileSdkVersion(project)}", "android.jar")
@ -76,12 +78,14 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler) :
val applicationId = configurations[project.name!!]?.applicationId!! val applicationId = configurations[project.name!!]?.applicationId!!
val intermediates = Paths.get(project.directory, "app", "build", "intermediates") val intermediates = Paths.get(project.directory, "app", "build", "intermediates")
val manifestDir = Paths.get(project.directory, "app", "src", "main").toString() val manifestDir = Paths.get(project.directory, "app", "src", "main").toString()
val manifestIntermediateDir = dirGet(intermediates, "manifests", "full", flavor) // val manifestIntermediateDir = dirGet(intermediates, "manifests", "full", flavor)
val manifest = Paths.get(manifestDir, "AndroidManifest.xml") val manifest = Paths.get(manifestDir, "AndroidManifest.xml")
val generated = Paths.get(project.directory, "app", "build", "generated") val generated = Paths.get(project.directory, "app", "build", "generated")
val aapt = "$ANDROID_HOME/build-tools/$buildToolsVersion/aapt" val aapt = "$ANDROID_HOME/build-tools/$buildToolsVersion/aapt"
val outputDir = dirGet(intermediates, "resources", "resources-$flavor") val outputDir = dirGet(intermediates, "resources", "resources-$flavor")
explodeAarFiles(project, generated)
val crunchedPngDir = dirGet(intermediates, "res", flavor) val crunchedPngDir = dirGet(intermediates, "res", flavor)
RunCommand(aapt).apply { RunCommand(aapt).apply {
directory = File(project.directory) directory = File(project.directory)
@ -119,6 +123,23 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler) :
return TaskResult() return TaskResult()
} }
/**
* Extract all the .aar files found in the dependencies and add the android.jar to classpathEntries,
* which will be added to the classpath at compile time
*/
private fun explodeAarFiles(project: Project, outputDir: Path) {
project.compileDependencies.filter {
it.jarFile.get().name.endsWith(".aar")
}.forEach {
log(2, "Exploding ${it.jarFile.get()}")
val mavenId = MavenId(it.id)
val destDir = Paths.get(outputDir.toFile().absolutePath, mavenId.artifactId, mavenId.version).toFile()
JarUtils.extractJarFile(it.jarFile.get(), destDir)
val classesJar = Paths.get(destDir.absolutePath, "classes.jar")
classpathEntries.put(project.name, FileDependency(classesJar.toFile().absolutePath))
}
}
private fun compile(project: Project, rDirectory: String) : File { private fun compile(project: Project, rDirectory: String) : File {
val sourceFiles = arrayListOf(Paths.get(rDirectory, "R.java").toFile().path) val sourceFiles = arrayListOf(Paths.get(rDirectory, "R.java").toFile().path)
val buildDir = Paths.get(project.buildDirectory, "generated", "classes").toFile() val buildDir = Paths.get(project.buildDirectory, "generated", "classes").toFile()
@ -127,6 +148,13 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler) :
sourceFiles, buildDir) sourceFiles, buildDir)
return buildDir return buildDir
} }
val classpathEntries = HashMultimap.create<String, IClasspathDependency>()
override fun entriesFor(project: Project): Collection<IClasspathDependency> {
return classpathEntries.get(project.name!!) ?: listOf()
}
} }

View file

@ -77,7 +77,7 @@ public class JavaPlugin @Inject constructor(
val sourceFiles = files.findRecursively(projectDir, project.sourceDirectories.map { File(it) }) val sourceFiles = files.findRecursively(projectDir, project.sourceDirectories.map { File(it) })
{ it: String -> it.endsWith(".java") } { it: String -> it.endsWith(".java") }
.map { File(projectDir, it).absolutePath } .map { File(projectDir, it).absolutePath }
val classpath = calculateClasspath(project.compileDependencies) val classpath = calculateClasspath(project, project.compileDependencies)
val args = arrayListOf( val args = arrayListOf(
javadoc!!.absolutePath, javadoc!!.absolutePath,
"-classpath", classpath.map { it.jarFile.get().absolutePath }.joinToString(File.pathSeparator), "-classpath", classpath.map { it.jarFile.get().absolutePath }.joinToString(File.pathSeparator),
@ -105,7 +105,7 @@ public class JavaPlugin @Inject constructor(
val sourceFiles = files.findRecursively(projectDir, project.sourceDirectories.map { File(it) }) val sourceFiles = files.findRecursively(projectDir, project.sourceDirectories.map { File(it) })
{ it: String -> it.endsWith(".java") } { it: String -> it.endsWith(".java") }
.map { File(projectDir, it).absolutePath } .map { File(projectDir, it).absolutePath }
val classpath = calculateClasspath(project.compileDependencies) val classpath = calculateClasspath(project, project.compileDependencies)
return compilePrivate(project, classpath, sourceFiles, buildDir) return compilePrivate(project, classpath, sourceFiles, buildDir)
} }

View file

@ -48,7 +48,7 @@ class KotlinCompiler @Inject constructor(override val localRepo : LocalRepo,
getKotlinCompilerJar("kotlin-compiler-embeddable")) getKotlinCompilerJar("kotlin-compiler-embeddable"))
classpathList.addAll(otherClasspath) classpathList.addAll(otherClasspath)
classpathList.addAll(calculateClasspath(compileDependencies).map { it.id }) classpathList.addAll(calculateClasspath(null, compileDependencies).map { it.id })
validateClasspath(classpathList) validateClasspath(classpathList)

View file

@ -41,7 +41,7 @@ class KotlinPlugin @Inject constructor(
@Task(name = TASK_COMPILE, description = "Compile the project") @Task(name = TASK_COMPILE, description = "Compile the project")
fun taskCompile(project: Project): TaskResult { fun taskCompile(project: Project): TaskResult {
copyResources(project, JvmCompilerPlugin.SOURCE_SET_MAIN) copyResources(project, JvmCompilerPlugin.SOURCE_SET_MAIN)
val classpath = calculateClasspath(project.compileDependencies, project.compileProvidedDependencies) val classpath = calculateClasspath(project, project.compileDependencies, project.compileProvidedDependencies)
val projectDirectory = java.io.File(project.directory) val projectDirectory = java.io.File(project.directory)
val buildDirectory = File(projectDirectory, project.buildDirectory + File.separator + "classes") val buildDirectory = File(projectDirectory, project.buildDirectory + File.separator + "classes")

View file

@ -1,6 +1,7 @@
package com.beust.kobalt.plugin.packaging package com.beust.kobalt.plugin.packaging
import com.beust.kobalt.IFileSpec import com.beust.kobalt.IFileSpec
import com.beust.kobalt.file
import com.beust.kobalt.misc.log import com.beust.kobalt.misc.log
import java.io.* import java.io.*
import java.util.jar.JarEntry import java.util.jar.JarEntry
@ -44,7 +45,7 @@ public class JarUtils {
// //
// var len = zis.read(buf) // var len = zis.read(buf)
// while (len >= 0) { // while (len >= 0) {
// outStream.write(buf, 0, len); // outStream.write(buf, 0, len)
// len = zis.read(buf) // len = zis.read(buf)
// } // }
// } // }
@ -154,5 +155,30 @@ public class JarUtils {
log(1, "Deduplicated $fromFile.name") log(1, "Deduplicated $fromFile.name")
} }
fun extractJarFile(jarFile: File, destDir: File) {
val jar = java.util.jar.JarFile(jarFile)
val enumEntries = jar.entries()
while (enumEntries.hasMoreElements()) {
val file = enumEntries.nextElement() as JarEntry
val f = File(destDir.path + java.io.File.separator + file.name)
if (file.isDirectory) {
f.mkdir()
continue
}
var ins: InputStream? = null
var fos: OutputStream? = null
try {
ins = jar.getInputStream(file)
f.parentFile.mkdirs()
fos = FileOutputStream(f)
while (ins.available() > 0) {
fos.write(ins.read())
}
} finally {
fos?.close()
ins?.close()
}
}
}
} }
} }