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

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

Conflicts:
	src/main/kotlin/com/beust/kobalt/Main.kt
This commit is contained in:
Cedric Beust 2015-11-05 16:48:37 -08:00
commit dffcee0cd4
33 changed files with 470 additions and 404 deletions

View file

@ -32,6 +32,7 @@ To do:
Done: Done:
- [x] Get rid of the $JAVA_HOME requirement
- [x] getDependencies() should return the transitive dependencies - [x] getDependencies() should return the transitive dependencies
- [x] Project ordering: kotlinProject(wrapper) {} - [x] Project ordering: kotlinProject(wrapper) {}
- [x] Make files appear in download list automatically on bintray (undocumented API) - [x] Make files appear in download list automatically on bintray (undocumented API)

View file

@ -16,30 +16,7 @@
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.0.0-beta-1038" level="project" /> <orderEntry type="library" scope="TEST" name="kobalt (Test)" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-compiler-embeddable:1.0.0-beta-1038" level="project" /> <orderEntry type="library" name="kobalt (Compile)" level="project" />
<orderEntry type="library" name="Gradle: com.beust:jcommander:1.48" level="project" />
<orderEntry type="library" name="Gradle: com.squareup.okhttp:okhttp:2.4.0" level="project" />
<orderEntry type="library" name="Gradle: org.jsoup:jsoup:1.8.2" level="project" />
<orderEntry type="library" name="Gradle: com.google.inject:guice:4.0" level="project" />
<orderEntry type="library" name="Gradle: com.google.inject.extensions:guice-assistedinject:4.0" level="project" />
<orderEntry type="library" name="Gradle: com.google.guava:guava:18.0" level="project" />
<orderEntry type="library" name="Gradle: org.apache.maven:maven-model:3.3.3" level="project" />
<orderEntry type="library" name="Gradle: com.github.spullara.mustache.java:compiler:0.8.18" level="project" />
<orderEntry type="library" name="Gradle: io.reactivex:rxjava:1.0.14" level="project" />
<orderEntry type="library" name="Gradle: com.google.code.gson:gson:2.4" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-runtime:1.0.0-beta-1038" level="project" />
<orderEntry type="library" name="Gradle: com.squareup.okio:okio:1.4.0" level="project" />
<orderEntry type="library" name="Gradle: javax.inject:javax.inject:1" level="project" />
<orderEntry type="library" name="Gradle: aopalliance:aopalliance:1.0" level="project" />
<orderEntry type="library" name="Gradle: org.codehaus.plexus:plexus-utils:3.0.20" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.testng:testng:6.9.6" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: com.google.inject:guice:4.0:no_aop" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.beanshell:bsh:2.0b4" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.apache.ant:ant:1.7.0" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.yaml:snakeyaml:1.15" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: junit:junit:4.10" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.apache.ant:ant-launcher:1.7.0" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.hamcrest:hamcrest-core:1.1" level="project" />
</component> </component>
</module> </module>

View file

@ -1 +1 @@
kobalt.version=0.217 kobalt.version=0.219

View file

@ -7,5 +7,7 @@
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" scope="TEST" name="kobalt (Test)" level="project" />
<orderEntry type="library" name="kobalt (Compile)" level="project" />
</component> </component>
</module> </module>

View file

