diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/Directives.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/Directives.kt index f665f5d2..93d9434c 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/Directives.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/Directives.kt @@ -4,6 +4,8 @@ import com.beust.kobalt.api.Kobalt import com.beust.kobalt.api.Project import com.beust.kobalt.api.annotation.Directive import com.beust.kobalt.internal.JvmCompilerPlugin +import kotlin.properties.ReadWriteProperty +import kotlin.reflect.KProperty @Directive fun project(vararg projects: Project, init: Project.() -> Unit): Project { @@ -19,4 +21,19 @@ fun buildScript(init: BuildScriptConfig.() -> Unit): BuildScriptConfig { val buildScriptConfig = BuildScriptConfig().apply { init() } BUILD_SCRIPT_CONFIG = buildScriptConfig return buildScriptConfig -} \ No newline at end of file +} + +@Directive +fun profile(): ReadWriteProperty { + val result = object: ReadWriteProperty { + var value: Boolean = false + override operator fun getValue(thisRef: Nothing?, property: KProperty<*>): Boolean { + return value + } + + override operator fun setValue(thisRef: Nothing?, property: KProperty<*>, value: Boolean) { + this.value = value + } + } + return result +} 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 7e30198f..c2bdc557 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 @@ -56,7 +56,7 @@ class BlockExtractor(val regexp: Pattern, val opening: Char, val closing: Char) startLine = currentLineNumber foundKeyword = true count = 1 - result.append(topLines.joinToString("\n")) + result.append(topLines.joinToString("\n")).append("\n") result.append(line).append("\n") } else { val allowedImports = listOf("com.beust", "java") diff --git a/src/main/kotlin/com/beust/kobalt/app/BuildFileCompiler.kt b/src/main/kotlin/com/beust/kobalt/app/BuildFileCompiler.kt index 730cb304..68cabd40 100644 --- a/src/main/kotlin/com/beust/kobalt/app/BuildFileCompiler.kt +++ b/src/main/kotlin/com/beust/kobalt/app/BuildFileCompiler.kt @@ -111,7 +111,8 @@ class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val buildFil KFiles.saveFile(modifiedBuildFile, parsedBuildFile.buildScriptCode) val taskResult = maybeCompileBuildFile(context, BuildFile(Paths.get(modifiedBuildFile.path), "Modified ${Constants.BUILD_FILE_NAME}", buildFile.realPath), - buildScriptJarFile, pluginUrls, context.internalContext.forceRecompile) + buildScriptJarFile, pluginUrls, context.internalContext.forceRecompile, + parsedBuildFile.containsProfiles) if (taskResult.success) { projects.addAll(buildScriptUtil.runBuildScriptJarFile(buildScriptJarFile, pluginUrls, context)) } else { @@ -130,7 +131,7 @@ class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val buildFil } private fun maybeCompileBuildFile(context: KobaltContext, buildFile: BuildFile, buildScriptJarFile: File, - pluginUrls: List, forceRecompile: Boolean) : TaskResult { + pluginUrls: List, forceRecompile: Boolean, containsProfiles: Boolean) : TaskResult { kobaltLog(2, "Running build file ${buildFile.name} jar: $buildScriptJarFile") // If the user specifed --profiles, always recompile the build file since we don't know if @@ -140,12 +141,15 @@ class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val buildFil // to have a side file that describes which profiles the current buildScript.jar was // compiled with. val bs = BuildScriptJarFile(buildScriptJarFile) - val same = bs.sameProfiles(args.profiles) - if (same && ! forceRecompile && buildScriptUtil.isUpToDate(buildFile, buildScriptJarFile)) { + if (! containsProfiles && !forceRecompile && buildScriptUtil.isUpToDate(buildFile, buildScriptJarFile)) { kobaltLog(2, " Build file $buildScriptJarFile is up to date") return TaskResult() } else { - kobaltLog(2, " Need to recompile ${buildFile.name}") + val reason = + if (containsProfiles) "it contains profiles" + else if (forceRecompile) "forceRecompile is true" + else "it is not up to date" + kobaltLog(2, " Need to recompile ${buildFile.name} because $reason") buildScriptJarFile.deleteRecursively() val buildFileClasspath = Kobalt.buildFileClasspath.map { it.jarFile.get() }.map { it.absolutePath } diff --git a/src/main/kotlin/com/beust/kobalt/app/BuildScriptJarFile.kt b/src/main/kotlin/com/beust/kobalt/app/BuildScriptJarFile.kt index 49610569..c34ce817 100644 --- a/src/main/kotlin/com/beust/kobalt/app/BuildScriptJarFile.kt +++ b/src/main/kotlin/com/beust/kobalt/app/BuildScriptJarFile.kt @@ -22,25 +22,5 @@ class BuildScriptJarFile(val jarFile: File) { file.delete() } } - - /** - * @{profiles} is a comma-separated list of profiles, or null - */ - fun sameProfiles(profiles: String?) : Boolean { - if (! file.exists()) { - return profiles == null - } else { - val fileContent = file.readText().trim() - if (fileContent.isEmpty() && profiles == null) { - return true - } else if (profiles != null) { - val savedProfiles = fileContent.split(" ").sorted() - val expected = profiles.split(",").sorted() - return savedProfiles == expected - } else { - return fileContent.isEmpty() - } - } - } } diff --git a/src/main/kotlin/com/beust/kobalt/app/ParsedBuildFile.kt b/src/main/kotlin/com/beust/kobalt/app/ParsedBuildFile.kt index cf9afc94..05f805ef 100644 --- a/src/main/kotlin/com/beust/kobalt/app/ParsedBuildFile.kt +++ b/src/main/kotlin/com/beust/kobalt/app/ParsedBuildFile.kt @@ -8,7 +8,6 @@ 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.maven.aether.Filters.EXCLUDE_OPTIONAL_FILTER import com.beust.kobalt.misc.BlockExtractor import com.beust.kobalt.misc.KFiles import com.beust.kobalt.misc.kobaltLog @@ -29,6 +28,8 @@ class ParsedBuildFile(val buildFile: BuildFile, val context: KobaltContext, val val projects = arrayListOf() val activeProfiles = arrayListOf() + var containsProfiles = false + private val preBuildScript = arrayListOf( "import com.beust.kobalt.*", "import com.beust.kobalt.api.*") @@ -48,13 +49,19 @@ class ParsedBuildFile(val buildFile: BuildFile, val context: KobaltContext, val * 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 + (context.profiles as List).forEach { profile -> + val re = Regex(".*va[rl][ \\t]+([a-zA-Z0-9_]+)[ \\t]*.*profile\\(\\).*") + val matcher = re.matchEntire(line) + if (matcher != null && matcher.groups.size > 0) { + containsProfiles = true + val variable = matcher.groups[1]?.value + if (profile == variable) { + with("val $variable = true") { + kobaltLog(2, "Activating profile $profile in build file") + activeProfiles.add(profile) + profileLines.add(this) + return this + } } } } @@ -102,20 +109,23 @@ class ParsedBuildFile(val buildFile: BuildFile, val context: KobaltContext, val // val pluginSourceFile = KFiles.createTempBuildFileInTempDirectory(deleteOnExit = true) pluginSourceFile.writeText(preBuildScriptCode, Charset.defaultCharset()) - kobaltLog(2, "Saved ${pluginSourceFile.absolutePath}") + kobaltLog(2, "Saved " + KFiles.fixSlashes(pluginSourceFile.absolutePath)) // // Compile to preBuildScript.jar // val buildScriptJar = KFiles.findBuildScriptLocation(buildFile, "preBuildScript.jar") val buildScriptJarFile = File(buildScriptJar) - if (! buildScriptUtil.isUpToDate(buildFile, File(buildScriptJar))) { + + // Because of profiles, it's not possible to find out if a preBuildScript.jar is up to date + // or not so recompile it every time. +// if (! buildScriptUtil.isUpToDate(buildFile, File(buildScriptJar))) { buildScriptJarFile.parentFile.mkdirs() generateJarFile(context, BuildFile(Paths.get(pluginSourceFile.path), "Plugins", Paths.get(buildScriptJar)), buildScriptJarFile, buildFile) VersionFile.generateVersionFile(buildScriptJarFile.parentFile) Kobalt.context!!.internalContext.buildFileOutOfDate = true - } +// } // // Run preBuildScript.jar to initialize plugins and repos diff --git a/src/test/kotlin/com/beust/kobalt/internal/ProfileTest.kt b/src/test/kotlin/com/beust/kobalt/internal/ProfileTest.kt index 960e5965..19e4f052 100644 --- a/src/test/kotlin/com/beust/kobalt/internal/ProfileTest.kt +++ b/src/test/kotlin/com/beust/kobalt/internal/ProfileTest.kt @@ -24,7 +24,7 @@ class ProfileTest @Inject constructor(compilerFactory: BuildFileCompiler.IFactor return """ import com.beust.kobalt.* import com.beust.kobalt.api.* - val profile = false + val profile by profile() val $projectVal = project { name = if (profile) "profileOn" else "profileOff" directory = "$projectDirectory"