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

OsgiPlugin.

This commit is contained in:
Cedric Beust 2017-04-26 14:19:55 -07:00
parent a367621ee4
commit 161e5db53c
5 changed files with 125 additions and 32 deletions

View file

@ -50,12 +50,14 @@ class TaskContributor @Inject constructor(val incrementalManagerFactory: Increme
reverseDependsOn : List<String> = emptyList(), reverseDependsOn : List<String> = emptyList(),
runBefore : List<String> = emptyList(), runBefore : List<String> = emptyList(),
runAfter : List<String> = emptyList(), runAfter : List<String> = emptyList(),
alwaysRunAfter: List<String> = emptyList(),
runTask: (Project) -> TaskResult) { runTask: (Project) -> TaskResult) {
dynamicTasks.add(DynamicTask(plugin, taskName, description, group, project, dynamicTasks.add(DynamicTask(plugin, taskName, description, group, project,
dependsOn = dependsOn, dependsOn = dependsOn,
reverseDependsOn = reverseDependsOn, reverseDependsOn = reverseDependsOn,
runBefore = runBefore, runBefore = runBefore,
runAfter = runAfter, runAfter = runAfter,
alwaysRunAfter = alwaysRunAfter,
closure = { p: Project -> closure = { p: Project ->
runTask(project) runTask(project)
})) }))

View file

@ -1,8 +1,9 @@
package com.beust.kobalt package com.beust.kobalt
import com.beust.jcommander.JCommander import com.beust.jcommander.JCommander
import com.beust.kobalt.api.ITask
import com.beust.kobalt.api.Kobalt import com.beust.kobalt.api.Kobalt
import com.beust.kobalt.api.PluginTask import com.beust.kobalt.api.KobaltContext
import com.beust.kobalt.api.Project import com.beust.kobalt.api.Project
import com.beust.kobalt.app.ProjectFinder import com.beust.kobalt.app.ProjectFinder
import com.beust.kobalt.app.ProjectGenerator import com.beust.kobalt.app.ProjectGenerator
@ -109,7 +110,7 @@ class Options @Inject constructor(
Option( { args.tasks }, { Option( { args.tasks }, {
// --tasks // --tasks
runIfSuccessfulBuild(buildError) { runIfSuccessfulBuild(buildError) {
displayTasks() displayTasks(allProjects, Kobalt.context!!)
} }
}), }),
Option( { args.checkVersions }, { Option( { args.checkVersions }, {
@ -177,19 +178,29 @@ class Options @Inject constructor(
} }
} }
private fun displayTasks() { private fun displayTasks(projects: List<Project>, context: KobaltContext) {
// //
// List of tasks, --tasks // List of tasks, --tasks
// //
val tasksByPlugins = HashMultimap.create<String, PluginTask>() val tasksByPlugins = HashMultimap.create<String, ITask>()
taskManager.annotationTasks.forEach { projects.forEach { project ->
tasksByPlugins.put(it.plugin.name, it) pluginInfo.taskContributors.forEach {
val tasks = it.tasksFor(project, context)
tasks.forEach {
tasksByPlugins.put(it.plugin.name, it)
}
}
}
listOf(taskManager.annotationTasks, taskManager.dynamicTasks).forEach { tasks ->
tasks.forEach {
tasksByPlugins.put(it.plugin.name, it)
}
} }
val sb = StringBuffer("List of tasks\n") val sb = StringBuffer("List of tasks\n")
tasksByPlugins.keySet().forEach { name -> tasksByPlugins.keySet().forEach { name ->
sb.append("\n " + AsciiArt.horizontalDoubleLine + " $name " sb.append("\n " + AsciiArt.horizontalDoubleLine + " $name "
+ AsciiArt.horizontalDoubleLine + "\n") + AsciiArt.horizontalDoubleLine + "\n")
tasksByPlugins[name].distinctBy(PluginTask::name).sortedBy(PluginTask::name).forEach { task -> tasksByPlugins[name].distinctBy(ITask::name).sortedBy(ITask::name).forEach { task ->
sb.append(" ${task.name}\t\t${task.doc}\n") sb.append(" ${task.name}\t\t${task.doc}\n")
} }
} }

View file

@ -0,0 +1,103 @@
package com.beust.kobalt.plugin.osgi
import aQute.bnd.osgi.Analyzer
import com.beust.kobalt.TaskResult
import com.beust.kobalt.api.*
import com.beust.kobalt.api.annotation.Directive
import com.beust.kobalt.archive.Archives
import com.beust.kobalt.maven.DependencyManager
import com.beust.kobalt.misc.KFiles
import com.beust.kobalt.plugin.packaging.PackagingPlugin
import com.google.common.reflect.ClassPath
import com.google.inject.Inject
import com.google.inject.Singleton
import java.io.File
import java.net.URI
import java.net.URLClassLoader
import java.nio.file.FileSystems
import java.nio.file.Files
import java.nio.file.StandardOpenOption
/**
* Generate OSGi attributes in the MANIFEST.MF if an osgi{} directive was found in the project.
*/
@Singleton
class OsgiPlugin @Inject constructor(val configActor: ConfigActor<OsgiConfig>, val taskContributor: TaskContributor,
val dependencyManager: DependencyManager)
: BasePlugin(), ITaskContributor by taskContributor, IConfigActor<OsgiConfig> by configActor {
companion object {
const val PLUGIN_NAME = "Osgi"
}
override val name: String = PLUGIN_NAME
override fun apply(project: Project, context: KobaltContext) {
super.apply(project, context)
configurationFor(project)?.let { config ->
taskContributor.addTask(this, project, "generateOsgiManifest",
description = "Generate the OSGi information in the manifest",
group = "build",
alwaysRunAfter = listOf(PackagingPlugin.TASK_ASSEMBLE),
runTask = { generateManifest(project, context) })
}
}
private fun generateManifest(project: Project, context: KobaltContext): TaskResult {
val jarName = project.projectProperties.get(Archives.JAR_NAME) as String
val jarFile = File(KFiles.libsDir(project), jarName)
val cp = ClassPath.from(URLClassLoader(arrayOf(jarFile.toURI().toURL()), null))
val packages = cp.allClasses.map { it.packageName }.distinct()
val exportPackageLine = packages.map {
it + ";version=\"" + project.version + "\""
}.joinToString(",")
val analyzer = Analyzer().apply {
jar = aQute.bnd.osgi.Jar(jarName)
val dependencies = project.compileDependencies + project.compileRuntimeDependencies
dependencyManager.calculateDependencies(project, context, passedDependencies = dependencies).forEach {
addClasspath(it.jarFile.get())
}
setProperty(Analyzer.BUNDLE_VERSION, project.version)
setProperty(Analyzer.BUNDLE_NAME, project.group + "." + project.artifactId)
setProperty(Analyzer.BUNDLE_DESCRIPTION, project.description)
setProperty(Analyzer.IMPORT_PACKAGE, "*")
setProperty(Analyzer.EXPORT_PACKAGE, exportPackageLine)
project.pom?.let { pom ->
if (pom.licenses.any()) {
setProperty(Analyzer.BUNDLE_LICENSE, pom.licenses[0].url)
}
}
}
val manifest = analyzer.calcManifest()
val lines = manifest.mainAttributes.map {
it.key.toString() + ": " + it.value.toString()
}
context.logger.log(project.name, 2, " Generated manifest:")
lines.forEach {
context.logger.log(project.name, 2, " $it")
}
val uri = URI.create("jar:file:" + jarFile.absolutePath)
val options = hashMapOf<String, String>()
FileSystems.newFileSystem(uri, options).use { fs ->
val jarManifest = fs.getPath("/META-INF/MANIFEST.MF")
Files.write(jarManifest, lines, StandardOpenOption.APPEND)
}
return TaskResult()
}
}
class OsgiConfig
@Directive
fun Project.osgi(init: OsgiConfig.() -> Unit) {
OsgiConfig().let {
it.init()
(Kobalt.findPlugin(OsgiPlugin.PLUGIN_NAME) as OsgiPlugin).addConfiguration(this, it)
}
}

View file

@ -27,7 +27,7 @@ class PackagingPlugin @Inject constructor(val dependencyManager : DependencyMana
val zipGenerator: ZipGenerator, val taskContributor: TaskContributor, val zipGenerator: ZipGenerator, val taskContributor: TaskContributor,
val kobaltLog: ParallelLogger, val kobaltLog: ParallelLogger,
val pomFactory: PomGenerator.IFactory, val configActor: ConfigsActor<InstallConfig>) val pomFactory: PomGenerator.IFactory, val configActor: ConfigsActor<InstallConfig>)
: BasePlugin(), ITaskContributor, IIncrementalAssemblyContributor, : BasePlugin(), ITaskContributor by taskContributor, IIncrementalAssemblyContributor,
IConfigsActor<InstallConfig> by configActor { IConfigsActor<InstallConfig> by configActor {
companion object { companion object {
@ -196,27 +196,6 @@ class PackagingPlugin @Inject constructor(val dependencyManager : DependencyMana
packages.add(p) packages.add(p)
} }
// @Task(name = "generateOsgiManifest", alwaysRunAfter = arrayOf(TASK_ASSEMBLE))
// fun generateManifest(project: Project): TaskResult {
// val analyzer = Analyzer().apply {
// jar = aQute.bnd.osgi.Jar(project.projectProperties.get(Archives.JAR_NAME) as String)
// val dependencies = project.compileDependencies + project.compileRuntimeDependencies
// dependencyManager.calculateDependencies(project, context, passedDependencies = dependencies).forEach {
// addClasspath(it.jarFile.get())
// }
// setProperty(Analyzer.BUNDLE_VERSION, project.version)
// setProperty(Analyzer.BUNDLE_NAME, project.group)
// setProperty(Analyzer.BUNDLE_DESCRIPTION, project.description)
// setProperty(Analyzer.IMPORT_PACKAGE, "*")
// setProperty(Analyzer.EXPORT_PACKAGE, "*;-noimport:=false;version=" + project.version)
// }
//
// val manifest = analyzer.calcManifest()
// manifest.write(System.out)
// return TaskResult()
// }
private fun taskInstall(project: Project, context: KobaltContext, config: InstallConfig) : TaskResult { private fun taskInstall(project: Project, context: KobaltContext, config: InstallConfig) : TaskResult {
val buildDir = project.projectProperties.getString(LIBS_DIR) val buildDir = project.projectProperties.getString(LIBS_DIR)
val buildDirFile = File(buildDir) val buildDirFile = File(buildDir)
@ -248,9 +227,6 @@ class PackagingPlugin @Inject constructor(val dependencyManager : DependencyMana
return TaskResult() return TaskResult()
} }
//ITaskContributor
override fun tasksFor(project: Project, context: KobaltContext): List<DynamicTask> = taskContributor.dynamicTasks
} }
@Directive @Directive

View file

@ -15,6 +15,7 @@
<class-name>com.beust.kobalt.plugin.groovy.GroovyPlugin</class-name> <class-name>com.beust.kobalt.plugin.groovy.GroovyPlugin</class-name>
<class-name>com.beust.kobalt.internal.JvmCompilerPlugin</class-name> <class-name>com.beust.kobalt.internal.JvmCompilerPlugin</class-name>
<class-name>com.beust.kobalt.internal.BuildListeners</class-name> <class-name>com.beust.kobalt.internal.BuildListeners</class-name>
<class-name>com.beust.kobalt.plugin.osgi.OsgiPlugin</class-name>
<!-- These classes manage -init for Java and Kotlin --> <!-- These classes manage -init for Java and Kotlin -->
<class-name>com.beust.kobalt.app.Templates</class-name> <class-name>com.beust.kobalt.app.Templates</class-name>