mirror of
https://github.com/ethauvin/kobalt.git
synced 2025-04-26 08:27:12 -07:00
Preliminary work for multiple build files.
This commit is contained in:
parent
2478040bff
commit
ccbfe3bd94
15 changed files with 137 additions and 254 deletions
|
@ -1,10 +1,8 @@
|
||||||
package com.beust.kobalt.internal.build
|
package com.beust.kobalt.internal.build
|
||||||
|
|
||||||
import com.beust.kobalt.misc.KFiles
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.attribute.BasicFileAttributes
|
|
||||||
/**
|
/**
|
||||||
* Sometimes, build files are moved to temporary files, so we give them a specific name for clarity.
|
* Sometimes, build files are moved to temporary files, so we give them a specific name for clarity.
|
||||||
* @param path is the path where that file was moved, @param realPath is where the actual file is.
|
* @param path is the path where that file was moved, @param realPath is where the actual file is.
|
||||||
|
@ -12,23 +10,5 @@ import java.nio.file.attribute.BasicFileAttributes
|
||||||
class BuildFile(val path: Path, val name: String, val realPath: Path = path) {
|
class BuildFile(val path: Path, val name: String, val realPath: Path = path) {
|
||||||
fun exists() : Boolean = Files.exists(path)
|
fun exists() : Boolean = Files.exists(path)
|
||||||
|
|
||||||
val lastModified : Long
|
|
||||||
get() = Files.readAttributes(realPath, BasicFileAttributes::class.java).lastModifiedTime().toMillis()
|
|
||||||
|
|
||||||
val directory : File get() = path.toFile().parentFile
|
val directory : File get() = path.toFile().parentFile
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the .kobalt directory where this build file will be compiled.
|
|
||||||
*/
|
|
||||||
val dotKobaltDir: File get() = File(directory.parentFile.parentFile, KFiles.KOBALT_DOT_DIR).apply {
|
|
||||||
mkdirs()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the absolute directory of this project's location, assuming the build file is in
|
|
||||||
* $project/kobalt/src/Build.kt.
|
|
||||||
*/
|
|
||||||
val absoluteDir : File? get() {
|
|
||||||
return path.parent?.parent?.parent?.toFile()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,18 @@ fun main(argv: Array<String>) {
|
||||||
// BlockExtractor("plugins", '(', ')').extractBlock(lines)
|
// BlockExtractor("plugins", '(', ')').extractBlock(lines)
|
||||||
}
|
}
|
||||||
|
|
||||||
class BuildScriptInfo(val content: String, val startLine: Int, val endLine: Int)
|
class Section(val start: Int, val end: Int) {
|
||||||
|
override fun toString() = "$start-$end"
|
||||||
|
}
|
||||||
|
|
||||||
|
class BuildScriptInfo(val content: String, val sections: List<Section>) {
|
||||||
|
fun isInSection(lineNumber: Int): Boolean {
|
||||||
|
sections.forEach {
|
||||||
|
if (lineNumber >= it.start && lineNumber <= it.end) return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to extract a keyword followed by opening and closing tags out of a list of strings,
|
* Used to extract a keyword followed by opening and closing tags out of a list of strings,
|
||||||
|
@ -26,7 +37,7 @@ class BlockExtractor(val regexp: Pattern, val opening: Char, val closing: Char)
|
||||||
var foundKeyword = false
|
var foundKeyword = false
|
||||||
var foundClosing = false
|
var foundClosing = false
|
||||||
var count = 0
|
var count = 0
|
||||||
val result = StringBuffer()
|
val buildScript = arrayListOf<String>()
|
||||||
val topLines = arrayListOf<String>()
|
val topLines = arrayListOf<String>()
|
||||||
|
|
||||||
fun updateCount(line: String) {
|
fun updateCount(line: String) {
|
||||||
|
@ -46,9 +57,13 @@ class BlockExtractor(val regexp: Pattern, val opening: Char, val closing: Char)
|
||||||
if (foundKeyword && count > 0) currentLine.append(c)
|
if (foundKeyword && count > 0) currentLine.append(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentLine.isNotEmpty()) result.append(currentLine.toString()).append("\n")
|
if (currentLine.isNotEmpty() && foundKeyword) buildScript.add(currentLine.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val allowedImports = listOf("com.beust", "java")
|
||||||
|
val disallowedImports = listOf("com.beust.kobalt.plugin")
|
||||||
|
val imports = arrayListOf<String>()
|
||||||
|
val sections = arrayListOf<Section>()
|
||||||
lines.forEach { line ->
|
lines.forEach { line ->
|
||||||
currentLineNumber++
|
currentLineNumber++
|
||||||
val found = regexp.matcher(line).matches()
|
val found = regexp.matcher(line).matches()
|
||||||
|
@ -56,26 +71,33 @@ class BlockExtractor(val regexp: Pattern, val opening: Char, val closing: Char)
|
||||||
startLine = currentLineNumber
|
startLine = currentLineNumber
|
||||||
foundKeyword = true
|
foundKeyword = true
|
||||||
count = 1
|
count = 1
|
||||||
result.append(topLines.joinToString("\n")).append("\n")
|
buildScript.add(line)
|
||||||
result.append(line).append("\n")
|
topLines.add(line)
|
||||||
} else {
|
} else {
|
||||||
val allowedImports = listOf("com.beust", "java")
|
if (line.startsWith("import")) {
|
||||||
val disallowedImports = listOf("com.beust.kobalt.plugin")
|
if (allowedImports.any { line.contains(it) } && !disallowedImports.any { line.contains(it) }) {
|
||||||
if (! line.startsWith("import") ||
|
imports.add(line)
|
||||||
(line.startsWith("import") && allowedImports.any { line.contains(it) }
|
}
|
||||||
&& ! disallowedImports.any { line.contains(it) })) {
|
} else {
|
||||||
topLines.add(line)
|
topLines.add(line)
|
||||||
}
|
}
|
||||||
updateCount(line)
|
updateCount(line)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foundKeyword && foundClosing && count == 0) {
|
if (foundKeyword && foundClosing && count == 0) {
|
||||||
return BuildScriptInfo(result.toString(), startLine, endLine)
|
sections.add(Section(startLine, endLine))
|
||||||
|
foundKeyword = false
|
||||||
|
foundClosing = false
|
||||||
|
count = 0
|
||||||
|
startLine = 0
|
||||||
|
endLine = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foundKeyword && foundClosing && count == 0) {
|
if (sections.isNotEmpty()) {
|
||||||
return BuildScriptInfo(result.toString(), startLine, endLine)
|
val result = (imports.distinct() + buildScript).joinToString("\n") + "\n"
|
||||||
|
|
||||||
|
return BuildScriptInfo(result, sections)
|
||||||
} else {
|
} else {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ package com.beust.kobalt.misc
|
||||||
import com.beust.kobalt.*
|
import com.beust.kobalt.*
|
||||||
import com.beust.kobalt.api.Kobalt
|
import com.beust.kobalt.api.Kobalt
|
||||||
import com.beust.kobalt.api.Project
|
import com.beust.kobalt.api.Project
|
||||||
import com.beust.kobalt.internal.build.BuildFile
|
import com.beust.kobalt.internal.build.IBuildSources
|
||||||
import com.beust.kobalt.maven.Md5
|
import com.beust.kobalt.maven.Md5
|
||||||
import java.io.*
|
import java.io.*
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
|
@ -261,9 +261,9 @@ class KFiles {
|
||||||
/**
|
/**
|
||||||
* The build location for build scripts is .kobalt/build
|
* The build location for build scripts is .kobalt/build
|
||||||
*/
|
*/
|
||||||
fun findBuildScriptLocation(buildFile: BuildFile, jarFile: String) : String {
|
fun findBuildScriptLocation(buildSources: IBuildSources, jarFile: String) : String {
|
||||||
val result = joinDir(buildFile.dotKobaltDir.path, KFiles.SCRIPT_BUILD_DIR, jarFile)
|
val result = joinDir(buildSources.root.path, KFiles.dotKobaltDir.path, KFiles.SCRIPT_BUILD_DIR, jarFile)
|
||||||
kobaltLog(2, "Build file dotKobaltDir: " + buildFile.dotKobaltDir)
|
kobaltLog(2, "Build file dotKobaltDir: " + KFiles.dotKobaltDir)
|
||||||
kobaltLog(2, "Script jar file: $result")
|
kobaltLog(2, "Script jar file: $result")
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
@ -387,18 +387,7 @@ class KFiles {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findBuildFile(projectRoot: String = "."): File {
|
val dotKobaltDir = File(KFiles.joinAndMakeDir(KFiles.KOBALT_DOT_DIR))
|
||||||
val deprecatedLocation = File(Constants.BUILD_FILE_NAME)
|
|
||||||
val result: File =
|
|
||||||
if (deprecatedLocation.exists()) {
|
|
||||||
warn(Constants.BUILD_FILE_NAME + " is in a deprecated location, please move it to "
|
|
||||||
+ Constants.BUILD_FILE_DIRECTORY)
|
|
||||||
deprecatedLocation
|
|
||||||
} else {
|
|
||||||
File(KFiles.joinDir(projectRoot, Constants.BUILD_FILE_DIRECTORY, Constants.BUILD_FILE_NAME))
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findRecursively(directory: File, function: Function1<String, Boolean>): List<String> {
|
fun findRecursively(directory: File, function: Function1<String, Boolean>): List<String> {
|
||||||
|
|
|
@ -108,7 +108,7 @@ private class Main @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun runWithArgs(jc: JCommander, args: Args, argv: Array<String>): Int {
|
private fun runWithArgs(jc: JCommander, args: Args, argv: Array<String>): Int {
|
||||||
val p = if (args.buildFile != null) File(args.buildFile) else KFiles.findBuildFile()
|
val p = if (args.buildFile != null) File(args.buildFile) else File(".")
|
||||||
args.buildFile = p.absolutePath
|
args.buildFile = p.absolutePath
|
||||||
|
|
||||||
if (!args.update) {
|
if (!args.update) {
|
||||||
|
|
|
@ -11,14 +11,12 @@ import com.beust.kobalt.app.UpdateKobalt
|
||||||
import com.beust.kobalt.app.remote.KobaltServer
|
import com.beust.kobalt.app.remote.KobaltServer
|
||||||
import com.beust.kobalt.internal.PluginInfo
|
import com.beust.kobalt.internal.PluginInfo
|
||||||
import com.beust.kobalt.internal.TaskManager
|
import com.beust.kobalt.internal.TaskManager
|
||||||
import com.beust.kobalt.internal.build.BuildFile
|
import com.beust.kobalt.internal.build.BuildSources
|
||||||
import com.beust.kobalt.misc.CheckVersions
|
import com.beust.kobalt.misc.CheckVersions
|
||||||
import com.beust.kobalt.misc.KFiles
|
|
||||||
import com.beust.kobalt.wrapper.Main
|
import com.beust.kobalt.wrapper.Main
|
||||||
import com.google.common.collect.HashMultimap
|
import com.google.common.collect.HashMultimap
|
||||||
import com.google.inject.Inject
|
import com.google.inject.Inject
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Paths
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some options require a build file, others shouldn't have one and some don't care. This
|
* Some options require a build file, others shouldn't have one and some don't care. This
|
||||||
|
@ -42,12 +40,13 @@ class Options @Inject constructor(
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun run(jc: JCommander, args: Args, argv: Array<String>): Int {
|
fun run(jc: JCommander, args: Args, argv: Array<String>): Int {
|
||||||
val p = if (args.buildFile != null) File(args.buildFile) else KFiles.findBuildFile()
|
val p = if (args.buildFile != null) File(args.buildFile) else File(".")
|
||||||
val buildFile = BuildFile(Paths.get(p.absolutePath), p.name)
|
// val buildFile = BuildFile(Paths.get(p.absolutePath), p.name)
|
||||||
|
val buildSources = BuildSources(File(p.absolutePath))
|
||||||
var pluginClassLoader = javaClass.classLoader
|
var pluginClassLoader = javaClass.classLoader
|
||||||
|
|
||||||
val allProjects =
|
val allProjects =
|
||||||
if (buildFile.exists()) projectFinder.initForBuildFile(buildFile, args)
|
if (buildSources.exists()) projectFinder.initForBuildFile(buildSources, args)
|
||||||
else emptyList<Project>()
|
else emptyList<Project>()
|
||||||
|
|
||||||
// Modify `args` with options found in buildScript { kobaltOptions(...) }, if any
|
// Modify `args` with options found in buildScript { kobaltOptions(...) }, if any
|
||||||
|
@ -105,10 +104,10 @@ class Options @Inject constructor(
|
||||||
var processedOption = false
|
var processedOption = false
|
||||||
options.forEach {
|
options.forEach {
|
||||||
if (it.enabled()) {
|
if (it.enabled()) {
|
||||||
if ((it.requireBuildFile && buildFile.exists()) || ! it.requireBuildFile) {
|
if ((it.requireBuildFile && buildSources.exists()) || ! it.requireBuildFile) {
|
||||||
it.action()
|
it.action()
|
||||||
processedOption = true
|
processedOption = true
|
||||||
} else if (it.requireBuildFile && ! buildFile.exists()) {
|
} else if (it.requireBuildFile && ! buildSources.exists()) {
|
||||||
throw KobaltException("Couldn't find a build file")
|
throw KobaltException("Couldn't find a build file")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package com.beust.kobalt.app
|
package com.beust.kobalt.app
|
||||||
|
|
||||||
import com.beust.kobalt.Args
|
import com.beust.kobalt.Args
|
||||||
import com.beust.kobalt.Constants
|
|
||||||
import com.beust.kobalt.Plugins
|
import com.beust.kobalt.Plugins
|
||||||
import com.beust.kobalt.TaskResult
|
import com.beust.kobalt.TaskResult
|
||||||
import com.beust.kobalt.api.Kobalt
|
import com.beust.kobalt.api.Kobalt
|
||||||
|
@ -12,7 +11,8 @@ import com.beust.kobalt.internal.IncrementalManager
|
||||||
import com.beust.kobalt.internal.KobaltSettings
|
import com.beust.kobalt.internal.KobaltSettings
|
||||||
import com.beust.kobalt.internal.ParallelLogger
|
import com.beust.kobalt.internal.ParallelLogger
|
||||||
import com.beust.kobalt.internal.PluginInfo
|
import com.beust.kobalt.internal.PluginInfo
|
||||||
import com.beust.kobalt.internal.build.BuildFile
|
import com.beust.kobalt.internal.build.BuildSources
|
||||||
|
import com.beust.kobalt.internal.build.IBuildSources
|
||||||
import com.beust.kobalt.internal.build.VersionFile
|
import com.beust.kobalt.internal.build.VersionFile
|
||||||
import com.beust.kobalt.maven.DependencyManager
|
import com.beust.kobalt.maven.DependencyManager
|
||||||
import com.beust.kobalt.maven.PomGenerator
|
import com.beust.kobalt.maven.PomGenerator
|
||||||
|
@ -24,7 +24,6 @@ import com.beust.kobalt.plugin.kotlin.kotlinCompilePrivate
|
||||||
import com.google.inject.assistedinject.Assisted
|
import com.google.inject.assistedinject.Assisted
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.nio.file.Paths
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,7 +31,7 @@ import javax.inject.Inject
|
||||||
* 1) Extract the repos() and plugins() statements in a separate .kt and compile it into preBuildScript.jar.
|
* 1) Extract the repos() and plugins() statements in a separate .kt and compile it into preBuildScript.jar.
|
||||||
* 2) Actually build the whole Build.kt file after adding to the classpath whatever phase 1 found (plugins, repos)
|
* 2) Actually build the whole Build.kt file after adding to the classpath whatever phase 1 found (plugins, repos)
|
||||||
*/
|
*/
|
||||||
class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val buildFiles: List<BuildFile>,
|
class BuildFileCompiler @Inject constructor(@Assisted("buildSources") val buildSources: IBuildSources,
|
||||||
@Assisted val pluginInfo: PluginInfo, val files: KFiles, val plugins: Plugins,
|
@Assisted val pluginInfo: PluginInfo, val files: KFiles, val plugins: Plugins,
|
||||||
val dependencyManager: DependencyManager, val pluginProperties: PluginProperties,
|
val dependencyManager: DependencyManager, val pluginProperties: PluginProperties,
|
||||||
val executors: KobaltExecutors, val buildScriptUtil: BuildScriptUtil, val settings: KobaltSettings,
|
val executors: KobaltExecutors, val buildScriptUtil: BuildScriptUtil, val settings: KobaltSettings,
|
||||||
|
@ -41,7 +40,7 @@ class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val buildFil
|
||||||
val parallelLogger: ParallelLogger) {
|
val parallelLogger: ParallelLogger) {
|
||||||
|
|
||||||
interface IFactory {
|
interface IFactory {
|
||||||
fun create(@Assisted("buildFiles") buildFiles: List<BuildFile>, pluginInfo: PluginInfo) : BuildFileCompiler
|
fun create(@Assisted("buildSources") buildSources: IBuildSources, pluginInfo: PluginInfo) : BuildFileCompiler
|
||||||
}
|
}
|
||||||
|
|
||||||
private val SCRIPT_JAR = "buildScript.jar"
|
private val SCRIPT_JAR = "buildScript.jar"
|
||||||
|
@ -85,16 +84,17 @@ class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val buildFil
|
||||||
private fun findProjects(context: KobaltContext): FindProjectResult {
|
private fun findProjects(context: KobaltContext): FindProjectResult {
|
||||||
var errorTaskResult: TaskResult? = null
|
var errorTaskResult: TaskResult? = null
|
||||||
val projects = arrayListOf<Project>()
|
val projects = arrayListOf<Project>()
|
||||||
buildFiles.forEach { buildFile ->
|
run {
|
||||||
val parsedBuildFile = parseBuildFile(context, buildFile)
|
// buildFiles.forEach { buildFile ->
|
||||||
|
val parsedBuildFile = parseBuildFile(context, buildSources)
|
||||||
parsedBuildFiles.add(parsedBuildFile)
|
parsedBuildFiles.add(parsedBuildFile)
|
||||||
val pluginUrls = parsedBuildFile.pluginUrls
|
val pluginUrls = parsedBuildFile.pluginUrls
|
||||||
val buildScriptJarFile = File(KFiles.findBuildScriptLocation(buildFile, SCRIPT_JAR))
|
val buildScriptJarFile = File(KFiles.findBuildScriptLocation(buildSources, SCRIPT_JAR))
|
||||||
|
|
||||||
//
|
//
|
||||||
// Save the current build script absolute directory
|
// Save the current build script absolute directory
|
||||||
//
|
//
|
||||||
context.internalContext.absoluteDir = buildFile.absoluteDir
|
context.internalContext.absoluteDir = buildSources.root
|
||||||
|
|
||||||
// If the script jar files were generated by a different version, wipe them in case the API
|
// If the script jar files were generated by a different version, wipe them in case the API
|
||||||
// changed in-between
|
// changed in-between
|
||||||
|
@ -109,8 +109,7 @@ class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val buildFil
|
||||||
// compile it, jar it in buildScript.jar and run it
|
// compile it, jar it in buildScript.jar and run it
|
||||||
val modifiedBuildFile = KFiles.createTempBuildFileInTempDirectory(deleteOnExit = true)
|
val modifiedBuildFile = KFiles.createTempBuildFileInTempDirectory(deleteOnExit = true)
|
||||||
KFiles.saveFile(modifiedBuildFile, parsedBuildFile.buildScriptCode)
|
KFiles.saveFile(modifiedBuildFile, parsedBuildFile.buildScriptCode)
|
||||||
val taskResult = maybeCompileBuildFile(context, BuildFile(Paths.get(modifiedBuildFile.path),
|
val taskResult = maybeCompileBuildFile(context, listOf(modifiedBuildFile.path),
|
||||||
"Modified ${Constants.BUILD_FILE_NAME}", buildFile.realPath),
|
|
||||||
buildScriptJarFile, pluginUrls, context.internalContext.forceRecompile,
|
buildScriptJarFile, pluginUrls, context.internalContext.forceRecompile,
|
||||||
parsedBuildFile.containsProfiles)
|
parsedBuildFile.containsProfiles)
|
||||||
if (taskResult.success) {
|
if (taskResult.success) {
|
||||||
|
@ -130,9 +129,14 @@ class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val buildFil
|
||||||
if (errorTaskResult != null) errorTaskResult!! else TaskResult())
|
if (errorTaskResult != null) errorTaskResult!! else TaskResult())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun maybeCompileBuildFile(context: KobaltContext, buildFile: BuildFile, buildScriptJarFile: File,
|
private fun maybeCompileBuildFile(context: KobaltContext, buildSources: BuildSources, buildScriptJarFile: File,
|
||||||
|
pluginUrls: List<URL>, forceRecompile: Boolean, containsProfiles: Boolean) : TaskResult
|
||||||
|
= maybeCompileBuildFile(context, buildSources.findSourceFiles().map { it.path }, buildScriptJarFile,
|
||||||
|
pluginUrls, forceRecompile, containsProfiles)
|
||||||
|
|
||||||
|
private fun maybeCompileBuildFile(context: KobaltContext, sourceFiles: List<String>, buildScriptJarFile: File,
|
||||||
pluginUrls: List<URL>, forceRecompile: Boolean, containsProfiles: Boolean) : TaskResult {
|
pluginUrls: List<URL>, forceRecompile: Boolean, containsProfiles: Boolean) : TaskResult {
|
||||||
kobaltLog(2, "Running build file ${buildFile.name} jar: $buildScriptJarFile")
|
kobaltLog(2, "Compiling into $buildScriptJarFile")
|
||||||
|
|
||||||
// If the user specifed --profiles, always recompile the build file since we don't know if
|
// If the user specifed --profiles, always recompile the build file since we don't know if
|
||||||
// the current buildScript.jar we have contains the correct value for these profiles
|
// the current buildScript.jar we have contains the correct value for these profiles
|
||||||
|
@ -141,15 +145,15 @@ class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val buildFil
|
||||||
// to have a side file that describes which profiles the current buildScript.jar was
|
// to have a side file that describes which profiles the current buildScript.jar was
|
||||||
// compiled with.
|
// compiled with.
|
||||||
val bs = BuildScriptJarFile(buildScriptJarFile)
|
val bs = BuildScriptJarFile(buildScriptJarFile)
|
||||||
if (! containsProfiles && !forceRecompile && buildScriptUtil.isUpToDate(buildFile, buildScriptJarFile)) {
|
if (! containsProfiles && !forceRecompile && buildScriptUtil.isUpToDate(buildSources, buildScriptJarFile)) {
|
||||||
kobaltLog(2, " Build file $buildScriptJarFile is up to date")
|
kobaltLog(2, " Build file $buildScriptJarFile is up to date")
|
||||||
return TaskResult()
|
return TaskResult()
|
||||||
} else {
|
} else {
|
||||||
val reason =
|
val reason =
|
||||||
if (containsProfiles) "it contains profiles"
|
if (containsProfiles) "profiles were found"
|
||||||
else if (forceRecompile) "forceRecompile is true"
|
else if (forceRecompile) "forceRecompile is true"
|
||||||
else "it is not up to date"
|
else "it is not up to date"
|
||||||
kobaltLog(2, " Need to recompile ${buildFile.name} because $reason")
|
kobaltLog(2, " Need to recompile $buildSources because $reason")
|
||||||
|
|
||||||
buildScriptJarFile.deleteRecursively()
|
buildScriptJarFile.deleteRecursively()
|
||||||
val buildFileClasspath = Kobalt.buildFileClasspath.map { it.jarFile.get() }.map { it.absolutePath }
|
val buildFileClasspath = Kobalt.buildFileClasspath.map { it.jarFile.get() }.map { it.absolutePath }
|
||||||
|
@ -157,7 +161,7 @@ class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val buildFil
|
||||||
classpath(files.kobaltJar)
|
classpath(files.kobaltJar)
|
||||||
classpath(pluginUrls.map { it.file })
|
classpath(pluginUrls.map { it.file })
|
||||||
classpath(buildFileClasspath)
|
classpath(buildFileClasspath)
|
||||||
sourceFiles(listOf(buildFile.path.toFile().absolutePath))
|
sourceFiles(sourceFiles)
|
||||||
output = buildScriptJarFile
|
output = buildScriptJarFile
|
||||||
noIncrementalKotlin = true
|
noIncrementalKotlin = true
|
||||||
}.compile(context = context)
|
}.compile(context = context)
|
||||||
|
@ -177,6 +181,6 @@ class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val buildFil
|
||||||
* - the source code for the modified Build.kt (after profiles are applied)
|
* - the source code for the modified Build.kt (after profiles are applied)
|
||||||
* - the URL's of all the plug-ins that were found.
|
* - the URL's of all the plug-ins that were found.
|
||||||
*/
|
*/
|
||||||
private fun parseBuildFile(context: KobaltContext, buildFile: BuildFile) =
|
private fun parseBuildFile(context: KobaltContext, buildSources: IBuildSources) =
|
||||||
ParsedBuildFile(buildFile, context, buildScriptUtil, dependencyManager, files)
|
ParsedBuildFile(buildSources, context, buildScriptUtil, dependencyManager, files)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import com.beust.kobalt.api.Project
|
||||||
import com.beust.kobalt.api.annotation.IncrementalTask
|
import com.beust.kobalt.api.annotation.IncrementalTask
|
||||||
import com.beust.kobalt.api.annotation.Task
|
import com.beust.kobalt.api.annotation.Task
|
||||||
import com.beust.kobalt.internal.TaskManager
|
import com.beust.kobalt.internal.TaskManager
|
||||||
import com.beust.kobalt.internal.build.BuildFile
|
import com.beust.kobalt.internal.build.IBuildSources
|
||||||
import com.beust.kobalt.misc.KFiles
|
import com.beust.kobalt.misc.KFiles
|
||||||
import com.beust.kobalt.misc.Topological
|
import com.beust.kobalt.misc.Topological
|
||||||
import com.beust.kobalt.misc.kobaltLog
|
import com.beust.kobalt.misc.kobaltLog
|
||||||
|
@ -123,9 +123,9 @@ class BuildScriptUtil @Inject constructor(val plugins: Plugins, val files: KFile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isUpToDate(buildFile: BuildFile, jarFile: File) =
|
fun isUpToDate(buildSources: IBuildSources, jarFile: File) =
|
||||||
buildFile.exists() && jarFile.exists()
|
buildSources.exists() && jarFile.exists()
|
||||||
&& buildFile.lastModified < jarFile.lastModified()
|
&& buildSources.findSourceFiles().all { it.lastModified() < jarFile.lastModified() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make sure all the projects have a unique name.
|
* Make sure all the projects have a unique name.
|
||||||
|
|
|
@ -6,6 +6,8 @@ import com.beust.kobalt.api.Kobalt
|
||||||
import com.beust.kobalt.api.KobaltContext
|
import com.beust.kobalt.api.KobaltContext
|
||||||
import com.beust.kobalt.api.Project
|
import com.beust.kobalt.api.Project
|
||||||
import com.beust.kobalt.internal.build.BuildFile
|
import com.beust.kobalt.internal.build.BuildFile
|
||||||
|
import com.beust.kobalt.internal.build.BuildSources
|
||||||
|
import com.beust.kobalt.internal.build.IBuildSources
|
||||||
import com.beust.kobalt.internal.build.VersionFile
|
import com.beust.kobalt.internal.build.VersionFile
|
||||||
import com.beust.kobalt.maven.DependencyManager
|
import com.beust.kobalt.maven.DependencyManager
|
||||||
import com.beust.kobalt.misc.BlockExtractor
|
import com.beust.kobalt.misc.BlockExtractor
|
||||||
|
@ -16,10 +18,9 @@ import com.beust.kobalt.plugin.kotlin.kotlinCompilePrivate
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
import java.nio.file.Paths
|
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
class ParsedBuildFile(val buildFile: BuildFile, val context: KobaltContext, val buildScriptUtil: BuildScriptUtil,
|
class ParsedBuildFile(val buildSources: IBuildSources, val context: KobaltContext, val buildScriptUtil: BuildScriptUtil,
|
||||||
val dependencyManager: DependencyManager, val files: KFiles) {
|
val dependencyManager: DependencyManager, val files: KFiles) {
|
||||||
val pluginList = arrayListOf<String>()
|
val pluginList = arrayListOf<String>()
|
||||||
val repos = arrayListOf<String>()
|
val repos = arrayListOf<String>()
|
||||||
|
@ -36,8 +37,8 @@ class ParsedBuildFile(val buildFile: BuildFile, val context: KobaltContext, val
|
||||||
"import com.beust.kobalt.api.*")
|
"import com.beust.kobalt.api.*")
|
||||||
val preBuildScriptCode : String get() = preBuildScript.joinToString("\n")
|
val preBuildScriptCode : String get() = preBuildScript.joinToString("\n")
|
||||||
|
|
||||||
private val buildScript = arrayListOf<String>()
|
private val nonBuildScript = arrayListOf<String>()
|
||||||
val buildScriptCode : String get() = buildScript.joinToString("\n")
|
val buildScriptCode : String get() = nonBuildScript.joinToString("\n")
|
||||||
|
|
||||||
init {
|
init {
|
||||||
parseBuildFile()
|
parseBuildFile()
|
||||||
|
@ -93,12 +94,16 @@ class ParsedBuildFile(val buildFile: BuildFile, val context: KobaltContext, val
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
val buildWithCorrectProfiles = applyProfiles(buildFile.path.toFile().readLines())
|
val buildWithCorrectProfiles = arrayListOf<String>()
|
||||||
|
buildSources.findSourceFiles().forEach {
|
||||||
|
buildWithCorrectProfiles.addAll(applyProfiles(it.readLines()))
|
||||||
|
}
|
||||||
|
|
||||||
val buildScriptInfo = BlockExtractor(Pattern.compile("^val.*buildScript.*\\{"), '{', '}')
|
val buildScriptInfo = BlockExtractor(Pattern.compile("^val.*buildScript.*\\{"), '{', '}')
|
||||||
.extractBlock(buildWithCorrectProfiles)
|
.extractBlock(buildWithCorrectProfiles)
|
||||||
|
|
||||||
if (buildScriptInfo != null) {
|
if (buildScriptInfo != null) {
|
||||||
kobaltLog(3, "About to compile build file:\n=====\n" + buildScriptInfo.content + "\n=====")
|
kobaltLog(2, "About to compile build file:\n=====\n" + buildScriptInfo.content + "\n=====")
|
||||||
preBuildScript.add(buildScriptInfo.content)
|
preBuildScript.add(buildScriptInfo.content)
|
||||||
} else {
|
} else {
|
||||||
repos.forEach { preBuildScript.add(it) }
|
repos.forEach { preBuildScript.add(it) }
|
||||||
|
@ -107,15 +112,18 @@ class ParsedBuildFile(val buildFile: BuildFile, val context: KobaltContext, val
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Write the build file excluding the buildScript{} tag since we already ran it
|
// Write the build file excluding the nonBuildScript{} tag since we already ran it
|
||||||
//
|
//
|
||||||
var lineNumber = 1
|
var lineNumber = 1
|
||||||
buildFile.path.toFile().forEachLine { line ->
|
buildSources.findSourceFiles().forEach { buildFile ->
|
||||||
if (buildScriptInfo == null ||
|
buildFile.forEachLine() { line ->
|
||||||
(lineNumber < buildScriptInfo.startLine || lineNumber > buildScriptInfo.endLine)) {
|
if (buildScriptInfo == null || ! buildScriptInfo.isInSection(lineNumber)) {
|
||||||
buildScript.add(correctProfileLine(line))
|
val cpl = correctProfileLine(line)
|
||||||
|
if (cpl.startsWith("import")) nonBuildScript.add(0, cpl)
|
||||||
|
else nonBuildScript.add(cpl)
|
||||||
|
}
|
||||||
|
lineNumber++
|
||||||
}
|
}
|
||||||
lineNumber++
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,15 +139,14 @@ class ParsedBuildFile(val buildFile: BuildFile, val context: KobaltContext, val
|
||||||
//
|
//
|
||||||
// Compile to preBuildScript.jar
|
// Compile to preBuildScript.jar
|
||||||
//
|
//
|
||||||
val buildScriptJar = KFiles.findBuildScriptLocation(buildFile, "preBuildScript.jar")
|
val buildScriptJar = KFiles.findBuildScriptLocation(buildSources, "preBuildScript.jar")
|
||||||
val buildScriptJarFile = File(buildScriptJar)
|
val buildScriptJarFile = File(buildScriptJar)
|
||||||
|
|
||||||
// Because of profiles, it's not possible to find out if a preBuildScript.jar is up to date
|
// 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.
|
// or not so recompile it every time.
|
||||||
// if (! buildScriptUtil.isUpToDate(buildFile, File(buildScriptJar))) {
|
// if (! buildScriptUtil.isUpToDate(buildFile, File(buildScriptJar))) {
|
||||||
buildScriptJarFile.parentFile.mkdirs()
|
buildScriptJarFile.parentFile.mkdirs()
|
||||||
generateJarFile(context, BuildFile(Paths.get(pluginSourceFile.path), "Plugins",
|
generateJarFile(context, listOf(pluginSourceFile.path), buildScriptJarFile)
|
||||||
Paths.get(buildScriptJar)), buildScriptJarFile, buildFile)
|
|
||||||
VersionFile.generateVersionFile(buildScriptJarFile.parentFile)
|
VersionFile.generateVersionFile(buildScriptJarFile.parentFile)
|
||||||
Kobalt.context!!.internalContext.buildFileOutOfDate = true
|
Kobalt.context!!.internalContext.buildFileOutOfDate = true
|
||||||
// }
|
// }
|
||||||
|
@ -157,9 +164,8 @@ class ParsedBuildFile(val buildFile: BuildFile, val context: KobaltContext, val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateJarFile(context: KobaltContext, buildFile: BuildFile,
|
private fun generateJarFile(context: KobaltContext, sourceFiles: List<String>,
|
||||||
buildScriptJarFile: File, originalFile: BuildFile) {
|
buildScriptJarFile: File, originalFile: BuildFile? = null) {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Compile the jar file
|
// Compile the jar file
|
||||||
//
|
//
|
||||||
|
@ -170,14 +176,18 @@ class ParsedBuildFile(val buildFile: BuildFile, val context: KobaltContext, val
|
||||||
val result = kotlinCompilePrivate {
|
val result = kotlinCompilePrivate {
|
||||||
classpath(files.kobaltJar)
|
classpath(files.kobaltJar)
|
||||||
classpath(deps)
|
classpath(deps)
|
||||||
sourceFiles(buildFile.path.toFile().absolutePath)
|
sourceFiles(sourceFiles)
|
||||||
output = outputJar
|
output = outputJar
|
||||||
noIncrementalKotlin = true
|
noIncrementalKotlin = true
|
||||||
}.compile(context = context)
|
}.compile(context = context)
|
||||||
if (! result.success) {
|
if (! result.success) {
|
||||||
throw KobaltException("Couldn't compile ${originalFile.realPath}:\n"
|
val org = originalFile?.realPath ?: sourceFiles.joinToString(",")
|
||||||
+ result.errorMessage)
|
throw KobaltException("Couldn't compile $org:\n" + result.errorMessage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun generateJarFile(context: KobaltContext, buildSources: BuildSources,
|
||||||
|
buildScriptJarFile: File)
|
||||||
|
= generateJarFile(context, buildSources.findSourceFiles().map { it.path }, buildScriptJarFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import com.beust.kobalt.api.IClasspathDependency
|
||||||
import com.beust.kobalt.api.Kobalt
|
import com.beust.kobalt.api.Kobalt
|
||||||
import com.beust.kobalt.api.Project
|
import com.beust.kobalt.api.Project
|
||||||
import com.beust.kobalt.internal.PluginInfo
|
import com.beust.kobalt.internal.PluginInfo
|
||||||
import com.beust.kobalt.internal.build.BuildFile
|
import com.beust.kobalt.internal.build.BuildSources
|
||||||
import com.beust.kobalt.misc.kobaltLog
|
import com.beust.kobalt.misc.kobaltLog
|
||||||
import com.google.inject.Inject
|
import com.google.inject.Inject
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
@ -15,8 +15,8 @@ import java.util.*
|
||||||
class ProjectFinder @Inject constructor(val buildFileCompilerFactory: BuildFileCompiler.IFactory,
|
class ProjectFinder @Inject constructor(val buildFileCompilerFactory: BuildFileCompiler.IFactory,
|
||||||
val pluginInfo: PluginInfo, val plugins: Plugins) {
|
val pluginInfo: PluginInfo, val plugins: Plugins) {
|
||||||
|
|
||||||
fun initForBuildFile(buildFile: BuildFile, args: Args): List<Project> {
|
fun initForBuildFile(buildSources: BuildSources, args: Args): List<Project> {
|
||||||
val findProjectResult = buildFileCompilerFactory.create(listOf(buildFile), pluginInfo)
|
val findProjectResult = buildFileCompilerFactory.create(buildSources, pluginInfo)
|
||||||
.compileBuildFiles(args)
|
.compileBuildFiles(args)
|
||||||
if (! findProjectResult.taskResult.success) {
|
if (! findProjectResult.taskResult.success) {
|
||||||
throw KobaltException("Couldn't compile build file: " + findProjectResult.taskResult.errorMessage)
|
throw KobaltException("Couldn't compile build file: " + findProjectResult.taskResult.errorMessage)
|
||||||
|
|
|
@ -3,7 +3,7 @@ package com.beust.kobalt.app.remote
|
||||||
import com.beust.kobalt.Args
|
import com.beust.kobalt.Args
|
||||||
import com.beust.kobalt.api.Kobalt
|
import com.beust.kobalt.api.Kobalt
|
||||||
import com.beust.kobalt.app.ProjectFinder
|
import com.beust.kobalt.app.ProjectFinder
|
||||||
import com.beust.kobalt.internal.build.BuildFile
|
import com.beust.kobalt.internal.build.BuildSources
|
||||||
import com.beust.kobalt.internal.eventbus.ArtifactDownloadedEvent
|
import com.beust.kobalt.internal.eventbus.ArtifactDownloadedEvent
|
||||||
import com.beust.kobalt.maven.aether.Exceptions
|
import com.beust.kobalt.maven.aether.Exceptions
|
||||||
import com.beust.kobalt.misc.KFiles
|
import com.beust.kobalt.misc.KFiles
|
||||||
|
@ -13,6 +13,7 @@ import com.google.gson.Gson
|
||||||
import org.eclipse.jetty.websocket.api.RemoteEndpoint
|
import org.eclipse.jetty.websocket.api.RemoteEndpoint
|
||||||
import org.eclipse.jetty.websocket.api.Session
|
import org.eclipse.jetty.websocket.api.Session
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketListener
|
import org.eclipse.jetty.websocket.api.WebSocketListener
|
||||||
|
import java.io.File
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,14 +44,14 @@ class GetDependencyGraphHandler : WebSocketListener {
|
||||||
errorMessage = errorMessage)))
|
errorMessage = errorMessage)))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findBuildFile(map: Map<String, List<String>>) : String? {
|
private fun findBuildFile(map: Map<String, List<String>>) : BuildSources? {
|
||||||
val projectRoot = map[PARAMETER_PROJECT_ROOT]
|
val projectRoot = map[PARAMETER_PROJECT_ROOT]
|
||||||
val buildFile = map[PARAMETER_BUILD_FILE]
|
val buildFile = map[PARAMETER_BUILD_FILE]
|
||||||
val result =
|
val result =
|
||||||
if (projectRoot != null) {
|
if (projectRoot != null) {
|
||||||
KFiles.findBuildFile(projectRoot[0]).absolutePath
|
BuildSources(File(projectRoot[0]))
|
||||||
} else if (buildFile != null) {
|
} else if (buildFile != null) {
|
||||||
buildFile[0]
|
BuildSources(File(buildFile[0]))
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
@ -59,13 +60,13 @@ class GetDependencyGraphHandler : WebSocketListener {
|
||||||
|
|
||||||
override fun onWebSocketConnect(s: Session) {
|
override fun onWebSocketConnect(s: Session) {
|
||||||
session = s
|
session = s
|
||||||
val buildFile = findBuildFile(s.upgradeRequest.parameterMap)
|
val buildSources = findBuildFile(s.upgradeRequest.parameterMap)
|
||||||
|
|
||||||
fun <T> getInstance(cls: Class<T>) : T = Kobalt.INJECTOR.getInstance(cls)
|
fun <T> getInstance(cls: Class<T>) : T = Kobalt.INJECTOR.getInstance(cls)
|
||||||
|
|
||||||
// Parse the request
|
// Parse the request
|
||||||
val result =
|
val result =
|
||||||
if (buildFile != null) {
|
if (buildSources != null) {
|
||||||
// Track all the downloads that this dependency call might trigger and
|
// Track all the downloads that this dependency call might trigger and
|
||||||
// send them as a progress message to the web socket
|
// send them as a progress message to the web socket
|
||||||
val eventBus = getInstance(EventBus::class.java)
|
val eventBus = getInstance(EventBus::class.java)
|
||||||
|
@ -84,10 +85,9 @@ class GetDependencyGraphHandler : WebSocketListener {
|
||||||
val dependencyData = getInstance(RemoteDependencyData::class.java)
|
val dependencyData = getInstance(RemoteDependencyData::class.java)
|
||||||
val args = getInstance(Args::class.java)
|
val args = getInstance(Args::class.java)
|
||||||
|
|
||||||
val allProjects = projectFinder.initForBuildFile(BuildFile(Paths.get(buildFile), buildFile),
|
val allProjects = projectFinder.initForBuildFile(buildSources, args)
|
||||||
args)
|
|
||||||
|
|
||||||
dependencyData.dependenciesDataFor(buildFile, args, object : IProgressListener {
|
dependencyData.dependenciesDataFor(buildSources, args, object : IProgressListener {
|
||||||
override fun onProgress(progress: Int?, message: String?) {
|
override fun onProgress(progress: Int?, message: String?) {
|
||||||
sendWebsocketCommand(s.remote, ProgressCommand.NAME, ProgressCommand(progress, message))
|
sendWebsocketCommand(s.remote, ProgressCommand.NAME, ProgressCommand(progress, message))
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,11 @@ package com.beust.kobalt.app.remote
|
||||||
import com.beust.kobalt.Args
|
import com.beust.kobalt.Args
|
||||||
import com.beust.kobalt.api.Kobalt
|
import com.beust.kobalt.api.Kobalt
|
||||||
import com.beust.kobalt.app.MainModule
|
import com.beust.kobalt.app.MainModule
|
||||||
|
import com.beust.kobalt.homeDir
|
||||||
import com.beust.kobalt.internal.KobaltSettings
|
import com.beust.kobalt.internal.KobaltSettings
|
||||||
|
import com.beust.kobalt.internal.build.BuildSources
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
//enum class Command(val n: Int, val command: ICommand) {
|
//enum class Command(val n: Int, val command: ICommand) {
|
||||||
// GET_DEPENDENCIES(1, Kobalt.INJECTOR.getInstance(GetDependenciesCommand::class.java)),
|
// GET_DEPENDENCIES(1, Kobalt.INJECTOR.getInstance(GetDependenciesCommand::class.java)),
|
||||||
|
@ -19,12 +22,13 @@ class KobaltHub(val dependencyData: RemoteDependencyData) {
|
||||||
val args = Args()
|
val args = Args()
|
||||||
|
|
||||||
fun runCommand(n: Int) : String {
|
fun runCommand(n: Int) : String {
|
||||||
|
val buildSources = BuildSources(File(homeDir("kotlin/klaxon")))
|
||||||
val data =
|
val data =
|
||||||
when(n) {
|
when(n) {
|
||||||
1 -> Gson().toJson(
|
1 -> Gson().toJson(
|
||||||
dependencyData.dependenciesDataFor("/Users/beust/kotlin/klaxon/kobalt/src/Build.kt", args))
|
dependencyData.dependenciesDataFor(buildSources, args))
|
||||||
2 -> Gson().toJson(
|
2 -> Gson().toJson(
|
||||||
dependencyData.dependenciesDataFor("/Users/beust/kotlin/klaxon/kobalt/src/Build.kt", args,
|
dependencyData.dependenciesDataFor(buildSources, args,
|
||||||
useGraph = true))
|
useGraph = true))
|
||||||
else -> throw RuntimeException("Unknown command")
|
else -> throw RuntimeException("Unknown command")
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ class OldServer(val initCallback: (String) -> List<Project>, val cleanUpCallback
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val COMMAND_CLASSES = listOf(GetDependenciesCommand::class.java, PingCommand::class.java)
|
private val COMMAND_CLASSES = listOf(PingCommand::class.java)
|
||||||
private val COMMANDS = COMMAND_CLASSES.map {
|
private val COMMANDS = COMMAND_CLASSES.map {
|
||||||
Kobalt.INJECTOR.getInstance(it).let { Pair(it.name, it) }
|
Kobalt.INJECTOR.getInstance(it).let { Pair(it.name, it) }
|
||||||
}.toMap()
|
}.toMap()
|
||||||
|
|
|
@ -8,7 +8,7 @@ import com.beust.kobalt.internal.DynamicGraph
|
||||||
import com.beust.kobalt.internal.GraphUtil
|
import com.beust.kobalt.internal.GraphUtil
|
||||||
import com.beust.kobalt.internal.PluginInfo
|
import com.beust.kobalt.internal.PluginInfo
|
||||||
import com.beust.kobalt.internal.TaskManager
|
import com.beust.kobalt.internal.TaskManager
|
||||||
import com.beust.kobalt.internal.build.BuildFile
|
import com.beust.kobalt.internal.build.BuildSources
|
||||||
import com.beust.kobalt.maven.DependencyManager
|
import com.beust.kobalt.maven.DependencyManager
|
||||||
import com.beust.kobalt.misc.KFiles
|
import com.beust.kobalt.misc.KFiles
|
||||||
import com.beust.kobalt.misc.KobaltExecutors
|
import com.beust.kobalt.misc.KobaltExecutors
|
||||||
|
@ -16,7 +16,6 @@ import com.beust.kobalt.misc.StringVersion
|
||||||
import com.beust.kobalt.misc.log
|
import com.beust.kobalt.misc.log
|
||||||
import com.google.inject.Inject
|
import com.google.inject.Inject
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Paths
|
|
||||||
|
|
||||||
interface IProgressListener {
|
interface IProgressListener {
|
||||||
/**
|
/**
|
||||||
|
@ -29,7 +28,7 @@ class RemoteDependencyData @Inject constructor(val executors: KobaltExecutors, v
|
||||||
val buildFileCompilerFactory: BuildFileCompiler.IFactory, val pluginInfo: PluginInfo,
|
val buildFileCompilerFactory: BuildFileCompiler.IFactory, val pluginInfo: PluginInfo,
|
||||||
val taskManager: TaskManager) {
|
val taskManager: TaskManager) {
|
||||||
|
|
||||||
fun dependenciesDataFor(buildFilePath: String, args: Args, progressListener: IProgressListener? = null,
|
fun dependenciesDataFor(buildSources: BuildSources, args: Args, progressListener: IProgressListener? = null,
|
||||||
useGraph : Boolean = false): GetDependenciesData {
|
useGraph : Boolean = false): GetDependenciesData {
|
||||||
val projectDatas = arrayListOf<ProjectData>()
|
val projectDatas = arrayListOf<ProjectData>()
|
||||||
|
|
||||||
|
@ -41,8 +40,8 @@ class RemoteDependencyData @Inject constructor(val executors: KobaltExecutors, v
|
||||||
fun allDeps(l: List<IClasspathDependency>, name: String) = dependencyManager.transitiveClosure(l,
|
fun allDeps(l: List<IClasspathDependency>, name: String) = dependencyManager.transitiveClosure(l,
|
||||||
requiredBy = name)
|
requiredBy = name)
|
||||||
|
|
||||||
val buildFile = BuildFile(Paths.get(buildFilePath), "GetDependenciesCommand")
|
// val buildFile = BuildFile(Paths.get(buildFilePath), "GetDependenciesCommand")
|
||||||
val buildFileCompiler = buildFileCompilerFactory.create(listOf(buildFile), pluginInfo)
|
val buildFileCompiler = buildFileCompilerFactory.create(buildSources, pluginInfo)
|
||||||
val projectResult = buildFileCompiler.compileBuildFiles(args)
|
val projectResult = buildFileCompiler.compileBuildFiles(args)
|
||||||
|
|
||||||
val pluginDependencies = projectResult.pluginUrls.map { File(it.toURI()) }.map {
|
val pluginDependencies = projectResult.pluginUrls.map { File(it.toURI()) }.map {
|
||||||
|
@ -125,7 +124,7 @@ class RemoteDependencyData @Inject constructor(val executors: KobaltExecutors, v
|
||||||
.map { toDependencyData2("testCompile", it)}
|
.map { toDependencyData2("testCompile", it)}
|
||||||
}
|
}
|
||||||
|
|
||||||
val projectRoot = File(buildFilePath).parentFile.parentFile.parentFile
|
val projectRoot = buildSources.file
|
||||||
|
|
||||||
val allTasks = hashSetOf<TaskData>()
|
val allTasks = hashSetOf<TaskData>()
|
||||||
projectResult.projects.withIndex().forEach { wi ->
|
projectResult.projects.withIndex().forEach { wi ->
|
||||||
|
|
|
@ -1,25 +1,13 @@
|
||||||
package com.beust.kobalt.app.remote
|
package com.beust.kobalt.app.remote
|
||||||
|
|
||||||
import com.beust.kobalt.Args
|
|
||||||
import com.beust.kobalt.api.ITemplate
|
import com.beust.kobalt.api.ITemplate
|
||||||
import com.beust.kobalt.api.Kobalt
|
|
||||||
import com.beust.kobalt.app.ProjectFinder
|
|
||||||
import com.beust.kobalt.app.Templates
|
import com.beust.kobalt.app.Templates
|
||||||
import com.beust.kobalt.internal.PluginInfo
|
import com.beust.kobalt.internal.PluginInfo
|
||||||
import com.beust.kobalt.internal.build.BuildFile
|
|
||||||
import com.beust.kobalt.internal.eventbus.ArtifactDownloadedEvent
|
|
||||||
import com.beust.kobalt.maven.aether.Exceptions
|
|
||||||
import com.google.common.collect.ListMultimap
|
import com.google.common.collect.ListMultimap
|
||||||
import com.google.common.eventbus.EventBus
|
|
||||||
import com.google.common.eventbus.Subscribe
|
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import org.eclipse.jetty.websocket.api.RemoteEndpoint
|
|
||||||
import org.eclipse.jetty.websocket.api.Session
|
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketListener
|
|
||||||
import spark.ResponseTransformer
|
import spark.ResponseTransformer
|
||||||
import spark.Route
|
import spark.Route
|
||||||
import spark.Spark
|
import spark.Spark
|
||||||
import java.nio.file.Paths
|
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
|
|
||||||
class SparkServer(val cleanUpCallback: () -> Unit, val pluginInfo : PluginInfo) : KobaltServer.IServer {
|
class SparkServer(val cleanUpCallback: () -> Unit, val pluginInfo : PluginInfo) : KobaltServer.IServer {
|
||||||
|
@ -45,7 +33,6 @@ class SparkServer(val cleanUpCallback: () -> Unit, val pluginInfo : PluginInfo)
|
||||||
override fun run(port: Int) {
|
override fun run(port: Int) {
|
||||||
log.debug("Server running")
|
log.debug("Server running")
|
||||||
Spark.port(port)
|
Spark.port(port)
|
||||||
Spark.webSocket("/v1/getDependencies", GetDependenciesHandler::class.java)
|
|
||||||
Spark.webSocket("/v1/getDependencyGraph", GetDependencyGraphHandler::class.java)
|
Spark.webSocket("/v1/getDependencyGraph", GetDependencyGraphHandler::class.java)
|
||||||
Spark.get("/ping") { req, res ->
|
Spark.get("/ping") { req, res ->
|
||||||
log.debug(" Received ping")
|
log.debug(" Received ping")
|
||||||
|
@ -63,30 +50,6 @@ class SparkServer(val cleanUpCallback: () -> Unit, val pluginInfo : PluginInfo)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
//
|
|
||||||
// The /v0 endpoints are deprecated and will eventually be removed
|
|
||||||
// (replaced by /v1 which uses WebSockets
|
|
||||||
jsonRoute("/v0/getDependencies", Route { request, response ->
|
|
||||||
val buildFile = request.queryParams("buildFile")
|
|
||||||
val result =
|
|
||||||
if (buildFile != null) {
|
|
||||||
try {
|
|
||||||
val dependencyData = Kobalt.INJECTOR.getInstance(RemoteDependencyData::class.java)
|
|
||||||
val args = Kobalt.INJECTOR.getInstance(Args::class.java)
|
|
||||||
|
|
||||||
dependencyData.dependenciesDataFor(buildFile, args)
|
|
||||||
} catch(ex: Exception) {
|
|
||||||
RemoteDependencyData.GetDependenciesData(errorMessage = ex.message)
|
|
||||||
} finally {
|
|
||||||
cleanUpCallback()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
RemoteDependencyData.GetDependenciesData(
|
|
||||||
errorMessage = "buildFile wasn't passed in the query parameter")
|
|
||||||
}
|
|
||||||
cleanUpCallback()
|
|
||||||
result
|
|
||||||
})
|
|
||||||
jsonRoute("/v0/getTemplates", Route { request, response ->
|
jsonRoute("/v0/getTemplates", Route { request, response ->
|
||||||
TemplatesData.create(Templates().getTemplates(pluginInfo))
|
TemplatesData.create(Templates().getTemplates(pluginInfo))
|
||||||
})
|
})
|
||||||
|
@ -94,93 +57,6 @@ class SparkServer(val cleanUpCallback: () -> Unit, val pluginInfo : PluginInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Manage the websocket endpoint "/v1/getDependencies".
|
|
||||||
*/
|
|
||||||
@Deprecated(message = "Replaced with GetDependencyGraphHandler")
|
|
||||||
class GetDependenciesHandler : WebSocketListener {
|
|
||||||
// The SparkJava project refused to merge https://github.com/perwendel/spark/pull/383
|
|
||||||
// so I have to do dependency injections manually :-(
|
|
||||||
val projectFinder = Kobalt.INJECTOR.getInstance(ProjectFinder::class.java)
|
|
||||||
|
|
||||||
var session: Session? = null
|
|
||||||
|
|
||||||
override fun onWebSocketClose(code: Int, reason: String?) {
|
|
||||||
println("ON CLOSE $code reason: $reason")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onWebSocketError(cause: Throwable?) {
|
|
||||||
Exceptions.printStackTrace(cause!!)
|
|
||||||
throw UnsupportedOperationException()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T> sendWebsocketCommand(endpoint: RemoteEndpoint, commandName: String, payload: T) {
|
|
||||||
endpoint.sendString(Gson().toJson(WebSocketCommand(commandName, payload = Gson().toJson(payload))))
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onWebSocketConnect(s: Session) {
|
|
||||||
session = s
|
|
||||||
val buildFileParams = s.upgradeRequest.parameterMap["buildFile"]
|
|
||||||
if (buildFileParams != null) {
|
|
||||||
val buildFile = buildFileParams[0]
|
|
||||||
|
|
||||||
fun <T> getInstance(cls: Class<T>) : T = Kobalt.INJECTOR.getInstance(cls)
|
|
||||||
|
|
||||||
val result = if (buildFile != null) {
|
|
||||||
// Track all the downloads that this dependency call might trigger and
|
|
||||||
// send them as a progress message to the web socket
|
|
||||||
val eventBus = getInstance(EventBus::class.java)
|
|
||||||
val busListener = object {
|
|
||||||
@Subscribe
|
|
||||||
fun onArtifactDownloaded(event: ArtifactDownloadedEvent) {
|
|
||||||
sendWebsocketCommand(s.remote, ProgressCommand.NAME,
|
|
||||||
ProgressCommand(null, "Downloaded " + event.artifactId))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
eventBus.register(busListener)
|
|
||||||
|
|
||||||
// Get the dependencies for the requested build file and send progress to the web
|
|
||||||
// socket for each project
|
|
||||||
try {
|
|
||||||
val dependencyData = getInstance(RemoteDependencyData::class.java)
|
|
||||||
val args = getInstance(Args::class.java)
|
|
||||||
|
|
||||||
val allProjects = projectFinder.initForBuildFile(BuildFile(Paths.get(buildFile), buildFile),
|
|
||||||
args)
|
|
||||||
|
|
||||||
dependencyData.dependenciesDataFor(buildFile, args, object : IProgressListener {
|
|
||||||
override fun onProgress(progress: Int?, message: String?) {
|
|
||||||
sendWebsocketCommand(s.remote, ProgressCommand.NAME, ProgressCommand(progress, message))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} catch(ex: Throwable) {
|
|
||||||
ex.printStackTrace()
|
|
||||||
val errorMessage = ex.stackTrace.map { it.toString() }.joinToString("\n<p>")
|
|
||||||
RemoteDependencyData.GetDependenciesData(errorMessage = errorMessage)
|
|
||||||
} finally {
|
|
||||||
SparkServer.cleanUpCallback()
|
|
||||||
eventBus.unregister(busListener)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
RemoteDependencyData.GetDependenciesData(
|
|
||||||
errorMessage = "buildFile wasn't passed in the query parameter")
|
|
||||||
}
|
|
||||||
sendWebsocketCommand(s.remote, RemoteDependencyData.GetDependenciesData.NAME, result)
|
|
||||||
s.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onWebSocketText(message: String?) {
|
|
||||||
println("RECEIVED TEXT: $message")
|
|
||||||
session?.remote?.sendString("Response: $message")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onWebSocketBinary(payload: ByteArray?, offset: Int, len: Int) {
|
|
||||||
println("RECEIVED BINARY: $payload")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class ProgressCommand(val progress: Int? = null, val message: String? = null) {
|
class ProgressCommand(val progress: Int? = null, val message: String? = null) {
|
||||||
companion object {
|
companion object {
|
||||||
val NAME = "ProgressCommand"
|
val NAME = "ProgressCommand"
|
||||||
|
|
|
@ -6,7 +6,7 @@ import com.beust.kobalt.app.BuildFileCompiler
|
||||||
import com.beust.kobalt.internal.JvmCompilerPlugin
|
import com.beust.kobalt.internal.JvmCompilerPlugin
|
||||||
import com.beust.kobalt.internal.KobaltPluginXml
|
import com.beust.kobalt.internal.KobaltPluginXml
|
||||||
import com.beust.kobalt.internal.PluginInfo
|
import com.beust.kobalt.internal.PluginInfo
|
||||||
import com.beust.kobalt.internal.build.BuildFile
|
import com.beust.kobalt.internal.build.SingleFileBuildSources
|
||||||
import com.beust.kobalt.misc.KFiles
|
import com.beust.kobalt.misc.KFiles
|
||||||
import com.beust.kobalt.misc.log
|
import com.beust.kobalt.misc.log
|
||||||
import org.testng.annotations.BeforeClass
|
import org.testng.annotations.BeforeClass
|
||||||
|
@ -70,11 +70,11 @@ open class BaseTest(val compilerFactory: BuildFileCompiler.IFactory? = null) {
|
||||||
val actualBuildFile = createBuildFile(projectDirectory)
|
val actualBuildFile = createBuildFile(projectDirectory)
|
||||||
val tmpBuildFile = createBuildFile(Files.createTempDirectory("").toFile().absolutePath)
|
val tmpBuildFile = createBuildFile(Files.createTempDirectory("").toFile().absolutePath)
|
||||||
|
|
||||||
val thisBuildFile = BuildFile(Paths.get(tmpBuildFile.absolutePath), "Build.kt",
|
val thisBuildFile = SingleFileBuildSources(tmpBuildFile)
|
||||||
Paths.get(actualBuildFile.absolutePath))
|
// , "Build.kt",
|
||||||
Kobalt.context?.log(2, "About to compile build file "
|
// Paths.get(actualBuildFile.absolutePath))
|
||||||
+ thisBuildFile.path + " " + thisBuildFile.realPath
|
Kobalt.context?.log(2, "About to compile build file $thisBuildFile"
|
||||||
+ ".kobaltDir: " + thisBuildFile.dotKobaltDir)
|
+ ".kobaltDir: " + KFiles.dotKobaltDir)
|
||||||
args.apply {
|
args.apply {
|
||||||
buildFile = actualBuildFile.absolutePath
|
buildFile = actualBuildFile.absolutePath
|
||||||
noIncremental = true
|
noIncremental = true
|
||||||
|
@ -84,7 +84,7 @@ open class BaseTest(val compilerFactory: BuildFileCompiler.IFactory? = null) {
|
||||||
val pluginInfo = PluginInfo(KobaltPluginXml(), null, null).apply {
|
val pluginInfo = PluginInfo(KobaltPluginXml(), null, null).apply {
|
||||||
projectContributors.add(jvmCompilerPlugin)
|
projectContributors.add(jvmCompilerPlugin)
|
||||||
}
|
}
|
||||||
return compilerFactory!!.create(listOf(thisBuildFile), pluginInfo).compileBuildFiles(args,
|
return compilerFactory!!.create(thisBuildFile, pluginInfo).compileBuildFiles(args,
|
||||||
forceRecompile = true)
|
forceRecompile = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue