mirror of
https://github.com/ethauvin/kobalt.git
synced 2025-04-25 07:57:12 -07:00
Merge branch 'master' of github.com:cbeust/kobalt
This commit is contained in:
commit
49e69d0964
22 changed files with 445 additions and 168 deletions
10
dist/kobaltw
vendored
10
dist/kobaltw
vendored
|
@ -1,7 +1,11 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
DIRNAME=`dirname $(readlink -f "$0")`
|
||||
if [[ "$(uname)" == "CYGWIN"* ]]; then
|
||||
DIRNAME=`cygpath -d "$DIRNAME"`
|
||||
case "$(uname)" in
|
||||
CYGWIN*) DIRNAME=$(cygpath -d "$(dirname "$(readlink -f "$0")")");;
|
||||
Darwin*) DIRNAME=$(dirname "$(readlink "$0")");;
|
||||
*) DIRNAME=$(dirname "$(readlink -f "$0")");;
|
||||
esac
|
||||
if [ "$DIRNAME" = "." ]; then
|
||||
DIRNAME="$(dirname "$0")"
|
||||
fi
|
||||
java -jar "${DIRNAME}/../kobalt/wrapper/kobalt-wrapper.jar" $*
|
|
@ -43,7 +43,6 @@ object Versions {
|
|||
val junitVintageVersion = "$junit.0-M4"
|
||||
}
|
||||
|
||||
|
||||
fun mavenResolver(vararg m: String)
|
||||
= m.map { "org.apache.maven.resolver:maven-resolver-$it:${Versions.mavenResolver}" }
|
||||
.toTypedArray()
|
||||
|
@ -114,7 +113,7 @@ val kobaltPluginApi = project {
|
|||
"org.slf4j:slf4j-simple:${Versions.slf4j}",
|
||||
*mavenResolver("api", "spi", "util", "impl", "connector-basic", "transport-http", "transport-file"),
|
||||
"org.apache.maven:maven-aether-provider:3.3.9",
|
||||
"org.testng.testng-remote:testng-remote:1.3.0",
|
||||
"org.testng.testng-remote:testng-remote:1.3.2",
|
||||
"org.testng:testng:${Versions.testng}",
|
||||
"commons-io:commons-io:2.5",
|
||||
"org.junit.platform:junit-platform-surefire-provider:${Versions.junitPlatform}",
|
||||
|
@ -140,12 +139,8 @@ val kobaltPluginApi = project {
|
|||
}
|
||||
}
|
||||
|
||||
// install {
|
||||
// libDir = "lib-test"
|
||||
// }
|
||||
|
||||
kotlinCompiler {
|
||||
args("-nowarn")
|
||||
args("nowarn")
|
||||
}
|
||||
|
||||
bintray {
|
||||
|
@ -233,7 +228,7 @@ val kobaltApp = project(kobaltPluginApi, wrapper) {
|
|||
}
|
||||
|
||||
kotlinCompiler {
|
||||
args("-nowarn")
|
||||
args("nowarn")
|
||||
}
|
||||
|
||||
bintray {
|
||||
|
|
|
@ -1 +1 @@
|
|||
kobalt.version=1.0.62
|
||||
kobalt.version=1.0.72
|
|
@ -74,8 +74,18 @@ data class ProxyConfig(val host: String = "", val port: Int = 0, val type: Strin
|
|||
fun toAetherProxy() = Proxy(type, host, port) // TODO make support for proxy auth
|
||||
}
|
||||
|
||||
data class HostConfig(var url: String = "", var name: String = url, var username: String? = null,
|
||||
var password: String? = null) {
|
||||
data class HostConfig(var url: String = "", var name: String = HostConfig.createRepoName(url),
|
||||
var username: String? = null, var password: String? = null) {
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* For repos specified in the build file (repos()) that don't have an associated unique name,
|
||||
* create such a name from the URL. This is a requirement from Maven Resolver, and failing to do
|
||||
* this leads to very weird resolution errors.
|
||||
*/
|
||||
private fun createRepoName(url: String) = url.replace("/", "_").replace("\\", "_").replace(":", "_")
|
||||
}
|
||||
|
||||
fun hasAuth() : Boolean {
|
||||
return (! username.isNullOrBlank()) && (! password.isNullOrBlank())
|
||||
}
|
||||
|
@ -106,6 +116,7 @@ fun buildFileClasspath(vararg deps: String) {
|
|||
}
|
||||
|
||||
fun newBuildFileClasspath(vararg deps: String) {
|
||||
//FIXME newBuildFileClasspath called twice
|
||||
deps.forEach { Kobalt.addBuildFileClasspath(it) }
|
||||
}
|
||||
|
||||
|
@ -115,7 +126,7 @@ fun authRepos(vararg repos : HostConfig) {
|
|||
}
|
||||
|
||||
@Directive
|
||||
fun authRepo(init: HostConfig.() -> Unit) = HostConfig().apply { init() }
|
||||
fun authRepo(init: HostConfig.() -> Unit) = HostConfig(name = "").apply { init() }
|
||||
|
||||
@Directive
|
||||
fun glob(g: String) : IFileSpec.GlobSpec = IFileSpec.GlobSpec(g)
|
||||
|
|
|
@ -2,8 +2,10 @@ package com.beust.kobalt
|
|||
|
||||
class SystemProperties {
|
||||
companion object {
|
||||
val javaBase = System.getProperty("java.home") ?:
|
||||
(System.getenv("JAVA_HOME") ?: throw IllegalArgumentException("JAVA_HOME not defined"))
|
||||
val javaBase =
|
||||
System.getenv("JAVA_HOME")
|
||||
?: System.getProperty("java.home")
|
||||
?: throw IllegalArgumentException("JAVA_HOME not defined")
|
||||
val javaVersion = System.getProperty("java.version")
|
||||
val homeDir = System.getProperty("user.home")
|
||||
val tmpDir = System.getProperty("java.io.tmpdir")
|
||||
|
|
|
@ -12,4 +12,5 @@ data class CompilerActionInfo(val directory: String?,
|
|||
val outputDir: File,
|
||||
val compilerArgs: List<String>,
|
||||
val friendPaths: List<String>,
|
||||
val forceRecompile: Boolean)
|
||||
val forceRecompile: Boolean,
|
||||
val compilerSeparateProcess: Boolean = false)
|
||||
|
|
|
@ -5,6 +5,7 @@ import com.beust.kobalt.HostConfig
|
|||
import com.beust.kobalt.Plugins
|
||||
import com.beust.kobalt.internal.PluginInfo
|
||||
import com.beust.kobalt.maven.DependencyManager
|
||||
import com.beust.kobalt.maven.aether.KobaltMavenResolver
|
||||
import com.google.inject.Guice
|
||||
import com.google.inject.Injector
|
||||
import com.google.inject.Module
|
||||
|
@ -55,6 +56,9 @@ class Kobalt {
|
|||
// Repos from the build file
|
||||
result.addAll(reposFromBuildFiles)
|
||||
|
||||
result.forEach {
|
||||
KobaltMavenResolver.initAuthentication(it)
|
||||
}
|
||||
return result.toHashSet()
|
||||
}
|
||||
|
||||
|
@ -131,6 +135,7 @@ class Kobalt {
|
|||
|
||||
fun cleanUp() {
|
||||
buildSourceDirs.clear()
|
||||
buildFileClasspath.clear()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.beust.kobalt.*
|
|||
import com.beust.kobalt.api.*
|
||||
import com.beust.kobalt.misc.KFiles
|
||||
import com.google.common.annotations.VisibleForTesting
|
||||
import com.google.inject.Inject
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
|
@ -19,6 +20,9 @@ abstract class GenericTestRunner: ITestRunnerContributor {
|
|||
open var shortMessage: String? = null
|
||||
open var longMessage: String? = null
|
||||
|
||||
@Inject
|
||||
private lateinit var jvm: Jvm
|
||||
|
||||
abstract fun args(project: Project, context: KobaltContext, classpath: List<IClasspathDependency>,
|
||||
testConfig: TestConfig) : List<String>
|
||||
|
||||
|
@ -26,7 +30,7 @@ abstract class GenericTestRunner: ITestRunnerContributor {
|
|||
|
||||
open val extraClasspath: List<String> = emptyList()
|
||||
|
||||
open fun filterTestClasses(classes: List<String>) : List<String> = classes
|
||||
open fun filterTestClasses(project: Project, context: KobaltContext, classes: List<String>) : List<String> = classes
|
||||
|
||||
override fun run(project: Project, context: KobaltContext, configName: String,
|
||||
classpath: List<IClasspathDependency>) : TaskResult {
|
||||
|
@ -65,7 +69,7 @@ abstract class GenericTestRunner: ITestRunnerContributor {
|
|||
// }
|
||||
|
||||
context.logger.log(project.name, 2, "Found ${result.size} test classes")
|
||||
return filterTestClasses(result.map { it.second })
|
||||
return filterTestClasses(project, context, result.map { it.second })
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -116,7 +120,7 @@ abstract class GenericTestRunner: ITestRunnerContributor {
|
|||
val args = args(project, context, classpath, testConfig)
|
||||
if (args.size > 0) {
|
||||
|
||||
val java = JavaInfo.create(File(SystemProperties.javaBase)).javaExecutable
|
||||
val java = jvm.javaExecutable
|
||||
val jvmArgs = calculateAllJvmArgs(project, context, testConfig, classpath,
|
||||
Kobalt.INJECTOR.getInstance (PluginInfo::class.java))
|
||||
val allArgs = arrayListOf<String>().apply {
|
||||
|
|
|
@ -4,6 +4,10 @@ import com.beust.kobalt.TestConfig
|
|||
import com.beust.kobalt.api.IClasspathDependency
|
||||
import com.beust.kobalt.api.KobaltContext
|
||||
import com.beust.kobalt.api.Project
|
||||
import com.beust.kobalt.maven.DependencyManager
|
||||
import com.google.inject.Inject
|
||||
import java.lang.reflect.Modifier
|
||||
import java.net.URLClassLoader
|
||||
|
||||
open class JUnitRunner() : GenericTestRunner() {
|
||||
|
||||
|
@ -14,5 +18,15 @@ open class JUnitRunner() : GenericTestRunner() {
|
|||
|
||||
override fun args(project: Project, context: KobaltContext, classpath: List<IClasspathDependency>,
|
||||
testConfig: TestConfig) = findTestClasses(project, context, testConfig)
|
||||
|
||||
@Inject
|
||||
lateinit var dependencyManager: DependencyManager
|
||||
|
||||
override fun filterTestClasses(project: Project, context: KobaltContext, classes: List<String>) : List<String> {
|
||||
val deps = dependencyManager.testDependencies(project, context)
|
||||
val cl = URLClassLoader(deps.map { it.jarFile.get().toURI().toURL() }.toTypedArray())
|
||||
return classes.filter { !Modifier.isAbstract(cl.loadClass(it).modifiers) }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package com.beust.kobalt.internal
|
||||
|
||||
import com.beust.kobalt.api.KobaltContext
|
||||
import com.beust.kobalt.api.Project
|
||||
|
||||
/**
|
||||
* KotlinTestRunner triggers if it finds a dependency on io.kotlintest but other than that, it just
|
||||
* uses the regular JUnitRunner.
|
||||
|
@ -12,6 +15,7 @@ class KotlinTestRunner : JUnitRunner() {
|
|||
* KotlinTestRunner runs tests in the init{} initializer, so ignore all the extra
|
||||
* classes generated by the Kotlin compiler.
|
||||
*/
|
||||
override fun filterTestClasses(classes: List<String>) = classes.filter { ! it.contains("$") }
|
||||
override fun filterTestClasses(projet: Project, context: KobaltContext, classes: List<String>)
|
||||
= classes.filter { !it.contains("$") }
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
package com.beust.kobalt.maven
|
||||
|
||||
import com.beust.kobalt.HostConfig
|
||||
import com.beust.kobalt.KobaltException
|
||||
import com.beust.kobalt.maven.aether.KobaltMavenResolver
|
||||
import com.beust.kobalt.maven.dependency.FileDependency
|
||||
import com.beust.kobalt.misc.LocalProperties
|
||||
import java.io.*
|
||||
import java.net.HttpURLConnection
|
||||
import java.net.URL
|
||||
|
@ -21,27 +20,7 @@ class Kurl(val hostInfo: HostConfig) {
|
|||
}
|
||||
|
||||
init {
|
||||
// See if the URL needs to be authenticated. Look in local.properties for keys
|
||||
// of the format authUrl.<host>.user=xxx and authUrl.<host>.password=xxx
|
||||
val properties = LocalProperties().localProperties
|
||||
val host = java.net.URL(hostInfo.url).host
|
||||
properties.entries.forEach {
|
||||
val key = it.key.toString()
|
||||
if (key == "$KEY.$host.$VALUE_USER") {
|
||||
hostInfo.username = properties.getProperty(key)
|
||||
} else if (key == "$KEY.$host.$VALUE_PASSWORD") {
|
||||
hostInfo.password = properties.getProperty(key)
|
||||
}
|
||||
}
|
||||
fun error(s1: String, s2: String) {
|
||||
throw KobaltException("Found \"$s1\" but not \"$s2\" in local.properties for $KEY.$host",
|
||||
docUrl = "http://beust.com/kobalt/documentation/index.html#maven-repos-authenticated")
|
||||
}
|
||||
if (! hostInfo.username.isNullOrBlank() && hostInfo.password.isNullOrBlank()) {
|
||||
error("username", "password")
|
||||
} else if(hostInfo.username.isNullOrBlank() && ! hostInfo.password.isNullOrBlank()) {
|
||||
error("password", "username")
|
||||
}
|
||||
KobaltMavenResolver.initAuthentication(hostInfo)
|
||||
}
|
||||
|
||||
override fun toString() = hostInfo.toString()
|
||||
|
|
|
@ -2,11 +2,14 @@ package com.beust.kobalt.maven.aether
|
|||
|
||||
import com.beust.kobalt.Args
|
||||
import com.beust.kobalt.HostConfig
|
||||
import com.beust.kobalt.KobaltException
|
||||
import com.beust.kobalt.api.Kobalt
|
||||
import com.beust.kobalt.internal.KobaltSettings
|
||||
import com.beust.kobalt.internal.getProxy
|
||||
import com.beust.kobalt.maven.Kurl
|
||||
import com.beust.kobalt.maven.LocalRepo
|
||||
import com.beust.kobalt.maven.MavenId
|
||||
import com.beust.kobalt.misc.LocalProperties
|
||||
import com.google.common.eventbus.EventBus
|
||||
import com.google.inject.Inject
|
||||
import org.eclipse.aether.artifact.Artifact
|
||||
|
@ -21,6 +24,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 org.eclipse.aether.util.repository.AuthenticationBuilder
|
||||
import java.util.*
|
||||
|
||||
class KobaltMavenResolver @Inject constructor(val settings: KobaltSettings,
|
||||
|
@ -32,6 +36,31 @@ class KobaltMavenResolver @Inject constructor(val settings: KobaltSettings,
|
|||
MavenId.toId(it.groupId, it.artifactId, it.extension, it.classifier, it.version)
|
||||
}
|
||||
fun isRangeVersion(id: String) = id.contains(",")
|
||||
|
||||
fun initAuthentication(hostInfo: HostConfig) {
|
||||
// See if the URL needs to be authenticated. Look in local.properties for keys
|
||||
// of the format authUrl.<host>.user=xxx and authUrl.<host>.password=xxx
|
||||
val properties = LocalProperties().localProperties
|
||||
val host = java.net.URL(hostInfo.url).host
|
||||
properties.entries.forEach {
|
||||
val key = it.key.toString()
|
||||
if (key == "${Kurl.KEY}.$host.${Kurl.VALUE_USER}") {
|
||||
hostInfo.username = properties.getProperty(key)
|
||||
} else if (key == "${Kurl.KEY}.$host.${Kurl.VALUE_PASSWORD}") {
|
||||
hostInfo.password = properties.getProperty(key)
|
||||
}
|
||||
}
|
||||
fun error(s1: String, s2: String) {
|
||||
throw KobaltException("Found \"$s1\" but not \"$s2\" in local.properties for ${Kurl.KEY}.$host",
|
||||
docUrl = "http://beust.com/kobalt/documentation/index.html#maven-repos-authenticated")
|
||||
}
|
||||
if (! hostInfo.username.isNullOrBlank() && hostInfo.password.isNullOrBlank()) {
|
||||
error("username", "password")
|
||||
} else if(hostInfo.username.isNullOrBlank() && ! hostInfo.password.isNullOrBlank()) {
|
||||
error("password", "username")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun resolveToArtifact(id: String, scope: Scope? = null,
|
||||
|
@ -110,8 +139,17 @@ 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(hostConfig: HostConfig) =
|
||||
RemoteRepository.Builder(hostConfig.name, "default", hostConfig.url).build()
|
||||
private fun createRepo(hostConfig: HostConfig) : RemoteRepository {
|
||||
val builder = RemoteRepository.Builder(hostConfig.name, "default", hostConfig.url)
|
||||
if (hostConfig.hasAuth()) {
|
||||
val auth = AuthenticationBuilder()
|
||||
.addUsername(hostConfig.username)
|
||||
.addPassword(hostConfig.password)
|
||||
.build()
|
||||
builder.setAuthentication(auth)
|
||||
}
|
||||
return builder.build()
|
||||
}
|
||||
|
||||
private val kobaltRepositories: List<RemoteRepository>
|
||||
get() = Kobalt.repos.map {
|
||||
|
|
|
@ -79,10 +79,12 @@ open class NewRunCommand(val info: RunCommandInfo) {
|
|||
|
||||
// Run the command and collect the return code and streams
|
||||
val returnCode = process.waitFor(30, TimeUnit.SECONDS)
|
||||
val input = if (process.inputStream.available() > 0) fromStream(process.inputStream)
|
||||
else listOf()
|
||||
val error = if (process.errorStream.available() > 0) fromStream(process.errorStream)
|
||||
else listOf()
|
||||
val input =
|
||||
if (process.inputStream.available() > 0) fromStream(process.inputStream)
|
||||
else listOf()
|
||||
val error =
|
||||
if (process.errorStream.available() > 0) fromStream(process.errorStream)
|
||||
else listOf()
|
||||
|
||||
// Check to see if the command succeeded
|
||||
val isSuccess =
|
||||
|
@ -105,10 +107,10 @@ open class NewRunCommand(val info: RunCommandInfo) {
|
|||
open protected fun isSuccess(isSuccess: Boolean, input: List<String>, error: List<String>) : Boolean {
|
||||
var hasErrors = ! isSuccess
|
||||
if (info.useErrorStreamAsErrorIndicator && ! hasErrors) {
|
||||
hasErrors = hasErrors || error.size > 0
|
||||
hasErrors = hasErrors || error.isNotEmpty()
|
||||
}
|
||||
if (info.useInputStreamAsErrorIndicator && ! hasErrors) {
|
||||
hasErrors = hasErrors || input.size > 0
|
||||
hasErrors = hasErrors || input.isNotEmpty()
|
||||
}
|
||||
|
||||
return ! hasErrors
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.beust.kobalt
|
|||
import com.beust.jcommander.JCommander
|
||||
import com.beust.kobalt.api.Kobalt
|
||||
import com.beust.kobalt.api.PluginTask
|
||||
import com.beust.kobalt.api.Project
|
||||
import com.beust.kobalt.app.ProjectFinder
|
||||
import com.beust.kobalt.app.ProjectGenerator
|
||||
import com.beust.kobalt.app.Templates
|
||||
|
@ -44,10 +45,26 @@ class Options @Inject constructor(
|
|||
val p = if (args.buildFile != null) File(args.buildFile) else File(".")
|
||||
// val buildFile = BuildFile(Paths.get(p.absolutePath), p.name)
|
||||
val buildSources = if (p.isDirectory) BuildSources(p.absoluteFile) else SingleFileBuildSources(p)
|
||||
var pluginClassLoader = javaClass.classLoader
|
||||
val pluginClassLoader = javaClass.classLoader
|
||||
|
||||
val allProjectResult = projectFinder.initForBuildFile(buildSources, args)
|
||||
val allProjects = allProjectResult.projects
|
||||
//
|
||||
// Attempt to parse the build file in order to correctly set up repos, plug-ins, etc...
|
||||
// If the build file can't be parsed, don't give up just yet since some options don't need
|
||||
// a correct build file to work.
|
||||
//
|
||||
var buildError: Throwable? = null
|
||||
val allProjects =
|
||||
try {
|
||||
projectFinder.initForBuildFile(buildSources, args).projects
|
||||
} catch(ex: Exception) {
|
||||
buildError = ex
|
||||
listOf<Project>()
|
||||
}
|
||||
|
||||
fun runIfSuccessfulBuild(buildError: Throwable?, action: () -> Unit) {
|
||||
buildError?.let { throw it }
|
||||
action()
|
||||
}
|
||||
|
||||
// Modify `args` with options found in buildScript { kobaltOptions(...) }, if any
|
||||
addOptionsFromBuild(args, Kobalt.optionsFromBuild)
|
||||
|
@ -77,9 +94,11 @@ class Options @Inject constructor(
|
|||
}),
|
||||
Option( { -> args.projectInfo }, {
|
||||
// --projectInfo
|
||||
allProjects.forEach {
|
||||
it.compileDependencies.filter { it.isMaven }.forEach {
|
||||
resolveDependency.run(it.id)
|
||||
runIfSuccessfulBuild(buildError) {
|
||||
allProjects.forEach {
|
||||
it.compileDependencies.filter { it.isMaven }.forEach {
|
||||
resolveDependency.run(it.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
@ -89,11 +108,15 @@ class Options @Inject constructor(
|
|||
}),
|
||||
Option( { args.tasks }, {
|
||||
// --tasks
|
||||
displayTasks()
|
||||
runIfSuccessfulBuild(buildError) {
|
||||
displayTasks()
|
||||
}
|
||||
}),
|
||||
Option( { args.checkVersions }, {
|
||||
// --checkVersions
|
||||
checkVersions.run(allProjects)
|
||||
runIfSuccessfulBuild(buildError) {
|
||||
checkVersions.run(allProjects)
|
||||
}
|
||||
}),
|
||||
Option( { args.download }, {
|
||||
// --download
|
||||
|
@ -121,17 +144,19 @@ class Options @Inject constructor(
|
|||
if (! buildSources.exists()) {
|
||||
throw KobaltException("Could not find build file: " + buildSources)
|
||||
}
|
||||
val runTargetResult = taskManager.runTargets(args.targets, allProjects)
|
||||
if (result == 0) {
|
||||
result = if (runTargetResult.taskResult.success) 0 else 1
|
||||
}
|
||||
runIfSuccessfulBuild(buildError) {
|
||||
val runTargetResult = taskManager.runTargets(args.targets, allProjects)
|
||||
if (result == 0) {
|
||||
result = if (runTargetResult.taskResult.success) 0 else 1
|
||||
}
|
||||
|
||||
// Shutdown all plug-ins
|
||||
plugins.shutdownPlugins()
|
||||
// Shutdown all plug-ins
|
||||
plugins.shutdownPlugins()
|
||||
|
||||
// Run the build report contributors
|
||||
pluginInfo.buildReportContributors.forEach {
|
||||
it.generateReport(Kobalt.context!!)
|
||||
// Run the build report contributors
|
||||
pluginInfo.buildReportContributors.forEach {
|
||||
it.generateReport(Kobalt.context!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package com.beust.kobalt.app
|
||||
|
||||
import com.beust.kobalt.Args
|
||||
import com.beust.kobalt.JavaInfo
|
||||
import com.beust.kobalt.Jvm
|
||||
import com.beust.kobalt.app.remote.KobaltServer
|
||||
import com.beust.kobalt.internal.IncrementalManager
|
||||
import com.beust.kobalt.internal.KobaltSettings
|
||||
|
@ -17,6 +19,7 @@ import com.google.inject.Provider
|
|||
import com.google.inject.Singleton
|
||||
import com.google.inject.TypeLiteral
|
||||
import com.google.inject.assistedinject.FactoryModuleBuilder
|
||||
import java.io.File
|
||||
import java.util.concurrent.ExecutorService
|
||||
|
||||
open class MainModule(val args: Args, val settings: KobaltSettings) : AbstractModule() {
|
||||
|
@ -49,15 +52,14 @@ open class MainModule(val args: Args, val settings: KobaltSettings) : AbstractMo
|
|||
bind(Args::class.java).toProvider(Provider<Args> {
|
||||
args
|
||||
})
|
||||
EventBus().let { eventBus ->
|
||||
bind(EventBus::class.java).toInstance(eventBus)
|
||||
}
|
||||
bind(EventBus::class.java).toInstance(EventBus())
|
||||
bind(PluginInfo::class.java).toProvider(Provider<PluginInfo> {
|
||||
PluginInfo.readKobaltPluginXml()
|
||||
}).`in`(Singleton::class.java)
|
||||
bind(KobaltSettings::class.java).toProvider(Provider<KobaltSettings> {
|
||||
settings
|
||||
}).`in`(Singleton::class.java)
|
||||
bind(Jvm::class.java).toInstance(JavaInfo.create(File(com.beust.kobalt.SystemProperties.javaBase)))
|
||||
|
||||
// bindListener(Matchers.any(), object: TypeListener {
|
||||
// override fun <I> hear(typeLiteral: TypeLiteral<I>?, typeEncounter: TypeEncounter<I>?) {
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.beust.kobalt.app.remote
|
|||
|
||||
import com.beust.kobalt.Args
|
||||
import com.beust.kobalt.api.IClasspathDependency
|
||||
import com.beust.kobalt.api.Kobalt
|
||||
import com.beust.kobalt.api.Project
|
||||
import com.beust.kobalt.app.BuildFileCompiler
|
||||
import com.beust.kobalt.internal.DynamicGraph
|
||||
|
@ -29,7 +30,7 @@ class RemoteDependencyData @Inject constructor(val executors: KobaltExecutors, v
|
|||
val taskManager: TaskManager) {
|
||||
|
||||
fun dependenciesDataFor(buildSources: BuildSources, args: Args,
|
||||
findProjectResult: BuildFileCompiler.FindProjectResult,
|
||||
projectResult: BuildFileCompiler.FindProjectResult,
|
||||
progressListener: IProgressListener? = null,
|
||||
useGraph : Boolean = false): GetDependenciesData {
|
||||
val projectDatas = arrayListOf<ProjectData>()
|
||||
|
@ -42,9 +43,7 @@ class RemoteDependencyData @Inject constructor(val executors: KobaltExecutors, v
|
|||
fun allDeps(l: List<IClasspathDependency>, name: String) = dependencyManager.transitiveClosure(l,
|
||||
requiredBy = name)
|
||||
|
||||
// val buildFile = BuildFile(Paths.get(buildFilePath), "GetDependenciesCommand")
|
||||
val buildFileCompiler = buildFileCompilerFactory.create(buildSources, pluginInfo)
|
||||
val projectResult = buildFileCompiler.compileBuildFiles(args)
|
||||
val buildFileDependencies = Kobalt.buildFileClasspath.map {toDependencyData(it, "compile")}
|
||||
|
||||
val pluginDependencies = projectResult.pluginUrls.map { File(it.toURI()) }.map {
|
||||
DependencyData(it.name, "compile", it.absolutePath)
|
||||
|
@ -176,8 +175,8 @@ class RemoteDependencyData @Inject constructor(val executors: KobaltExecutors, v
|
|||
})
|
||||
}
|
||||
|
||||
return GetDependenciesData(projectDatas, allTasks, pluginDependencies, findProjectResult.buildContentRoots,
|
||||
projectResult.taskResult.errorMessage)
|
||||
return GetDependenciesData(projectDatas, allTasks, pluginDependencies, buildFileDependencies,
|
||||
projectResult.buildContentRoots, projectResult.taskResult.errorMessage)
|
||||
}
|
||||
|
||||
/////
|
||||
|
@ -202,6 +201,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 buildFileDependencies: List<DependencyData> = emptyList(),
|
||||
val buildContentRoots: List<String> = emptyList(),
|
||||
val errorMessage: String?) {
|
||||
companion object {
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package com.beust.kobalt.plugin.application
|
||||
|
||||
import com.beust.kobalt.*
|
||||
import com.beust.kobalt.Jvm
|
||||
import com.beust.kobalt.KobaltException
|
||||
import com.beust.kobalt.Plugins
|
||||
import com.beust.kobalt.TaskResult
|
||||
import com.beust.kobalt.api.*
|
||||
import com.beust.kobalt.api.annotation.Directive
|
||||
import com.beust.kobalt.api.annotation.Task
|
||||
|
@ -42,7 +45,7 @@ fun Project.application(init: ApplicationConfig.() -> Unit): ApplicationConfig {
|
|||
@Singleton
|
||||
class ApplicationPlugin @Inject constructor(val configActor: ConfigActor<ApplicationConfig>,
|
||||
val executors: KobaltExecutors, val nativeManager: NativeManager,
|
||||
val dependencyManager: DependencyManager, val taskContributor : TaskContributor)
|
||||
val dependencyManager: DependencyManager, val taskContributor : TaskContributor, val jvm: Jvm)
|
||||
: BasePlugin(), IRunnerContributor, ITaskContributor, IConfigActor<ApplicationConfig> by configActor {
|
||||
|
||||
companion object {
|
||||
|
@ -111,7 +114,7 @@ class ApplicationPlugin @Inject constructor(val configActor: ConfigActor<Applica
|
|||
@Suppress("UNCHECKED_CAST")
|
||||
val packages = project.projectProperties.get(PackagingPlugin.PACKAGES) as List<PackageConfig>
|
||||
val allDeps = arrayListOf(jarName)
|
||||
val java = JavaInfo.create(File(SystemProperties.javaBase)).javaExecutable!!
|
||||
val java = jvm.javaExecutable!!
|
||||
if (! isFatJar(packages, jarName)) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
// If the jar file is not fat, we need to add the transitive closure of all dependencies
|
||||
|
|
|
@ -1,10 +1,20 @@
|
|||
package com.beust.kobalt.plugin.apt
|
||||
|
||||
import com.beust.kobalt.Constants
|
||||
import com.beust.kobalt.Jvm
|
||||
import com.beust.kobalt.TaskResult
|
||||
import com.beust.kobalt.api.*
|
||||
import com.beust.kobalt.api.annotation.AnnotationDefault
|
||||
import com.beust.kobalt.api.annotation.Directive
|
||||
import com.beust.kobalt.internal.CompilerUtils
|
||||
import com.beust.kobalt.maven.DependencyManager
|
||||
import com.beust.kobalt.maven.aether.Filters
|
||||
import com.beust.kobalt.maven.aether.Scope
|
||||
import com.beust.kobalt.maven.dependency.FileDependency
|
||||
import com.beust.kobalt.misc.KFiles
|
||||
import com.beust.kobalt.misc.KobaltLogger
|
||||
import com.beust.kobalt.misc.warn
|
||||
import com.beust.kobalt.plugin.kotlin.KotlinPlugin
|
||||
import com.google.common.collect.ArrayListMultimap
|
||||
import com.google.inject.Inject
|
||||
import java.io.File
|
||||
|
@ -12,21 +22,62 @@ import java.util.*
|
|||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* The AptPlugin has two components:
|
||||
* The AptPlugin manages both apt and kapt. Each of them has two components:
|
||||
* 1) A new apt directive inside a dependency{} block (similar to compile()) that declares where
|
||||
* the annotation processor is found
|
||||
* 2) An apt{} configuration on Project that lets the user configure how the annotation is performed
|
||||
* (outputDir, etc...).
|
||||
*/
|
||||
@Singleton
|
||||
class AptPlugin @Inject constructor(val dependencyManager: DependencyManager)
|
||||
: BasePlugin(), ICompilerFlagContributor, ISourceDirectoryContributor {
|
||||
class AptPlugin @Inject constructor(val dependencyManager: DependencyManager, val kotlinPlugin: KotlinPlugin,
|
||||
val compilerUtils: CompilerUtils, val jvm: Jvm)
|
||||
: BasePlugin(), ICompilerFlagContributor, ISourceDirectoryContributor, IClasspathContributor, ITaskContributor {
|
||||
|
||||
// ISourceDirectoryContributor
|
||||
companion object {
|
||||
const val PLUGIN_NAME = "Apt"
|
||||
const val KAPT_CONFIG = "kaptConfig"
|
||||
const val APT_CONFIG = "aptConfig"
|
||||
}
|
||||
|
||||
override val name = PLUGIN_NAME
|
||||
|
||||
var kaptConfig: KaptConfig? = null
|
||||
|
||||
override fun apply(project: Project, context: KobaltContext) {
|
||||
super.apply(project, context)
|
||||
kaptConfig = kaptConfigs[project.name]
|
||||
|
||||
// Delete the output directories
|
||||
listOf(aptConfigs[project.name]?.outputDir, kaptConfig?.outputDir)
|
||||
.filterNotNull()
|
||||
.distinct()
|
||||
.map { generatedDir(project, it) }
|
||||
.forEach {
|
||||
it.normalize().absolutePath.let { path ->
|
||||
context.logger.log(project.name, 1, " Deleting " + path)
|
||||
val success = it.deleteRecursively()
|
||||
if (!success) warn(" Couldn't delete " + path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IClasspathContributor
|
||||
override fun classpathEntriesFor(project: Project?, context: KobaltContext): Collection<IClasspathDependency> {
|
||||
val result = arrayListOf<IClasspathDependency>()
|
||||
if (project != null && kaptConfig != null) {
|
||||
kaptConfig?.let { config ->
|
||||
val c = generatedClasses(project, context, config.outputDir)
|
||||
File(c).mkdirs()
|
||||
result.add(FileDependency(c))
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun generatedDir(project: Project, outputDir: String) : File
|
||||
= File(KFiles.joinDir(project.directory, KFiles.KOBALT_BUILD_DIR, outputDir))
|
||||
= File(KFiles.joinDir(project.directory, KFiles.KOBALT_BUILD_DIR, outputDir))
|
||||
|
||||
// ISourceDirectoryContributor
|
||||
override fun sourceDirectoriesFor(project: Project, context: KobaltContext): List<File> {
|
||||
val result = arrayListOf<File>()
|
||||
aptConfigs[project.name]?.let { config ->
|
||||
|
@ -40,43 +91,157 @@ class AptPlugin @Inject constructor(val dependencyManager: DependencyManager)
|
|||
return result
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val PLUGIN_NAME = "Apt"
|
||||
const val KAPT_CONFIG = "kaptConfig"
|
||||
const val APT_CONFIG = "aptConfig"
|
||||
}
|
||||
|
||||
override val name = PLUGIN_NAME
|
||||
|
||||
override fun apply(project: Project, context: KobaltContext) {
|
||||
listOf(aptConfigs[project.name]?.outputDir, aptConfigs[project.name]?.outputDir)
|
||||
.filterNotNull()
|
||||
.distinct()
|
||||
.map { generatedDir(project, it) }
|
||||
.forEach {
|
||||
it.normalize().absolutePath.let { path ->
|
||||
context.logger.log(project.name, 1, " Deleting " + path)
|
||||
val success = it.deleteRecursively()
|
||||
if (!success) warn(" Couldn't delete " + path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun generated(project: Project, context: KobaltContext, outputDir: String) =
|
||||
KFiles.joinAndMakeDir(project.directory, project.buildDirectory, outputDir,
|
||||
context.variant.toIntermediateDir())
|
||||
KFiles.joinAndMakeDir(project.directory, project.buildDirectory, outputDir)
|
||||
|
||||
private fun generatedSources(project: Project, context: KobaltContext, outputDir: String) =
|
||||
KFiles.joinDir(generated(project, context, outputDir), "sources")
|
||||
private fun generatedStubs(project: Project, context: KobaltContext, outputDir: String) =
|
||||
KFiles.joinDir(generated(project, context, outputDir), "stubs")
|
||||
private fun generatedClasses(project: Project, context: KobaltContext, outputDir: String) =
|
||||
KFiles.joinDir(generated(project, context, outputDir), "classes")
|
||||
|
||||
// ITaskContributor
|
||||
override fun tasksFor(project: Project, context: KobaltContext): List<DynamicTask> {
|
||||
val result =
|
||||
if (kaptConfig != null) {
|
||||
listOf(
|
||||
DynamicTask(this, "runKapt", "Run kapt", AnnotationDefault.GROUP, project,
|
||||
reverseDependsOn = listOf("compile"), runAfter = listOf("clean"),
|
||||
closure = {p: Project -> taskRunKapt(p)}),
|
||||
DynamicTask(this, "compileKapt", "Compile the sources generated by kapt",
|
||||
AnnotationDefault.GROUP, project,
|
||||
dependsOn = listOf("runKapt"), reverseDependsOn = listOf("compile"),
|
||||
closure = {p: Project -> taskCompileKapt(p)})
|
||||
)
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun taskCompileKapt(project: Project) : TaskResult {
|
||||
var success = true
|
||||
kaptConfigs[project.name]?.let { config ->
|
||||
val sourceDirs = listOf(
|
||||
generatedStubs(project, context, config.outputDir),
|
||||
generatedSources(project, context, config.outputDir))
|
||||
val sourceFiles = KFiles.findSourceFiles(project.directory, sourceDirs, listOf("kt")).toList()
|
||||
val buildDirectory = File(KFiles.joinDir(project.directory,
|
||||
generatedClasses(project, context, config.outputDir)))
|
||||
val flags = listOf<String>()
|
||||
val cai = CompilerActionInfo(project.directory, allDependencies(project), sourceFiles, listOf(".kt"),
|
||||
buildDirectory, flags, emptyList(), forceRecompile = true, compilerSeparateProcess = true)
|
||||
|
||||
val cr = compilerUtils.invokeCompiler(project, context, kotlinPlugin.compiler, cai)
|
||||
success = cr.failedResult == null
|
||||
}
|
||||
|
||||
return TaskResult(success)
|
||||
}
|
||||
|
||||
val annotationDependencyId = "org.jetbrains.kotlin:kotlin-annotation-processing:" +
|
||||
Constants.KOTLIN_COMPILER_VERSION
|
||||
|
||||
fun annotationProcessorDependency() = dependencyManager.create(annotationDependencyId)
|
||||
|
||||
fun aptJarDependencies(project: Project) = aptDependencies[project.name].map { dependencyManager.create(it) }
|
||||
|
||||
fun allDependencies(project: Project): List<IClasspathDependency> {
|
||||
val allDeps = arrayListOf<IClasspathDependency>()
|
||||
allDeps.add(annotationProcessorDependency())
|
||||
allDeps.addAll(aptJarDependencies(project))
|
||||
|
||||
return allDeps
|
||||
}
|
||||
|
||||
fun taskRunKapt(project: Project) : TaskResult {
|
||||
var success = true
|
||||
val flags = arrayListOf<String>()
|
||||
kaptConfig?.let { config ->
|
||||
|
||||
|
||||
val generated = generated(project, context, config.outputDir)
|
||||
val generatedSources = generatedSources(project, context, config.outputDir).replace("//", "/")
|
||||
File(generatedSources).mkdirs()
|
||||
|
||||
//
|
||||
// Tell the Kotlin compiler to use the annotation plug-in
|
||||
//
|
||||
val allDeps = allDependencies(project)
|
||||
flags.add("-Xplugin")
|
||||
flags.add(annotationProcessorDependency().jarFile.get().absolutePath)
|
||||
|
||||
// Also need tools.jar on the plug-in classpath
|
||||
jvm.toolsJar?.let { toolsJar ->
|
||||
flags.add("-Xplugin")
|
||||
flags.add(toolsJar.absolutePath)
|
||||
}
|
||||
|
||||
aptJarDependencies(project).forEach {
|
||||
flags.add("-Xplugin")
|
||||
flags.add(it.jarFile.get().absolutePath)
|
||||
}
|
||||
|
||||
//
|
||||
// Pass options to the annotation plugin
|
||||
//
|
||||
flags.add("-P")
|
||||
fun kaptPluginFlag(flagValue: String) = "plugin:org.jetbrains.kotlin.kapt3:$flagValue"
|
||||
val kaptPluginFlags = arrayListOf<String>()
|
||||
val verbose = KobaltLogger.LOG_LEVEL >= 2
|
||||
listOf("sources=" + generatedSources,
|
||||
"classes=" + generatedClasses(project, context, config.outputDir),
|
||||
"stubs=" + generatedStubs(project, context, config.outputDir),
|
||||
"verbose=$verbose",
|
||||
"aptOnly=true").forEach {
|
||||
kaptPluginFlags.add(kaptPluginFlag(it))
|
||||
}
|
||||
|
||||
//
|
||||
// Dependencies for the annotation plug-in and the generation
|
||||
//
|
||||
val dependencies = dependencyManager.calculateDependencies(project, context,
|
||||
Filters.EXCLUDE_OPTIONAL_FILTER,
|
||||
listOf(Scope.COMPILE),
|
||||
allDeps)
|
||||
dependencies.forEach {
|
||||
val jarFile = it.jarFile.get().absolutePath
|
||||
kaptPluginFlags.add(kaptPluginFlag("apclasspath=$jarFile"))
|
||||
}
|
||||
|
||||
flags.add(kaptPluginFlags.joinToString(","))
|
||||
listOf("-language-version", "1.1", "-api-version", "1.1").forEach {
|
||||
flags.add(it)
|
||||
}
|
||||
|
||||
val sourceFiles =
|
||||
KFiles.findSourceFiles(project.directory, project.sourceDirectories, listOf("kt"))
|
||||
.toList() + generatedSources
|
||||
val buildDirectory = File(KFiles.joinDir(project.directory, generated))
|
||||
val cai = CompilerActionInfo(project.directory, allDeps, sourceFiles, listOf(".kt"),
|
||||
buildDirectory, flags, emptyList(), forceRecompile = true, compilerSeparateProcess = true)
|
||||
|
||||
context.logger.log(project.name, 2, " " + kaptPluginFlags.joinToString("\n "))
|
||||
val cr = compilerUtils.invokeCompiler(project, context, kotlinPlugin.compiler, cai)
|
||||
success = cr.failedResult == null
|
||||
}
|
||||
|
||||
return TaskResult(success)
|
||||
}
|
||||
|
||||
// ICompilerFlagContributor
|
||||
override fun compilerFlagsFor(project: Project, context: KobaltContext, currentFlags: List<String>,
|
||||
suffixesBeingCompiled: List<String>): List<String> {
|
||||
if (!suffixesBeingCompiled.contains("java")) return emptyList()
|
||||
|
||||
val result = arrayListOf<String>()
|
||||
|
||||
// Only run for Java files
|
||||
if (!suffixesBeingCompiled.contains("java")) return emptyList()
|
||||
|
||||
fun addFlags(outputDir: String) {
|
||||
aptDependencies[project.name]?.let {
|
||||
result.add("-s")
|
||||
result.add(generated(project, context, outputDir))
|
||||
result.add(generatedSources(project, context, outputDir))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,10 +249,6 @@ class AptPlugin @Inject constructor(val dependencyManager: DependencyManager)
|
|||
addFlags(config.outputDir)
|
||||
}
|
||||
|
||||
kaptConfigs[project.name]?.let { config ->
|
||||
addFlags(config.outputDir)
|
||||
}
|
||||
|
||||
context.logger.log(project.name, 2, "New flags from apt: " + result.joinToString(" "))
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package com.beust.kobalt.plugin.java
|
||||
|
||||
import com.beust.kobalt.JavaInfo
|
||||
import com.beust.kobalt.SystemProperties
|
||||
import com.beust.kobalt.Jvm
|
||||
import com.beust.kobalt.TaskResult
|
||||
import com.beust.kobalt.api.*
|
||||
import com.beust.kobalt.internal.CompilerUtils
|
||||
|
@ -22,7 +21,7 @@ import javax.tools.ToolProvider
|
|||
|
||||
@Singleton
|
||||
class JavaCompiler @Inject constructor(val jvmCompiler: JvmCompiler, val kobaltLog: ParallelLogger,
|
||||
val compilerUtils: CompilerUtils) : ICompiler {
|
||||
val compilerUtils: CompilerUtils, val jvm: Jvm) : ICompiler {
|
||||
fun compilerAction(executable: File) = object : ICompilerAction {
|
||||
override fun compile(project: Project?, info: CompilerActionInfo): TaskResult {
|
||||
val projectName = project?.name
|
||||
|
@ -119,7 +118,7 @@ class JavaCompiler @Inject constructor(val jvmCompiler: JvmCompiler, val kobaltL
|
|||
-> it.compilerFlagsFor(project, context, currentFlags, suffixesBeingCompiled) }
|
||||
FlagContributor(it.flagPriority, closure)
|
||||
}
|
||||
return run(project, context, info, JavaInfo.create(File(SystemProperties.javaBase)).javacExecutable!!,
|
||||
return run(project, context, info, jvm.javacExecutable!!,
|
||||
compilerUtils.compilerFlags(project, context, info, adapters))
|
||||
}
|
||||
|
||||
|
@ -130,7 +129,7 @@ class JavaCompiler @Inject constructor(val jvmCompiler: JvmCompiler, val kobaltL
|
|||
-> it.docFlagsFor(project, context, currentFlags, suffixesBeingCompiled) }
|
||||
FlagContributor(it.flagPriority, closure)
|
||||
}
|
||||
return run(project, context, info, JavaInfo.create(File(SystemProperties.javaBase)).javadocExecutable!!,
|
||||
return run(project, context, info, jvm.javadocExecutable!!,
|
||||
compilerUtils.compilerFlags(project, context, info, adapters))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,8 @@ class KotlinCompiler @Inject constructor(
|
|||
val settings: KobaltSettings,
|
||||
val jvmCompiler: JvmCompiler,
|
||||
val compilerUtils: CompilerUtils,
|
||||
val kobaltLog: ParallelLogger) {
|
||||
val kobaltLog: ParallelLogger,
|
||||
val jvm: Jvm) {
|
||||
|
||||
val compilerAction = object: ICompilerAction {
|
||||
override fun compile(project: Project?, info: CompilerActionInfo): TaskResult {
|
||||
|
@ -44,14 +45,16 @@ class KotlinCompiler @Inject constructor(
|
|||
var filesToCompile = 0
|
||||
if (! info.outputDir.path.endsWith("ript.jar")) {
|
||||
// Don't display the message if compiling Build.kt
|
||||
filesToCompile =
|
||||
info.sourceFiles.map(::File).map {
|
||||
if (it.isDirectory) KFiles.findRecursively(it).size else 1
|
||||
}.reduce { a, b ->
|
||||
a + b
|
||||
}
|
||||
kobaltLog.log(projectName ?: "", 1,
|
||||
" Kotlin $version compiling " + Strings.pluralizeAll(filesToCompile, "file"))
|
||||
if (info.sourceFiles.isNotEmpty()) {
|
||||
filesToCompile =
|
||||
info.sourceFiles.map(::File).map {
|
||||
if (it.isDirectory) KFiles.findRecursively(it).size else 1
|
||||
}.reduce { a, b ->
|
||||
a + b
|
||||
}
|
||||
kobaltLog.log(projectName ?: "", 1,
|
||||
" Kotlin $version compiling " + Strings.pluralizeAll(filesToCompile, "file"))
|
||||
}
|
||||
}
|
||||
val cp = compilerFirst(info.dependencies.map { it.jarFile.get() })
|
||||
val infoDir = info.directory
|
||||
|
@ -86,7 +89,8 @@ class KotlinCompiler @Inject constructor(
|
|||
// the K2JVMCompiler class directly
|
||||
val actualVersion = kotlinVersion(project)
|
||||
|
||||
if (settings.kobaltCompilerSeparateProcess || actualVersion != Constants.KOTLIN_COMPILER_VERSION) {
|
||||
if (settings.kobaltCompilerSeparateProcess || actualVersion != Constants.KOTLIN_COMPILER_VERSION
|
||||
|| info.compilerSeparateProcess) {
|
||||
return invokeCompilerInSeparateProcess(classpath, info, actualVersion, project)
|
||||
|
||||
} else {
|
||||
|
@ -97,7 +101,7 @@ class KotlinCompiler @Inject constructor(
|
|||
|
||||
private fun invokeCompilerInSeparateProcess(classpath: String, info: CompilerActionInfo,
|
||||
compilerVersion: String, project: Project?): TaskResult {
|
||||
val java = JavaInfo.create(File(SystemProperties.javaBase)).javaExecutable
|
||||
val java = jvm.javaExecutable
|
||||
|
||||
val compilerClasspath = compilerDep(compilerVersion).jarFile.get().path + File.pathSeparator +
|
||||
compilerEmbeddableDependencies(null, compilerVersion).map { it.jarFile.get().path }
|
||||
|
@ -111,20 +115,24 @@ class KotlinCompiler @Inject constructor(
|
|||
val newArgs = listOf(
|
||||
"-classpath", compilerClasspath,
|
||||
K2JVMCompiler::class.java.name,
|
||||
*info.compilerArgs.toTypedArray(),
|
||||
"-classpath", classpath,
|
||||
"-d", info.outputDir.absolutePath,
|
||||
*xFlagsArray,
|
||||
*info.sourceFiles.toTypedArray())
|
||||
.filter { ! it.isEmpty() }
|
||||
|
||||
log(2, " Invoking separate kotlinc:\n " + java!!.absolutePath + " " + newArgs.joinToString())
|
||||
log(2, " Invoking separate kotlinc:\n " + java!!.absolutePath + " " + newArgs.joinToString(" "))
|
||||
|
||||
val result = NewRunCommand(RunCommandInfo().apply {
|
||||
command = java.absolutePath
|
||||
args = newArgs
|
||||
directory = File(".")
|
||||
// The Kotlin compiler issues warnings on stderr :-(
|
||||
containsErrors = { errors: List<String> -> errors.any { it.contains("rror")} }
|
||||
// // The Kotlin compiler issues warnings on stderr :-(
|
||||
useErrorStreamAsErrorIndicator = false
|
||||
// containsErrors = {
|
||||
// errors: List<String> -> errors.any { it.contains("rror")}
|
||||
// }
|
||||
}).invoke()
|
||||
return TaskResult(result == 0, errorMessage = "Error while compiling")
|
||||
}
|
||||
|
@ -135,8 +143,9 @@ class KotlinCompiler @Inject constructor(
|
|||
val friends = info.friendPaths.toTypedArray()
|
||||
|
||||
// Collect the compiler args from kotlinCompiler{} and from settings.xml and parse them
|
||||
val args2 = (kotlinConfig(project)?.args ?: arrayListOf<String>()) +
|
||||
(settings.kobaltCompilerFlags?.split(" ") ?: listOf<String>())
|
||||
val args2 =
|
||||
info.compilerArgs +
|
||||
(settings.kobaltCompilerFlags?.split(" ") ?: listOf<String>())
|
||||
val args = K2JVMCompilerArguments()
|
||||
val compiler = K2JVMCompiler()
|
||||
compiler.parseArguments(args2.toTypedArray(), args)
|
||||
|
@ -185,13 +194,27 @@ class KotlinCompiler @Inject constructor(
|
|||
|
||||
fun logk(level: Int, message: CharSequence) = kobaltLog.log(projectName, level, message)
|
||||
|
||||
logk(2, " Invoking K2JVMCompiler with arguments:"
|
||||
fun pluginClasspaths(args: K2JVMCompilerArguments) : String {
|
||||
var result = ""
|
||||
args.pluginClasspaths?.forEach {
|
||||
result += " -Xplugin " + it
|
||||
}
|
||||
args.pluginOptions?.let {
|
||||
result += " -P "
|
||||
result += it.joinToString(",")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
logk(2, " Invoking K2JVMCompiler with arguments: kotlinc "
|
||||
+ if (args.skipMetadataVersionCheck) " -Xskip-metadata-version-check" else ""
|
||||
+ " -moduleName " + args.moduleName
|
||||
+ " -d " + args.destination
|
||||
+ " -friendPaths " + args.friendPaths.joinToString(";")
|
||||
+ " -classpath " + args.classpath
|
||||
+ pluginClasspaths(args)
|
||||
+ " " + sourceFiles.joinToString(" "))
|
||||
logk(2, " Additional kotlinc arguments: "
|
||||
+ " -moduleName " + args.moduleName
|
||||
+ " -friendPaths " + args.friendPaths.joinToString(";"))
|
||||
val collector = object : MessageCollector {
|
||||
override fun clear() {
|
||||
throw UnsupportedOperationException("not implemented")
|
||||
|
@ -214,7 +237,6 @@ class KotlinCompiler @Inject constructor(
|
|||
message: String, location: CompilerMessageLocation) {
|
||||
if (severity.isError) {
|
||||
"Couldn't compile file: ${dump(location, message)}".let { fullMessage ->
|
||||
System.err.println(fullMessage)
|
||||
throw KobaltException(fullMessage)
|
||||
}
|
||||
} else if (severity == CompilerMessageSeverity.WARNING && KobaltLogger.LOG_LEVEL >= 2) {
|
||||
|
@ -224,28 +246,28 @@ class KotlinCompiler @Inject constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.setProperty("kotlin.incremental.compilation", "true")
|
||||
// TODO: experimental should be removed as soon as it becomes standard
|
||||
System.setProperty("kotlin.incremental.compilation.experimental", "true")
|
||||
//
|
||||
// System.setProperty("kotlin.incremental.compilation", "true")
|
||||
// // TODO: experimental should be removed as soon as it becomes standard
|
||||
// System.setProperty("kotlin.incremental.compilation.experimental", "true")
|
||||
|
||||
val result =
|
||||
if (cliArgs.noIncrementalKotlin || Kobalt.context?.internalContext?.noIncrementalKotlin ?: false) {
|
||||
log(2, " Kotlin incremental compilation is disabled")
|
||||
val duration = benchmarkMillis {
|
||||
compiler.exec(collector, Services.Builder().build(), args)
|
||||
if (cliArgs.noIncrementalKotlin || Kobalt.context?.internalContext?.noIncrementalKotlin ?: false) {
|
||||
log(2, " Kotlin incremental compilation is disabled")
|
||||
val duration = benchmarkMillis {
|
||||
compiler.exec(collector, Services.Builder().build(), args)
|
||||
}
|
||||
log(1, " Regular compilation time: ${duration.first} ms")
|
||||
TaskResult(duration.second == ExitCode.OK)
|
||||
} else {
|
||||
log(1, " Kotlin incremental compilation is enabled")
|
||||
val start = System.currentTimeMillis()
|
||||
val duration = benchmarkMillis {
|
||||
compileIncrementally(filesToCompile, sourceFiles, outputDir, info, args, collector)
|
||||
}
|
||||
log(1, " Incremental compilation time: ${duration.first} ms")
|
||||
TaskResult()
|
||||
}
|
||||
log(1, " Regular compilation time: ${duration.first} ms")
|
||||
TaskResult(duration.second == ExitCode.OK)
|
||||
} else {
|
||||
log(1, " Kotlin incremental compilation is enabled")
|
||||
val start = System.currentTimeMillis()
|
||||
val duration = benchmarkMillis {
|
||||
compileIncrementally(filesToCompile, sourceFiles, outputDir, info, args, collector)
|
||||
}
|
||||
log(1, " Incremental compilation time: ${duration.first} ms")
|
||||
TaskResult()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
@ -370,7 +392,8 @@ class KotlinCompiler @Inject constructor(
|
|||
* JvmCompilerPlugin#createCompilerActionInfo instead
|
||||
*/
|
||||
fun compile(project: Project?, context: KobaltContext?, compileDependencies: List<IClasspathDependency>,
|
||||
otherClasspath: List<String>, sourceFiles: List<String>, outputDir: File, args: List<String>) : TaskResult {
|
||||
otherClasspath: List<String>, sourceFiles: List<String>, outputDir: File, args: List<String>,
|
||||
compilerSeparateProcess: Boolean) : TaskResult {
|
||||
|
||||
val executor = executors.newExecutor("KotlinCompiler", 10)
|
||||
|
||||
|
@ -396,10 +419,12 @@ class KotlinCompiler @Inject constructor(
|
|||
emptyList<String>()
|
||||
}
|
||||
val info = CompilerActionInfo(project?.directory, dependencies, sourceFiles, listOf("kt"), outputDir, args,
|
||||
friendPaths, context?.internalContext?.forceRecompile ?: false)
|
||||
friendPaths, context?.internalContext?.forceRecompile ?: false, compilerSeparateProcess)
|
||||
|
||||
return jvmCompiler.doCompile(project, context, compilerAction, info,
|
||||
if (context != null) compilerUtils.sourceCompilerFlags(project, context, info) else emptyList())
|
||||
val compilerFlags =
|
||||
if (context != null) compilerUtils.sourceCompilerFlags(project, context, info)
|
||||
else emptyList()
|
||||
return jvmCompiler.doCompile(project, context, compilerAction, info, compilerFlags)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -410,6 +435,7 @@ class KConfiguration @Inject constructor(val compiler: KotlinCompiler){
|
|||
var output: File by Delegates.notNull()
|
||||
val args = arrayListOf<String>()
|
||||
var noIncrementalKotlin = false
|
||||
var compilerSeparateProcess = false
|
||||
|
||||
fun sourceFiles(s: String) = source.add(s)
|
||||
|
||||
|
@ -424,7 +450,8 @@ class KConfiguration @Inject constructor(val compiler: KotlinCompiler){
|
|||
fun compile(project: Project? = null, context: KobaltContext? = null) : TaskResult {
|
||||
val saved = context?.internalContext?.noIncrementalKotlin ?: false
|
||||
if (context != null) context.internalContext.noIncrementalKotlin = noIncrementalKotlin
|
||||
val result = compiler.compile(project, context, dependencies, classpath, source, output, args)
|
||||
val result = compiler.compile(project, context, dependencies, classpath, source, output, args,
|
||||
compilerSeparateProcess)
|
||||
if (context != null) context.internalContext.noIncrementalKotlin = saved
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -83,6 +83,7 @@ class KotlinPlugin @Inject constructor(val executors: KobaltExecutors, val depen
|
|||
sourceFiles(info.sourceFiles)
|
||||
compilerArgs(info.compilerArgs)
|
||||
output = info.outputDir
|
||||
compilerSeparateProcess = info.compilerSeparateProcess
|
||||
}.compile(project, context)
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
kobalt.version=1.0.62
|
||||
kobalt.version=1.0.72
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue