diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/BuildScript.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/BuildScript.kt index 074469da..a91e82e0 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/BuildScript.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/BuildScript.kt @@ -7,6 +7,7 @@ import com.beust.kobalt.internal.KobaltSettings import com.beust.kobalt.internal.PluginInfo import com.beust.kobalt.maven.DependencyManager import com.beust.kobalt.maven.dependency.FileDependency +import com.beust.kobalt.misc.KobaltLogger import org.eclipse.aether.repository.Proxy import java.io.File import java.net.InetSocketAddress @@ -14,12 +15,17 @@ import java.net.InetSocketAddress var BUILD_SCRIPT_CONFIG : BuildScriptConfig? = null class BuildScriptConfig { -// var repos = listOf() -// var plugins = listOf() + /** The list of repos used to locate plug-ins. */ + fun repos(vararg r: String) = newRepos(*r) - // The following settings are used to modify the compiler used to - // compile the build file. Projects should use kotlinCompiler { compilerVersion } to configure - // the Kotin compiler for their source files. + /** The list of plug-ins to use for this build file. */ + fun plugins(vararg pl: String) = newPlugins(*pl) + + /** The build file classpath. */ + fun buildFileClasspath(vararg bfc: String) = newBuildFileClasspath(*bfc) + + // The following settings modify the compiler used to compile the build file. + // Projects should use kotlinCompiler { compilerVersion } to configure the Kotin compiler for their source files. var kobaltCompilerVersion : String? = null var kobaltCompilerRepo: String? = null var kobaltCompilerFlags: String? = null @@ -37,13 +43,18 @@ fun homeDir(vararg dirs: String) : String = SystemProperties.homeDir + @Directive fun file(file: String) : String = FileDependency.PREFIX_FILE + file -@Directive fun plugins(vararg dependency : IClasspathDependency) { dependency.forEach { Plugins.addDynamicPlugin(it) } } -@Directive fun plugins(vararg dependencies : String) { + KobaltLogger.logger.warn("Build.kt", + "Invoking plugins() directly is deprecated, use the buildScript{} directive") + newPlugins(*dependencies) +} + +@Directive +fun newPlugins(vararg dependencies : String) { val factory = Kobalt.INJECTOR.getInstance(DependencyManager::class.java) dependencies.forEach { Plugins.addDynamicPlugin(factory.create(it)) @@ -70,13 +81,23 @@ data class HostConfig(var url: String = "", var username: String? = null, var pa } } -@Directive fun repos(vararg repos : String) { + KobaltLogger.logger.warn("Build.kt", + "Invoking repos() directly is deprecated, use the buildScript{} directive") + newRepos(*repos) +} + +fun newRepos(vararg repos: String) { repos.forEach { Kobalt.addRepo(HostConfig(it)) } } -@Directive fun buildFileClasspath(vararg deps: String) { + KobaltLogger.logger.warn("Build.kt", + "Invoking buildFileClasspath() directly is deprecated, use the buildScript{} directive") + newBuildFileClasspath(*deps) +} + +fun newBuildFileClasspath(vararg deps: String) { deps.forEach { Kobalt.addBuildFileClasspath(it) } } @@ -103,3 +124,4 @@ fun localMaven() : String { } return result.toURI().toString() } + diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/BlockExtractor.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/BlockExtractor.kt index 52cdb694..3e6caa8f 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/BlockExtractor.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/BlockExtractor.kt @@ -2,59 +2,65 @@ package com.beust.kobalt.misc import com.beust.kobalt.homeDir import java.io.File +import java.util.regex.Pattern fun main(argv: Array) { val lines = File(homeDir("kotlin/kobalt/kobalt/src/Build.kt")).readLines() - val result = BlockExtractor("buildScript", '{', '}').extractBlock(lines) + val result = BlockExtractor(Pattern.compile("val.*buildScript.*\\{"), '{', '}').extractBlock(lines) - BlockExtractor("plugins", '(', ')').extractBlock(lines) +// BlockExtractor("plugins", '(', ')').extractBlock(lines) } -class BlockExtractor(val keyword: String, val opening: Char, val closing: Char) { - +/** + * Used to extract a keyword followed by opening and closing tags out of a list of strings, + * e.g. buildScript { ... }. + */ +class BlockExtractor(val regexp: Pattern, val opening: Char, val closing: Char) { fun extractBlock(lines: List): String? { var foundKeyword = false - var foundOpening = false var foundClosing = false var count = 0 val result = StringBuffer() fun updateCount(line: String) { - val onlyBlanks = foundKeyword && ! foundOpening - var blanks = true + val currentLine = StringBuffer() line.toCharArray().forEach { c -> if (c == opening) { count++ - if (onlyBlanks && blanks) foundOpening = true } if (c == closing) { count-- - foundClosing = true + if (count == 0) { + currentLine.append(closing).append("\n") + foundClosing = true + } } - if (c != ' ' && c != '\t' && c != '\n') blanks = false - result.append(c) + if (foundKeyword && count > 0) currentLine.append(c) } - result.append("\n") + + if (currentLine.isNotEmpty()) result.append(currentLine.toString()).append("\n") } lines.forEach { line -> - if (! foundKeyword) { - val index = line.indexOf(keyword) - if (index >= 0) { - foundKeyword = true - result.append(keyword) - updateCount(line.substring(index + keyword.length)) - } + val found = regexp.matcher(line).matches() + if (found) { + foundKeyword = true + count = 1 + result.append(line).append("\n") } else { updateCount(line) } - if (foundKeyword && foundOpening && foundClosing && count == 0) { + if (foundKeyword && foundClosing && count == 0) { println("Done extracting: @$result@") return result.toString() } } - return null + if (foundKeyword && foundClosing && count == 0) { + return result.toString() + } else { + return null + } } } diff --git a/src/main/kotlin/com/beust/kobalt/app/ParsedBuildFile.kt b/src/main/kotlin/com/beust/kobalt/app/ParsedBuildFile.kt index 9029358b..e7777b46 100644 --- a/src/main/kotlin/com/beust/kobalt/app/ParsedBuildFile.kt +++ b/src/main/kotlin/com/beust/kobalt/app/ParsedBuildFile.kt @@ -8,6 +8,7 @@ import com.beust.kobalt.api.Project import com.beust.kobalt.internal.build.BuildFile import com.beust.kobalt.internal.build.VersionFile import com.beust.kobalt.maven.DependencyManager +import com.beust.kobalt.misc.BlockExtractor import com.beust.kobalt.misc.KFiles import com.beust.kobalt.misc.countChar import com.beust.kobalt.misc.kobaltLog @@ -17,6 +18,7 @@ import java.net.URL import java.nio.charset.Charset import java.nio.file.Paths import java.util.* +import java.util.regex.Pattern class ParsedBuildFile(val buildFile: BuildFile, val context: KobaltContext, val buildScriptUtil: BuildScriptUtil, val dependencyManager: DependencyManager, val files: KFiles) { @@ -44,6 +46,36 @@ class ParsedBuildFile(val buildFile: BuildFile, val context: KobaltContext, val private fun parseBuildFile() { var parenCount = 0 var current: ArrayList? = null + + /** + * If the current line matches one of the profiles, turn the declaration into + * val profile = true, otherwise return the same line + */ + fun correctProfileLine(line: String) : String { + (context.profiles as List).forEach { + if (line.matches(Regex("[ \\t]*val[ \\t]+$it[ \\t]*=.*"))) { + with("val $it = true") { + kobaltLog(2, "Activating profile $it in build file") + activeProfiles.add(it) + profileLines.add(this) + return this + } + } + } + return line + } + + fun applyProfiles(lines: List) : List { + val result = arrayListOf() + lines.forEach { line -> + result.add(correctProfileLine(line)) + } + return result + } + + val buildWithCorrectProfiles = applyProfiles(buildFile.path.toFile().readLines()) + val bs = BlockExtractor(Pattern.compile("^val.*buildScript.*\\{"), '{', '}').extractBlock(buildWithCorrectProfiles) + buildFile.path.toFile().forEachLine(Charset.defaultCharset()) { line -> var index = line.indexOf("plugins(") if (current == null) { @@ -77,30 +109,16 @@ class ParsedBuildFile(val buildFile: BuildFile, val context: KobaltContext, val current = null } - /** - * If the current line matches one of the profiles, turn the declaration into - * val profile = true, otherwise return the same line - */ - fun correctProfileLine(line: String) : String { - (context.profiles as List).forEach { - if (line.matches(Regex("[ \\t]*val[ \\t]+$it[ \\t]*=.*"))) { - with("val $it = true") { - kobaltLog(2, "Activating profile $it in build file") - activeProfiles.add(it) - profileLines.add(this) - return this - } - } - } - return line - } - buildScript.add(correctProfileLine(line)) } - repos.forEach { preBuildScript.add(it) } - pluginList.forEach { preBuildScript.add(it) } - buildFileClasspath.forEach { preBuildScript.add(it) } + if (bs != null) { + preBuildScript.add(bs) + } else { + repos.forEach { preBuildScript.add(it) } + pluginList.forEach { preBuildScript.add(it) } + buildFileClasspath.forEach { preBuildScript.add(it) } + } } private fun initPluginUrls() {