diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/build/BuildSources.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/build/BuildSources.kt index c46d9022..65f173d3 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/build/BuildSources.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/build/BuildSources.kt @@ -1,8 +1,6 @@ package com.beust.kobalt.internal.build -import com.beust.kobalt.api.Kobalt import com.beust.kobalt.homeDir -import com.beust.kobalt.misc.kobaltLog import java.io.File import java.nio.file.* import java.nio.file.attribute.BasicFileAttributes @@ -19,30 +17,27 @@ class SingleFileBuildSources(val file: File) : IBuildSources { override val root: File = file.parentFile.parentFile } -class BuildSources(val file: File) : IBuildSources { +class BuildSources(val file: File = File("")) : IBuildSources { override val root = file override fun findSourceFiles() : List { - val result = arrayListOf("kobalt/src/Build.kt") - if (Kobalt.buildSourceDirs.isNotEmpty()) result.addAll(findBuildFiles(Kobalt.buildSourceDirs)) - - return result.map(::File) + return findBuildFiles(listOf(file)) } override fun exists() = findSourceFiles().isNotEmpty() override fun toString() = "{BuildSources " + findSourceFiles().joinToString(", ") + "}" - fun findBuildFiles(roots: List) : List { - val result = arrayListOf() + fun findBuildFiles(roots: List) : List { + val result = arrayListOf() roots.forEach { file -> - Files.walkFileTree(Paths.get(file), object : SimpleFileVisitor() { + Files.walkFileTree(Paths.get(file.path), object : SimpleFileVisitor() { override fun preVisitDirectory(dir: Path?, attrs: BasicFileAttributes?): FileVisitResult { if (dir != null) { val path = dir.toFile() if (path.name == "src" && path.parentFile.name == "kobalt") { - val sources = path.listFiles().filter { it.name.endsWith(".kt") }.map { it.path } + val sources = path.listFiles().filter { it.name.endsWith(".kt") } result.addAll(sources) } } 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 4e92ea2a..1ed97120 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 @@ -1,26 +1,29 @@ 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(Pattern.compile("val.*buildScript.*\\{"), '{', '}').extractBlock(lines) -// BlockExtractor("plugins", '(', ')').extractBlock(lines) -} - class Section(val start: Int, val end: Int) { override fun toString() = "$start-$end" } -class BuildScriptInfo(val content: String, val sections: List
) { +class IncludedBuildSourceDir(val line: Int, val dirs: List) + +class BuildScriptInfo(val file: File, val fullBuildFile: List, val sections: List
, + val imports: List) { fun isInSection(lineNumber: Int): Boolean { sections.forEach { if (lineNumber >= it.start && lineNumber <= it.end) return true } return false } + + val includedBuildSourceDirs = arrayListOf() + + fun includedBuildSourceDirsForLine(line: Int): List { + val result = includedBuildSourceDirs.find { it.line == line }?.dirs + return result ?: emptyList() + } } /** @@ -28,7 +31,7 @@ class BuildScriptInfo(val content: String, val sections: List
) { * e.g. buildScript { ... }. */ class BlockExtractor(val regexp: Pattern, val opening: Char, val closing: Char) { - fun extractBlock(lines: List): BuildScriptInfo? { + fun extractBlock(file: File, lines: List): BuildScriptInfo? { var currentLineNumber = 0 // First line of the buildScript block var startLine = 0 @@ -60,12 +63,9 @@ class BlockExtractor(val regexp: Pattern, val opening: Char, val closing: Char) if (currentLine.isNotEmpty() && foundKeyword) buildScript.add(currentLine.toString()) } - val allowedImports = listOf("com.beust", "java") - val disallowedImports = listOf("com.beust.kobalt.plugin") val imports = arrayListOf() val sections = arrayListOf
() lines.forEach { line -> - currentLineNumber++ val found = regexp.matcher(line).matches() if (found) { startLine = currentLineNumber @@ -75,7 +75,7 @@ class BlockExtractor(val regexp: Pattern, val opening: Char, val closing: Char) topLines.add(line) } else { if (line.startsWith("import")) { - if (allowedImports.any { line.contains(it) } && !disallowedImports.any { line.contains(it) }) { + if (isAllowedImport(line)) { imports.add(line) } } else { @@ -92,14 +92,25 @@ class BlockExtractor(val regexp: Pattern, val opening: Char, val closing: Char) startLine = 0 endLine = 0 } + + currentLineNumber++ } if (sections.isNotEmpty()) { val result = (imports.distinct() + buildScript).joinToString("\n") + "\n" - return BuildScriptInfo(result, sections) + return BuildScriptInfo(file, lines, sections, imports) } else { return null } } + + companion object { + private val allowedImports = listOf("com.beust", "java") + private val disallowedImports = listOf("com.beust.kobalt.plugin") + + fun isAllowedImport(line: String) : Boolean { + return allowedImports.any { line.contains(it) } && !disallowedImports.any { line.contains(it) } + } + } } diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/KFiles.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/KFiles.kt index 2fcdbed4..ab5b1f8e 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/KFiles.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/KFiles.kt @@ -3,7 +3,6 @@ package com.beust.kobalt.misc import com.beust.kobalt.* import com.beust.kobalt.api.Kobalt import com.beust.kobalt.api.Project -import com.beust.kobalt.internal.build.IBuildSources import com.beust.kobalt.maven.Md5 import java.io.* import java.nio.file.Files @@ -261,9 +260,9 @@ class KFiles { /** * The build location for build scripts is .kobalt/build */ - fun findBuildScriptLocation(buildSources: IBuildSources, jarFile: String) : String { - val result = joinDir(buildSources.root.path, KFiles.dotKobaltDir.path, KFiles.SCRIPT_BUILD_DIR, jarFile) - kobaltLog(2, " Script jar file: $result") + fun findBuildScriptDir(parent: String = ".") : File { + val result = File(joinDir(parent, KFiles.dotKobaltDir.path, KFiles.SCRIPT_BUILD_DIR)) + kobaltLog(2, " Script jar files in: $result") return result } diff --git a/src/main/kotlin/com/beust/kobalt/app/BuildFileCompiler.kt b/src/main/kotlin/com/beust/kobalt/app/BuildFileCompiler.kt index 4d53fac9..29d3fcbd 100644 --- a/src/main/kotlin/com/beust/kobalt/app/BuildFileCompiler.kt +++ b/src/main/kotlin/com/beust/kobalt/app/BuildFileCompiler.kt @@ -37,7 +37,7 @@ class BuildFileCompiler @Inject constructor(@Assisted("buildSources") val buildS val executors: KobaltExecutors, val buildScriptUtil: BuildScriptUtil, val settings: KobaltSettings, val incrementalManagerFactory: IncrementalManager.IFactory, val args: Args, val resolver: KobaltMavenResolver, val pomGeneratorFactory: PomGenerator.IFactory, - val parallelLogger: ParallelLogger) { + val parallelLogger: ParallelLogger, val buildFiles: BuildFiles) { interface IFactory { fun create(@Assisted("buildSources") buildSources: IBuildSources, pluginInfo: PluginInfo) : BuildFileCompiler @@ -76,22 +76,33 @@ class BuildFileCompiler @Inject constructor(@Assisted("buildSources") val buildS return projectResult } - val parsedBuildFiles = arrayListOf() + val parsedBuildFiles = arrayListOf<_ParsedBuildFile>() class FindProjectResult(val context: KobaltContext, val projects: List, val pluginUrls: List, val taskResult: TaskResult) +// private fun findProjects(context: KobaltContext): FindProjectResult { +// buildFiles.run(File(".").absolutePath, context) +// val pluginUrls = Plugins.dynamicPlugins.map { it.jarFile.get().toURI().toURL()} +// val projects = listOf() +// val result = FindProjectResult(context, projects, pluginUrls, TaskResult()) +// return result +// } + private fun findProjects(context: KobaltContext): FindProjectResult { + val root = buildSources.root var errorTaskResult: TaskResult? = null val projects = arrayListOf() run { // buildFiles.forEach { buildFile -> // Parse kobalt/src/Build.kt - val parsedBuildFile = parseBuildFile(context, buildSources) - parsedBuildFiles.add(parsedBuildFile) - val pluginUrls = parsedBuildFile.pluginUrls - val buildScriptJarFile = File(KFiles.findBuildScriptLocation(buildSources, SCRIPT_JAR)) +// val parsedBuildFile = parseBuildFile(context, buildSources) +// parsedBuildFiles.add(parsedBuildFile) +// val pluginUrls = parsedBuildFile.pluginUrls +// val buildScriptJarFile = File(KFiles.findBuildScriptLocation(buildSources, SCRIPT_JAR)) + + val newBuildKt = buildFiles.run(root.absolutePath, context) // // Save the current build script absolute directory @@ -100,32 +111,47 @@ class BuildFileCompiler @Inject constructor(@Assisted("buildSources") val buildS // If the script jar files were generated by a different version, wipe them in case the API // changed in-between - buildScriptJarFile.parentFile.let { dir -> + val buildScriptJarDir = KFiles.findBuildScriptDir(root.absolutePath) + buildScriptJarDir.let { dir -> if (! VersionFile.isSameVersionFile(dir)) { kobaltLog(1, "Detected new installation, wiping $dir") dir.listFiles().map(File::delete) } } + val buildScriptJarFile = File(KFiles.findBuildScriptDir(root.absolutePath), SCRIPT_JAR) + + // + // Compile the newly generated Build.kt file + // + val pluginUrls = Plugins.dynamicPlugins.map { it.jarFile.get().toURI().toURL() } + val containsProfiles = false + val taskResult = maybeCompileBuildFile(context, listOf(newBuildKt.absolutePath), + buildScriptJarFile, pluginUrls, context.internalContext.forceRecompile, + containsProfiles) + // // Now that Build.kt has been parsed, we might have additional build files (buildSources will // return additional build files) so we parse again. // - val newParsedBuildFile = parseBuildFile(context, buildSources) - - // Write the modified Build.kt (e.g. maybe profiles were applied) to a temporary file, - // compile it, jar it in buildScript.jar and run it - val modifiedBuildFile = KFiles.createTempBuildFileInTempDirectory(deleteOnExit = true) - KFiles.saveFile(modifiedBuildFile, newParsedBuildFile.nonBuildScriptCode) - val taskResult = maybeCompileBuildFile(context, listOf(modifiedBuildFile.path), - buildScriptJarFile, pluginUrls, context.internalContext.forceRecompile, - newParsedBuildFile.containsProfiles) - if (taskResult.success) { - projects.addAll(buildScriptUtil.runBuildScriptJarFile(buildScriptJarFile, pluginUrls, context)) - } else { - if (errorTaskResult == null) { - errorTaskResult = taskResult - } +// Kobalt.buildSourceDirs.forEach { dir -> +// val additionalSourceFiles = BuildSources(File(dir)) +// val newParsedBuildFile = parseBuildFile(context, additionalSourceFiles) +// +// // Write the modified Build.kt (e.g. maybe profiles were applied) to a temporary file, +// // compile it, jar it in buildScript.jar and run it +// val modifiedBuildFile = KFiles.createTempBuildFileInTempDirectory(deleteOnExit = true) +// KFiles.saveFile(modifiedBuildFile, newParsedBuildFile.nonBuildScriptCode) +// val taskResult = maybeCompileBuildFile(context, listOf(modifiedBuildFile.path), +// buildScriptJarFile, pluginUrls, context.internalContext.forceRecompile, +// newParsedBuildFile.containsProfiles) + if (taskResult.success) { + projects.addAll(buildScriptUtil.runBuildScriptJarFile(buildScriptJarFile, pluginUrls, context)) + } else { + if (errorTaskResult == null) { + errorTaskResult = taskResult + } +// } } // Clear the absolute dir @@ -142,7 +168,7 @@ class BuildFileCompiler @Inject constructor(@Assisted("buildSources") val buildS = maybeCompileBuildFile(context, buildSources.findSourceFiles().map { it.path }, buildScriptJarFile, pluginUrls, forceRecompile, containsProfiles) - private fun maybeCompileBuildFile(context: KobaltContext, sourceFiles: List, buildScriptJarFile: File, + fun maybeCompileBuildFile(context: KobaltContext, sourceFiles: List, buildScriptJarFile: File, pluginUrls: List, forceRecompile: Boolean, containsProfiles: Boolean) : TaskResult { kobaltLog(2, "Compiling into $buildScriptJarFile") @@ -188,6 +214,6 @@ class BuildFileCompiler @Inject constructor(@Assisted("buildSources") val buildS * - the source code for the modified Build.kt (after profiles are applied) * - the URL's of all the plug-ins that were found. */ - private fun parseBuildFile(context: KobaltContext, buildSources: IBuildSources) = - ParsedBuildFile(buildSources, context, buildScriptUtil, dependencyManager, files) +// private fun _parseBuildFile(context: KobaltContext, buildSources: IBuildSources) = +// _ParsedBuildFile(buildSources, context, buildScriptUtil, dependencyManager, files) } diff --git a/src/main/kotlin/com/beust/kobalt/app/BuildFiles.kt b/src/main/kotlin/com/beust/kobalt/app/BuildFiles.kt index bcadedd6..dcc3cf13 100644 --- a/src/main/kotlin/com/beust/kobalt/app/BuildFiles.kt +++ b/src/main/kotlin/com/beust/kobalt/app/BuildFiles.kt @@ -22,14 +22,13 @@ import java.util.regex.Pattern * save the location where they appear (file, start/end). * Compile each of these buildScriptInfo separately, note which new build files they add - * and at which location + * and at which location. * Go back over all the files from kobalt/src/ *kt, insert each new build file in it, - * save it as a modified, concatenated build file - - * Create buildScript.jar out of compiling all these modified build files -*/ + * save it as a modified, concatenated big build file in .kobalt/build/Built.kt. + * Create buildScript.jar out of compiling all these modified build files. + */ fun main(argv: Array) { val args = Args().apply { noIncrementalKotlin = true @@ -74,8 +73,11 @@ class BuildFiles @Inject constructor(val factory: BuildFileCompiler.IFactory, return result } - fun run(projectDir: String, context: KobaltContext) { - val sourceDirs = arrayListOf().apply { add(projectDir + KOBALT_SRC) } + /** + * @return the new Build.kt + */ + fun run(projectDir: String, context: KobaltContext) : File { + val sourceDirs = arrayListOf().apply { add(projectDir + File.separator + KOBALT_SRC) } val map = hashMapOf() val newSourceDirs = arrayListOf() sourceDirs.forEach { @@ -88,61 +90,80 @@ class BuildFiles @Inject constructor(val factory: BuildFileCompiler.IFactory, val bsi = af.buildScriptInfo newSourceDirs.addAll(bsi.includedBuildSourceDirs) } - println("FOUND buildScriptInfos: " + filesWithBuildScript) + log(2, " Found buildScriptInfos: " + filesWithBuildScript) } else { - println("No buildScriptInfos") + log(2, " No buildScriptInfos") } } // // Go through all the build files and insert the content of included directories wherever appropriate // - val bigFileContent = arrayListOf() + val imports = arrayListOf() + val code = arrayListOf() sourceDirs.forEach { sourceDir -> findFiles(File(sourceDir), { it.name.endsWith(".kt") }).forEach { file -> - println("Looking at " + file) - bigFileContent.add("// $file") + code.add("\n// $file") val analyzedFile = map[file] val bsi = analyzedFile?.buildScriptInfo file.readLines().forEachIndexed { lineNumber, line -> if (bsi == null || ! bsi.isInSection(lineNumber)) { - bigFileContent.add(correctProfileLine(context, line)) + correctProfileLine(context, line).let { cpl -> + (if (cpl.startsWith("import")) imports else code).add(cpl) + } } else { val isd = bsi.includedBuildSourceDirsForLine(lineNumber) - println("Skipping line $lineNumber from file $file") + log(2, " Skipping line $lineNumber from file $file") if (isd.any()) { + // If we found any new buildSourceDirs, all all the files found in these directories + // to the big Build.kt val allBuildFiles = isd.flatMap { findBuildSourceFiles(projectDir + File.separator + it) } - includeFileContent(context, allBuildFiles, bigFileContent) + val sbf = includeFileContent(context, allBuildFiles) + imports.addAll(sbf.imports) + code.addAll(sbf.code) } } } } } - val bigFile = File(homeDir("t/Build.kt")) - bigFile.writeText(bigFileContent.joinToString("\n")) - println("New included source dirs: " + newSourceDirs) + // + // Create the big Build.kt out of the imports and code we've found so far + // + val result = File(KFiles.findBuildScriptDir(), "Build.kt") + result.writeText(imports.joinToString("\n")) + result.appendText(code.joinToString("\n")) + + return result } - private fun includeFileContent(context: KobaltContext, files: List, out: ArrayList) { + class SplitBuildFile(val imports: List, val code: List) + + private fun includeFileContent(context: KobaltContext, files: List) : SplitBuildFile { + val imports = arrayListOf() + val code = arrayListOf() + files.forEach { - out.add("// $it") - out.addAll(applyProfiles(context, it.readLines())) + code.add("// $it") + val sbf = applyProfiles(context, it.readLines()) + imports.addAll(sbf.imports) + code.addAll(sbf.code) } + return SplitBuildFile(imports, code) } fun parseBuildScriptInfos(projectDir: String, context: KobaltContext) : List { - val root = File(projectDir + KOBALT_SRC) + val root = File(projectDir + File.separator + KOBALT_SRC) val files = findBuildSourceFiles(projectDir) val toProcess = arrayListOf().apply { addAll(files) } // Parse each build file, associated it with a BuildScriptInfo if any found val analyzedFiles = arrayListOf() toProcess.forEach { buildFile -> - val lines = applyProfiles(context, buildFile.readLines()) + val splitBuildFile = applyProfiles(context, buildFile.readLines()) val bsi = BlockExtractor(Pattern.compile("^val.*buildScript.*\\{"), '{', '}') - .extractBlock(buildFile, lines) + .extractBlock(buildFile, (splitBuildFile.imports + splitBuildFile.code)) if (bsi != null) analyzedFiles.add(AnalyzedBuildFile(buildFile, bsi)) } @@ -159,21 +180,23 @@ class BuildFiles @Inject constructor(val factory: BuildFileCompiler.IFactory, val sourceFile = File(homeDir("t", "bf", "a.kt")).apply { writeText(source) } - val buildScriptJarFile = File(homeDir("t", "preBuildScript-$counter.jar")).apply { + + val buildScriptJarFile = File(KFiles.findBuildScriptDir(projectDir), "preBuildScript-$counter.jar").apply { delete() } + counter++ // // Compile it to preBuildScript-xxx.jar // - kobaltLog(1, "Compiling $sourceFile to $buildScriptJarFile") + kobaltLog(2, " Compiling buildScriptInfo $sourceFile to $buildScriptJarFile") val taskResult = factory.create(BuildSources(root), context.pluginInfo).maybeCompileBuildFile(context, listOf(sourceFile.path), buildScriptJarFile, emptyList(), context.internalContext.forceRecompile, containsProfiles) - println("Created $buildScriptJarFile") + log(2, "Created $buildScriptJarFile") // // Run preBuildScript.jar to initialize plugins and repos @@ -184,7 +207,6 @@ class BuildFiles @Inject constructor(val factory: BuildFileCompiler.IFactory, newDirs.removeAll(currentDirs) if (newDirs.any()) { af.buildScriptInfo.includedBuildSourceDirs.add(IncludedBuildSourceDir(section.start, newDirs)) - println("*** ADDED DIRECTORIES " + newDirs) } } @@ -193,13 +215,16 @@ class BuildFiles @Inject constructor(val factory: BuildFileCompiler.IFactory, return analyzedFiles } - private fun applyProfiles(context: KobaltContext, lines: List): List { - val result = arrayListOf() + private fun applyProfiles(context: KobaltContext, lines: List): SplitBuildFile { + val imports = arrayListOf() + val code = arrayListOf() lines.forEach { line -> - result.add(correctProfileLine(context, line)) - + val isImport = line.startsWith("import") + val correctLine = correctProfileLine(context, line) + if (isImport) imports.add(correctLine) + else code.add(correctLine) } - return result + return SplitBuildFile(imports, code) } /** diff --git a/src/main/kotlin/com/beust/kobalt/app/ParsedBuildFile.kt b/src/main/kotlin/com/beust/kobalt/app/ParsedBuildFile.kt index a67967bf..19ae4012 100644 --- a/src/main/kotlin/com/beust/kobalt/app/ParsedBuildFile.kt +++ b/src/main/kotlin/com/beust/kobalt/app/ParsedBuildFile.kt @@ -1,28 +1,23 @@ package com.beust.kobalt.app -import com.beust.kobalt.KobaltException -import com.beust.kobalt.Plugins -import com.beust.kobalt.api.Kobalt import com.beust.kobalt.api.KobaltContext import com.beust.kobalt.api.Project -import com.beust.kobalt.internal.build.BuildFile import com.beust.kobalt.internal.build.IBuildSources -import com.beust.kobalt.internal.build.VersionFile import com.beust.kobalt.maven.DependencyManager -import com.beust.kobalt.misc.* -import com.beust.kobalt.plugin.kotlin.kotlinCompilePrivate -import java.io.File +import com.beust.kobalt.misc.BuildScriptInfo +import com.beust.kobalt.misc.KFiles +import com.beust.kobalt.misc.kobaltLog +import com.beust.kobalt.misc.warn +import com.google.inject.Singleton import java.net.URL -import java.nio.charset.Charset -import java.util.regex.Pattern -class ParsedBuildFile(val buildSources: IBuildSources, val context: KobaltContext, val buildScriptUtil: BuildScriptUtil, +@Singleton +class _ParsedBuildFile(val buildSources: IBuildSources, val context: KobaltContext, val buildScriptUtil: +BuildScriptUtil, val dependencyManager: DependencyManager, val files: KFiles) { private val profileLines = arrayListOf() private val projects = arrayListOf() private val activeProfiles = arrayListOf() - private val preBuildScriptJar = KFiles.findBuildScriptLocation(buildSources, "preBuildScript.jar") - private val preBuildScriptJarFile = File(preBuildScriptJar) private val nonBuildScript = arrayListOf() var containsProfiles = false @@ -30,7 +25,7 @@ class ParsedBuildFile(val buildSources: IBuildSources, val context: KobaltContex /** * Contains the addition of all the build files corrected with the active profiles and with - * the buildScripts{} sections removed. + * the buildScript{} sections removed. */ val nonBuildScriptCode : String get() = nonBuildScript.joinToString("\n") @@ -38,153 +33,182 @@ class ParsedBuildFile(val buildSources: IBuildSources, val context: KobaltContex // Because profiles may have changed between two builds, we have to delete preBuildScript.jar file // every time and then generate a new one (or skip that phase if no buildScript{} was found in the // buid files) - preBuildScriptJarFile.delete() +// preBuildScriptJarFile.delete() - val buildScriptInfo = parseBuildFile() +// val buildScriptInfos = parseBuildFile() // Only generate preBuildScript.jar if we found at least one buildScript{} - if (buildScriptInfo != null) { - parseBuildScriptInfo(buildScriptInfo) - } +// if (buildScriptInfos.isNotEmpty()) { +// parseBuildScriptInfo(buildScriptInfos) +// } + +// generateFinalBuildFile(buildScriptInfos) } - private fun parseBuildFile() : BuildScriptInfo? { - /** - * 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 { profile -> - val re = Regex(".*va[rl][ \\t]+([a-zA-Z0-9_]+)[ \\t]*.*profile\\(\\).*") - val oldRe = Regex(".*va[rl][ \\t]+([a-zA-Z0-9_]+)[ \\t]*=[ \\t]*[tf][ra][ul][es].*") - val matcher = re.matchEntire(line) - val oldMatcher = oldRe.matchEntire(line) +// private fun generateFinalBuildFile(buildScriptInfos: List) { +// // +// // Write the build file to `nonBuildScript` excluding the buildScript{} directives since we already ran them +// // +// var lineNumber = 1 +// buildSources.findSourceFiles().forEach { buildFile -> +// val buildScriptInfo = buildScriptInfos.find { it.file == buildFile } +// if (buildFile == buildScriptInfo?.file) { +// println("Found file with buildScript in it: " + buildFile) +// } +// buildFile.forEachLine() { line -> +// if (buildScriptInfo == null || ! buildScriptInfo.isInSection(lineNumber)) { +// val cpl = correctProfileLine(line) +// if (cpl.startsWith("import")) nonBuildScript.add(0, cpl) +// else nonBuildScript.add(cpl) +// } +// lineNumber++ +// } +// } +// } - fun profileMatch(matcher: MatchResult?) : Pair { - val variable = if (matcher != null) matcher.groups[1]?.value else null - return Pair(profile == variable, variable) - } + /** + * 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 { profile -> + val re = Regex(".*va[rl][ \\t]+([a-zA-Z0-9_]+)[ \\t]*.*profile\\(\\).*") + val oldRe = Regex(".*va[rl][ \\t]+([a-zA-Z0-9_]+)[ \\t]*=[ \\t]*[tf][ra][ul][es].*") + val matcher = re.matchEntire(line) + val oldMatcher = oldRe.matchEntire(line) - if ((matcher != null && matcher.groups.isNotEmpty()) - || (oldMatcher != null && oldMatcher.groups.isNotEmpty())) { - containsProfiles = true - val match = profileMatch(matcher) - val oldMatch = profileMatch(oldMatcher) - if (match.first || oldMatch.first) { - val variable = if (match.first) match.second else oldMatch.second + fun profileMatch(matcher: MatchResult?) : Pair { + val variable = if (matcher != null) matcher.groups[1]?.value else null + return Pair(profile == variable, variable) + } - if (oldMatch.first) { - warn("Old profile syntax detected for \"$line\"," + - " please update to \"val $variable by profile()\"") - } + if ((matcher != null && matcher.groups.isNotEmpty()) + || (oldMatcher != null && oldMatcher.groups.isNotEmpty())) { + containsProfiles = true + val match = profileMatch(matcher) + val oldMatch = profileMatch(oldMatcher) + if (match.first || oldMatch.first) { + val variable = if (match.first) match.second else oldMatch.second - with("val $variable = true") { - kobaltLog(2, "Activating profile $profile in build file") - activeProfiles.add(profile) - profileLines.add(this) - return this - } + if (oldMatch.first) { + warn("Old profile syntax detected for \"$line\"," + + " please update to \"val $variable by profile()\"") + } + + with("val $variable = true") { + kobaltLog(2, "Activating profile $profile in build file") + activeProfiles.add(profile) + profileLines.add(this) + return this } } } - return line } - - fun applyProfiles(lines: List): List { - val result = arrayListOf() - lines.forEach { line -> - result.add(correctProfileLine(line)) - } - return result - } - - // - // Take all the build files and adjust them with the active profiles - // - val buildWithCorrectProfiles = arrayListOf() - buildSources.findSourceFiles().forEach { - buildWithCorrectProfiles.addAll(applyProfiles(it.readLines())) - } - - // - // Now extract all the `buildScript{}` blocks from all these build files - // - val buildScriptInfo = BlockExtractor(Pattern.compile("^val.*buildScript.*\\{"), '{', '}') - .extractBlock(buildWithCorrectProfiles) - - // - // Write the build file to `nonBuildScript` excluding the buildScript{} directives since we already ran them - // - var lineNumber = 1 - buildSources.findSourceFiles().forEach { buildFile -> - buildFile.forEachLine() { line -> - if (buildScriptInfo == null || ! buildScriptInfo.isInSection(lineNumber)) { - val cpl = correctProfileLine(line) - if (cpl.startsWith("import")) nonBuildScript.add(0, cpl) - else nonBuildScript.add(cpl) - } - lineNumber++ - } - } - - return buildScriptInfo + return line } +// private fun parseBuildFile() : List { +// fun applyProfiles(lines: List): List { +// val result = arrayListOf() +// lines.forEach { line -> +// result.add(correctProfileLine(line)) +// +// } +// return result +// } +// +// // +// // Take all the build files and adjust them with the active profiles +// // +// val buildScriptInfos = arrayListOf() +// val buildWithCorrectProfiles = arrayListOf() +// val buildFiles = buildSources.findSourceFiles() +// buildFiles.forEach { +// buildWithCorrectProfiles.addAll(applyProfiles(it.readLines())) +// +// // +// // Now extract all the `buildScript{}` blocks from all these build files +// // +// val lsi = BlockExtractor(Pattern.compile("^val.*buildScript.*\\{"), '{', '}') +// .extractBlock(it, buildWithCorrectProfiles) +// if (lsi != null) buildScriptInfos.add(lsi) +// } +// +// return buildScriptInfos +// } + /** * Generate preBuildScript.jar based on the buildScript{} found in the build files. */ - private fun parseBuildScriptInfo(buildScriptInfo: BuildScriptInfo) { - // - // Compile and run preBuildScriptCode, which contains all the plugins() calls extracted. This - // will add all the dynamic plugins found in this code to Plugins.dynamicPlugins - // - val buildScriptSourceFile = KFiles.createTempBuildFileInTempDirectory(deleteOnExit = true) - buildScriptSourceFile.writeText(buildScriptInfo.content, Charset.defaultCharset()) - kobaltLog(2, "Saved " + KFiles.fixSlashes(buildScriptSourceFile.absolutePath)) +// private fun parseBuildScriptInfo(buildScriptInfos: List) { +// buildScriptInfos.forEach { buildScriptInfo -> +// buildScriptInfo.sections.forEach { section -> +// val buildScriptSection = (buildScriptInfo.imports + +// buildScriptInfo.fullBuildFile.subList(section.start - 1, section.end)) +// .joinToString("\n") +// println("=== Compiling\n" + buildScriptSection + " for line " + (section.start - 1)) +// +// // +// // Compile and run preBuildScriptCode, which contains all the plugins() calls extracted. This +// // will add all the dynamic plugins found in this code to Plugins.dynamicPlugins +// // +// val buildScriptSourceFile = KFiles.createTempBuildFileInTempDirectory(deleteOnExit = true) +// buildScriptSourceFile.writeText(buildScriptSection, Charset.defaultCharset()) +// kobaltLog(2, "Saved " + KFiles.fixSlashes(buildScriptSourceFile.absolutePath)) +// +// // +// // Compile to preBuildScript.jar +// // +// +// val dir = preBuildScriptJarFile.parentFile +// dir.mkdirs() +// val bsJar = java.io.File(dir, "buildScript-" + section.start + ".jar") +// generateJarFile(context, listOf(buildScriptSourceFile.path), bsJar) +// VersionFile.generateVersionFile(preBuildScriptJarFile.parentFile) +// Kobalt.context!!.internalContext.buildFileOutOfDate = true +// +// // +// // Run preBuildScript.jar to initialize plugins and repos +// // +// val currentDirs = arrayListOf().apply { addAll(Kobalt.buildSourceDirs) } +// projects.addAll(buildScriptUtil.runBuildScriptJarFile(bsJar, arrayListOf(), context)) +// val newDirs = arrayListOf().apply { addAll(Kobalt.buildSourceDirs) } +// newDirs.removeAll(currentDirs) +// buildScriptInfo.includedBuildSourceDirs.add(IncludedBuildSourceDir(section.start - 1, newDirs)) +// println("*** ADDED DIRECTORIES " + newDirs) +// } +// } +// +// // +// // All the plug-ins are now in Plugins.dynamicPlugins, download them if they're not already +// // +// Plugins.dynamicPlugins.forEach { +// pluginUrls.add(it.jarFile.get().toURI().toURL()) +// } +// } - // - // Compile to preBuildScript.jar - // - preBuildScriptJarFile.parentFile.mkdirs() - generateJarFile(context, listOf(buildScriptSourceFile.path), preBuildScriptJarFile) - VersionFile.generateVersionFile(preBuildScriptJarFile.parentFile) - Kobalt.context!!.internalContext.buildFileOutOfDate = true - - // - // Run preBuildScript.jar to initialize plugins and repos - // - projects.addAll(buildScriptUtil.runBuildScriptJarFile(preBuildScriptJarFile, arrayListOf(), context)) - - // - // All the plug-ins are now in Plugins.dynamicPlugins, download them if they're not already - // - Plugins.dynamicPlugins.forEach { - pluginUrls.add(it.jarFile.get().toURI().toURL()) - } - } - - private fun generateJarFile(context: KobaltContext, sourceFiles: List, - buildScriptJarFile: File, originalFile: BuildFile? = null) { - // - // Compile the jar file - // - val kotlinDeps = dependencyManager.calculateDependencies(null, context) - val deps: List = kotlinDeps.map { it.jarFile.get().absolutePath } - val outputJar = File(buildScriptJarFile.absolutePath) - val saved = context.internalContext.noIncrementalKotlin - val result = kotlinCompilePrivate { - classpath(files.kobaltJar) - classpath(deps) - sourceFiles(sourceFiles) - output = outputJar - noIncrementalKotlin = true - }.compile(context = context) - if (! result.success) { - val org = originalFile?.realPath ?: sourceFiles.joinToString(",") - throw KobaltException("Couldn't compile $org:\n" + result.errorMessage) - } - - context.internalContext.noIncrementalKotlin = saved - } +// private fun generateJarFile(context: KobaltContext, sourceFiles: List, +// buildScriptJarFile: File, originalFile: BuildFile? = null) { +// // +// // Compile the jar file +// // +// val kotlinDeps = dependencyManager.calculateDependencies(null, context) +// val deps: List = kotlinDeps.map { it.jarFile.get().absolutePath } +// val outputJar = File(buildScriptJarFile.absolutePath) +// val saved = context.internalContext.noIncrementalKotlin +// val result = kotlinCompilePrivate { +// classpath(files.kobaltJar) +// classpath(deps) +// sourceFiles(sourceFiles) +// output = outputJar +// noIncrementalKotlin = true +// }.compile(context = context) +// if (! result.success) { +// val org = originalFile?.realPath ?: sourceFiles.joinToString(",") +// throw KobaltException("Couldn't compile $org:\n" + result.errorMessage) +// } +// +// context.internalContext.noIncrementalKotlin = saved +// } }