From 5f2b037bbda6fbdddc3e38a63e8110958e42af0f Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 9 Oct 2015 22:49:29 -0700 Subject: [PATCH] Plug-in doc. --- css/kobalt.css | 56 ++++++++++++++ plug-in-development/index.html | 134 ++++++++++++++++++++++++++++++++- 2 files changed, 187 insertions(+), 3 deletions(-) create mode 100644 css/kobalt.css diff --git a/css/kobalt.css b/css/kobalt.css new file mode 100644 index 0000000..575e3ef --- /dev/null +++ b/css/kobalt.css @@ -0,0 +1,56 @@ +.bs-callout { + padding: 20px; + margin: 20px 0; + border: 1px solid #eee; + border-left-width: 5px; + border-radius: 3px; +} +.bs-callout h4 { + margin-top: 0; + margin-bottom: 5px; +} +.bs-callout p:last-child { + margin-bottom: 0; +} +.bs-callout code { + border-radius: 3px; +} +.bs-callout+.bs-callout { + margin-top: -5px; +} +.bs-callout-default { + border-left-color: #777; +} +.bs-callout-default h4 { + color: #777; +} +.bs-callout-primary { + border-left-color: #428bca; +} +.bs-callout-primary h4 { + color: #428bca; +} +.bs-callout-success { + border-left-color: #5cb85c; +} +.bs-callout-success h4 { + color: #5cb85c; +} +.bs-callout-danger { + border-left-color: #d9534f; +} +.bs-callout-danger h4 { + color: #d9534f; +} +.bs-callout-warning { + border-left-color: #f0ad4e; +} +.bs-callout-warning h4 { + color: #f0ad4e; +} +.bs-callout-info { + border-left-color: #5bc0de; +} +.bs-callout-info h4 { + color: #5bc0de; +} diff --git a/plug-in-development/index.html b/plug-in-development/index.html index a71335a..f3e2915 100644 --- a/plug-in-development/index.html +++ b/plug-in-development/index.html @@ -9,7 +9,7 @@ - + @@ -52,6 +52,19 @@
+

Introduction

+ +

+ Kobalt plug-ins are usually made of two parts. + +

+

+

+ We'll cover these two items shortly but first of all, let's go over a quick example that will show you the whole process of writing a plug-in from scratch and publishing it on JCenter in ten minutes. +

Writing and publishing a plug-in in ten minutes

@@ -235,7 +248,7 @@ Found 4972 lines in 65 files And that's it! You can now iterate on your plug-in and upload it with additional ./kobaltw uploadJcenter. This plug-in is available on github.

-

Debugging a Kobalt plug-in

+

Debugging

The simplest way to run your plug-in in your IDE is to create a main function in the main class of your plug-in as follows: @@ -269,7 +282,122 @@ val p = plugins(

You can now set a breakpoint in your plug-in and launch the configuration you created above.

-
+

Initialization

+

+ When your plug-in is activated, Kobalt will invoke its apply() function: +

+
+override fun apply(project: Project, context: KobaltContext) {
+}
+
+

+ project is the project that your plug-in is currently being initialized for (keep in mind there can be multiple projects in a build) and the context gives you some information about other external data you might find useful, such as the command line that was passed to Kobalt. +

+ +

Directives

+

+ Directives are functions that users of your plug-in can use in their build file in order to configure your plug-in. These can be any kind of Kotlin function but in the interest of preserving a clean syntax in the build file, it's recommended to use the type safe builder pattern, as described here. +

+

+ Imagine that you want to offer a boolean parameter publish to users of your plug-in, you start by creating a class to hold that parameter: +

+
+class Info(val publish: Boolean)
+
+

+ Next, you create a directive that returns such a class and which also allows to configure it via the type safe builder pattern: +

+
+@Directive
+public fun myConfig(init: Info.() -> Unit) : Info {
+    val info = Info()
+    info.init()
+    return info
+}
+
+

+ The @Directive annotation is not enforced but you should always use it in order to help future tools (e.g. an IDEA plug-in) identify Kobalt directives so they can be treated differently from regular Kotlin functions. +

+

+ Users can now specify the following in their build file: +

+
+// Build.kt
+import.com.example.plugin.myConfig
+
+myConfig {
+    publish = true
+}
+
+

+ If you need access to the project being built, just declare an additional parameter of type Project to your directive and have the user pass that project: +

+
+@Directive
+public fun myConfig(project: Project, init: Info.() -> Unit) : Info {
+// ...
+
+
+myConfig(project) {
+    publish = true
+}
+
+

+ The last piece of this puzzle is how you give this data back to your plug-in so it can act on it. In order to do this, you simply look up the name of your plug-in in the Plugins registry and invoke whatever function you need to run: +

+ +
+@Directive
+public fun myConfig(project: Project, init: Info.() -> Unit) : Info {
+    val info = Info()
+    info.init()
+    (Plugins.getPlugin("my-plug-in") as MyPlugin).addInfo(info)
+    return info
+}
+
+ +

Tasks

+

+ Tasks are provided by plug-ins and can be invoked from the command line, e.g. ./gradlew assemble. There are two kinds of tasks: static and dynamic. +

+

Static tasks

+

+ Static tasks are functions declared directly on your plug-in and annotated with the @Task annotation. Here is an example: +

+
+@Task(name = "lineCount", description = "Count the lines", runBefore = arrayOf("compile"))
+fun lineCount(project: Project): TaskResult {
+    // ...
+    return TaskResult()
+}
+
+

+ A Kobalt task needs to accept a Project in parameter and return a TaskResult, which indicates whether this task completed successfully. +

+ +
+

Request for feedback

+ Having the Project passed in both the apply() function and in each task feels redundant, although it avoids the trouble from having to store that project in a field of the plug-in, making it essentially stateless. +
+ +

+ The @Task annotation accepts the following attributes: +

+
name
+
The name of the task, which will be used to invoke it from the command line.
+
description
+
The description of this command, which will be displayed if the user invokes the usage for the gradlew command.
+
runBefore
+
A list of all the tasks that this task should run prior to.
+
runAfter
+
A list of all the tasks that should run before this task does.
+
+

+

Dynamic tasks

+ + + +