Kobalt ships with a number of plug-ins that are available to use right away.
The Java and Kotlin plug-ins are extremely similar, the only difference is that you configure a Java project with the javaProject
directive and a Kotlin project with kotlinProject
:
val p = javaProject(wrapper) { name = "kobalt" group = "com.beust" artifactId = name version = "0.1" }
Both these directives create an object of type Project
.
A Project
has two mandatory attributes: name
and version
. If you are planning to deploy your project to a Maven repository, you also have to specify its group
(e.g. com.beust
) and artifactId
(e.g. kobalt
).
Additionally, a Project
lets you specify the following parameters:
Once you have at least one project configured, the plug-in lets you invoke the following tasks:
Variants let you configure your project to generate different artifacts compiled from different sources depending on the variant you selected.
A variant is made of at least one of the following two components:
Product flavors usually contains different source files and different logic (e.g. a "free version" and a "pro version". Build types lead to different archives (e.g. "debug" and "release", with the "release" version being obfuscated). This effect is achieved by defining identical source files in different directories and then letting Kobalt build the correct one. Each product flavor and build type has a name which translates directory into a source directory. For example:
productFlavor("free") { } buildType("release") { }
With these variants defined, you can now add source files in the "src/free/java
" and "src/release/java
" directories (Kotlin is also supported):
src/free/java/Product.java src/release/java/Product.java
If you define at least one variant, new tasks get added to your build:
$ ./kobaltw --tasks ===== java ===== compileFreeRelease compileFreeDebug ===== packaging ===== assembleFreeRelease assembleFreeDebug
For example, if you define two flavors, "pro" and "free", and two build types, "debug" and "release", four tasks will be added that combine these: "proDebug", "proRelease", "freeDebug" and "freeRelease". If you assemble any of these, an artifact named after that combination will be created, e.g. "kobalt-0.273-free-debug.jar".
If you defined at least one variant defined, a special file called BuildConfig.java
(or
BuildConfig.kt
) will be automatically generated.
packageName
in your project in order for this file to be generated or
Kobalt will fail.
This class contains at least two fields defining the current variant:
class BuildConfig { companion object { val PRODUCT_FLAVOR : String = "pro" val BUILD_TYPE : String = "debug" } }
You can add your own custom fields to this file by calling the buildConfig
directive
inside your
flavor:
productFlavor("free") { buildConfig { field("aStringField", "String", "\"The free field\"") field("anIntField", "Int", "42") } }
The generated file will then contain:
class BuildConfig { companion object { val PRODUCT_FLAVOR : String = "free" val BUILD_TYPE : String = "debug" val aStringField : String = "The free field" val anIntField : Int = 42 } }
Take a look at the variants example
project to see an actual example using variants and BuildConfig
.
The "application" plug-in lets you run your application directly from kobaltw
. You configure
it as follows:
application { mainClass = "com.beust.kobalt.wrapper.Main" jvmArgs("-Djava.library.path=libs", "-Ddebug=true") }
And you launch you app with "run
":
./kobaltw run
Here's the list of configuration parameters for the application
directive:
main
function.
The apt
plug-in adds support for annotation processing. It's made of two parts.
apt
dependency directivedependencies { apt("com.google.dagger:dagger:2.0.2") }
Instead of using compile
, you use apt
in your dependencies and you point to the jar file that contains the annotation processor. This will instruct any compiler involved in the build to run this annotation processor first.
apt
configuration directiveapt { outputDir = "generated/sources/apt" }
This directive lets you configure the output directory and a few other settings that drive the annotation processor. This directive is optional.
For a full example defining and then using an annotation processor, see the version-processor project.
The Packaging plug-in lets you generate (directive assemble
) and install (directive install
) various archives for your project: jar, war and zip files.
The assemble
directive controls which artifacts get generated for your project.
assemble { jar { } }
If you don't specify a name
for your archive, a default one will be used that contains your project name, version and the corresponding suffix, e.g. kobalt-1.1.jar
or sec-0.2.war
.
All these archives are zip files, so the zip
archive is at the top of the hierarchy and jar
and war
inherit all its attributes, which include name
, include
and exclude
.
All archives let you include and exclude files.
include
has two different forms:
assemble { zip { include("kobaltw", "README") include(from("doc/"), to("html/"), glob("**html")) } }
The first form, with just one parameter, simply copies the file from your directory into the archive, preserving its path. The second form has three parameters which allow you to move the file to a different path into your archive. Note the use of the from
, to
and glob
directives, which are necessary to disambiguate the call.
A jar
is like a zip
with two additional available parameters:
Here is how you generate an executable jar file:
assemble { jar { fatJar = true manifest { attributes("Main-Class", "com.beust.kobalt.KobaltPackage") } } }
The war
directive generates a war file suitable to be deployed into a servlet container.
The mavenJars
directive generates several jar files (binary, source, javadoc) which are required by Maven repositories. It's basically a shortcut that saves you the trouble from having to assemble these jar files manually in your build file. It allows you to specify Manifest attributes, just like the jar
directive.
The install
section lets you specify how the artifacts get installed. If you don't specify any install
directive, then the install
task will do nothing on your project when invoked.
install { libDir = "libs" }
The Publishing plug-in lets you upload files to JCenter. These files can be either generic ones (e.g. a zip file, a README, etc...) or a Maven-compatible form of your project.
Before you can upload, you need to create a file local.properties
in the root directory of your project with the following keys:
bintray.user=... bintray.apikey=...
The values for the user
and apikey
keys can be found in your bintray profile, as described here. Add this file to your .gitignore
file and make sure you never upload it to your source control.
Before you can upload, you also need to create the package in bintray, as explained here. Once this is done, you are ready to do your first upload.
You define what to upload with the jcenter
directive:
jcenter { publish = true file("${kobalt.buildDirectory}/libs/${kobalt.name}-${kobalt.version}.zip", "${kobalt.name}/${kobalt.version}/${kobalt.name}-${kobalt.version}.zip") }
The jcenter
directive accepts the following parameters:
https://dl.bintray.com/cbeust/maven
). Once the file is uploaded there, it can be automatically synchronized to JCenter by linking your project to JCenter on the bintray web site. By default, files are not published.
$ ./kobaltw uploadJcenter ... ========== kobalt-line-count:uploadJcenter kobalt-line-count: Found 2 artifacts to upload All artifacts successfully uploaded
Dokka is Kotlin's documentation tool. The Kobalt Dokka plug-in allows you to launch it and configure it as follows:
import com.beust.kobalt.plugin.dokka.dokka // ... dokka { outputFormat = "markdown" sourceLinks { dir = "src/main/kotlin" url = "https://github.com/cy6erGn0m/vertx3-lang-kotlin/blob/master/src/main/kotlin" urlSuffix = "#L" } }
You can then generate your documentation by running the dokka
task. Here is the full list of configuration parameters allowed:
@sample
tag).html
, markdown
, jekyll
,
or javadoc
.