diff --git a/TODO.md b/TODO.md index 6465eeff..eaebb89f 100644 --- a/TODO.md +++ b/TODO.md @@ -32,6 +32,7 @@ To do: Done: +- [x] Get rid of the $JAVA_HOME requirement - [x] getDependencies() should return the transitive dependencies - [x] Project ordering: kotlinProject(wrapper) {} - [x] Make files appear in download list automatically on bintray (undocumented API) diff --git a/kobalt.iml b/kobalt.iml index e9de3254..58c05388 100644 --- a/kobalt.iml +++ b/kobalt.iml @@ -16,30 +16,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/kobalt/wrapper/kobalt-wrapper.properties b/kobalt/wrapper/kobalt-wrapper.properties index 7b26e3be..33a44602 100644 --- a/kobalt/wrapper/kobalt-wrapper.properties +++ b/kobalt/wrapper/kobalt-wrapper.properties @@ -1 +1 @@ -kobalt.version=0.217 \ No newline at end of file +kobalt.version=0.219 \ No newline at end of file diff --git a/modules/wrapper/wrapper.iml b/modules/wrapper/wrapper.iml index 46884ee5..d3218a2d 100644 --- a/modules/wrapper/wrapper.iml +++ b/modules/wrapper/wrapper.iml @@ -7,5 +7,7 @@ + + \ No newline at end of file diff --git a/src/main/kotlin/com/beust/kobalt/Jvm.kt b/src/main/kotlin/com/beust/kobalt/Jvm.kt index e7cd1fe7..1902c618 100644 --- a/src/main/kotlin/com/beust/kobalt/Jvm.kt +++ b/src/main/kotlin/com/beust/kobalt/Jvm.kt @@ -95,10 +95,13 @@ public open class Jvm constructor( // } override public fun findExecutable(command: String): File { - val exec = File(javaHome, "bin/" + command) - val executable = java.io.File(os.getExecutableName(exec.getAbsolutePath())) - if (executable.isFile()) { - return executable + if (javaHome != null) { + val jdkHome = if (javaHome!!.endsWith("jre")) javaHome!!.parentFile else javaHome + val exec = File(jdkHome, "bin/" + command) + var executable = File(os.getExecutableName(exec.absolutePath)) + if (executable.isFile) { + return executable + } } // if (userSupplied) { @@ -108,12 +111,12 @@ public open class Jvm constructor( val pathExecutable = os.findInPath(command) if (pathExecutable != null) { - log(1, "Unable to find the ${command} executable using home: " + - "%{javaHome}. We found it on the PATH: ${pathExecutable}.") + log(1, "Unable to find the $command executable using home: " + + "%{javaHome}. We found it on the PATH: $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 " + "working folder.") return java.io.File(os.getExecutableName(command)) diff --git a/src/main/kotlin/com/beust/kobalt/Main.kt b/src/main/kotlin/com/beust/kobalt/Main.kt index 6ec0c2af..2f8aa5ea 100644 --- a/src/main/kotlin/com/beust/kobalt/Main.kt +++ b/src/main/kotlin/com/beust/kobalt/Main.kt @@ -1,7 +1,9 @@ package com.beust.kobalt 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.remote.KobaltClient import com.beust.kobalt.internal.remote.KobaltServer @@ -18,7 +20,6 @@ import java.io.File import java.nio.file.Paths import java.util.* import javax.inject.Inject -import javax.xml.bind.JAXBContext public fun main(argv: Array) { val result = mainNoExit(argv) @@ -35,6 +36,7 @@ private fun parseArgs(argv: Array): Main.RunInfo { return Main.RunInfo(result, args) } + public fun mainNoExit(argv: Array) : Int { val (jc, args) = parseArgs(argv) Kobalt.INJECTOR = Guice.createInjector(MainModule(args)) @@ -55,7 +57,8 @@ private class Main @Inject constructor( val updateKobalt: UpdateKobalt, val client: KobaltClient, val server: KobaltServer, - val pluginInfoDescription: PluginInfoDescription) { + val pluginInfo: PluginInfo, + val projectGenerator: ProjectGenerator) { data class RunInfo(val jc: JCommander, val args: Args) @@ -97,11 +100,11 @@ private class Main @Inject constructor( public fun runTest() { val file = File("src\\main\\resources\\META-INF\\plugin.xml") - val jaxbContext = JAXBContext.newInstance(KobaltPluginXml::class.java) - - val kotlinPlugin : KobaltPluginXml = jaxbContext.createUnmarshaller().unmarshal(file) as KobaltPluginXml - val pluginInfo = PluginInfo.create(kotlinPlugin) - System.out.println(kotlinPlugin.name) +// val jaxbContext = JAXBContext.newInstance(KobaltPluginXml::class.java) +// +// val kotlinPlugin : KobaltPluginXml = jaxbContext.createUnmarshaller().unmarshal(file) as KobaltPluginXml +// val pluginInfo = PluginInfo.create(kotlinPlugin) +// System.out.println(kotlinPlugin.name) } 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 // Wrapper().install() - ProjectGenerator().run(args) + projectGenerator.run(args) } else if (args.usage) { jc.usage() } else if (args.serverMode) { @@ -128,8 +131,7 @@ private class Main @Inject constructor( if (! buildFile.exists()) { error(buildFile.path.toFile().path + " does not exist") } else { - var allProjects = listOf() - val pluginInfo = PluginInfo(pluginInfoDescription) + var allProjects = arrayListOf() try { allProjects = buildFileCompilerFactory.create(listOf(buildFile), pluginInfo).compileBuildFiles(args) } catch(ex: KobaltException) { @@ -142,8 +144,8 @@ private class Main @Inject constructor( return 1 } else { log(1, "Deleted .kobalt") - allProjects = buildFileCompilerFactory.create(listOf(buildFile), pluginInfo) - .compileBuildFiles(args) + allProjects.addAll(buildFileCompilerFactory.create(listOf(buildFile), pluginInfo) + .compileBuildFiles(args)) } } @@ -178,7 +180,6 @@ private class Main @Inject constructor( } return result } - private fun findBuildFile(): File { val files = arrayListOf("Build.kt", "build.kobalt", KFiles.src("build.kobalt"), KFiles.src("Build.kt")) diff --git a/src/main/kotlin/com/beust/kobalt/Plugins.kt b/src/main/kotlin/com/beust/kobalt/Plugins.kt index d2bab348..130055a7 100644 --- a/src/main/kotlin/com/beust/kobalt/Plugins.kt +++ b/src/main/kotlin/com/beust/kobalt/Plugins.kt @@ -37,6 +37,9 @@ public class Plugins @Inject constructor (val taskManagerProvider : Provider() // private var storageMap = HashMap>() // fun storeValue(pluginName: String, key: String, value: Any) { diff --git a/src/main/kotlin/com/beust/kobalt/ProjectGenerator.kt b/src/main/kotlin/com/beust/kobalt/ProjectGenerator.kt index 60accc5c..3bde0814 100644 --- a/src/main/kotlin/com/beust/kobalt/ProjectGenerator.kt +++ b/src/main/kotlin/com/beust/kobalt/ProjectGenerator.kt @@ -1,133 +1,57 @@ package com.beust.kobalt -import com.beust.kobalt.api.ICompilerInfo -import com.beust.kobalt.api.Kobalt -import com.beust.kobalt.maven.Pom -import com.beust.kobalt.maven.Pom.Dependency -import com.beust.kobalt.misc.KFiles +import com.beust.kobalt.api.IInitContributor +import com.beust.kobalt.api.PluginInfo import com.beust.kobalt.misc.log -import com.github.mustachejava.DefaultMustacheFactory +import com.google.inject.Inject import java.io.File -import java.io.InputStreamReader -import java.io.PrintWriter -import java.io.StringWriter -import java.util.ArrayList -import java.util.Collections -import java.util.HashMap +import java.io.FileOutputStream +import java.util.* /** - * Generate a new project. + * Invoked with --init. Generate a new project. */ -public class ProjectGenerator { +public class ProjectGenerator @Inject constructor(val pluginInfo: PluginInfo){ companion object { /** * Turns a dot property into a proper Kotlin identifier, e.g. common.version -> commonVersion */ - fun translate(key: String): String { - return key.split('.').mapIndexed( { index, value -> if (index == 0) value else value.upperFirst() }) + fun toIdentifier(key: String): String { + 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("") } } fun run(args: Args) { - if (File(args.buildFile).exists()) { - log(1, "Build file ${args.buildFile} already exists, not overwriting it") - return + val contributor = findBestInitContributor(File(".")) + if (contributor != null) { + contributor.generateBuildFile(FileOutputStream(File(args.buildFile))) + log(1, "Created ${args.buildFile}") + } else { + log(1, "Couldn't identify project, not generating any build file") } + } - val compilerInfos = detect(File(".")) - if (compilerInfos.size > 1) { - log(1, "Multi language project detected, not supported yet") - } - val map = hashMapOf() - 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") + /** + * Run through all the IInitContributors and return the best one. + */ + private fun findBestInitContributor(dir: File) : IInitContributor? { + val result = arrayListOf>() + pluginInfo.initContributors.forEach { + it.filesManaged(dir).let { count -> + if (count > 0) { + result.add(Pair(it, count)) } } } - - var mainDeps = arrayListOf() - var testDeps = arrayListOf() - 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, testDeps: ArrayList, - map: HashMap) { - 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) = - 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) + if (result.size > 0) { + Collections.sort(result, { p1, p2 -> p2.second.compareTo(p1.second) }) + return result[0].first } else { - dep + return null } - - - /** - * Detect all the languages contained in this project. - */ - private fun detect(dir: File) : List { - val result = arrayListOf>>() - Kobalt.compilers.forEach { - val managedFiles = it.findManagedFiles(dir) - if (managedFiles.size > 0) { - result.add(Pair(it, managedFiles)) - } - } - Collections.sort(result, { p1, p2 -> p1.second.size.compareTo(p2.second.size) }) - return result.map { it.first } } } -private fun String.upperFirst(): String { - return if (this.isBlank()) this else this.substring(0, 1).toUpperCase() + this.substring(1) -} diff --git a/src/main/kotlin/com/beust/kobalt/SystemProperties.kt b/src/main/kotlin/com/beust/kobalt/SystemProperties.kt index eb223589..b7877264 100644 --- a/src/main/kotlin/com/beust/kobalt/SystemProperties.kt +++ b/src/main/kotlin/com/beust/kobalt/SystemProperties.kt @@ -1,11 +1,9 @@ package com.beust.kobalt -import java.util.concurrent.locks.ReentrantLock -import javax.inject.Inject - public class SystemProperties { 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 homeDir = System.getProperty("user.home") val tmpDir = System.getProperty("java.io.tmpdir") diff --git a/src/main/kotlin/com/beust/kobalt/api/Kobalt.kt b/src/main/kotlin/com/beust/kobalt/api/Kobalt.kt index eefaaeb1..c1105c10 100644 --- a/src/main/kotlin/com/beust/kobalt/api/Kobalt.kt +++ b/src/main/kotlin/com/beust/kobalt/api/Kobalt.kt @@ -2,38 +2,17 @@ package com.beust.kobalt.api import com.beust.kobalt.Plugins import com.google.inject.Injector -import java.io.File import java.io.InputStream import java.nio.file.Files import java.nio.file.Paths import java.util.* -public interface ICompilerInfo { - /** Used to detect what kind of language this project is */ - fun findManagedFiles(dir: File) : List - - /** Used to generate the imports */ - val name: String - - /** Used to generate the imports */ - val directive: String - - val defaultSourceDirectories : ArrayList - val defaultTestDirectories : ArrayList -} - public class Kobalt { companion object { lateinit var INJECTOR : Injector - public val compilers : ArrayList = arrayListOf() - var context: KobaltContext? = null - fun registerCompiler(c: ICompilerInfo) { - compilers.add(c) - } - private val DEFAULT_REPOS = arrayListOf( "http://repo1.maven.org/maven2/", "https://repository.jboss.org/nexus/content/repositories/root_repository/", diff --git a/src/main/kotlin/com/beust/kobalt/api/KobaltPluginFile.kt b/src/main/kotlin/com/beust/kobalt/api/KobaltPluginFile.kt deleted file mode 100644 index 236a6836..00000000 --- a/src/main/kotlin/com/beust/kobalt/api/KobaltPluginFile.kt +++ /dev/null @@ -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) - -interface IProjectContributor { - fun projects() : List -} - -/** - * 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 -} - -interface IFactory { - fun instanceOf(c: Class) : T -} - -class ContributorFactory : IFactory { - override fun instanceOf(c: Class) : T = Kobalt.INJECTOR.getInstance(c) -} - -/** - * All the information gathered from the various plugin.xml that were collected. - */ -class PluginInfoDescription { - fun instanceOf(c: Class) : T = Kobalt.INJECTOR.getInstance(c) - - val projectContributors : ArrayList> = - arrayListOf(JavaPlugin::class.java, KotlinPlugin::class.java) - - val classpathContributors: ArrayList> = - 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() - val classpathContributors = arrayListOf() - - 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 = arrayListOf() -} - -@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 -} - diff --git a/src/main/kotlin/com/beust/kobalt/api/KobaltPluginXml.kt b/src/main/kotlin/com/beust/kobalt/api/KobaltPluginXml.kt new file mode 100644 index 00000000..11a99147 --- /dev/null +++ b/src/main/kotlin/com/beust/kobalt/api/KobaltPluginXml.kt @@ -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 +} + +class ProjectDescription(val project: Project, val dependsOn: List) + +/** + * Plugins that export classpath entries need to implement this interface. + */ +interface IClasspathContributor { + fun entriesFor(project: Project) : Collection +} + +/** + * The factory function to use to instantiate all the contributors and other entities + * found in plugin.xml. + */ +interface IFactory { + fun instanceOf(c: Class) : T +} + +class ContributorFactory : IFactory { + override fun instanceOf(c: Class) : 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 = 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() + val classpathContributors = arrayListOf() + val initContributors = arrayListOf() + + // 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) + } + } +} + diff --git a/src/main/kotlin/com/beust/kobalt/api/Project.kt b/src/main/kotlin/com/beust/kobalt/api/Project.kt index 68bc0156..ca815e63 100644 --- a/src/main/kotlin/com/beust/kobalt/api/Project.kt +++ b/src/main/kotlin/com/beust/kobalt/api/Project.kt @@ -1,6 +1,7 @@ package com.beust.kobalt.api import com.beust.kobalt.api.annotation.Directive +import com.beust.kobalt.internal.IProjectInfo import com.beust.kobalt.maven.IClasspathDependency import com.beust.kobalt.maven.MavenDependency import com.beust.kobalt.misc.KFiles @@ -16,11 +17,11 @@ open public class Project( @Directive open var packaging: String? = null, @Directive open var dependencies: Dependencies? = null, @Directive open var sourceSuffix : String = "", - @Directive open var compilerInfo : ICompilerInfo, @Directive open var description : String = "", @Directive open var scm : Scm? = null, @Directive open var url: String? = null, - @Directive open var licenses: List = arrayListOf()) { + @Directive open var licenses: List = arrayListOf(), + val projectInfo: IProjectInfo) { var testArgs: ArrayList = arrayListOf() @@ -44,7 +45,7 @@ open public class Project( } var sourceDirectories : ArrayList = arrayListOf() - get() = if (field.isEmpty()) compilerInfo.defaultSourceDirectories else field + get() = if (field.isEmpty()) projectInfo.defaultSourceDirectories else field set(value) { field = value } @@ -57,7 +58,7 @@ open public class Project( } var sourceDirectoriesTest : ArrayList = arrayListOf() - get() = if (field.isEmpty()) compilerInfo.defaultTestDirectories + get() = if (field.isEmpty()) projectInfo.defaultTestDirectories else field set(value) { field = value diff --git a/src/main/kotlin/com/beust/kobalt/internal/BuildGenerator.kt b/src/main/kotlin/com/beust/kobalt/internal/BuildGenerator.kt new file mode 100644 index 00000000..190a583b --- /dev/null +++ b/src/main/kotlin/com/beust/kobalt/internal/BuildGenerator.kt @@ -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 + abstract val defaultTestDirectories : ArrayList + 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, testDeps: ArrayList, + map: HashMap) { + 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) = + 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() + 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() + var testDeps = arrayListOf() + 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() + } +} + diff --git a/src/main/kotlin/com/beust/kobalt/internal/ProjectInfo.kt b/src/main/kotlin/com/beust/kobalt/internal/ProjectInfo.kt new file mode 100644 index 00000000..2c8ee288 --- /dev/null +++ b/src/main/kotlin/com/beust/kobalt/internal/ProjectInfo.kt @@ -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 + val defaultTestDirectories: ArrayList +} diff --git a/src/main/kotlin/com/beust/kobalt/internal/remote/GetDependenciesCommand.kt b/src/main/kotlin/com/beust/kobalt/internal/remote/GetDependenciesCommand.kt index 69501c41..8cbe2f4c 100644 --- a/src/main/kotlin/com/beust/kobalt/internal/remote/GetDependenciesCommand.kt +++ b/src/main/kotlin/com/beust/kobalt/internal/remote/GetDependenciesCommand.kt @@ -2,7 +2,6 @@ package com.beust.kobalt.internal.remote import com.beust.kobalt.Args import com.beust.kobalt.api.PluginInfo -import com.beust.kobalt.api.PluginInfoDescription import com.beust.kobalt.kotlin.BuildFile import com.beust.kobalt.kotlin.BuildFileCompiler import com.beust.kobalt.maven.DependencyManager @@ -26,11 +25,11 @@ import javax.inject.Inject */ class GetDependenciesCommand @Inject constructor(val executors: KobaltExecutors, 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 fun run(sender: ICommandSender, received: JsonObject) { 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 { buildScriptInfo -> if (buildScriptInfo.projects.size > 0) { sender.sendData(toData(buildScriptInfo)) diff --git a/src/main/kotlin/com/beust/kobalt/misc/KFiles.kt b/src/main/kotlin/com/beust/kobalt/misc/KFiles.kt index 6ebb661e..157ab4a7 100644 --- a/src/main/kotlin/com/beust/kobalt/misc/KFiles.kt +++ b/src/main/kotlin/com/beust/kobalt/misc/KFiles.kt @@ -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 = 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) = 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() diff --git a/src/main/kotlin/com/beust/kobalt/misc/MainModule.kt b/src/main/kotlin/com/beust/kobalt/misc/MainModule.kt index bcb21dfe..1e4f7f03 100644 --- a/src/main/kotlin/com/beust/kobalt/misc/MainModule.kt +++ b/src/main/kotlin/com/beust/kobalt/misc/MainModule.kt @@ -1,6 +1,7 @@ package com.beust.kobalt.misc import com.beust.kobalt.Args +import com.beust.kobalt.api.PluginInfo import com.beust.kobalt.kotlin.BuildFileCompiler import com.beust.kobalt.maven.* 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.TypeLiteral import com.google.inject.assistedinject.FactoryModuleBuilder -import java.lang.annotation.RetentionPolicy import java.util.concurrent.ExecutorService //@Singleton @@ -49,9 +49,12 @@ public open class MainModule(val args: Args) : AbstractModule() { bind(object: TypeLiteral() {}).toInstance(executors) bind(object: TypeLiteral() {}).annotatedWith(DependencyExecutor::class.java) .toInstance(executors.dependencyExecutor) - bind(Args::class.java).toProvider(object : Provider { + bind(Args::class.java).toProvider(object: Provider { override fun get(): Args? = args }) + bind(PluginInfo::class.java).toProvider(object: Provider { + override fun get(): PluginInfo? = PluginInfo.readKobaltPluginXml() + }) // bindListener(Matchers.any(), object: TypeListener { diff --git a/src/main/kotlin/com/beust/kobalt/misc/RunCommand.kt b/src/main/kotlin/com/beust/kobalt/misc/RunCommand.kt index 790ddc65..9fceb11e 100644 --- a/src/main/kotlin/com/beust/kobalt/misc/RunCommand.kt +++ b/src/main/kotlin/com/beust/kobalt/misc/RunCommand.kt @@ -6,10 +6,13 @@ import java.io.InputStream import java.io.InputStreamReader open class RunCommand(val command: String) { - val defaultSuccess = { output: List -> log(1, "Success:\n " + output.joinToString("\n"))} - val defaultError = { output: List -> log(1, "Error:\n " + output.joinToString("\n"))} + val defaultSuccess = { output: List -> log(2, "Success:\n " + output.joinToString("\n"))} + val defaultError = { + output: List -> error("Error:\n " + output.joinToString("\n")) + } var directory = File(".") + var env = hashMapOf() fun run(args: List, error: Function1, Unit>? = defaultError, success: Function1, 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)) 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 55c28c56..5df7a7af 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/android/AndroidPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/android/AndroidPlugin.kt @@ -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"), diff --git a/src/main/kotlin/com/beust/kobalt/plugin/java/JavaBuildGenerator.kt b/src/main/kotlin/com/beust/kobalt/plugin/java/JavaBuildGenerator.kt new file mode 100644 index 00000000..848429b8 --- /dev/null +++ b/src/main/kotlin/com/beust/kobalt/plugin/java/JavaBuildGenerator.kt @@ -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") } +} diff --git a/src/main/kotlin/com/beust/kobalt/plugin/java/JavaCompilerInfo.kt b/src/main/kotlin/com/beust/kobalt/plugin/java/JavaCompilerInfo.kt deleted file mode 100644 index c4c3ab63..00000000 --- a/src/main/kotlin/com/beust/kobalt/plugin/java/JavaCompilerInfo.kt +++ /dev/null @@ -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 { - 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" - -} diff --git a/src/main/kotlin/com/beust/kobalt/plugin/java/JavaPlugin.kt b/src/main/kotlin/com/beust/kobalt/plugin/java/JavaPlugin.kt index 25b5257d..11307667 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/java/JavaPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/java/JavaPlugin.kt @@ -31,11 +31,6 @@ public class JavaPlugin @Inject constructor( override val jvmCompiler: JvmCompiler) : JvmCompilerPlugin(localRepo, files, depFactory, dependencyManager, executors, jvmCompiler), IProjectContributor { - - init { - Kobalt.registerCompiler(JavaCompilerInfo()) - } - companion object { public const val TASK_COMPILE : String = "compile" public const val TASK_JAVADOC : String = "javadoc" diff --git a/src/main/kotlin/com/beust/kobalt/plugin/java/JavaProject.kt b/src/main/kotlin/com/beust/kobalt/plugin/java/JavaProject.kt index 6f1c1df2..3f0173a8 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/java/JavaProject.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/java/JavaProject.kt @@ -25,7 +25,7 @@ public class JavaProject( @Directive override var packaging: String? = null) : Project(name, version, directory, buildDirectory, group, artifactId, packaging, dependencies, - ".java", JavaCompilerInfo()) { + ".java", projectInfo = JavaProjectInfo()) { override public fun toString() = toString("JavaProject", "name", name!!) } diff --git a/src/main/kotlin/com/beust/kobalt/plugin/java/JavaProjectInfo.kt b/src/main/kotlin/com/beust/kobalt/plugin/java/JavaProjectInfo.kt new file mode 100644 index 00000000..9b5513ec --- /dev/null +++ b/src/main/kotlin/com/beust/kobalt/plugin/java/JavaProjectInfo.kt @@ -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") +} diff --git a/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinBuildGenerator.kt b/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinBuildGenerator.kt new file mode 100644 index 00000000..82c9e9de --- /dev/null +++ b/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinBuildGenerator.kt @@ -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") } +} + diff --git a/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinCompilerInfo.kt b/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinCompilerInfo.kt deleted file mode 100644 index 22bf436d..00000000 --- a/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinCompilerInfo.kt +++ /dev/null @@ -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 { - 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" -} - diff --git a/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinPlugin.kt b/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinPlugin.kt index 4596a2db..9c2d446b 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinPlugin.kt @@ -24,10 +24,6 @@ class KotlinPlugin @Inject constructor( : JvmCompilerPlugin(localRepo, files, depFactory, dependencyManager, executors, jvmCompiler), IProjectContributor, IClasspathContributor { - init { - Kobalt.registerCompiler(KotlinCompilerInfo()) - } - companion object { public const val TASK_COMPILE: String = "compile" public const val TASK_COMPILE_TEST: String = "compileTest" diff --git a/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinProject.kt b/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinProject.kt index 1bdaf15a..028ae693 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinProject.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinProject.kt @@ -25,7 +25,7 @@ public class KotlinProject( @Directive override var packaging: String? = null) : Project(name, version, directory, buildDirectory, group, artifactId, packaging, dependencies, ".kt", - KotlinCompilerInfo()) { + projectInfo = KotlinProjectInfo()) { override public fun toString() = toString("KotlinProject", "name", name!!) } diff --git a/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinProjectInfo.kt b/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinProjectInfo.kt new file mode 100644 index 00000000..77a07678 --- /dev/null +++ b/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinProjectInfo.kt @@ -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") +} + diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 5425b2c8..9c79eadd 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -9,4 +9,8 @@ com.beust.kobalt.plugin.java.JavaPlugin com.beust.kobalt.plugin.kotlin.KotlinPlugin + + com.beust.kobalt.plugin.java.JavaBuildGenerator + com.beust.kobalt.plugin.kotlin.KotlinBuildGenerator + \ No newline at end of file diff --git a/src/main/resources/kobalt.properties b/src/main/resources/kobalt.properties index f39d71c1..7b2692ae 100644 --- a/src/main/resources/kobalt.properties +++ b/src/main/resources/kobalt.properties @@ -1 +1 @@ -kobalt.version=0.217 +kobalt.version=0.219 diff --git a/src/test/kotlin/com/beust/kobalt/maven/PomTest.kt b/src/test/kotlin/com/beust/kobalt/maven/PomTest.kt index b840bd99..5a9a54ae 100644 --- a/src/test/kotlin/com/beust/kobalt/maven/PomTest.kt +++ b/src/test/kotlin/com/beust/kobalt/maven/PomTest.kt @@ -2,11 +2,13 @@ package com.beust.kobalt.maven import com.beust.kobalt.Args import com.beust.kobalt.ProjectGenerator +import com.beust.kobalt.api.PluginInfo +import com.google.inject.Inject import org.testng.Assert import org.testng.annotations.Test import java.io.File -class PomTest { +class PomTest @Inject constructor(val pluginInfo: PluginInfo){ @Test fun importPom() { val pomSrc = File("src/test/resources/pom.xml") @@ -52,13 +54,13 @@ class PomTest { val args = Args() args.buildFile = file.absolutePath args.init = true - ProjectGenerator().run(args) + ProjectGenerator(pluginInfo).run(args) var contents = file.readText() 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("version = \"${pom.version}\""), "Should find the version defined") 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") } pom.repositories.forEach {