@ -95,11 +95,14 @@ public open class Jvm constructor(
// } // }
override public fun findExecutable(command: String): File { override public fun findExecutable(command: String): File {
val exec = File(javaHome, "bin/" + command) if (javaHome != null) {
val executable = java.io.File(os.getExecutableName(exec.getAbsolutePath())) val jdkHome = if (javaHome!!.endsWith("jre")) javaHome!!.parentFile else javaHome
if (executable.isFile()) { val exec = File(jdkHome, "bin/" + command)
var executable = File(os.getExecutableName(exec.absolutePath))
if (executable.isFile) {
return executable return executable
} }
}
// if (userSupplied) { // if (userSupplied) {
// //then we want to validate strictly // //then we want to validate strictly
@ -108,12 +111,12 @@ public open class Jvm constructor(
val pathExecutable = os.findInPath(command) val pathExecutable = os.findInPath(command)
if (pathExecutable != null) { if (pathExecutable != null) {
log(1, "Unable to find the ${command} executable using home: " + log(1, "Unable to find the $command executable using home: " +
"%{javaHome}. We found it on the PATH: ${pathExecutable}.") "%{javaHome}. We found it on the PATH: $pathExecutable.")
return pathExecutable return pathExecutable
} }
warn("Unable to find the ${command} executable. Tried the java home: ${javaHome}" + warn("Unable to find the $command executable. Tried the java home: $javaHome" +
" and the PATH. We will assume the executable can be ran in the current " + " and the PATH. We will assume the executable can be ran in the current " +
"working folder.") "working folder.")
return java.io.File(os.getExecutableName(command)) return java.io.File(os.getExecutableName(command))

View file

@ -1,7 +1,9 @@
package com.beust.kobalt package com.beust.kobalt
import com.beust.jcommander.JCommander import com.beust.jcommander.JCommander
import com.beust.kobalt.api.* import com.beust.kobalt.api.Kobalt
import com.beust.kobalt.api.PluginInfo
import com.beust.kobalt.api.Project
import com.beust.kobalt.internal.TaskManager import com.beust.kobalt.internal.TaskManager
import com.beust.kobalt.internal.remote.KobaltClient import com.beust.kobalt.internal.remote.KobaltClient
import com.beust.kobalt.internal.remote.KobaltServer import com.beust.kobalt.internal.remote.KobaltServer
@ -18,7 +20,6 @@ import java.io.File
import java.nio.file.Paths import java.nio.file.Paths
import java.util.* import java.util.*
import javax.inject.Inject import javax.inject.Inject
import javax.xml.bind.JAXBContext
public fun main(argv: Array<String>) { public fun main(argv: Array<String>) {
val result = mainNoExit(argv) val result = mainNoExit(argv)
@ -35,6 +36,7 @@ private fun parseArgs(argv: Array<String>): Main.RunInfo {
return Main.RunInfo(result, args) return Main.RunInfo(result, args)
} }
public fun mainNoExit(argv: Array<String>) : Int { public fun mainNoExit(argv: Array<String>) : Int {
val (jc, args) = parseArgs(argv) val (jc, args) = parseArgs(argv)
Kobalt.INJECTOR = Guice.createInjector(MainModule(args)) Kobalt.INJECTOR = Guice.createInjector(MainModule(args))
@ -55,7 +57,8 @@ private class Main @Inject constructor(
val updateKobalt: UpdateKobalt, val updateKobalt: UpdateKobalt,
val client: KobaltClient, val client: KobaltClient,
val server: KobaltServer, val server: KobaltServer,
val pluginInfoDescription: PluginInfoDescription) { val pluginInfo: PluginInfo,
val projectGenerator: ProjectGenerator) {
data class RunInfo(val jc: JCommander, val args: Args) data class RunInfo(val jc: JCommander, val args: Args)
@ -97,11 +100,11 @@ private class Main @Inject constructor(
public fun runTest() { public fun runTest() {
val file = File("src\\main\\resources\\META-INF\\plugin.xml") val file = File("src\\main\\resources\\META-INF\\plugin.xml")
val jaxbContext = JAXBContext.newInstance(KobaltPluginXml::class.java) // val jaxbContext = JAXBContext.newInstance(KobaltPluginXml::class.java)
//
val kotlinPlugin : KobaltPluginXml = jaxbContext.createUnmarshaller().unmarshal(file) as KobaltPluginXml // val kotlinPlugin : KobaltPluginXml = jaxbContext.createUnmarshaller().unmarshal(file) as KobaltPluginXml
val pluginInfo = PluginInfo.create(kotlinPlugin) // val pluginInfo = PluginInfo.create(kotlinPlugin)
System.out.println(kotlinPlugin.name) // System.out.println(kotlinPlugin.name)
} }
private fun runWithArgs(jc: JCommander, args: Args) : Int { private fun runWithArgs(jc: JCommander, args: Args) : Int {
@ -119,7 +122,7 @@ private class Main @Inject constructor(
// --init: create a new build project and install the wrapper // --init: create a new build project and install the wrapper
// //
Wrapper().install() Wrapper().install()
ProjectGenerator().run(args) projectGenerator.run(args)
} else if (args.usage) { } else if (args.usage) {
jc.usage() jc.usage()
} else if (args.serverMode) { } else if (args.serverMode) {
@ -128,8 +131,7 @@ private class Main @Inject constructor(
if (! buildFile.exists()) { if (! buildFile.exists()) {
error(buildFile.path.toFile().path + " does not exist") error(buildFile.path.toFile().path + " does not exist")
} else { } else {
var allProjects = listOf<Project>() var allProjects = arrayListOf<Project>()
val pluginInfo = PluginInfo(pluginInfoDescription)
try { try {
allProjects = buildFileCompilerFactory.create(listOf(buildFile), pluginInfo).compileBuildFiles(args) allProjects = buildFileCompilerFactory.create(listOf(buildFile), pluginInfo).compileBuildFiles(args)
} catch(ex: KobaltException) { } catch(ex: KobaltException) {
@ -142,8 +144,8 @@ private class Main @Inject constructor(
return 1 return 1
} else { } else {
log(1, "Deleted .kobalt") log(1, "Deleted .kobalt")
allProjects = buildFileCompilerFactory.create(listOf(buildFile), pluginInfo) allProjects.addAll(buildFileCompilerFactory.create(listOf(buildFile), pluginInfo)
.compileBuildFiles(args) .compileBuildFiles(args))
} }
} }
@ -178,7 +180,6 @@ private class Main @Inject constructor(
} }
return result return result
} }
private fun findBuildFile(): File { private fun findBuildFile(): File {
val files = arrayListOf("Build.kt", "build.kobalt", KFiles.src("build.kobalt"), val files = arrayListOf("Build.kt", "build.kobalt", KFiles.src("build.kobalt"),
KFiles.src("Build.kt")) KFiles.src("Build.kt"))

View file

@ -37,6 +37,9 @@ public class Plugins @Inject constructor (val taskManagerProvider : Provider<Tas
companion object { companion object {
public val MANIFEST_PLUGIN_CLASS : String = "Kobalt-Plugin-Class" public val MANIFEST_PLUGIN_CLASS : String = "Kobalt-Plugin-Class"
/** The name of the XML file describing a plug-in */
val PLUGIN_XML = "plugin.xml"
private var pluginMap = hashMapOf<String, Plugin>() private var pluginMap = hashMapOf<String, Plugin>()
// private var storageMap = HashMap<String, HashMap<String, Any>>() // private var storageMap = HashMap<String, HashMap<String, Any>>()
// fun storeValue(pluginName: String, key: String, value: Any) { // fun storeValue(pluginName: String, key: String, value: Any) {

View file

@ -1,133 +1,57 @@
package com.beust.kobalt package com.beust.kobalt
import com.beust.kobalt.api.ICompilerInfo import com.beust.kobalt.api.IInitContributor
import com.beust.kobalt.api.Kobalt import com.beust.kobalt.api.PluginInfo
import com.beust.kobalt.maven.Pom
import com.beust.kobalt.maven.Pom.Dependency
import com.beust.kobalt.misc.KFiles
import com.beust.kobalt.misc.log import com.beust.kobalt.misc.log
import com.github.mustachejava.DefaultMustacheFactory import com.google.inject.Inject
import java.io.File import java.io.File
import java.io.InputStreamReader import java.io.FileOutputStream
import java.io.PrintWriter import java.util.*
import java.io.StringWriter
import java.util.ArrayList
import java.util.Collections
import java.util.HashMap
/** /**
* Generate a new project. * Invoked with --init. Generate a new project.
*/ */
public class ProjectGenerator { public class ProjectGenerator @Inject constructor(val pluginInfo: PluginInfo){
companion object { companion object {
/** /**
* Turns a dot property into a proper Kotlin identifier, e.g. common.version -> commonVersion * Turns a dot property into a proper Kotlin identifier, e.g. common.version -> commonVersion
*/ */
fun translate(key: String): String { fun toIdentifier(key: String): String {
return key.split('.').mapIndexed( { index, value -> if (index == 0) value else value.upperFirst() }) fun upperFirst(s: String) = if (s.isBlank()) s else s.substring(0, 1).toUpperCase() + s.substring(1)
return key.split('.').mapIndexed( { index, value -> if (index == 0) value else upperFirst(value) })
.joinToString("") .joinToString("")
} }
} }
fun run(args: Args) { fun run(args: Args) {
if (File(args.buildFile).exists()) { val contributor = findBestInitContributor(File("."))
log(1, "Build file ${args.buildFile} already exists, not overwriting it") if (contributor != null) {
return contributor.generateBuildFile(FileOutputStream(File(args.buildFile)))
} log(1, "Created ${args.buildFile}")
val compilerInfos = detect(File("."))
if (compilerInfos.size > 1) {
log(1, "Multi language project detected, not supported yet")
}
val map = hashMapOf<String, Any?>()
map.put("directive", if (compilerInfos.isEmpty()) "project" else compilerInfos.get(0).directive)
if (compilerInfos.size > 0) {
compilerInfos.get(0).let {
val currentDir = File(".").absoluteFile.parentFile
with(map) {
put("name", currentDir.name)
put("group", "com.example")
put("version", "0.1")
put("directory", currentDir.absolutePath)
put("sourceDirectories", it.defaultSourceDirectories)
put("sourceDirectoriesTest", it.defaultTestDirectories)
put("imports", "import com.beust.kobalt.plugin.${it.name}.*")
put("directive", it.name + "Project")
}
}
}
var mainDeps = arrayListOf<Dependency>()
var testDeps = arrayListOf<Dependency>()
map.put("mainDependencies", mainDeps)
map.put("testDependencies", testDeps)
File("pom.xml").let {
if (it.absoluteFile.exists()) {
importPom(it, mainDeps, testDeps, map)
}
}
val fileInputStream = javaClass.classLoader.getResource("build-template.mustache").openStream()
val sw = StringWriter()
val pw = PrintWriter(sw)
var mf = DefaultMustacheFactory();
var mustache = mf.compile(InputStreamReader(fileInputStream), "kobalt");
mustache.execute(pw, map).flush();
KFiles.saveFile(File(args.buildFile), sw.toString())
}
private fun importPom(pomFile: File, mainDeps: ArrayList<Dependency>, testDeps: ArrayList<Dependency>,
map: HashMap<String, Any?>) {
var pom = Pom("imported", pomFile.absoluteFile)
with(map) {
put("group", pom.groupId ?: "com.example")
put("artifactId", pom.artifactId ?: "com.example")
put("version", pom.version ?: "0.1")
put("name", pom.name ?: pom.artifactId)
put("repositories", pom.repositories.map({ "\"${it}\"" }).joinToString(","))
}
val properties = pom.properties
val mapped = properties.entries.toMap({it.key}, {translate(it.key)})
map.put("properties", properties.entries.map({ Pair(mapped.get(it.key), it.value) }))
val partition = pom.dependencies.groupBy { it.scope }
.flatMap { it.value }
.map { updateVersion(it, mapped) }
.sortedBy { it.groupId + ":" + it.artifactId }
.partition { it.scope != "test" }
mainDeps.addAll(partition.first)
testDeps.addAll(partition.second)
}
private fun updateVersion(dep: Dependency, mapped: Map<String, String>) =
if ( dep.version.startsWith("\${")) {
val property = dep.version.substring(2, dep.version.length - 1)
Dependency(dep.groupId, dep.artifactId, dep.packaging, "\${${mapped.get(property)}}", dep.optional,
dep.scope)
} else { } else {
dep log(1, "Couldn't identify project, not generating any build file")
}
} }
/** /**
* Detect all the languages contained in this project. * Run through all the IInitContributors and return the best one.
*/ */
private fun detect(dir: File) : List<ICompilerInfo> { private fun findBestInitContributor(dir: File) : IInitContributor? {
val result = arrayListOf<Pair<ICompilerInfo, List<File>>>() val result = arrayListOf<Pair<IInitContributor, Int>>()
Kobalt.compilers.forEach { pluginInfo.initContributors.forEach {
val managedFiles = it.findManagedFiles(dir) it.filesManaged(dir).let { count ->
if (managedFiles.size > 0) { if (count > 0) {
result.add(Pair(it, managedFiles)) result.add(Pair(it, count))
} }
} }
Collections.sort(result, { p1, p2 -> p1.second.size.compareTo(p2.second.size) }) }
return result.map { it.first } if (result.size > 0) {
Collections.sort(result, { p1, p2 -> p2.second.compareTo(p1.second) })
return result[0].first
} else {
return null
}
} }
} }
private fun String.upperFirst(): String {
return if (this.isBlank()) this else this.substring(0, 1).toUpperCase() + this.substring(1)
}

View file

@ -1,11 +1,9 @@
package com.beust.kobalt package com.beust.kobalt
import java.util.concurrent.locks.ReentrantLock
import javax.inject.Inject
public class SystemProperties { public class SystemProperties {
companion object { companion object {
val javaBase = System.getenv("JAVA_HOME") ?: throw IllegalArgumentException("JAVA_HOME not defined") val javaBase = System.getProperty("java.home") ?:
(System.getenv("JAVA_HOME") ?: throw IllegalArgumentException("JAVA_HOME not defined"))
val javaVersion = System.getProperty("java.version") val javaVersion = System.getProperty("java.version")
val homeDir = System.getProperty("user.home") val homeDir = System.getProperty("user.home")
val tmpDir = System.getProperty("java.io.tmpdir") val tmpDir = System.getProperty("java.io.tmpdir")

View file

@ -2,38 +2,17 @@ package com.beust.kobalt.api
import com.beust.kobalt.Plugins import com.beust.kobalt.Plugins
import com.google.inject.Injector import com.google.inject.Injector
import java.io.File
import java.io.InputStream import java.io.InputStream
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.Paths import java.nio.file.Paths
import java.util.* import java.util.*
public interface ICompilerInfo {
/** Used to detect what kind of language this project is */
fun findManagedFiles(dir: File) : List<File>
/** Used to generate the imports */
val name: String
/** Used to generate the imports */
val directive: String
val defaultSourceDirectories : ArrayList<String>
val defaultTestDirectories : ArrayList<String>
}
public class Kobalt { public class Kobalt {
companion object { companion object {
lateinit var INJECTOR : Injector lateinit var INJECTOR : Injector
public val compilers : ArrayList<ICompilerInfo> = arrayListOf()
var context: KobaltContext? = null var context: KobaltContext? = null
fun registerCompiler(c: ICompilerInfo) {
compilers.add(c)
}
private val DEFAULT_REPOS = arrayListOf( private val DEFAULT_REPOS = arrayListOf(
"http://repo1.maven.org/maven2/", "http://repo1.maven.org/maven2/",
"https://repository.jboss.org/nexus/content/repositories/root_repository/", "https://repository.jboss.org/nexus/content/repositories/root_repository/",

View file

@ -1,104 +0,0 @@
package com.beust.kobalt.api
import com.beust.kobalt.maven.IClasspathDependency
import com.beust.kobalt.plugin.java.JavaPlugin
import com.beust.kobalt.plugin.kotlin.KotlinPlugin
import java.util.*
import javax.xml.bind.annotation.XmlElement
import javax.xml.bind.annotation.XmlRootElement
class ProjectDescription(val project: Project, val dependsOn: List<Project>)
interface IProjectContributor {
fun projects() : List<ProjectDescription>
}
/**
* 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>
}
interface IFactory {
fun <T> instanceOf(c: Class<T>) : T
}
class ContributorFactory : IFactory {
override fun <T> instanceOf(c: Class<T>) : T = Kobalt.INJECTOR.getInstance(c)
}
/**
* All the information gathered from the various plugin.xml that were collected.
*/
class PluginInfoDescription {
fun <T> instanceOf(c: Class<T>) : T = Kobalt.INJECTOR.getInstance(c)
val projectContributors : ArrayList<Class<out IProjectContributor>> =
arrayListOf(JavaPlugin::class.java, KotlinPlugin::class.java)
val classpathContributors: ArrayList<Class<out IClasspathContributor>> =
arrayListOf(KotlinPlugin::class.java)
// Future contributors:
// compilerArgs
// source files
// compilers
// --init
}
/**
* Turn the classes found in PluginInfoDescription into concrete objects that plugins can then use.
*/
class PluginInfo(val description: PluginInfoDescription?) {
val projectContributors = arrayListOf<IProjectContributor>()
val classpathContributors = arrayListOf<IClasspathContributor>()
companion object {
fun create(xml: KobaltPluginXml) : PluginInfo {
val factory = Class.forName(xml.factoryClassName).newInstance() as IFactory
val result = PluginInfo(null)
xml.classpathContributors?.className?.forEach {
result.classpathContributors.add(factory.instanceOf(Class.forName(it)) as IClasspathContributor)
}
xml.projectContributors?.className?.forEach {
result.projectContributors.add(factory.instanceOf(Class.forName(it)) as IProjectContributor)
}
return result
}
}
init {
if (description != null) {
classpathContributors.addAll(description.classpathContributors.map { description.instanceOf(it) })
projectContributors.addAll(description.projectContributors.map { description.instanceOf(it) })
}
}
}
class ContributorXml {
@XmlElement @JvmField
val name: String? = null
}
class ContributorsXml {
@XmlElement(name = "class-name") @JvmField
var className: List<String> = arrayListOf<String>()
}
@XmlRootElement(name = "kobalt-plugin")
class KobaltPluginXml {
@XmlElement @JvmField
var name: String? = null
@XmlElement(name = "factory-class-name") @JvmField
var factoryClassName: String? = null
@XmlElement(name = "classpath-contributors") @JvmField
var classpathContributors : ContributorsXml? = null
@XmlElement(name = "project-contributors") @JvmField
var projectContributors : ContributorsXml? = null
}

View file

@ -0,0 +1,155 @@
package com.beust.kobalt.api
import com.beust.kobalt.maven.IClasspathDependency
import com.beust.kobalt.misc.KFiles
import java.io.File
import java.io.InputStream
import java.io.OutputStream
import javax.xml.bind.JAXBContext
import javax.xml.bind.annotation.XmlElement
import javax.xml.bind.annotation.XmlRootElement
//
// Operations related to the parsing of plugin.xml: contributors, XML mapping, etc...
//
/////
// Contributors
//
/**
* Plugins that create project need to implement this interface.
*/
interface IProjectContributor {
fun projects() : List<ProjectDescription>
}
class ProjectDescription(val project: Project, val dependsOn: List<Project>)
/**
* Plugins that export classpath entries need to implement this interface.
*/
interface IClasspathContributor {
fun entriesFor(project: Project) : Collection<IClasspathDependency>
}
/**
* The factory function to use to instantiate all the contributors and other entities
* found in plugin.xml.
*/
interface IFactory {
fun <T> instanceOf(c: Class<T>) : T
}
class ContributorFactory : IFactory {
override fun <T> instanceOf(c: Class<T>) : T = Kobalt.INJECTOR.getInstance(c)
}
/**
* Plugins that want to participate in the --init process (they can generate files to initialize
* a new project).
*/
interface IInitContributor {
/**
* How many files your plug-in understands in the given directory. The contributor with the
* highest number will be asked to generate the build file.
*/
fun filesManaged(dir: File): Int
/**
* Generate the Build.kt file into the given OutputStream.
*/
fun generateBuildFile(os: OutputStream)
}
/////
// XML parsing
//
// The following classes are used by JAXB to parse the plugin.xml file.
/**
* The root element of plugin.xml
*/
@XmlRootElement(name = "kobalt-plugin")
class KobaltPluginXml {
@XmlElement @JvmField
var name: String? = null
@XmlElement(name = "factory-class-name") @JvmField
var factoryClassName: String? = null
@XmlElement(name = "classpath-contributors") @JvmField
var classpathContributors : ContributorsXml? = null
@XmlElement(name = "project-contributors") @JvmField
var projectContributors : ContributorsXml? = null
@XmlElement(name = "init-contributors") @JvmField
var initContributors : ContributorsXml? = null
}
class ContributorXml {
@XmlElement @JvmField
val name: String? = null
}
class ContributorsXml {
@XmlElement(name = "class-name") @JvmField
var className: List<String> = arrayListOf()
}
/**
* Turn a KobaltPluginXml (the raw content of plugin.xml mapped to POJO's) into a PluginInfo object, which contains
* all the contributors instantiated and other information that Kobalt can actually use. Kobalt code that
* needs to access plug-in info can then just inject a PluginInfo object.
*/
class PluginInfo(val xml: KobaltPluginXml) {
val projectContributors = arrayListOf<IProjectContributor>()
val classpathContributors = arrayListOf<IClasspathContributor>()
val initContributors = arrayListOf<IInitContributor>()
// Future contributors:
// compilerArgs
// source files
// compilers
// repos
companion object {
/**
* Read Kobalt's own plugin.xml.
*/
fun readKobaltPluginXml() : PluginInfo {
val pluginXml = KFiles.joinDir("META-INF", "plugin.xml") // Plugins.PLUGIN_XML)
val url = Kobalt::class.java.classLoader.getResource(pluginXml)
if (url != null) {
return readPluginXml(url.openConnection().inputStream)
} else {
throw AssertionError("Couldn't find $pluginXml")
}
}
/**
* Read a general plugin.xml.
*/
private fun readPluginXml(ins: InputStream): PluginInfo {
val jaxbContext = JAXBContext.newInstance(KobaltPluginXml::class.java)
val kotlinPlugin: KobaltPluginXml = jaxbContext.createUnmarshaller().unmarshal(ins)
as KobaltPluginXml
return PluginInfo(kotlinPlugin)
}
}
init {
val factory = Class.forName(xml.factoryClassName).newInstance() as IFactory
xml.classpathContributors?.className?.forEach {
classpathContributors.add(factory.instanceOf(Class.forName(it)) as IClasspathContributor)
}
xml.projectContributors?.className?.forEach {
projectContributors.add(factory.instanceOf(Class.forName(it)) as IProjectContributor)
}
xml.initContributors?.className?.forEach {
initContributors.add(factory.instanceOf(Class.forName(it)) as IInitContributor)
}
}
}

View file

@ -1,6 +1,7 @@
package com.beust.kobalt.api package com.beust.kobalt.api
import com.beust.kobalt.api.annotation.Directive import com.beust.kobalt.api.annotation.Directive
import com.beust.kobalt.internal.IProjectInfo
import com.beust.kobalt.maven.IClasspathDependency import com.beust.kobalt.maven.IClasspathDependency
import com.beust.kobalt.maven.MavenDependency import com.beust.kobalt.maven.MavenDependency
import com.beust.kobalt.misc.KFiles import com.beust.kobalt.misc.KFiles
@ -16,11 +17,11 @@ open public class Project(
@Directive open var packaging: String? = null, @Directive open var packaging: String? = null,
@Directive open var dependencies: Dependencies? = null, @Directive open var dependencies: Dependencies? = null,
@Directive open var sourceSuffix : String = "", @Directive open var sourceSuffix : String = "",
@Directive open var compilerInfo : ICompilerInfo,
@Directive open var description : String = "", @Directive open var description : String = "",
@Directive open var scm : Scm? = null, @Directive open var scm : Scm? = null,
@Directive open var url: String? = null, @Directive open var url: String? = null,
@Directive open var licenses: List<License> = arrayListOf<License>()) { @Directive open var licenses: List<License> = arrayListOf<License>(),
val projectInfo: IProjectInfo) {
var testArgs: ArrayList<String> = arrayListOf() var testArgs: ArrayList<String> = arrayListOf()
@ -44,7 +45,7 @@ open public class Project(
} }
var sourceDirectories : ArrayList<String> = arrayListOf() var sourceDirectories : ArrayList<String> = arrayListOf()
get() = if (field.isEmpty()) compilerInfo.defaultSourceDirectories else field get() = if (field.isEmpty()) projectInfo.defaultSourceDirectories else field
set(value) { set(value) {
field = value field = value
} }
@ -57,7 +58,7 @@ open public class Project(
} }
var sourceDirectoriesTest : ArrayList<String> = arrayListOf() var sourceDirectoriesTest : ArrayList<String> = arrayListOf()
get() = if (field.isEmpty()) compilerInfo.defaultTestDirectories get() = if (field.isEmpty()) projectInfo.defaultTestDirectories
else field else field
set(value) { set(value) {
field = value field = value

View file

@ -0,0 +1,99 @@
package com.beust.kobalt.internal
import com.beust.kobalt.ProjectGenerator
import com.beust.kobalt.api.IInitContributor
import com.beust.kobalt.maven.Pom
import com.beust.kobalt.misc.KFiles
import com.github.mustachejava.DefaultMustacheFactory
import java.io.*
import java.util.*
/**
* Abstract base class for the build generators that use build-template.mustache.
*/
abstract class BuildGenerator : IInitContributor {
abstract val defaultSourceDirectories : ArrayList<String>
abstract val defaultTestDirectories : ArrayList<String>
abstract val directive : String
abstract val name : String
abstract val fileMatch : (String) -> Boolean
override fun generateBuildFile(os: OutputStream) {
PrintWriter(os).use {
it.print(buildFileContent)
}
}
override fun filesManaged(dir: File) = KFiles.findRecursively(dir, fileMatch).size
private fun importPom(pomFile: File, mainDeps: ArrayList<Pom.Dependency>, testDeps: ArrayList<Pom.Dependency>,
map: HashMap<String, Any?>) {
var pom = Pom("imported", pomFile.absoluteFile)
with(map) {
put("group", pom.groupId ?: "com.example")
put("artifactId", pom.artifactId ?: "com.example")
put("version", pom.version ?: "0.1")
put("name", pom.name ?: pom.artifactId)
put("repositories", pom.repositories.map({ "\"$it\"" }).joinToString(","))
}
val properties = pom.properties
val mapped = properties.entries.toMap({it.key}, { ProjectGenerator.toIdentifier(it.key) })
map.put("properties", properties.entries.map({ Pair(mapped[it.key], it.value) }))
val partition = pom.dependencies.groupBy { it.scope }
.flatMap { it.value }
.map { updateVersion(it, mapped) }
.sortedBy { it.groupId + ":" + it.artifactId }
.partition { it.scope != "test" }
mainDeps.addAll(partition.first)
testDeps.addAll(partition.second)
}
private fun updateVersion(dep: Pom.Dependency, mapped: Map<String, String>) =
if ( dep.version.startsWith("\${")) {
val property = dep.version.substring(2, dep.version.length - 1)
Pom.Dependency(dep.groupId, dep.artifactId, dep.packaging, "\${${mapped[property]}}", dep.optional,
dep.scope)
} else {
dep
}
private val buildFileContent: String
get() {
val map = hashMapOf<String, Any?>()
map.put("directive", directive)
val currentDir = File(".").absoluteFile.parentFile
with(map) {
put("name", currentDir.name)
put("group", "com.example")
put("version", "0.1")
put("directory", currentDir.absolutePath)
put("sourceDirectories", defaultSourceDirectories)
put("sourceDirectoriesTest", defaultTestDirectories)
put("imports", "import com.beust.kobalt.plugin.$name.*")
put("directive", name + "Project")
}
var mainDeps = arrayListOf<Pom.Dependency>()
var testDeps = arrayListOf<Pom.Dependency>()
map.put("mainDependencies", mainDeps)
map.put("testDependencies", testDeps)
File("pom.xml").let {
if (it.absoluteFile.exists()) {
importPom(it, mainDeps, testDeps, map)
}
}
val fileInputStream = javaClass.classLoader.getResource("build-template.mustache").openStream()
val sw = StringWriter()
val pw = PrintWriter(sw)
var mf = DefaultMustacheFactory();
var mustache = mf.compile(InputStreamReader(fileInputStream), "kobalt");
mustache.execute(pw, map).flush();
return sw.toString()
}
}

View file

@ -0,0 +1,11 @@
package com.beust.kobalt.internal
import java.util.*
/**
* Data that is useful for projects to have but should not be specified in the DSL.
*/
interface IProjectInfo {
val defaultSourceDirectories: ArrayList<String>
val defaultTestDirectories: ArrayList<String>
}

View file

@ -2,7 +2,6 @@ package com.beust.kobalt.internal.remote
import com.beust.kobalt.Args import com.beust.kobalt.Args
import com.beust.kobalt.api.PluginInfo import com.beust.kobalt.api.PluginInfo
import com.beust.kobalt.api.PluginInfoDescription
import com.beust.kobalt.kotlin.BuildFile import com.beust.kobalt.kotlin.BuildFile
import com.beust.kobalt.kotlin.BuildFileCompiler import com.beust.kobalt.kotlin.BuildFileCompiler
import com.beust.kobalt.maven.DependencyManager import com.beust.kobalt.maven.DependencyManager
@ -26,11 +25,11 @@ import javax.inject.Inject
*/ */
class GetDependenciesCommand @Inject constructor(val executors: KobaltExecutors, class GetDependenciesCommand @Inject constructor(val executors: KobaltExecutors,
val buildFileCompilerFactory: BuildFileCompiler.IFactory, val args: Args, val buildFileCompilerFactory: BuildFileCompiler.IFactory, val args: Args,
val dependencyManager: DependencyManager, val pluginInfoDescription: PluginInfoDescription) : ICommand { val dependencyManager: DependencyManager, val pluginInfo: PluginInfo) : ICommand {
override val name = "getDependencies" override val name = "getDependencies"
override fun run(sender: ICommandSender, received: JsonObject) { override fun run(sender: ICommandSender, received: JsonObject) {
val buildFile = BuildFile(Paths.get(received.get("buildFile").asString), "GetDependenciesCommand") val buildFile = BuildFile(Paths.get(received.get("buildFile").asString), "GetDependenciesCommand")
val scriptCompiler = buildFileCompilerFactory.create(listOf(buildFile), PluginInfo(pluginInfoDescription)) val scriptCompiler = buildFileCompilerFactory.create(listOf(buildFile), pluginInfo)
scriptCompiler.observable.subscribe { scriptCompiler.observable.subscribe {
buildScriptInfo -> if (buildScriptInfo.projects.size > 0) { buildScriptInfo -> if (buildScriptInfo.projects.size > 0) {
sender.sendData(toData(buildScriptInfo)) sender.sendData(toData(buildScriptInfo))

View file

@ -55,7 +55,33 @@ public class KFiles {
public val TEST_CLASSES_DIR : String = "test-classes" 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) = fun makeDir(dir: String, s: String? = null) =
(if (s != null) File(dir, s) else File(dir)).apply { mkdirs() } (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 = public fun createTempFile(suffix : String = "", deleteOnExit: Boolean = false) : File =
File.createTempFile("kobalt", suffix, File(SystemProperties.tmpDir)).let { File.createTempFile("kobalt", suffix, File(SystemProperties.tmpDir)).let {
if (deleteOnExit) it.deleteOnExit() if (deleteOnExit) it.deleteOnExit()

View file

@ -1,6 +1,7 @@
package com.beust.kobalt.misc package com.beust.kobalt.misc
import com.beust.kobalt.Args import com.beust.kobalt.Args
import com.beust.kobalt.api.PluginInfo
import com.beust.kobalt.kotlin.BuildFileCompiler import com.beust.kobalt.kotlin.BuildFileCompiler
import com.beust.kobalt.maven.* import com.beust.kobalt.maven.*
import com.beust.kobalt.plugin.publish.JCenterApi import com.beust.kobalt.plugin.publish.JCenterApi
@ -9,7 +10,6 @@ import com.google.inject.BindingAnnotation
import com.google.inject.Provider import com.google.inject.Provider
import com.google.inject.TypeLiteral import com.google.inject.TypeLiteral
import com.google.inject.assistedinject.FactoryModuleBuilder import com.google.inject.assistedinject.FactoryModuleBuilder
import java.lang.annotation.RetentionPolicy
import java.util.concurrent.ExecutorService import java.util.concurrent.ExecutorService
//@Singleton //@Singleton
@ -49,9 +49,12 @@ public open class MainModule(val args: Args) : AbstractModule() {
bind(object: TypeLiteral<KobaltExecutors>() {}).toInstance(executors) bind(object: TypeLiteral<KobaltExecutors>() {}).toInstance(executors)
bind(object: TypeLiteral<ExecutorService>() {}).annotatedWith(DependencyExecutor::class.java) bind(object: TypeLiteral<ExecutorService>() {}).annotatedWith(DependencyExecutor::class.java)
.toInstance(executors.dependencyExecutor) .toInstance(executors.dependencyExecutor)
bind(Args::class.java).toProvider(object : Provider<Args> { bind(Args::class.java).toProvider(object: Provider<Args> {
override fun get(): Args? = args override fun get(): Args? = args
}) })
bind(PluginInfo::class.java).toProvider(object: Provider<PluginInfo> {
override fun get(): PluginInfo? = PluginInfo.readKobaltPluginXml()
})
// bindListener(Matchers.any(), object: TypeListener { // bindListener(Matchers.any(), object: TypeListener {

View file

@ -6,10 +6,13 @@ import java.io.InputStream
import java.io.InputStreamReader import java.io.InputStreamReader
open class RunCommand(val command: String) { open class RunCommand(val command: String) {
val defaultSuccess = { output: List<String> -> log(1, "Success:\n " + output.joinToString("\n"))} val defaultSuccess = { output: List<String> -> log(2, "Success:\n " + output.joinToString("\n"))}
val defaultError = { output: List<String> -> log(1, "Error:\n " + output.joinToString("\n"))} val defaultError = {
output: List<String> -> error("Error:\n " + output.joinToString("\n"))
}
var directory = File(".") var directory = File(".")
var env = hashMapOf<String, String>()
fun run(args: List<String>, error: Function1<List<String>, Unit>? = defaultError, fun run(args: List<String>, error: Function1<List<String>, Unit>? = defaultError,
success: Function1<List<String>, Unit>? = defaultSuccess) : Int { success: Function1<List<String>, Unit>? = defaultSuccess) : Int {
@ -19,9 +22,13 @@ open class RunCommand(val command: String) {
val pb = ProcessBuilder(allArgs) val pb = ProcessBuilder(allArgs)
pb.directory(directory) pb.directory(directory)
log(2, "Running command: " + allArgs.joinToString(" ")) log(2, "Running command: " + allArgs.joinToString(" ") + "\n Current directory: $directory")
val process = pb.start() 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() val errorCode = process.waitFor()
if (errorCode != 0 && error != null) { if (errorCode != 0 && error != null) {
error(fromStream(process.errorStream)) 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!!) 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" val flavor = "debug"
fun compileSdkVersion(project: Project) = configurations[project.name!!]?.compileSdkVersion 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 = fun androidJar(project: Project) : Path =
Paths.get(androidHome(project), "platforms", "android-${compileSdkVersion(project)}", "android.jar") 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 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 { private fun apk(project: Project, flavor: String)
val outputDir = dirGet(intermediates(project), "resources", "resources-$flavor") = KFiles.joinFileAndMakeDir(project.buildDirectory!!, "outputs", "apk" ,"app-$flavor.apk")
return Paths.get(outputDir, "resources-$flavor.$suffix").toString()
}
private fun intermediates(project: Project) = Paths.get(project.directory, "app", "build", "intermediates")
@Task(name = "generateR", description = "Generate the R.java file", @Task(name = "generateR", description = "Generate the R.java file",
runBefore = arrayOf("compile"), runAfter = arrayOf("clean")) runBefore = arrayOf("compile"), runAfter = arrayOf("clean"))
@ -119,8 +109,14 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler) :
return TaskResult() return TaskResult()
} }
class AaptCommand(project: Project, aapt: String, val aaptCommand: String, open class AndroidCommand(androidHome: String, command: String) : RunCommand(command) {
cwd: File = File(project.directory)) : RunCommand(aapt) { 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 { init {
directory = cwd 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 manifestDir = Paths.get(project.directory, "app", "src", "main").toString()
val manifest = Paths.get(manifestDir, "AndroidManifest.xml") 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( AaptCommand(project, aapt, "crunch").call(listOf(
"-v", "-v",
@ -149,14 +145,16 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler) :
"-M", manifest.toString(), "-M", manifest.toString(),
"-S", crunchedPngDir, "-S", crunchedPngDir,
"-S", "app/src/main/res", "-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 "-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), "-F", temporaryApk(project, flavor),
"--debug-mode", "--debug-mode",
"-0", "apk", "-0", "apk",
"--custom-package", applicationId, "--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, 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 buildToolsDir = buildToolsVersion(project)
val dx = "${androidHome(project)}/build-tools/$buildToolsDir/dx" val dx = "${androidHome(project)}/build-tools/$buildToolsDir/dx"
val buildDir = context.pluginProperties.get("java", JvmCompilerPlugin.BUILD_DIR) val buildDir = context.pluginProperties.get("java", JvmCompilerPlugin.BUILD_DIR)
val libsDir = context.pluginProperties.get("packaging", PackagingPlugin.LIBS_DIR) val libsDir = (context.pluginProperties.get("packaging", PackagingPlugin.LIBS_DIR) as File).path
File(libsDir!!.toString()).mkdirs() File(libsDir.toString()).mkdirs()
val classesDex = "classes.dex" val classesDex = "classes.dex"
val outClassesDex = KFiles.joinDir(libsDir.toString(), classesDex) val classesDexDir = KFiles.joinAndMakeDir(libsDir, "intermediates", "dex", flavor)
val relClassesDex = File(outClassesDex).parentFile val outClassesDex = KFiles.joinDir(classesDexDir, classesDex)
RunCommand(dx).run(listOf("--dex", "--output", outClassesDex,
buildDir!!.toString()))
RunCommand(dx).run(listOf("--dex", "--output", outClassesDex, buildDir!!.toString()))
// //
// Add classes.dex to existing .ap_ // Add classes.dex to existing .ap_
// //
AaptCommand(project, aapt(project), "add", relClassesDex).call(listOf( AaptCommand(project, aapt(project), "add").apply {
"-v", temporaryApk(project, flavor), classesDex directory = File(outClassesDex).parentFile
)) }.call(listOf("-v", KFiles.joinDir("../../../../..", temporaryApk(project, flavor)), classesDex))
return TaskResult() 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), @Task(name = "signApk", description = "Sign the apk file", runAfter = arrayOf(TASK_GENERATE),
runBefore = arrayOf("assemble")) runBefore = arrayOf("assemble"))
fun signApk(project: Project) : TaskResult { fun signApk(project: Project) : TaskResult {
val apk = apk(project, flavor, "apk") val apk = apk(project, flavor)
val temporaryApk = temporaryApk(project, flavor) val temporaryApk = temporaryApk(project, flavor)
RunCommand("jarsigner").run(listOf( RunCommand("jarsigner").run(listOf(
"-keystore", homeDir(".android", "debug.keystore"), "-keystore", homeDir(".android", "debug.keystore"),

View file

@ -0,0 +1,12 @@
package com.beust.kobalt.plugin.java
import com.beust.kobalt.internal.BuildGenerator
import com.google.inject.Inject
public class JavaBuildGenerator @Inject constructor (val projectInfo: JavaProjectInfo) : BuildGenerator() {
override val defaultSourceDirectories = projectInfo.defaultSourceDirectories
override val defaultTestDirectories = projectInfo.defaultTestDirectories
override val directive = "javaProject"
override val name = "java"
override val fileMatch = { f: String -> f.endsWith(".java") }
}

View file

@ -1,24 +0,0 @@
package com.beust.kobalt.plugin.java
import com.beust.kobalt.api.ICompilerInfo
import com.beust.kobalt.misc.KFiles
import com.google.inject.Singleton
import java.io.File
@Singleton
public class JavaCompilerInfo : ICompilerInfo {
override val name = "java"
override fun findManagedFiles(dir: File) : List<File> {
val result = KFiles.findRecursively(dir, { it.endsWith(".java") })
.map { File(it) }
return result
}
override val defaultSourceDirectories = arrayListOf("src/main/java", "src/main/resources")
override val defaultTestDirectories = arrayListOf("src/test/java", "src/test/resources")
override val directive = "javaProject"
}

View file

@ -31,11 +31,6 @@ public class JavaPlugin @Inject constructor(
override val jvmCompiler: JvmCompiler) override val jvmCompiler: JvmCompiler)
: JvmCompilerPlugin(localRepo, files, depFactory, dependencyManager, executors, jvmCompiler), : JvmCompilerPlugin(localRepo, files, depFactory, dependencyManager, executors, jvmCompiler),
IProjectContributor { IProjectContributor {
init {
Kobalt.registerCompiler(JavaCompilerInfo())
}
companion object { companion object {
public const val TASK_COMPILE : String = "compile" public const val TASK_COMPILE : String = "compile"
public const val TASK_JAVADOC : String = "javadoc" public const val TASK_JAVADOC : String = "javadoc"

View file

@ -25,7 +25,7 @@ public class JavaProject(
@Directive @Directive
override var packaging: String? = null) override var packaging: String? = null)
: Project(name, version, directory, buildDirectory, group, artifactId, packaging, dependencies, : Project(name, version, directory, buildDirectory, group, artifactId, packaging, dependencies,
".java", JavaCompilerInfo()) { ".java", projectInfo = JavaProjectInfo()) {
override public fun toString() = toString("JavaProject", "name", name!!) override public fun toString() = toString("JavaProject", "name", name!!)
} }

View file

@ -0,0 +1,10 @@
package com.beust.kobalt.plugin.java
import com.beust.kobalt.internal.IProjectInfo
import com.google.inject.Singleton
@Singleton
class JavaProjectInfo : IProjectInfo {
override val defaultSourceDirectories = arrayListOf("src/main/java", "src/main/resources")
override val defaultTestDirectories = arrayListOf("src/test/java", "src/test/resources")
}

View file

@ -0,0 +1,13 @@
package com.beust.kobalt.plugin.kotlin
import com.beust.kobalt.internal.BuildGenerator
import com.google.inject.Inject
public class KotlinBuildGenerator @Inject constructor (val projectInfo: KotlinProjectInfo) : BuildGenerator() {
override val defaultSourceDirectories = projectInfo.defaultSourceDirectories
override val defaultTestDirectories = projectInfo.defaultTestDirectories
override val directive = "kotlinProject"
override val name = "kotlin"
override val fileMatch = { f: String -> f.endsWith(".kt") }
}

View file

@ -1,22 +0,0 @@
package com.beust.kobalt.plugin.kotlin
import com.beust.kobalt.api.ICompilerInfo
import com.beust.kobalt.misc.KFiles
import java.io.File
public class KotlinCompilerInfo : ICompilerInfo {
override val name = "kotlin"
override fun findManagedFiles(dir: File): List<File> {
val result = KFiles.findRecursively(dir, { it.endsWith(".kt") })
.map { File(it) }
return result
}
override val defaultSourceDirectories = arrayListOf("src/main/kotlin", "src/main/resources")
override val defaultTestDirectories = arrayListOf("src/test/kotlin", "src/test/resources")
override val directive = "javaProject"
}

View file

@ -24,10 +24,6 @@ class KotlinPlugin @Inject constructor(
: JvmCompilerPlugin(localRepo, files, depFactory, dependencyManager, executors, jvmCompiler), : JvmCompilerPlugin(localRepo, files, depFactory, dependencyManager, executors, jvmCompiler),
IProjectContributor, IClasspathContributor { IProjectContributor, IClasspathContributor {
init {
Kobalt.registerCompiler(KotlinCompilerInfo())
}
companion object { companion object {
public const val TASK_COMPILE: String = "compile" public const val TASK_COMPILE: String = "compile"
public const val TASK_COMPILE_TEST: String = "compileTest" public const val TASK_COMPILE_TEST: String = "compileTest"

View file

@ -25,7 +25,7 @@ public class KotlinProject(
@Directive @Directive
override var packaging: String? = null) override var packaging: String? = null)
: Project(name, version, directory, buildDirectory, group, artifactId, packaging, dependencies, ".kt", : Project(name, version, directory, buildDirectory, group, artifactId, packaging, dependencies, ".kt",
KotlinCompilerInfo()) { projectInfo = KotlinProjectInfo()) {
override public fun toString() = toString("KotlinProject", "name", name!!) override public fun toString() = toString("KotlinProject", "name", name!!)
} }

View file

@ -0,0 +1,11 @@
package com.beust.kobalt.plugin.kotlin
import com.beust.kobalt.internal.IProjectInfo
import com.google.inject.Singleton
@Singleton
class KotlinProjectInfo : IProjectInfo {
override val defaultSourceDirectories = arrayListOf("src/main/kotlin", "src/main/resources")
override val defaultTestDirectories = arrayListOf("src/test/kotlin", "src/test/resources")
}

View file

@ -9,4 +9,8 @@
<class-name>com.beust.kobalt.plugin.java.JavaPlugin</class-name> <class-name>com.beust.kobalt.plugin.java.JavaPlugin</class-name>
<class-name>com.beust.kobalt.plugin.kotlin.KotlinPlugin</class-name> <class-name>com.beust.kobalt.plugin.kotlin.KotlinPlugin</class-name>
</project-contributors> </project-contributors>
<init-contributors>
<class-name>com.beust.kobalt.plugin.java.JavaBuildGenerator</class-name>
<class-name>com.beust.kobalt.plugin.kotlin.KotlinBuildGenerator</class-name>
</init-contributors>
</kobalt-plugin> </kobalt-plugin>

View file

@ -1 +1 @@
kobalt.version=0.217 kobalt.version=0.219

View file

@ -2,11 +2,13 @@ package com.beust.kobalt.maven
import com.beust.kobalt.Args import com.beust.kobalt.Args
import com.beust.kobalt.ProjectGenerator import com.beust.kobalt.ProjectGenerator
import com.beust.kobalt.api.PluginInfo
import com.google.inject.Inject
import org.testng.Assert import org.testng.Assert
import org.testng.annotations.Test import org.testng.annotations.Test
import java.io.File import java.io.File
class PomTest { class PomTest @Inject constructor(val pluginInfo: PluginInfo){
@Test @Test
fun importPom() { fun importPom() {
val pomSrc = File("src/test/resources/pom.xml") val pomSrc = File("src/test/resources/pom.xml")
@ -52,13 +54,13 @@ class PomTest {
val args = Args() val args = Args()
args.buildFile = file.absolutePath args.buildFile = file.absolutePath
args.init = true args.init = true
ProjectGenerator().run(args) ProjectGenerator(pluginInfo).run(args)
var contents = file.readText() var contents = file.readText()
Assert.assertTrue(contents.contains("group = \"${pom.groupId}\""), "Should find the group defined") Assert.assertTrue(contents.contains("group = \"${pom.groupId}\""), "Should find the group defined")
Assert.assertTrue(contents.contains("name = \"${pom.name}\""), "Should find the name defined") Assert.assertTrue(contents.contains("name = \"${pom.name}\""), "Should find the name defined")
Assert.assertTrue(contents.contains("version = \"${pom.version}\""), "Should find the version defined") Assert.assertTrue(contents.contains("version = \"${pom.version}\""), "Should find the version defined")
pom.properties.forEach { pom.properties.forEach {
Assert.assertTrue(contents.contains("val ${ProjectGenerator.translate(it.key)} = \"${it.value}\""), "Should find the " + Assert.assertTrue(contents.contains("val ${ProjectGenerator.toIdentifier(it.key)} = \"${it.value}\""), "Should find the " +
"property defined") "property defined")
} }
pom.repositories.forEach { pom.repositories.forEach {