1
0
Fork 0
mirror of https://github.com/ethauvin/kobalt.git synced 2025-04-26 16:28:12 -07:00

More flexible option parsing.

This commit is contained in:
Cedric Beust 2017-03-27 09:53:24 -07:00
parent 096b2c20a4
commit ba24de7d08

View file

@ -1,36 +1,59 @@
package com.beust.kobalt package com.beust.kobalt
import com.beust.jcommander.JCommander 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.ProjectGenerator
import com.beust.kobalt.app.Templates
import com.beust.kobalt.app.UpdateKobalt import com.beust.kobalt.app.UpdateKobalt
import com.beust.kobalt.app.remote.KobaltServer import com.beust.kobalt.app.remote.KobaltServer
import com.beust.kobalt.internal.PluginInfo import com.beust.kobalt.internal.PluginInfo
import com.beust.kobalt.internal.TaskManager import com.beust.kobalt.internal.TaskManager
import com.beust.kobalt.internal.build.BuildFile import com.beust.kobalt.internal.build.BuildFile
import com.beust.kobalt.misc.CheckVersions
import com.beust.kobalt.misc.KFiles import com.beust.kobalt.misc.KFiles
import com.beust.kobalt.wrapper.Main import com.beust.kobalt.wrapper.Main
import com.google.common.collect.HashMultimap
import com.google.inject.Inject import com.google.inject.Inject
import java.io.File import java.io.File
import java.nio.file.Paths import java.nio.file.Paths
/**
* Some options require a build file, others shouldn't have one and some don't care. This
* class captures these requirements.
*/
open class Option(open val enabled: () -> Boolean, open val action: () -> Unit, open class Option(open val enabled: () -> Boolean, open val action: () -> Unit,
open val requireBuildFile: Boolean = true) open val requireBuildFile: Boolean = true)
class OptionalBuildOption(override val enabled: () -> Boolean, override val action: () -> Unit) class OptionalBuildOption(override val enabled: () -> Boolean, override val action: () -> Unit)
: Option(enabled, action, false) : Option(enabled, action, false)
class Options @Inject constructor( class Options @Inject constructor(
val plugins: Plugins,
val checkVersions: CheckVersions,
val projectGenerator: ProjectGenerator, val projectGenerator: ProjectGenerator,
val pluginInfo: PluginInfo, val pluginInfo: PluginInfo,
val serverFactory: KobaltServer.IFactory, val serverFactory: KobaltServer.IFactory,
val updateKobalt: UpdateKobalt, val updateKobalt: UpdateKobalt,
val taskManager: TaskManager val projectFinder: ProjectFinder,
val taskManager: TaskManager,
val resolveDependency: ResolveDependency
) { ) {
fun run(jc: JCommander, args: Args, argv: Array<String>) { fun run(jc: JCommander, args: Args, argv: Array<String>): Int {
val p = if (args.buildFile != null) File(args.buildFile) else KFiles.findBuildFile() val p = if (args.buildFile != null) File(args.buildFile) else KFiles.findBuildFile()
val buildFile = BuildFile(Paths.get(p.absolutePath), p.name) val buildFile = BuildFile(Paths.get(p.absolutePath), p.name)
var pluginClassLoader = javaClass.classLoader var pluginClassLoader = javaClass.classLoader
val options = arrayListOf<Option>(
val allProjects =
if (buildFile.exists()) projectFinder.initForBuildFile(buildFile, args)
else emptyList<Project>()
// Modify `args` with options found in buildScript { kobaltOptions(...) }, if any
addOptionsFromBuild(args, Kobalt.optionsFromBuild)
val options = listOf<Option>(
OptionalBuildOption( { -> args.templates != null }, { OptionalBuildOption( { -> args.templates != null }, {
// //
// --init: create a new build project and install the wrapper // --init: create a new build project and install the wrapper
@ -48,18 +71,68 @@ class Options @Inject constructor(
OptionalBuildOption( { -> args.serverMode }, { OptionalBuildOption( { -> args.serverMode }, {
// --server // --server
val port = serverFactory.create(args.force, args.port, { cleanUp() }).call() val port = serverFactory.create(args.force, args.port, { cleanUp() }).call()
}),
OptionalBuildOption( { -> args.listTemplates}, {
// --listTemplates
Templates().displayTemplates(pluginInfo)
}),
Option( { -> args.projectInfo }, {
// --projectInfo
allProjects.forEach {
it.compileDependencies.filter { it.isMaven }.forEach {
resolveDependency.run(it.id)
}
}
}),
Option( { args.dependency != null }, {
// --resolve
args.dependency?.let { resolveDependency.run(it) }
}),
Option( { args.tasks }, {
// --tasks
displayTasks()
}),
Option( { args.checkVersions }, {
// --checkVersions
checkVersions.run(allProjects)
}),
Option( { args.download }, {
// --download
updateKobalt.downloadKobalt()
}) })
) )
var processedOption = false
options.forEach { options.forEach {
if (it.enabled()) { if (it.enabled()) {
if ((it.requireBuildFile && buildFile.exists()) || ! it.requireBuildFile) { if ((it.requireBuildFile && buildFile.exists()) || ! it.requireBuildFile) {
it.action() it.action()
processedOption = true
} else if (it.requireBuildFile && ! buildFile.exists()) { } else if (it.requireBuildFile && ! buildFile.exists()) {
throw IllegalArgumentException("Couldn't find a build file") throw KobaltException("Couldn't find a build file")
} }
} }
} }
var result = 0
if (! processedOption) {
//
// Launch the build
//
val runTargetResult = taskManager.runTargets(args.targets, allProjects)
if (result == 0) {
result = if (runTargetResult.taskResult.success) 0 else 1
}
// Shutdown all plug-ins
plugins.shutdownPlugins()
// Run the build report contributors
pluginInfo.buildReportContributors.forEach {
it.generateReport(Kobalt.context!!)
}
}
return result
} }
private fun cleanUp() { private fun cleanUp() {
@ -67,4 +140,32 @@ class Options @Inject constructor(
taskManager.cleanUp() taskManager.cleanUp()
} }
private fun addOptionsFromBuild(args: Args, optionsFromBuild: ArrayList<String>) {
optionsFromBuild.forEach {
when(it) {
Args.SEQUENTIAL -> args.sequential = true
else -> throw IllegalArgumentException("Unsupported option found in kobaltOptions(): " + it)
}
}
}
private fun displayTasks() {
//
// List of tasks, --tasks
//
val tasksByPlugins = HashMultimap.create<String, PluginTask>()
taskManager.annotationTasks.forEach {
tasksByPlugins.put(it.plugin.name, it)
}
val sb = StringBuffer("List of tasks\n")
tasksByPlugins.keySet().forEach { name ->
sb.append("\n " + AsciiArt.horizontalDoubleLine + " $name "
+ AsciiArt.horizontalDoubleLine + "\n")
tasksByPlugins[name].distinctBy(PluginTask::name).sortedBy(PluginTask::name).forEach { task ->
sb.append(" ${task.name}\t\t${task.doc}\n")
}
}
println(sb.toString())
}
} }