From bdd80bdedd020cb157c412f98a64d402890fe555 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 7 Mar 2017 13:53:45 -0800 Subject: [PATCH] =?UTF-8?q?Don=E2=80=99t=20run=20buildScript{}=20twice.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/beust/kobalt/misc/BlockExtractor.kt | 16 ++++- .../com/beust/kobalt/app/ParsedBuildFile.kt | 64 ++++++------------- 2 files changed, 31 insertions(+), 49 deletions(-) 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 4a5c56ab..bc1f41cc 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 @@ -11,12 +11,19 @@ fun main(argv: Array) { // BlockExtractor("plugins", '(', ')').extractBlock(lines) } +class BuildScriptInfo(val content: String, val startLine: Int, val endLine: Int) + /** * 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? { + fun extractBlock(lines: List): BuildScriptInfo? { + var currentLineNumber = 0 + // First line of the buildScript block + var startLine = 0 + // Last line of the buildScript block + var endLine = 0 var foundKeyword = false var foundClosing = false var count = 0 @@ -34,6 +41,7 @@ class BlockExtractor(val regexp: Pattern, val opening: Char, val closing: Char) if (count == 0) { currentLine.append(closing).append("\n") foundClosing = true + endLine = currentLineNumber } } if (foundKeyword && count > 0) currentLine.append(c) @@ -43,8 +51,10 @@ class BlockExtractor(val regexp: Pattern, val opening: Char, val closing: Char) } lines.forEach { line -> + currentLineNumber++ val found = regexp.matcher(line).matches() if (found) { + startLine = currentLineNumber foundKeyword = true count = 1 result.append(topLines.joinToString("\n")) @@ -55,12 +65,12 @@ class BlockExtractor(val regexp: Pattern, val opening: Char, val closing: Char) } if (foundKeyword && foundClosing && count == 0) { - return result.toString() + return BuildScriptInfo(result.toString(), startLine, endLine) } } if (foundKeyword && foundClosing && count == 0) { - return result.toString() + return BuildScriptInfo(result.toString(), startLine, endLine) } 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 f7064e02..50ea72b0 100644 --- a/src/main/kotlin/com/beust/kobalt/app/ParsedBuildFile.kt +++ b/src/main/kotlin/com/beust/kobalt/app/ParsedBuildFile.kt @@ -10,14 +10,12 @@ 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 import com.beust.kobalt.plugin.kotlin.kotlinCompilePrivate import java.io.File 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, @@ -44,14 +42,11 @@ 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 { + fun correctProfileLine(line: String): String { (context.profiles as List).forEach { if (line.matches(Regex("[ \\t]*val[ \\t]+$it[ \\t]*=.*"))) { with("val $it = true") { @@ -65,7 +60,7 @@ class ParsedBuildFile(val buildFile: BuildFile, val context: KobaltContext, val return line } - fun applyProfiles(lines: List) : List { + fun applyProfiles(lines: List): List { val result = arrayListOf() lines.forEach { line -> result.add(correctProfileLine(line)) @@ -74,51 +69,28 @@ class ParsedBuildFile(val buildFile: BuildFile, val context: KobaltContext, val } val buildWithCorrectProfiles = applyProfiles(buildFile.path.toFile().readLines()) - val bs = BlockExtractor(Pattern.compile("^val.*buildScript.*\\{"), '{', '}').extractBlock(buildWithCorrectProfiles) + val buildScriptInfo = BlockExtractor(Pattern.compile("^val.*buildScript.*\\{"), '{', '}') + .extractBlock(buildWithCorrectProfiles) - buildFile.path.toFile().forEachLine(Charset.defaultCharset()) { line -> - var index = line.indexOf("plugins(") - if (current == null) { - if (index >= 0) { - current = pluginList - } else { - index = line.indexOf("repos(") - if (index >= 0) { - current = repos - } else { - index = line.indexOf("buildFileClasspath(") - if (index >= 0) { - current = buildFileClasspath - } - } - } - } - - if (parenCount > 0 || current != null) { - if (index == -1) index = 0 - with(line.substring(index)) { - parenCount += line countChar '(' - if (parenCount > 0) { - current!!.add(line) - } - parenCount -= line countChar ')' - } - } - - if (parenCount == 0) { - current = null - } - - buildScript.add(correctProfileLine(line)) - } - - if (bs != null) { - preBuildScript.add(bs) + if (buildScriptInfo != null) { + preBuildScript.add(buildScriptInfo.content) } else { repos.forEach { preBuildScript.add(it) } pluginList.forEach { preBuildScript.add(it) } buildFileClasspath.forEach { preBuildScript.add(it) } } + + // + // Write the build file excluding the buildScript{} tag since we already ran it + // + var lineNumber = 1 + buildFile.path.toFile().forEachLine { line -> + if (buildScriptInfo == null || + (lineNumber < buildScriptInfo.startLine || lineNumber > buildScriptInfo.endLine)) { + buildScript.add(correctProfileLine(line)) + } + lineNumber++ + } } private fun initPluginUrls() {