diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/Args.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/Args.kt index bf1b44e8..7eca0631 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/Args.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/Args.kt @@ -29,8 +29,8 @@ class Args { @Parameter(names = arrayOf("--help", "--usage"), description = "Display the help") var usage: Boolean = false - @Parameter(names = arrayOf("-i", "--init"), description = "Create a build file based on the current project") - var init: Boolean = false + @Parameter(names = arrayOf("-i", "--init"), description = "Invoke the archetypes named, separated by a comma") + var archetypes : String? = null @Parameter(names = arrayOf("--log"), description = "Define the log level (1-3)") var log: Int = 1 diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/Constants.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/Constants.kt index 5d2fe07c..c30f0a1e 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/Constants.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/Constants.kt @@ -1,8 +1,11 @@ package com.beust.kobalt +import com.beust.kobalt.misc.KFiles + object Constants { val BUILD_FILE_NAME = "Build.kt" val BUILD_FILE_DIRECTORY = "kobalt/src" + val BUILD_FILE_PATH = KFiles.joinDir(BUILD_FILE_DIRECTORY, BUILD_FILE_NAME) internal val DEFAULT_REPOS = listOf( "http://repo1.maven.org/maven2/", diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/IInitContributor.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/IInitContributor.kt index 4d537107..6e6cd0fd 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/IInitContributor.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/IInitContributor.kt @@ -1,15 +1,14 @@ package com.beust.kobalt.api -import java.io.OutputStream +import com.beust.kobalt.Args /** * Plugins that want to participate in the --init process (they can generate files to initialize * a new project). */ -interface IInitContributor : ISimpleAffinity { - /** - * Generate the Build.kt file into the given OutputStream. - */ - fun generateBuildFile(os: OutputStream) +interface IInitContributor { + val name: String + + fun generateArchetype(args: Args) } diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/KobaltPluginXml.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/KobaltPluginXml.kt index 8b29a9d1..dc7172dd 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/KobaltPluginXml.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/KobaltPluginXml.kt @@ -59,7 +59,7 @@ class PluginInfo(val xml: KobaltPluginXml, val classLoader: ClassLoader?) { val plugins = arrayListOf() val projectContributors = arrayListOf() val classpathContributors = arrayListOf() - val initContributors = arrayListOf>() + val initContributors = arrayListOf() val repoContributors = arrayListOf() val compilerFlagContributors = arrayListOf() val compilerInterceptors = arrayListOf() @@ -147,7 +147,7 @@ class PluginInfo(val xml: KobaltPluginXml, val classLoader: ClassLoader?) { if (this is ICompilerFlagContributor) compilerFlagContributors.add(this) if (this is ICompilerInterceptor) compilerInterceptors.add(this) if (this is IDocContributor) docContributors.add(this) - if (this is IInitContributor<*>) initContributors.add(this as IInitContributor) + if (this is IInitContributor) initContributors.add(this as IInitContributor) if (this is IPlugin) plugins.add(this) if (this is IProjectContributor) projectContributors.add(this) if (this is IRepoContributor) repoContributors.add(this) diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/RepoFinder.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/RepoFinder.kt index b7afc048..a415901a 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/RepoFinder.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/RepoFinder.kt @@ -28,6 +28,9 @@ import javax.xml.xpath.XPathFactory class RepoFinder @Inject constructor(val executors: KobaltExecutors) { fun findCorrectRepo(id: String) = FOUND_REPOS.get(id) + /** + * archiveUrl: full URL + */ data class RepoResult(val hostConfig: HostConfig, val version: Version? = null, val archiveUrl: String? = null, val snapshotVersion: Version? = null) { val found = archiveUrl != null @@ -96,7 +99,7 @@ class RepoFinder @Inject constructor(val executors: KobaltExecutors) { val path = ud.toMetadataXmlPath(false, isLocal) val foundVersion = findCorrectVersionRelease(path, repoUrl) if (foundVersion != null) { - return RepoResult(repo, Version.of(foundVersion), path) + return RepoResult(repo, Version.of(foundVersion), repoUrl + path) } else { return RepoResult(repo) } diff --git a/src/main/kotlin/com/beust/kobalt/Main.kt b/src/main/kotlin/com/beust/kobalt/Main.kt index c5ca3f61..9096b885 100644 --- a/src/main/kotlin/com/beust/kobalt/Main.kt +++ b/src/main/kotlin/com/beust/kobalt/Main.kt @@ -118,7 +118,7 @@ private class Main @Inject constructor( println(AsciiArt.banner + Kobalt.version + "\n") } - if (args.init) { + if (args.archetypes != null) { // // --init: create a new build project and install the wrapper // Make sure the wrapper won't call us back with --noLaunch diff --git a/src/main/kotlin/com/beust/kobalt/app/BuildGenerator.kt b/src/main/kotlin/com/beust/kobalt/app/BuildGenerator.kt index 8c9c7359..cc06e35f 100644 --- a/src/main/kotlin/com/beust/kobalt/app/BuildGenerator.kt +++ b/src/main/kotlin/com/beust/kobalt/app/BuildGenerator.kt @@ -1,8 +1,9 @@ package com.beust.kobalt.app +import com.beust.kobalt.Args import com.beust.kobalt.api.IInitContributor import com.beust.kobalt.maven.Pom -import com.beust.kobalt.misc.KFiles +import com.beust.kobalt.misc.log import com.github.mustachejava.DefaultMustacheFactory import java.io.* import java.util.* @@ -10,20 +11,35 @@ import java.util.* /** * Abstract base class for the build generators that use build-template.mustache. */ -abstract class BuildGenerator : IInitContributor { +abstract class BuildGenerator : IInitContributor { abstract val defaultSourceDirectories : HashSet abstract val defaultTestDirectories : HashSet abstract val directive : String - abstract val name : String + override abstract val name : String abstract val fileMatch : (String) -> Boolean - override fun generateBuildFile(os: OutputStream) { - PrintWriter(os).use { - it.print(buildFileContent) + companion object { + /** + * Turns a dot property into a proper Kotlin identifier, e.g. common.version -> commonVersion + */ + 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("") } } - override fun affinity(arg: File) = KFiles.findRecursively(arg, fileMatch).size + override fun generateArchetype(args: Args) { + val file = File(args.buildFile) + if (! file.exists()) { + PrintWriter(FileOutputStream(file)).use { + it.print(buildFileContent) + } + } else { + log(1, "Build file already exists, not overwriting it") + } + } private fun importPom(pomFile: File, mainDeps: ArrayList, testDeps: ArrayList, map: HashMap) { @@ -37,7 +53,7 @@ abstract class BuildGenerator : IInitContributor { } val properties = pom.properties - val mapped = properties.entries.associateBy({ it.key }, { ProjectGenerator.toIdentifier(it.key) }) + val mapped = properties.entries.associateBy({ it.key }, { toIdentifier(it.key) }) map.put("properties", properties.entries.map({ Pair(mapped[it.key], it.value) })) diff --git a/src/main/kotlin/com/beust/kobalt/app/ProjectGenerator.kt b/src/main/kotlin/com/beust/kobalt/app/ProjectGenerator.kt index c3cc50c2..62093715 100644 --- a/src/main/kotlin/com/beust/kobalt/app/ProjectGenerator.kt +++ b/src/main/kotlin/com/beust/kobalt/app/ProjectGenerator.kt @@ -1,43 +1,23 @@ package com.beust.kobalt.app import com.beust.kobalt.Args -import com.beust.kobalt.internal.ActorUtils import com.beust.kobalt.internal.PluginInfo import com.beust.kobalt.misc.log import com.google.inject.Inject import java.io.File -import java.io.FileOutputStream /** * Invoked with --init. Generate a new project. */ 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 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) { - val contributor = ActorUtils.selectAffinityActor(pluginInfo.initContributors, File(".")) File(args.buildFile).parentFile.mkdirs() - if (contributor != null) { - with(File(args.buildFile)) { - if (exists()) { - log(1, "Build file $path already exists, not overwriting it") - } else { - contributor.generateBuildFile(FileOutputStream(this)) - log(1, "Created $path") - } + args.archetypes?.let { archetypes -> + val contributors = pluginInfo.initContributors.filter { archetypes.contains(it.name) } + contributors.forEach { + log(2, "Running archetype ${it.name}") + it.generateArchetype(args) } - } else { - log(1, "Couldn't identify project, not generating any build file") } } } diff --git a/src/test/kotlin/com/beust/kobalt/maven/PomTest.kt b/src/test/kotlin/com/beust/kobalt/maven/PomTest.kt index ef8d6fc4..9e56999f 100644 --- a/src/test/kotlin/com/beust/kobalt/maven/PomTest.kt +++ b/src/test/kotlin/com/beust/kobalt/maven/PomTest.kt @@ -3,6 +3,7 @@ package com.beust.kobalt.maven import com.beust.kobalt.Args import com.beust.kobalt.KobaltTest import com.beust.kobalt.api.Kobalt +import com.beust.kobalt.app.BuildGenerator import com.beust.kobalt.app.ProjectGenerator import com.beust.kobalt.internal.PluginInfo import com.google.inject.Inject @@ -55,7 +56,7 @@ class PomTest @Inject constructor() : KobaltTest() { file.deleteOnExit() val args = Args() args.buildFile = file.absolutePath - args.init = true + args.archetypes = "java" ProjectGenerator(Kobalt.INJECTOR.getInstance(PluginInfo::class.java)).run(args) @@ -64,8 +65,9 @@ class PomTest @Inject constructor() : KobaltTest() { 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.toIdentifier(it.key)} = \"${it.value}\""), "Should find the " + - "property defined") + Assert.assertTrue(contents.contains( + "val ${BuildGenerator.toIdentifier(it.key)} = \"${it.value}\""), "Should find the " + + "property defined") } pom.repositories.forEach { Assert.assertTrue(contents.contains(it), "Should find the repository defined")