1
0
Fork 0
mirror of https://github.com/ethauvin/kobalt.git synced 2025-04-26 08:27:12 -07:00
This commit is contained in:
Dmitry Zhuravlev 2017-04-03 12:13:49 +03:00
commit 23bbcd4d84
18 changed files with 174 additions and 124 deletions

View file

@ -93,6 +93,7 @@ private class Main @Inject constructor(
}
var result = 1
val latestVersionFuture = github.latestKobaltVersion
try {

View file

@ -46,7 +46,8 @@ class Options @Inject constructor(
val buildSources = if (p.isDirectory) BuildSources(p.absoluteFile) else SingleFileBuildSources(p)
var pluginClassLoader = javaClass.classLoader
val allProjects = projectFinder.initForBuildFile(buildSources, args)
val allProjectResult = projectFinder.initForBuildFile(buildSources, args)
val allProjects = allProjectResult.projects
// Modify `args` with options found in buildScript { kobaltOptions(...) }, if any
addOptionsFromBuild(args, Kobalt.optionsFromBuild)
@ -139,6 +140,7 @@ class Options @Inject constructor(
private fun cleanUp() {
pluginInfo.cleanUp()
taskManager.cleanUp()
Kobalt.cleanUp()
}
private fun addOptionsFromBuild(args: Args, optionsFromBuild: ArrayList<String>) {

View file

@ -76,26 +76,14 @@ class BuildFileCompiler @Inject constructor(@Assisted("buildSources") val buildS
}
class FindProjectResult(val context: KobaltContext, val projects: List<Project>, val pluginUrls: List<URL>,
val taskResult: TaskResult)
val buildContentRoots: List<String>, val taskResult: TaskResult)
private fun findProjects(context: KobaltContext): FindProjectResult {
val root = buildSources.root
var errorTaskResult: TaskResult? = null
val projects = arrayListOf<Project>()
// Parse the build files in kobalt/src/*.kt, which will analyze all the buildScriptInfo{} sections
// and possibly add new source build directories. The output of this process is a new Build.kt
// file that contains the aggregation of all the build files with the profiles applied and with
// the included build files inserted at the correct line.
val newBuildKt = buildFiles.parseBuildFiles(root.absolutePath, context)
//
// Save the current build script absolute directory
//
context.internalContext.absoluteDir = buildSources.root
// If buildScript.jar was generated by a different version, wipe them it case the API
// changed in-between
// If buildScript.jar was generated by a different version, wipe our temporary build directory
val buildScriptJarDir = KFiles.findBuildScriptDir(root.absolutePath)
buildScriptJarDir.let { dir ->
if (! VersionFile.isSameVersionFile(dir)) {
@ -104,6 +92,18 @@ class BuildFileCompiler @Inject constructor(@Assisted("buildSources") val buildS
}
}
// Parse the build files in kobalt/src/*.kt, which will analyze all the buildScriptInfo{} sections
// and possibly add new source build directories. The output of this process is a new Build.kt
// file that contains the aggregation of all the build files with the profiles applied and with
// the included build files inserted at the correct line.
val parseResult = buildFiles.parseBuildFiles(root.absolutePath, context)
val newBuildKt = parseResult.buildKt
//
// Save the current build script absolute directory
//
context.internalContext.absoluteDir = buildSources.root
val buildScriptJarFile = File(KFiles.findBuildScriptDir(root.absolutePath), SCRIPT_JAR)
//
@ -129,7 +129,7 @@ class BuildFileCompiler @Inject constructor(@Assisted("buildSources") val buildS
// Clear the absolute dir
context.internalContext.absoluteDir = null
return FindProjectResult(context, projects, pluginUrls,
return FindProjectResult(context, projects, pluginUrls, parseResult.buildSourceDirectories,
if (errorTaskResult != null) errorTaskResult else TaskResult())
}

View file

@ -40,13 +40,17 @@ class BuildFiles @Inject constructor(val factory: BuildFileCompiler.IFactory,
class BuildFileWithBuildScript(val file: File, val buildScriptInfo: BuildScriptInfo)
class BuildFileParseResult(val projectRoot: String, val buildKt: File,
val buildSourceDirectories: List<String>)
/**
* @return the new Build.kt
*/
fun parseBuildFiles(projectDir: String, context: KobaltContext) : File {
fun parseBuildFiles(projectDir: String, context: KobaltContext) : BuildFileParseResult {
val profiles = Profiles(context)
val bsiMap = hashMapOf<File, BuildFileWithBuildScript>()
val newSourceDirs = arrayListOf<IncludedBuildSourceDir>()
//
// Create a map of File -> FileWithBuildScript
//
@ -94,7 +98,7 @@ class BuildFiles @Inject constructor(val factory: BuildFileCompiler.IFactory,
// We're inside a buildScriptInfo section, see if it includes any buildSourceDirs
// and if it does, include these build files here
//
val isd = bsi.includedBuildSourceDirsForLine(lineNumber)
val isd = bsi.includedBuildSourceDirsForLine(lineNumber)
log(2, " Skipping buildScript{} line $lineNumber from file $file")
if (isd.any()) {
// If we found any new buildSourceDirs, all all the files found in these directories
@ -111,7 +115,7 @@ class BuildFiles @Inject constructor(val factory: BuildFileCompiler.IFactory,
//
// Create the big Build.kt out of the imports and code we've found so far
//
with(File(KFiles.findBuildScriptDir(projectDir), "Build.kt")) {
val newBuildFile = with(File(KFiles.findBuildScriptDir(projectDir), "Build.kt")) {
parentFile.mkdirs()
val imp = arrayListOf<String>().apply {
addAll(imports)
@ -119,9 +123,12 @@ class BuildFiles @Inject constructor(val factory: BuildFileCompiler.IFactory,
Collections.sort(imp)
writeText(imp.joinToString("\n"))
appendText(code.joinToString("\n"))
return this
this
}
val newDirs = listOf(File(BuildFiles.buildContentRoot(projectDir)).relativeTo(File(projectDir)).path) +
newSourceDirs.flatMap{ it.dirs.map { BuildFiles.buildContentRoot(it)} }
return BuildFileParseResult(projectDir, newBuildFile, newDirs)
}
class SplitBuildFile(val imports: List<String>, val code: List<String>, val containsProfiles: Boolean)
@ -144,6 +151,10 @@ class BuildFiles @Inject constructor(val factory: BuildFileCompiler.IFactory,
val BUILD_SCRIPT_REGEXP: Pattern = Pattern.compile("^val.*buildScript.*\\{")
val BLOCK_EXTRACTOR = BlockExtractor(BUILD_SCRIPT_REGEXP, '{', '}')
/**
* The content root for a build file module.
*/
fun buildContentRoot(root: String) = root + File.separatorChar + "kobalt"
}
fun parseBuildScriptInfos(projectDir: String, context: KobaltContext, profiles: Profiles)
@ -205,7 +216,7 @@ class BuildFiles @Inject constructor(val factory: BuildFileCompiler.IFactory,
val newDirs = arrayListOf<String>().apply { addAll(Kobalt.buildSourceDirs) }
newDirs.removeAll(currentDirs)
if (newDirs.any()) {
buildScriptInfo.includedBuildSourceDirs.add(IncludedBuildSourceDir(section.start, newDirs))
buildScriptInfo.addBuildSourceDir(IncludedBuildSourceDir(section.start, newDirs))
}
}
@ -214,7 +225,7 @@ class BuildFiles @Inject constructor(val factory: BuildFileCompiler.IFactory,
return analyzedFiles
}
private fun sourceDir(root: String) = File(KFiles.joinDir(root, "kobalt", "src"))
private fun sourceDir(root: String) = File(KFiles.joinDir(buildContentRoot(root), "src"))
private fun findFiles(file: File, accept: (File) -> Boolean) : List<File> {
val result = arrayListOf<File>()
@ -231,6 +242,7 @@ class BuildFiles @Inject constructor(val factory: BuildFileCompiler.IFactory,
return result
}
private fun findBuildSourceFiles(root: String) : List<File> {
val result = arrayListOf<File>()

View file

@ -7,7 +7,6 @@ import com.beust.kobalt.api.IClasspathDependency
import com.beust.kobalt.api.Kobalt
import com.beust.kobalt.api.Project
import com.beust.kobalt.internal.PluginInfo
import com.beust.kobalt.internal.build.BuildSources
import com.beust.kobalt.internal.build.IBuildSources
import com.beust.kobalt.misc.kobaltLog
import com.google.inject.Inject
@ -16,7 +15,7 @@ import java.util.*
class ProjectFinder @Inject constructor(val buildFileCompilerFactory: BuildFileCompiler.IFactory,
val pluginInfo: PluginInfo, val plugins: Plugins) {
fun initForBuildFile(buildSources: IBuildSources, args: Args): List<Project> {
fun initForBuildFile(buildSources: IBuildSources, args: Args): BuildFileCompiler.FindProjectResult {
val findProjectResult = buildFileCompilerFactory.create(buildSources, pluginInfo)
.compileBuildFiles(args)
if (! findProjectResult.taskResult.success) {
@ -49,7 +48,7 @@ class ProjectFinder @Inject constructor(val buildFileCompilerFactory: BuildFileC
//
plugins.applyPlugins(Kobalt.context!!, allProjects)
return allProjects
return findProjectResult
}
private fun runClasspathInterceptors(allProjects: List<Project>) {

View file

@ -21,7 +21,8 @@ class UpdateKobalt @Inject constructor(val github: GithubApi2, val wrapperProper
val newVersion = github.latestKobaltVersion
wrapperProperties.create(newVersion.get())
VersionCheckTimestampFile.updateTimestamp(Instant.now())
Main.main(arrayOf())
val args = if (KobaltLogger.isQuiet) { arrayOf("--log", "0") } else { arrayOf() }
Main.main(args)
}
/**

View file

@ -22,8 +22,9 @@ class GetDependencyGraphHandler : WebSocketListener {
// so I have to do dependency injections manually :-(
val projectFinder = Kobalt.INJECTOR.getInstance(ProjectFinder::class.java)
// URL parameters sent by the client
val PARAMETER_PROJECT_ROOT = "projectRoot"
val PARAMETER_BUILD_FILE = "buildFile"
val PARAMETER_BUILD_FILE = "buildFile" // Deprecated
val PARAMETER_PROFILES = "profiles"
val PARAMETER_DOWNLOAD_SOURCES = "downloadSources"
@ -40,8 +41,9 @@ class GetDependencyGraphHandler : WebSocketListener {
fun <T> sendWebsocketCommand(endpoint: RemoteEndpoint, commandName: String, payload: T,
errorMessage: String? = null) {
endpoint.sendString(Gson().toJson(WebSocketCommand(commandName, payload = Gson().toJson(payload),
errorMessage = errorMessage)))
val json = Gson().toJson(WebSocketCommand(commandName, payload = Gson().toJson(payload),
errorMessage = errorMessage))
endpoint.sendString(json)
}
private fun findProfiles(map: Map<String, List<String>>) = map[PARAMETER_PROFILES]?.getOrNull(0)
@ -63,8 +65,9 @@ class GetDependencyGraphHandler : WebSocketListener {
override fun onWebSocketConnect(s: Session) {
session = s
val buildSources = findBuildFile(s.upgradeRequest.parameterMap)
val profiles = findProfiles(s.upgradeRequest.parameterMap)
val parameterMap = s.upgradeRequest.parameterMap
val buildSources = findBuildFile(parameterMap)
val profiles = findProfiles(parameterMap)
val downloadSources = findDownloadSources(s.upgradeRequest.parameterMap)
fun <T> getInstance(cls: Class<T>) : T = Kobalt.INJECTOR.getInstance(cls)
@ -89,12 +92,13 @@ class GetDependencyGraphHandler : WebSocketListener {
try {
val dependencyData = getInstance(RemoteDependencyData::class.java)
val args = getInstance(Args::class.java)
args.buildFile = buildSources.root.absolutePath
args.profiles = profiles
args.downloadSources = downloadSources
val allProjects = projectFinder.initForBuildFile(buildSources, args)
val projectResults = projectFinder.initForBuildFile(buildSources, args)
dependencyData.dependenciesDataFor(buildSources, args, object : IProgressListener {
dependencyData.dependenciesDataFor(buildSources, args, projectResults, object : IProgressListener {
override fun onProgress(progress: Int?, message: String?) {
sendWebsocketCommand(s.remote, ProgressCommand.NAME, ProgressCommand(progress, message))
}

View file

@ -1,14 +1,5 @@
package com.beust.kobalt.app.remote
import com.beust.kobalt.Args
import com.beust.kobalt.api.Kobalt
import com.beust.kobalt.app.MainModule
import com.beust.kobalt.homeDir
import com.beust.kobalt.internal.KobaltSettings
import com.beust.kobalt.internal.build.BuildSources
import com.google.gson.Gson
import java.io.File
//enum class Command(val n: Int, val command: ICommand) {
// GET_DEPENDENCIES(1, Kobalt.INJECTOR.getInstance(GetDependenciesCommand::class.java)),
// GET_DEPENDENCIES_GRAPH(2, Kobalt.INJECTOR.getInstance(GetDependenciesGraphCommand::class.java));
@ -18,29 +9,29 @@ import java.io.File
// }
//}
class KobaltHub(val dependencyData: RemoteDependencyData) {
val args = Args()
fun runCommand(n: Int) : String {
val buildSources = BuildSources(File(homeDir("kotlin/klaxon")))
val data =
when(n) {
1 -> Gson().toJson(
dependencyData.dependenciesDataFor(buildSources, args))
2 -> Gson().toJson(
dependencyData.dependenciesDataFor(buildSources, args,
useGraph = true))
else -> throw RuntimeException("Unknown command")
}
println("Data: $data")
return data
}
}
fun main(argv: Array<String>) {
Kobalt.init(MainModule(Args(), KobaltSettings.readSettingsXml()))
val dependencyData = Kobalt.INJECTOR.getInstance(RemoteDependencyData::class.java)
val json = KobaltHub(dependencyData).runCommand(1)
val dd = Gson().fromJson(json, RemoteDependencyData.GetDependenciesData::class.java)
println("Data2: $dd")
}
//class KobaltHub(val dependencyData: RemoteDependencyData) {
// val args = Args()
//
// fun runCommand(n: Int) : String {
// val buildSources = BuildSources(File(homeDir("kotlin/klaxon")))
// val data =
// when(n) {
// 1 -> Gson().toJson(
// dependencyData.dependenciesDataFor(buildSources, args))
// 2 -> Gson().toJson(
// dependencyData.dependenciesDataFor(buildSources, args,
// useGraph = true))
// else -> throw RuntimeException("Unknown command")
// }
// println("Data: $data")
// return data
// }
//}
//
//fun main(argv: Array<String>) {
// Kobalt.init(MainModule(Args(), KobaltSettings.readSettingsXml()))
// val dependencyData = Kobalt.INJECTOR.getInstance(RemoteDependencyData::class.java)
// val json = KobaltHub(dependencyData).runCommand(1)
// val dd = Gson().fromJson(json, RemoteDependencyData.GetDependenciesData::class.java)
// println("Data2: $dd")
//}

View file

@ -4,10 +4,16 @@ import com.beust.kobalt.Args
import com.beust.kobalt.api.IClasspathDependency
import com.beust.kobalt.api.Project
import com.beust.kobalt.app.BuildFileCompiler
import com.beust.kobalt.internal.*
import com.beust.kobalt.internal.DynamicGraph
import com.beust.kobalt.internal.GraphUtil
import com.beust.kobalt.internal.PluginInfo
import com.beust.kobalt.internal.TaskManager
import com.beust.kobalt.internal.build.BuildSources
import com.beust.kobalt.maven.DependencyManager
import com.beust.kobalt.misc.*
import com.beust.kobalt.misc.KFiles
import com.beust.kobalt.misc.KobaltExecutors
import com.beust.kobalt.misc.StringVersion
import com.beust.kobalt.misc.log
import com.google.inject.Inject
import java.io.File
@ -22,7 +28,9 @@ class RemoteDependencyData @Inject constructor(val executors: KobaltExecutors, v
val buildFileCompilerFactory: BuildFileCompiler.IFactory, val pluginInfo: PluginInfo,
val taskManager: TaskManager) {
fun dependenciesDataFor(buildSources: BuildSources, args: Args, progressListener: IProgressListener? = null,
fun dependenciesDataFor(buildSources: BuildSources, args: Args,
findProjectResult: BuildFileCompiler.FindProjectResult,
progressListener: IProgressListener? = null,
useGraph : Boolean = false): GetDependenciesData {
val projectDatas = arrayListOf<ProjectData>()
@ -168,7 +176,7 @@ class RemoteDependencyData @Inject constructor(val executors: KobaltExecutors, v
})
}
return GetDependenciesData(projectDatas, allTasks, pluginDependencies,
return GetDependenciesData(projectDatas, allTasks, pluginDependencies, findProjectResult.buildContentRoots,
projectResult.taskResult.errorMessage)
}
@ -194,6 +202,7 @@ class RemoteDependencyData @Inject constructor(val executors: KobaltExecutors, v
class GetDependenciesData(val projects: List<ProjectData> = emptyList(),
val allTasks: Collection<TaskData> = emptySet(),
val pluginDependencies: List<DependencyData> = emptyList(),
val buildContentRoots: List<String> = emptyList(),
val errorMessage: String?) {
companion object {
val NAME = "GetDependencies"

View file

@ -1 +1 @@
kobalt.version=1.0.41
kobalt.version=1.0.45

View file

@ -16,6 +16,7 @@ import org.eclipse.aether.graph.Dependency
import org.eclipse.aether.repository.RemoteRepository
import org.eclipse.aether.resolution.ArtifactResult
import org.eclipse.aether.resolution.DependencyRequest
import org.eclipse.aether.resolution.DependencyResolutionException
import org.testng.annotations.DataProvider
import org.testng.annotations.Guice
import org.testng.annotations.Test
@ -68,6 +69,21 @@ class MavenResolverTest {
assertThat(closure.none { it.toString().contains("android") })
}
@Test
fun shouldResolveSnapshots() {
try {
// Should throw
resolver.resolve("org.bukkit:bukkit:1.11.2-R0.1-SNAPSHOT")
} catch(ex: DependencyResolutionException) {
// Success. Note: run the failing test first, because once the resolve succeeds, its
// results are cached in the local repo.
}
// Should succeed
resolver.resolve("org.bukkit:bukkit:1.11.2-R0.1-SNAPSHOT",
repos = listOf("https://hub.spigotmc.org/nexus/content/repositories/snapshots"))
}
private fun resolve(id: String): List<ArtifactResult> {
val system = Booter.newRepositorySystem()
val session = Booter.newRepositorySystemSession(system,