diff --git a/kobalt/src/Build.kt b/kobalt/src/Build.kt index b6a58554..65d29bc0 100644 --- a/kobalt/src/Build.kt +++ b/kobalt/src/Build.kt @@ -117,6 +117,7 @@ val kobaltPluginApi = project { "org.testng:testng:${Versions.testng}" ) exclude(*aether("impl", "spi", "util", "api")) + compile("org.jetbrains.kotlin:kotlin-stdlib:1.1.1") } @@ -180,6 +181,7 @@ val kobaltApp = project(kobaltPluginApi, wrapper) { // "org.glassfish.jersey.media:jersey-media-moxy:${Versions.jersey}", // "org.wasabi:wasabi:0.1.182" ) + compile("org.jetbrains.kotlin:kotlin-stdlib:1.1.1") } @@ -188,6 +190,7 @@ val kobaltApp = project(kobaltPluginApi, wrapper) { "org.assertj:assertj-core:3.4.1", *mavenResolver("util") ) + compile("org.jetbrains.kotlin:kotlin-test:1.1.1") } assemble { diff --git a/kobalt/wrapper/kobalt-wrapper.properties b/kobalt/wrapper/kobalt-wrapper.properties index 07dff771..708f4587 100644 --- a/kobalt/wrapper/kobalt-wrapper.properties +++ b/kobalt/wrapper/kobalt-wrapper.properties @@ -1 +1 @@ -kobalt.version=1.0.41 \ No newline at end of file +kobalt.version=1.0.45 \ No newline at end of file diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/Kobalt.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/Kobalt.kt index 52c1a1f0..0808014e 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/Kobalt.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/Kobalt.kt @@ -128,5 +128,9 @@ class Kobalt { fun addBuildSourceDirs(dirs: Array) { buildSourceDirs.addAll(dirs) } + + fun cleanUp() { + buildSourceDirs.clear() + } } } diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/aether/AetherDependency.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/aether/AetherDependency.kt index f7de93a2..8fc960dc 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/aether/AetherDependency.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/aether/AetherDependency.kt @@ -4,9 +4,6 @@ import com.beust.kobalt.api.Dependencies import com.beust.kobalt.api.IClasspathDependency import com.beust.kobalt.api.Kobalt import com.beust.kobalt.maven.CompletedFuture -import com.beust.kobalt.maven.LocalDep -import com.beust.kobalt.maven.LocalRepo -import com.beust.kobalt.maven.MavenId import com.beust.kobalt.misc.StringVersion import com.beust.kobalt.misc.warn import org.eclipse.aether.artifact.Artifact @@ -26,18 +23,13 @@ class AetherDependency(val artifact: Artifact, override val optional: Boolean = private fun toId(a: Artifact) = a.toString() override val jarFile: Future - get() = if (artifact.file != null) { - CompletedFuture(artifact.file) - } else { - val localRepo = Kobalt.INJECTOR.getInstance(LocalRepo::class.java) - val file = File(LocalDep(MavenId.create(id), localRepo).toAbsoluteJarFilePath(version)) - if (file.exists()) { - CompletedFuture(file) + get() = + if (artifact.file != null) { + CompletedFuture(artifact.file) } else { val td = aether.resolve(artifact, null) CompletedFuture(td.root.artifact.file) } - } override fun toMavenDependencies(scope: String?) : org.apache.maven.model.Dependency { val passedScope = scope diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/aether/KobaltMavenResolver.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/aether/KobaltMavenResolver.kt index 2b79c432..293ab8cf 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/aether/KobaltMavenResolver.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/aether/KobaltMavenResolver.kt @@ -20,6 +20,7 @@ import org.eclipse.aether.resolution.DependencyRequest import org.eclipse.aether.resolution.DependencyResult import org.eclipse.aether.resolution.VersionRangeRequest import org.eclipse.aether.resolution.VersionRangeResult +import java.util.* class KobaltMavenResolver @Inject constructor(val settings: KobaltSettings, val args: Args, @@ -35,8 +36,9 @@ class KobaltMavenResolver @Inject constructor(val settings: KobaltSettings, fun resolveToArtifact(id: String, scope: Scope? = null, filter: DependencyFilter? = null) : Artifact = resolve(id, scope, filter).root.artifact - fun resolve(id: String, scope: Scope? = null, filter: DependencyFilter? = null): DependencyResult { - val dependencyRequest = DependencyRequest(createCollectRequest(id, scope), filter) + fun resolve(id: String, scope: Scope? = null, filter: DependencyFilter? = null, + repos: List = emptyList()): DependencyResult { + val dependencyRequest = DependencyRequest(createCollectRequest(id, scope, repos), filter) val result = system.resolveDependencies(session, dependencyRequest) if (args.downloadSources) { listOf("sources", "javadoc").forEach { @@ -98,11 +100,12 @@ class KobaltMavenResolver @Inject constructor(val settings: KobaltSettings, private val system = Booter.newRepositorySystem() private val session = Booter.newRepositorySystemSession(system, localRepo.localRepo, settings, eventBus) + private fun createRepo(url: String) = RemoteRepository.Builder(Random().nextInt().toString(), "default", url) + .build() + private val kobaltRepositories: List get() = Kobalt.repos.map { - RemoteRepository.Builder(null, "default", it.url) -// .setSnapshotPolicy(RepositoryPolicy(false, null, null)) - .build().let { repository -> + createRepo(it.url).let { repository -> val proxyConfigs = settings.proxyConfigs ?: return@map repository RemoteRepository.Builder(repository).apply { setProxy(proxyConfigs.getProxy(repository.protocol)?.toAetherProxy()) @@ -110,13 +113,14 @@ class KobaltMavenResolver @Inject constructor(val settings: KobaltSettings, } } - private fun createCollectRequest(id: String, scope: Scope? = null) = CollectRequest().apply { + private fun createCollectRequest(id: String, scope: Scope? = null, repos: List = emptyList()) + = CollectRequest().apply { val allIds = arrayListOf(MavenId.toMavenId(id)) dependencies = allIds.map { Dependency(DefaultArtifact(it), scope?.scope) } root = Dependency(DefaultArtifact(MavenId.toMavenId(id)), scope?.scope) - repositories = kobaltRepositories + repositories = kobaltRepositories + repos.map { createRepo(it) } } private fun createCollectRequest( artifact: DefaultArtifact, scope: Scope? = null) = CollectRequest().apply { 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 1edb66b0..a854156a 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 @@ -20,6 +20,8 @@ class BuildScriptInfo(val file: File, val fullBuildFile: List, val secti val includedBuildSourceDirs = arrayListOf() + fun addBuildSourceDir(dir: IncludedBuildSourceDir) = includedBuildSourceDirs.add(dir) + fun includedBuildSourceDirsForLine(line: Int): List { val result = includedBuildSourceDirs.find { it.line == line }?.dirs return result ?: emptyList() diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/GithubApi2.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/GithubApi2.kt index 2eafc2e3..9f89a01d 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/GithubApi2.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/GithubApi2.kt @@ -1,8 +1,11 @@ package com.beust.kobalt.misc +import com.beust.kobalt.Args import com.beust.kobalt.KobaltException +import com.beust.kobalt.api.Kobalt import com.beust.kobalt.internal.DocUrl import com.beust.kobalt.internal.KobaltSettings +import com.beust.kobalt.internal.build.VersionCheckTimestampFile import com.beust.kobalt.maven.Http import com.beust.kobalt.maven.aether.Exceptions import com.google.gson.Gson @@ -16,12 +19,15 @@ import retrofit2.converter.gson.GsonConverterFactory import retrofit2.http.* import rx.Observable import java.io.File +import java.time.Duration +import java.time.Instant import java.util.* import java.util.concurrent.Callable import java.util.concurrent.Future class GithubApi2 @Inject constructor( - val executors: KobaltExecutors, val localProperties: LocalProperties, val http: Http, val settings:KobaltSettings) { + val executors: KobaltExecutors, val localProperties: LocalProperties, val http: Http, + val settings:KobaltSettings, val args: Args) { companion object { const val PROPERTY_ACCESS_TOKEN = "github.accessToken" @@ -109,39 +115,42 @@ class GithubApi2 @Inject constructor( val latestKobaltVersion: Future get() { val callable = Callable { - var result = "0" - - val username = localProperties.getNoThrows(PROPERTY_USERNAME, DOC_URL) - val accessToken = localProperties.getNoThrows(PROPERTY_ACCESS_TOKEN, DOC_URL) - try { - val req = - if (username != null && accessToken != null) { - service.getReleases(username, "kobalt", accessToken) - } else { - service.getReleasesNoAuth("cbeust", "kobalt") - } - val ex = req.execute() - val errorBody = ex.errorBody() - if (errorBody != null) { - val jsonError = JsonParser().parse(errorBody.string()) - warn("Couldn't call Github.getReleases(): $jsonError") - } else { - val releases = ex.body() - if (releases != null) { - releases.firstOrNull()?.let { - try { - result = listOf(it.name, it.tagName).filterNotNull().first { !it.isBlank() } - } catch(ex: NoSuchElementException) { - throw KobaltException("Couldn't find the latest release") + var result = Kobalt.version + if (! args.dev && Duration.ofMinutes(10L) > + Duration.between(VersionCheckTimestampFile.timestamp, Instant.now())) { + kobaltLog(2, "Skipping GitHub latest release check, too soon.") + } else { + val username = localProperties.getNoThrows(PROPERTY_USERNAME, DOC_URL) + val accessToken = localProperties.getNoThrows(PROPERTY_ACCESS_TOKEN, DOC_URL) + try { + val req = + if (username != null && accessToken != null) { + service.getReleases(username, "kobalt", accessToken) + } else { + service.getReleasesNoAuth("cbeust", "kobalt") } - } + val ex = req.execute() + val errorBody = ex.errorBody() + if (errorBody != null) { + val jsonError = JsonParser().parse(errorBody.string()) + warn("Couldn't call Github.getReleases(): $jsonError") } else { - warn("Didn't receive any body in the response to GitHub.getReleases()") + val releases = ex.body() + if (releases != null) { + releases.firstOrNull()?.let { + try { + result = listOf(it.name, it.tagName).filterNotNull().first { !it.isBlank() } + } catch(ex: NoSuchElementException) { + throw KobaltException("Couldn't find the latest release") + } + } + } else { + warn("Didn't receive any body in the response to GitHub.getReleases()") + } } - } - } catch(e: Exception) { - kobaltLog(1, "Couldn't retrieve releases from github: " + e.message) - Exceptions.printStackTrace(e) + } catch(e: Exception) { + kobaltLog(1, "Couldn't retrieve releases from github: " + e.message) + Exceptions.printStackTrace(e) // val error = parseRetrofitError(e) // val details = if (error.errors != null) { // error.errors[0] @@ -152,6 +161,7 @@ class GithubApi2 @Inject constructor( // // using cbeust/kobalt, like above. Right now, just bailing. // kobaltLog(2, "Couldn't retrieve releases from github, ${error.message ?: e}: " // + details?.code + " field: " + details?.field) + } } result } diff --git a/src/main/kotlin/com/beust/kobalt/Main.kt b/src/main/kotlin/com/beust/kobalt/Main.kt index 2d55cac6..6c6e988e 100644 --- a/src/main/kotlin/com/beust/kobalt/Main.kt +++ b/src/main/kotlin/com/beust/kobalt/Main.kt @@ -93,6 +93,7 @@ private class Main @Inject constructor( } var result = 1 + val latestVersionFuture = github.latestKobaltVersion try { diff --git a/src/main/kotlin/com/beust/kobalt/Options.kt b/src/main/kotlin/com/beust/kobalt/Options.kt index b65e20e6..16166e11 100644 --- a/src/main/kotlin/com/beust/kobalt/Options.kt +++ b/src/main/kotlin/com/beust/kobalt/Options.kt @@ -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) { diff --git a/src/main/kotlin/com/beust/kobalt/app/BuildFileCompiler.kt b/src/main/kotlin/com/beust/kobalt/app/BuildFileCompiler.kt index 7037dcdc..fe214622 100644 --- a/src/main/kotlin/com/beust/kobalt/app/BuildFileCompiler.kt +++ b/src/main/kotlin/com/beust/kobalt/app/BuildFileCompiler.kt @@ -76,26 +76,14 @@ class BuildFileCompiler @Inject constructor(@Assisted("buildSources") val buildS } class FindProjectResult(val context: KobaltContext, val projects: List, val pluginUrls: List, - val taskResult: TaskResult) + val buildContentRoots: List, val taskResult: TaskResult) private fun findProjects(context: KobaltContext): FindProjectResult { val root = buildSources.root var errorTaskResult: TaskResult? = null val projects = arrayListOf() - // 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()) } diff --git a/src/main/kotlin/com/beust/kobalt/app/BuildFiles.kt b/src/main/kotlin/com/beust/kobalt/app/BuildFiles.kt index 2d185f31..98d8815a 100644 --- a/src/main/kotlin/com/beust/kobalt/app/BuildFiles.kt +++ b/src/main/kotlin/com/beust/kobalt/app/BuildFiles.kt @@ -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) + /** * @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() val newSourceDirs = arrayListOf() + // // 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().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, val code: List, 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().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 { val result = arrayListOf() @@ -231,6 +242,7 @@ class BuildFiles @Inject constructor(val factory: BuildFileCompiler.IFactory, return result } + private fun findBuildSourceFiles(root: String) : List { val result = arrayListOf() diff --git a/src/main/kotlin/com/beust/kobalt/app/ProjectFinder.kt b/src/main/kotlin/com/beust/kobalt/app/ProjectFinder.kt index c4449284..30dc0f9e 100644 --- a/src/main/kotlin/com/beust/kobalt/app/ProjectFinder.kt +++ b/src/main/kotlin/com/beust/kobalt/app/ProjectFinder.kt @@ -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 { + 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) { diff --git a/src/main/kotlin/com/beust/kobalt/app/UpdateKobalt.kt b/src/main/kotlin/com/beust/kobalt/app/UpdateKobalt.kt index ca9548ea..f4133b95 100644 --- a/src/main/kotlin/com/beust/kobalt/app/UpdateKobalt.kt +++ b/src/main/kotlin/com/beust/kobalt/app/UpdateKobalt.kt @@ -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) } /** diff --git a/src/main/kotlin/com/beust/kobalt/app/remote/GetDependencyGraphHandler.kt b/src/main/kotlin/com/beust/kobalt/app/remote/GetDependencyGraphHandler.kt index 80c656e1..3ac7c256 100644 --- a/src/main/kotlin/com/beust/kobalt/app/remote/GetDependencyGraphHandler.kt +++ b/src/main/kotlin/com/beust/kobalt/app/remote/GetDependencyGraphHandler.kt @@ -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 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>) = 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 getInstance(cls: Class) : 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)) } diff --git a/src/main/kotlin/com/beust/kobalt/app/remote/KobaltHub.kt b/src/main/kotlin/com/beust/kobalt/app/remote/KobaltHub.kt index 75982f7d..315f0217 100644 --- a/src/main/kotlin/com/beust/kobalt/app/remote/KobaltHub.kt +++ b/src/main/kotlin/com/beust/kobalt/app/remote/KobaltHub.kt @@ -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) { - 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) { +// 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") +//} diff --git a/src/main/kotlin/com/beust/kobalt/app/remote/RemoteDependencyData.kt b/src/main/kotlin/com/beust/kobalt/app/remote/RemoteDependencyData.kt index b03be293..bd1914ac 100644 --- a/src/main/kotlin/com/beust/kobalt/app/remote/RemoteDependencyData.kt +++ b/src/main/kotlin/com/beust/kobalt/app/remote/RemoteDependencyData.kt @@ -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() @@ -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 = emptyList(), val allTasks: Collection = emptySet(), val pluginDependencies: List = emptyList(), + val buildContentRoots: List = emptyList(), val errorMessage: String?) { companion object { val NAME = "GetDependencies" diff --git a/src/main/resources/kobalt.properties b/src/main/resources/kobalt.properties index ec989df5..8c44f111 100644 --- a/src/main/resources/kobalt.properties +++ b/src/main/resources/kobalt.properties @@ -1 +1 @@ -kobalt.version=1.0.41 +kobalt.version=1.0.45 diff --git a/src/test/kotlin/com/beust/kobalt/misc/MavenResolverTest.kt b/src/test/kotlin/com/beust/kobalt/misc/MavenResolverTest.kt index a0b4be9f..2e98cf28 100644 --- a/src/test/kotlin/com/beust/kobalt/misc/MavenResolverTest.kt +++ b/src/test/kotlin/com/beust/kobalt/misc/MavenResolverTest.kt @@ -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 { val system = Booter.newRepositorySystem() val session = Booter.newRepositorySystemSession(system,