From bb27130d07605cafdaff8cd1cd80070075108a38 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 20 Jan 2016 19:06:27 -0800 Subject: [PATCH 01/65] Rephrase. --- getting-started/index.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/getting-started/index.html b/getting-started/index.html index b3ae474..c5923e4 100644 --- a/getting-started/index.html +++ b/getting-started/index.html @@ -127,7 +127,9 @@ val p = kotlinProject {

4. Sync your build file

- If you're using Intellij IDEA, make sure you've installed the Kobalt plugin and then go to Kobalt -> Sync Build File. This will download dependencies in a way that IDEA understand so you no loger get errors. + If you're using Intellij IDEA, make sure you've installed the Kobalt plugin and then go to Kobalt -> Sync Build File. Once the build file is synchronized, the errors should disappear + and you can now use all the regular functions of IDEA on Build.kt just like any other Kotlin + files (auto completion, jump to symbol, etc...).

5. Next steps

From 174a59eadd8647e0498b6a8dfe8722948c26e851 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 27 Jan 2016 15:26:26 -0800 Subject: [PATCH 02/65] Update "Contributing" section. --- contributing/index.html | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/contributing/index.html b/contributing/index.html index 0f8e336..ca06646 100644 --- a/contributing/index.html +++ b/contributing/index.html @@ -37,7 +37,7 @@
-

License, Source code & Issues

+

License, Source code & Issues

Kobalt is licensed under Apache 2.0

@@ -53,8 +53,33 @@
  • Join kobalt-dev, the mailing-list for Kobalt developers. This mailing-list is for people interested in writing code for Kobalt, either the core, or writing plug-ins, or just to follow various technical discussions about Kobalt's internals.
  • -

    Launch configuration

    -

    Here is how to configure your development environment.

    +

    Configuring IDEA

    +

    + Working on the Kobalt code base with Intellij IDEA is very easy. +

    +

    Edit kobalt.version

    +

    + First of all, edit the file src/main/resources/kobalt.properties and set it + to a nonexistent version. For example, if the current version is 0.399, + set it to 0.400. +

    +
    +                    kobalt.version=0.400
    +                
    +

    + When you launch Kobalt from IDEA with a nonexistent version, Kobalt will show a message saying + that it couldn't locate that version and instead, it will use the classes generated by IDEA. This + way, you will always be running the files that you just modified with IDEA. On start up, + Kobalt will display a message looking like: +

    +
    +Couldn't find .../kobalt-0.400.jar, using ...
    +                
    +

    + Note that at the moment, Kobalt expects to be located in $HOME/kotlin/kobalt. +

    +

    Launch configuration

    +

    Next, create a launch configuration in IDEA.

    Kobalt's main class is com.beust.kobalt.MainKt. Here is a typical launch configuration:

    From f7da7c961add9eeaafa71685e496943e847d4de1 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 30 Jan 2016 00:49:21 +0400 Subject: [PATCH 03/65] Add u2020. --- home/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/home/index.html b/home/index.html index eef955f..f7f7a94 100644 --- a/home/index.html +++ b/home/index.html @@ -172,6 +172,7 @@ Kobalt is currently in Beta but already used in several projects. Here are links
  • JCommander.
  • TestNG (this build file shows an example of adding a custom task in the build itself).
  • Klaxon
  • +
  • u2020 (Android show case application)
  • ... and of course, Kobalt itself (this build file demonstrates multi projects and project dependencies).
  • From 7d170bfb53e681d2374ce0b99c0a72458dd47947 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 2 Feb 2016 23:40:30 +0400 Subject: [PATCH 04/65] Document mixed projects. --- plug-ins/index.html | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/plug-ins/index.html b/plug-ins/index.html index 466b2f2..e8755bf 100644 --- a/plug-ins/index.html +++ b/plug-ins/index.html @@ -58,8 +58,7 @@ val p = javaProject(wrapper) { group = "com.beust" artifactId = name version = "0.1" -} - +}

    Both these directives create an object of type Project. @@ -85,6 +84,25 @@ A Project has two mandatory attributes: name and The dependencies for your tests +

    Mixed language projects

    +

    + A Kobalt project can have multiple languages in it (Kotlin and Java): just specify all the source + directories you need. For example, for a javaProject, add src/main/kotlin as a + source directory: +

    +
    +val p = javaProject(wrapper) {
    +    name = "kobalt"
    +    // ...
    +    sourceDirectories {
    +        path("src/main/java", "src/main/kotlin")
    +    }
    +}
    +

    Note that source files must be in their respective directory (.java in + src/main/java and .kt in src/main/kotlin). This restrictions + might be relaxed in the future. +

    +

    Tasks

    Once you have at least one project configured, the plug-in lets you invoke the following tasks: From afa2b44dcf5a0540271b43b712768746f5520b4a Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 2 Feb 2016 23:41:51 +0400 Subject: [PATCH 05/65] Remove. --- plug-ins/index.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plug-ins/index.html b/plug-ins/index.html index e8755bf..ba717e3 100644 --- a/plug-ins/index.html +++ b/plug-ins/index.html @@ -99,8 +99,7 @@ val p = javaProject(wrapper) { } }

    Note that source files must be in their respective directory (.java in - src/main/java and .kt in src/main/kotlin). This restrictions - might be relaxed in the future. + src/main/java and .kt in src/main/kotlin).

    Tasks

    From b8280cfa3177ae7a32fefe8ac4eda70d70a935d9 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 4 Feb 2016 06:51:36 -0800 Subject: [PATCH 06/65] Font size. --- home/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/home/index.html b/home/index.html index eef955f..0f06314 100644 --- a/home/index.html +++ b/home/index.html @@ -62,7 +62,7 @@

    - + Kobalt is a build system inspired by Gradle and Maven. It reuses the best concepts from these two successful and popular build systems while adding a few modern features of its own. Kobalt is written entirely in Kotlin and its build files are valid Kotlin files as well. Thanks to IDEA's top notch @@ -71,7 +71,7 @@

    - + Here are some of Kobalt's most prominent features.

    From 53c40c33b356339cbbe054fd696b12492c6ee1a1 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 4 Feb 2016 22:48:29 +0400 Subject: [PATCH 07/65] Remove kotlinProject/javaProject. --- documentation/index.html | 17 ++++++++--------- getting-started/index.html | 2 +- home/index.html | 2 +- plug-in-development/index.html | 2 +- plug-ins/index.html | 16 ++++++++-------- ten-minutes/index.html | 2 +- 6 files changed, 20 insertions(+), 21 deletions(-) diff --git a/documentation/index.html b/documentation/index.html index ab9d044..1eb11a2 100644 --- a/documentation/index.html +++ b/documentation/index.html @@ -68,9 +68,8 @@ The build file is located in kobalt/src/Built.kt and it is a valid
     import com.beust.kobalt.*
    -import com.beust.kobalt.plugin.kotlin.kotlinProject
     
    -val kobalt = kotlinProject {
    +val kobalt = project {
         name = "kobalt"
         group = "com.beust"
         artifactId = name
    @@ -84,7 +83,7 @@ Here are a few noteworthy details about this small build file:
     
    • You have now declared a variable called kobalt which you can reuse further in your build file, should you ever need to.
    • You can specify the directory of the project if it's not in the root, which means that one build file can be used to build multiple projects. -
    • The functions kotlinProject and homeDir are supplied by Kobalt and are referred to as "directives" +
    • The functions project and homeDir are supplied by Kobalt and are referred to as "directives"

    @@ -124,7 +123,7 @@ Now that we have declared a project, we can use it to configure additional steps

     import com.beust.kobalt.plugin.packaging.assemble
     
    -val kobalt = kotlinProject {
    +val kobalt = project {
         // ...
         assemble {
             jar {
    @@ -374,8 +373,8 @@ You can specify more than one project in a build file, simply by declaring them:
     

    -val p1 = javaProject { ... }
    -val p2 = kotlinProject { ... }
    +val p1 = project { ... }
    +val p2 = project { ... }
     

    @@ -383,7 +382,7 @@ If some of your projects need to be built in a certain order, you can specify de

    -val p2 = kotlinProject(p1) { ... }
    +val p2 = project(p1) { ... }
     

    @@ -502,7 +501,7 @@ First of all, make sure you specified the group, artifactId and version of your

    -val kobalt = kotlinProject {
    +val kobalt = project {
         group = "com.beust"
         artifactId = "kobalt"
         version = "0.72"
    @@ -551,7 +550,7 @@ Now, all you need to do is to upload your package:
       Then you use this variable wherever you need it in your build file:
     

    -  val p = javaProject {
    +  val p = project {
           name = if (experimental) "project-exp" else "project"
           version = "1.3"
     
    diff --git a/getting-started/index.html b/getting-started/index.html index c5923e4..af005fd 100644 --- a/getting-started/index.html +++ b/getting-started/index.html @@ -86,7 +86,7 @@ import com.beust.kobalt.plugin.kotlin.* val kotlinVersion = "1.0.0-beta-4583" -val p = kotlinProject { +val p = project { name = "wasabi" group = "com.example" diff --git a/home/index.html b/home/index.html index ffbfb99..19de4d6 100644 --- a/home/index.html +++ b/home/index.html @@ -109,7 +109,7 @@ import com.beust.kobalt.plugin.java.* import com.beust.kobalt.plugin.packaging.* import com.beust.kobalt.plugin.publish.* -val jcommander = javaProject { +val jcommander = project { name = "jcommander" group = "com.beust" artifactId = name diff --git a/plug-in-development/index.html b/plug-in-development/index.html index e96eb76..272caa2 100644 --- a/plug-in-development/index.html +++ b/plug-in-development/index.html @@ -68,7 +68,7 @@

    • kobalt-plugin.xml. A file that describes all the components (called "plug-in actors") of your plug-in, such as contributors.
    • -
    • Directives. Kotlin functions that users of your plug-in can invoke in their build file, such as kotlinProject or dependencies. These functions typically configure some data that your plug-in will later use to perform its functions.
    • +
    • Directives. Kotlin functions that users of your plug-in can invoke in their build file, such as project or dependencies. These functions typically configure some data that your plug-in will later use to perform its functions.
    • Tasks. These tasks are invoked from the command line and ask your plug-ins to perform certain actions.
    • Properties. Plug-ins can export properties and read properties from other plug-ins.
    diff --git a/plug-ins/index.html b/plug-ins/index.html index ba717e3..9179a68 100644 --- a/plug-ins/index.html +++ b/plug-ins/index.html @@ -50,10 +50,11 @@

    Java and Kotlin

    -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: + Java and Kotlin are supported by default by Kobalt. You use the directive project{} + to declare a new project and Kobalt will automatically detect how to compile it:

    -val p = javaProject(wrapper) {
    +val p = project(wrapper) {
       name = "kobalt"
       group = "com.beust"
       artifactId = name
    @@ -61,7 +62,7 @@ val p = javaProject(wrapper) {
     }

    -Both these directives create an object of type Project. +The project{} directive creates an object of type Project.

    Project

    @@ -87,19 +88,18 @@ A Project has two mandatory attributes: name and Mixed language projects

    A Kobalt project can have multiple languages in it (Kotlin and Java): just specify all the source - directories you need. For example, for a javaProject, add src/main/kotlin as a - source directory: + directories you need:

    -val p = javaProject(wrapper) {
    +val p = project(wrapper) {
         name = "kobalt"
         // ...
         sourceDirectories {
             path("src/main/java", "src/main/kotlin")
         }
     }
    -

    Note that source files must be in their respective directory (.java in - src/main/java and .kt in src/main/kotlin). +

    + Kotlin and Java files can be in the same directories.

    Tasks

    diff --git a/ten-minutes/index.html b/ten-minutes/index.html index 84897a8..4569eb3 100644 --- a/ten-minutes/index.html +++ b/ten-minutes/index.html @@ -84,7 +84,7 @@ $ $KOBALT_HOME/kobaltw --init

    -val project = kotlinProject {
    +val project = project {
         name = "kobalt-line-count"
         group = "com.beust.kobalt"
         artifactId = name
    
    From c43be1be61d71c3d1d31cdaeeb9800dd36519c66 Mon Sep 17 00:00:00 2001
    From: Cedric Beust 
    Date: Thu, 4 Feb 2016 22:50:23 +0400
    Subject: [PATCH 08/65] Double quotes.
    
    ---
     plug-ins/index.html | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/plug-ins/index.html b/plug-ins/index.html
    index 9179a68..890fd25 100644
    --- a/plug-ins/index.html
    +++ b/plug-ins/index.html
    @@ -68,7 +68,7 @@ The project{} directive creates 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). +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").

    From 83703478040f3c3d57367518df8366f7b785d4e1 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 4 Feb 2016 22:51:14 +0400 Subject: [PATCH 09/65] Fix. --- plug-ins/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plug-ins/index.html b/plug-ins/index.html index 890fd25..53abcdc 100644 --- a/plug-ins/index.html +++ b/plug-ins/index.html @@ -87,7 +87,7 @@ A Project has two mandatory attributes: name and Mixed language projects

    - A Kobalt project can have multiple languages in it (Kotlin and Java): just specify all the source + A Kobalt project can mix Kotlin and Java in it, simply specify all the source directories you need:

    
    From b55a44b42f5850511b5bb773955d24abdd8e7798 Mon Sep 17 00:00:00 2001
    From: Cedric Beust 
    Date: Thu, 11 Feb 2016 21:30:38 -0800
    Subject: [PATCH 10/65] Update archetype doc.
    
    ---
     documentation/index.html       |  8 ++--
     getting-started/index.html     | 75 +++++++++++++---------------------
     plug-in-development/index.html | 11 ++---
     ten-minutes/index.html         |  9 ++--
     4 files changed, 43 insertions(+), 60 deletions(-)
    
    diff --git a/documentation/index.html b/documentation/index.html
    index ab9d044..b11f85f 100644
    --- a/documentation/index.html
    +++ b/documentation/index.html
    @@ -454,10 +454,10 @@ New versions found:
       
       
         --init
    -    Boolean
    -    false
    -    Initialize a project for Kobalt.
    -    This option will create a build file in the current directory (unless one already exists) and will install the Kobalt wrapper.
    +    Comma-separated strings
    +    null
    +    Initialize a project for Kobalt with the given archetypes.
    +    The parameter to this argument is a list of archetype names separated by commas, e.g. "java,myProject". Each archetype will be invoked in order so they can generate their files.
       
       
         --log
    diff --git a/getting-started/index.html b/getting-started/index.html
    index c5923e4..a569246 100644
    --- a/getting-started/index.html
    +++ b/getting-started/index.html
    @@ -58,72 +58,55 @@ unzip kobalt-xxx.zip
                     

     cd ~/java/project
    -$KOBALT_HOME/kobaltw --init
    +$KOBALT_HOME/kobaltw --init java
     

    This command will do two things:

      -
    1. Create a default kobalt/src/Build.kt file based on what was found in your project. -
    2. Install the Kobalt Wrapper in your current directory (a script called kobaltw) and a few additional files in the kobalt/wrapper directory. From now on, you can just use ./kobaltw to build and you can ignore $KOBALT_HOME. -
    -

    - You can now attempt to build your project with Kobalt: -

    +
  • Create a default kobalt/src/Build.kt suitable for a brand new Java project. +
  • Install the Kobalt Wrapper in your current directory (a script called kobaltw) and a few additional files in the kobalt/wrapper directory. From now on, you can just use ./kobaltw to build and you can ignore $KOBALT_HOME. + +

    +You can now attempt to build your project with Kobalt: +

     ./kobaltw assemble
     
    - If your project follows a regular build structure (e.g.
    Maven's hierarchy), this should compile your file and create a .jar file. If not, you will have to make a few edits to your Build.kt. - As of this writing, Kobalt supports Java and Kotlin projects. - -

    3. Edit kobalt/src/Build.kt

    +If your project follows a regular build structure (e.g. Maven's hierarchy), this should compile your file and create a .jar file. If not, you will have to make a few edits to your Build.kt. +As of this writing, Kobalt supports Java and Kotlin projects. - Here is the Build.kt for the Wasabi HTTP framework: +

    3. Edit kobalt/src/Build.kt

    + +

    The build file generated by default might need some editing before you can build your project, so take a look at it and adjust whatever is necessary (e.g. package name, version, etc...)

    +

    +Here is the Build.kt for the JCommander project: +

     import com.beust.kobalt.*
    -import com.beust.kobalt.plugin.packaging.assemble
    -import com.beust.kobalt.plugin.kotlin.*
    +import com.beust.kobalt.plugin.java.*
    +import com.beust.kobalt.plugin.packaging.*
    +import com.beust.kobalt.plugin.publish.*
     
    -val kotlinVersion = "1.0.0-beta-4583"
    -
    -val p = kotlinProject {
    -
    -    name = "wasabi"
    -    group = "com.example"
    +val jcommander = project {
    +    name = "jcommander"
    +    group = "com.beust"
         artifactId = name
    -    version = "0.1"
    +    version = "1.54"
     
    -    // Tell Kobalt to also search here for dependencies
    -    val repos = repos("http://oss.sonatype.org/content/repositories/snapshots") 
    -
    -    dependencies {
    -        compile("org.jetbrains.kotlin:kotlin-stdlib:" + kotlinVersion,
    -            "org.jetbrains.kotlin:kotlin-reflect:" + kotlinVersion,
    -
    -            "io.netty:netty-all:4.0.31.Final",
    -            "commons-codec:commons-codec:1.6",
    -            "commons-logging:commons-logging:1.1.1",
    -            "joda-time:joda-time:2.3")
    -    }
    -
    -    // Test dependencies
         dependenciesTest {
    -        compile("junit:junit:4.9",
    -            "org.mockito:mockito-all:1.9.5",
    -            "org.apache.httpcomponents:httpclient:4.5.1")
    +        compile("org.testng:testng:6.9.9")
         }
     
    -    // Tell kobalt to produce a fat jar and also the artifacts required for Maven
         assemble {
    -        jar {
    -            fatJar=true
    -            name = "wasabi-fat-" + version + ".jar"
    -        }
    -        mavenJars{
    +        mavenJars {
             }
         }
    -}
    -
    + + jcenter { + publish = true + } +}
  • 4. Sync your build file

    diff --git a/plug-in-development/index.html b/plug-in-development/index.html index e96eb76..85dd34b 100644 --- a/plug-in-development/index.html +++ b/plug-in-development/index.html @@ -111,7 +111,7 @@ class JavaPlugin : ICompilerContributor, IDocContributor {

     class JavaBuildGenerator: IInitContributor {

    - This class is declaring that it wants to take part in the --init selection process, discussed below. + This class is declaring that it wants to take part in the --init process (i.e. it can generate an archetype), discussed below.

    List of plug-in actors

    @@ -187,10 +187,11 @@ class JavaBuildGenerator: IInitContributor {

    IInitContributor IContributor - Kobalt supports the --init command line parameter, which generates a default build file - based on the files found in the current directory. Any plug-in that wants to be part of this process need - to implement this interface. In this case, both the Java and Kotlin plug-ins define such a contributor - but future plug-ins might use this contributor to generate their own build file: Android, Ceylon, Spring, etc... + When invoked with --init followed by archetype names separated by commas, + Kobalt will invoke each of these contributors so they can generate their files. + Archetypes are useful to create projects from scratch with a minimal number of + files to get started. For example, the "java" archetype will generate a `Build.kt` + file suitable for a brand new Java project. diff --git a/ten-minutes/index.html b/ten-minutes/index.html index 84897a8..8fbb71c 100644 --- a/ten-minutes/index.html +++ b/ten-minutes/index.html @@ -75,13 +75,12 @@ $ mkdir linecount $ cd linecount $ mkdir -p src/main/kotlin/com/beust/plugin/linecount -$ touch src/main/kotlin/com/beust/plugin/linecount/Main.kt -$ $KOBALT_HOME/kobaltw --init +$ $KOBALT_HOME/kobaltw --init kotlin
    -

    - I create an empty Main.kt in the example above so that calling ./kobaltw --init will detect the project as a Kotlin one. This way, the Build.kt file generated is already configured for Kotlin. Since we will be publishing this project to a Maven repository, we need to make sure that its group, artifactId and version are correct. The only thing that the generator can't guess is the group, so let's go ahead and fix it: -

    +

    + ./kobaltw --init kotlin creates an empty Kotlin project. Since we will be publishing this project to a Maven repository, we need to make sure that its group, artifactId and version are correct. The only thing that the generator can't guess is the group, so let's go ahead and fix it: +

     val project = kotlinProject {
    
    From 03d436b3e1ad548b020cdbc7985510e58cdc022e Mon Sep 17 00:00:00 2001
    From: Cedric Beust 
    Date: Thu, 11 Feb 2016 21:35:02 -0800
    Subject: [PATCH 11/65] Fix links.
    
    ---
     plug-in-development/index.html | 66 +++++++++++++++++-----------------
     1 file changed, 33 insertions(+), 33 deletions(-)
    
    diff --git a/plug-in-development/index.html b/plug-in-development/index.html
    index 0e112c6..a814660 100644
    --- a/plug-in-development/index.html
    +++ b/plug-in-development/index.html
    @@ -124,69 +124,69 @@ class JavaBuildGenerator: IInitContributor {
    Description - + IBuildConfigFieldContributor - IInterceptor + IInterceptor Plug-ins that want to add custom fields to the generated BuildConfig class. - IBuildDirectoryInterceptor - IInterceptor + IBuildDirectoryInterceptor + IInterceptor Plug-ins that need to generate class files in a different directory than the default one should implement this interface. - IClasspathContributor + IClasspathContributor - IContributor + IContributor Classpath contributors let you specify additional jar files or directories that will be used by the "compile" task. - IClasspathInterceptor + IClasspathInterceptor - IInterceptor + IInterceptor Plug-ins that want to modify the classpath before Kobalt uses it should implement this interface. - ICompilerContributor - IContributor + ICompilerContributor + IContributor Plug-ins that know how to turn files into bytecodes should implement this interface. - ICompilerFlagContributor - IContributor + ICompilerFlagContributor + IContributor Plug-ins that need to add flags to the compiler. - ICompilerInterceptor - IInterceptor + ICompilerInterceptor + IInterceptor Plug-ins that implement this interface get a chance to alter the dependencies of a project (dependencies{}, dependenciesTest{}, ...) before Kobalt sees them. - IDocContributor - IContributor + IDocContributor + IContributor Plug-ins that know how to generate documentation out of source files should implement this interface. - IInitContributor - IContributor + IInitContributor + IContributor When invoked with --init followed by archetype names separated by commas, Kobalt will invoke each of these contributors so they can generate their files. Archetypes are useful to create projects from scratch with a minimal number of @@ -195,15 +195,15 @@ class JavaBuildGenerator: IInitContributor {
    - IProjectContributor - IContributor + IProjectContributor + IContributor Some plug-ins produce projects (Java, Kotlin) while others don't (Packaging, Application, etc...). The ones that do need to register themselves as project contributors. This is how Kobalt collects all the projects defined after a build file was parsed. - IRepoContributor - IContributor + IRepoContributor + IContributor Some plug-ins might want to add their own repository to the list of repositories that Kobalt already supports. This is the case of the Android plug-in which, once the ANDROID_HOME environment variable has been @@ -212,16 +212,16 @@ class JavaBuildGenerator: IInitContributor { - IRunnerContributor - IContributor + IRunnerContributor + IContributor Plug-ins that can operate when the "run" task gets invoked should implement that interface. - + ISourceDirectoryContributor - IContributor + IContributor Plug-ins that add source directories. @@ -229,25 +229,25 @@ class JavaBuildGenerator: IInitContributor { - + ISourceDirectoryInterceptor - IInterceptor + IInterceptor Plug-ins that want to add, remove or alter the source directories should implement this interface. - + ITestRunnerContributor - IContributor + IContributor Plug-ins that can operate when the "test" task gets invoked should implement that interface. - + ITestSourceDirectoryContributor - IContributor + IContributor Plug-ins that add test source directories. @@ -276,7 +276,7 @@ interface IProjectAffinity { fun affinity(project: Project, context: KobaltContext) : Int }

    - For example, the JavaPlugin implements the ICompilerContributor interface and then overrides + For example, the JavaPlugin implements the ICompilerContributor interface and then overrides the affinity() method to make sure it gets run for Java projects but ignored for others:

    
    From c4be449ae3c886cc99b84a93f0a6a88f9768053f Mon Sep 17 00:00:00 2001
    From: Cedric Beust 
    Date: Tue, 16 Feb 2016 19:18:03 -0800
    Subject: [PATCH 12/65] Indent.
    
    ---
     plug-in-development/index.html | 40 +++++++++++++++++-----------------
     1 file changed, 20 insertions(+), 20 deletions(-)
    
    diff --git a/plug-in-development/index.html b/plug-in-development/index.html
    index a814660..c48bfbf 100644
    --- a/plug-in-development/index.html
    +++ b/plug-in-development/index.html
    @@ -275,35 +275,35 @@ interface IProjectAffinity {
          */
         fun affinity(project: Project, context: KobaltContext) : Int
     }
    -

    - For example, the JavaPlugin implements the ICompilerContributor interface and then overrides - the affinity() method to make sure it gets run for Java projects but ignored for others: -

    +

    +For example, the JavaPlugin implements the ICompilerContributor interface and then overrides +the affinity() method to make sure it gets run for Java projects but ignored for others: +

     override fun affinity(project: Project, context: KobaltContext) =
     if (project.sourceSuffix == ".java") 1 else 0
    -

    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: -

    +

    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: -

    +

    +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().apply { init() }
    -

    - 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. The code above defines a myConfig function that accepts a closure as an argument. It creates an Info - object, calls the init() function on it (which runs all the code inside that closure) and then return that Info object. -

    -

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

    +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. The code above defines a myConfig function that accepts a closure as an argument. It creates an Info +object, calls the init() function on it (which runs all the code inside that closure) and then return that Info object. +

    +

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

     // Build.kt
    
    From c1f32212f2dfc47fe7894881310d590f146fdec8 Mon Sep 17 00:00:00 2001
    From: Cedric Beust 
    Date: Tue, 16 Feb 2016 20:31:24 -0800
    Subject: [PATCH 13/65] Template documentation.
    
    ---
     documentation/index.html       | 91 ++++++++++++++++++++++++++++++++--
     plug-in-development/index.html | 24 ++++-----
     2 files changed, 99 insertions(+), 16 deletions(-)
    
    diff --git a/documentation/index.html b/documentation/index.html
    index 277afae..95c4696 100644
    --- a/documentation/index.html
    +++ b/documentation/index.html
    @@ -265,7 +265,76 @@ dependencies {
                   
               
     
    -          

    Maven repos

    +

    Templates

    +

    + Templates are invoked with the --init parameter and typically used when you are creating + a new project and you want Kobalt to generate a few files to get you started. Plug-ins can provide multiple + templates and you can invoke as many as you need to get your project started. You can get a list of available + templates with the --listTemplates parameter: +

    +
    +$ kobaltw --listTemplates
    +Available templates
    +  Plug-in: Kobalt
    +    "java"              Generates a simple Java project
    +    "kotlin"            Generates a simple Kotlin project
    +    "kobalt-plugin"     Generate a sample Kobalt plug-in project
    +

    + You can then invoke any of these templates with --init: +

    +$ kobaltw --init kobalt-plugin
    +Build this project with `./kobaltw assemble`
    +

    + Kobalt just generated a full project that will create a simple Kobalt plug-in. This plug-in adds + a simple task to Kobalt, so let's build it and test it: +

    +
    +$ ./kobaltw assemble
    +----- kobalt-line-count:compile
    +----- kobalt-line-count:assemble
    +Created .\kobaltBuild\libs\kobalt-line-count-0.18.jar
    +Created .\kobaltBuild\libs\kobalt-line-count-0.18-sources.jar
    +Created .\kobaltBuild\libs\kobalt-line-count-0.18-javadoc.jar
    +Wrote .\kobaltBuild\libs\kobalt-line-count-0.18.pom
    +BUILD SUCCESSFUL (5 seconds)
    +

    + We can test this plug-in with another useful command line parameter: --pluginJarFiles. You give this parameter a comma-separated list of jar files, each of which is expected to be a Kobalt plug-in. Let's invoke + Kobalt with it and ask for a list of available tasks (some of the output was elided): +

    +
    +$ ./kobaltw --pluginJarFiles kobaltBuild/libs/kobalt-line-count-0.18.jar --tasks
    +...
    +  ===== kobalt-line-count =====
    +    dynamicTask         Dynamic task
    +    lineCount           Count the lines
    +...
    +
    +

    + Kobalt loaded this plug-in and added the tasks that it provides. The parameter + --pluginJarFiles is mostly targeted at Kobalt plug-in developers so you can test + your plug-ins on your local file system without having to upload them to a Maven repo. More commonly, + you will run templates from plug-ins published in a Maven repository, and for this, + you use the --plugins parameter. For example, let's see what templates the + Android Kobalt plug-in offers: +

    +
    +$ ./kobaltw --plugins com.beust:kobalt-android: --listTemplates
    +Available templates
    +  Plug-in: Kobalt
    +    "java"              Generates a simple Java project
    +    "kotlin"            Generates a simple Kotlin project
    +    "kobalt-plugin"             Generate a sample Kobalt plug-in project
    +  Plug-in: Android
    +    "android-java"              Generate a simple Android Java project
    +

    + We see the same plug-ins we just reviewed and a new one provided by the Android plug-in called + "android-java". The --plugins parameter expects a comma-separated list of plug-in + id's and it acts as if you had specified these Maven id's in your Build.kt file. + The reason why this parameter is useful is that typically, when you run a template, you don't + have a build file yet since you are starting a project from scratch. +

    + +

    Maven repos

    Unauthenticated repos

    Kobalt already knows the location of the most popular Maven repos (Maven Central, JCenter, JBoss) but you can add repos with the repos() directive: @@ -453,10 +522,17 @@ New versions found: --init - Comma-separated strings + Comma-separated strings of template names. null - Initialize a project for Kobalt with the given archetypes. - The parameter to this argument is a list of archetype names separated by commas, e.g. "java,myProject". Each archetype will be invoked in order so they can generate their files. + Initialize a project for Kobalt with the given templates. + The parameter to this argument is a list of template names separated by commas, e.g. "java,myProject". Each template will be invoked in order so they can generate their files. + + + --listTemplates + + N/A + List all the templates available. + Templates displayed by this command can then be passed as an argument to the --init parameter. --log @@ -472,6 +548,13 @@ New versions found: Display information about the given id. Display which repo this artifact can be found in and the whole graph of its dependencies. + + --resolve + Maven id
    (e.g. "com.beust:kobalt:0.228") + N/A + Display information about the given id. + Display which repo this artifact can be found in and the whole graph of its dependencies. + --tasks Boolean diff --git a/plug-in-development/index.html b/plug-in-development/index.html index c48bfbf..9a89bcb 100644 --- a/plug-in-development/index.html +++ b/plug-in-development/index.html @@ -109,9 +109,9 @@ class JavaPlugin : ICompilerContributor, IDocContributor {

    With this declaration, we know that the JavaPlugin contributes a compiler and a doc generator.

    -class JavaBuildGenerator: IInitContributor {
    +class JavaBuildGenerator: ITemplateContributor {

    - This class is declaring that it wants to take part in the --init process (i.e. it can generate an archetype), discussed below. + This class is declaring that it wants to take part in the --init process (i.e. it can generate a template), discussed below.

    List of plug-in actors

    @@ -184,16 +184,6 @@ class JavaBuildGenerator: IInitContributor { Plug-ins that know how to generate documentation out of source files should implement this interface. - - IInitContributor - IContributor - When invoked with --init followed by archetype names separated by commas, - Kobalt will invoke each of these contributors so they can generate their files. - Archetypes are useful to create projects from scratch with a minimal number of - files to get started. For example, the "java" archetype will generate a `Build.kt` - file suitable for a brand new Java project. - - IProjectContributor IContributor @@ -236,6 +226,16 @@ class JavaBuildGenerator: IInitContributor { Plug-ins that want to add, remove or alter the source directories should implement this interface. + + ITemplateContributor + IContributor + When invoked with --init followed by template names separated by commas, + Kobalt will invoke each of these contributors so they can generate their files. + Templates are useful to create projects from scratch with a minimal number of + files to get started. For example, the "java" template will generate a Build.kt + file suitable for a brand new Java project. + + ITestRunnerContributor From 61c14e58969864b74622228c6209a80255958f07 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 16 Feb 2016 20:36:54 -0800 Subject: [PATCH 14/65] Consistency. --- documentation/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/index.html b/documentation/index.html index 95c4696..b6b0ac1 100644 --- a/documentation/index.html +++ b/documentation/index.html @@ -276,8 +276,8 @@ dependencies { $ kobaltw --listTemplates Available templates Plug-in: Kobalt - "java" Generates a simple Java project - "kotlin" Generates a simple Kotlin project + "java" Generate a simple Java project + "kotlin" Generate a simple Kotlin project "kobalt-plugin" Generate a sample Kobalt plug-in project

    You can then invoke any of these templates with --init: From 388c1ff9f0da54c17c1b8fd4c81dcba706220575 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 18 Feb 2016 21:48:49 -0800 Subject: [PATCH 15/65] Template doc update. --- documentation/index.html | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/documentation/index.html b/documentation/index.html index b6b0ac1..bc5cb88 100644 --- a/documentation/index.html +++ b/documentation/index.html @@ -278,11 +278,11 @@ Available templates Plug-in: Kobalt "java" Generate a simple Java project "kotlin" Generate a simple Kotlin project - "kobalt-plugin" Generate a sample Kobalt plug-in project + "kobaltPlugin" Generate a sample Kobalt plug-in project

    You can then invoke any of these templates with --init:

    -$ kobaltw --init kobalt-plugin
    +$ kobaltw --init kobaltPlugin
     Build this project with `./kobaltw assemble`

    Kobalt just generated a full project that will create a simple Kobalt plug-in. This plug-in adds @@ -323,16 +323,17 @@ Available templates Plug-in: Kobalt "java" Generates a simple Java project "kotlin" Generates a simple Kotlin project - "kobalt-plugin" Generate a sample Kobalt plug-in project + "kobaltPlugin" Generate a sample Kobalt plug-in project Plug-in: Android - "android-java" Generate a simple Android Java project -

    - We see the same plug-ins we just reviewed and a new one provided by the Android plug-in called - "android-java". The --plugins parameter expects a comma-separated list of plug-in - id's and it acts as if you had specified these Maven id's in your Build.kt file. - The reason why this parameter is useful is that typically, when you run a template, you don't - have a build file yet since you are starting a project from scratch. -

    + "androidJava" Generate a simple Android Java project< + "androidKotlin" Generate a simple Android Kotlin project +

    +We see the same plug-ins we just reviewed and a new one provided by the Android plug-in called +"android-java". The --plugins parameter expects a comma-separated list of plug-in +id's and it acts as if you had specified these Maven id's in your Build.kt file. +The reason why this parameter is useful is that typically, when you run a template, you don't +have a build file yet since you are starting a project from scratch. +

    Maven repos

    Unauthenticated repos

    From 0d99a930fead15a5300206364f040d5936babfe7 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 18 Feb 2016 21:50:28 -0800 Subject: [PATCH 16/65] Templates. --- documentation/index.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/documentation/index.html b/documentation/index.html index bc5cb88..3a9785d 100644 --- a/documentation/index.html +++ b/documentation/index.html @@ -334,6 +334,9 @@ id's and it acts as if you had specified these Maven id's in your Build.kt The reason why this parameter is useful is that typically, when you run a template, you don't have a build file yet since you are starting a project from scratch.

    +

    +For a more in-depth description of templates, please refer to this article. +

    Maven repos

    Unauthenticated repos

    From 888360381da8a9cdbcfb8192187d4178070dae3f Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 19 Feb 2016 06:36:37 -0800 Subject: [PATCH 17/65] Update. --- documentation/index.html | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/documentation/index.html b/documentation/index.html index 3a9785d..148c673 100644 --- a/documentation/index.html +++ b/documentation/index.html @@ -545,6 +545,20 @@ New versions found: Specify the log level. The default level is 1. Level 0 will quiet everything and 2 and 3 will display increasingly verbose output. + + --plugins + Comma-separated list of plugin id's + + Specify the plug-ins to load. + This is similar to specifying these plug-in id's in a build file except that no build file is needed. + + + --pluginJarFiles + Comma-separated list of plugin jar files + + Specify the plug-ins to load. + This is similar to specifying these plug-in id's in a build file except that no build file is needed. + --resolve Maven id
    (e.g. "com.beust:kobalt:0.228") From 08b3d95ea49d1986220fa5e183be2d57e525195e Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 20 Feb 2016 11:27:40 -0800 Subject: [PATCH 18/65] Document tests. --- documentation/index.html | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/documentation/index.html b/documentation/index.html index 148c673..86eed20 100644 --- a/documentation/index.html +++ b/documentation/index.html @@ -589,7 +589,43 @@ New versions found: +

    Testing

    +

    + Kobalt automatically detects how to run your tests based on the test dependencies that you declared: +

    +
    +dependenciesTest {
    +    compile("org.testng:testng:6.9.9")
    +}
    +

    + By default, Kobalt supports TestNG, JUnit and Spek. You can also configure how your tests run + with the test{} directive: +

    +
    +test {
    +    args("-excludegroups", "broken", "src/test/resources/testng.xml")
    +}
    +

    + The full list of configuration parameters can be found in the TestConfig class. +

    +

    + Additionally, you can define multiple test configurations, each with a different name. Each + configuration will create an additional task named "test" followed by the name of + that configuration. For example: +

    +
    +test {
    +    args("-excludegroups", "broken", "src/test/resources/testng.xml")
    +}
     
    +test {
    +    name = "All"
    +    args("src/test/resources/testng.xml")
    +}
    +

    + The first configuration has no name, so it will be launched with the task "test", + while the second one can be run with the task "testAll". +

    Publishing

    From ae5d0712f876ce53c7fe60facd9754977ae08123 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 20 Feb 2016 11:29:43 -0800 Subject: [PATCH 19/65] Style. --- documentation/index.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/documentation/index.html b/documentation/index.html index 86eed20..3f45bd7 100644 --- a/documentation/index.html +++ b/documentation/index.html @@ -288,7 +288,7 @@ Build this project with `./kobaltw assemble` Kobalt just generated a full project that will create a simple Kobalt plug-in. This plug-in adds a simple task to Kobalt, so let's build it and test it:

    -
    +
     $ ./kobaltw assemble
     ----- kobalt-line-count:compile
     ----- kobalt-line-count:assemble
    @@ -301,7 +301,7 @@ BUILD SUCCESSFUL (5 seconds)
    We can test this plug-in with another useful command line parameter: --pluginJarFiles. You give this parameter a comma-separated list of jar files, each of which is expected to be a Kobalt plug-in. Let's invoke Kobalt with it and ask for a list of available tasks (some of the output was elided):

    -
    +
     $ ./kobaltw --pluginJarFiles kobaltBuild/libs/kobalt-line-count-0.18.jar --tasks
     ...
       ===== kobalt-line-count =====
    @@ -613,7 +613,7 @@ test {
       configuration will create an additional task named "test" followed by the name of
       that configuration. For example:
     

    -
    +
     test {
         args("-excludegroups", "broken", "src/test/resources/testng.xml")
     }
    
    From 68d5919e44b01c283e8a4bfa35df886f9e4d79ca Mon Sep 17 00:00:00 2001
    From: Cedric Beust 
    Date: Tue, 23 Feb 2016 21:00:42 +0400
    Subject: [PATCH 20/65] Add Homebrew instructions.
    
    ---
     getting-started/index.html | 45 +++++++++++++++++++++++---------------
     1 file changed, 27 insertions(+), 18 deletions(-)
    
    diff --git a/getting-started/index.html b/getting-started/index.html
    index a569246..b0d9d4a 100644
    --- a/getting-started/index.html
    +++ b/getting-started/index.html
    @@ -40,34 +40,42 @@
                 
                 
    -

    1. Download Kobalt

    +

    1. Install Kobalt

    +

    With HomeBrew

    - Download the zip file then unzip it in a location we'll call KOBALT_HOME: + If you are on MacOS and have brew installed: +

    +$ brew install kobalt
    +$ which kobaltw
    +/usr/local/bin/brew
    +

    +

    Manually

    +

    +Download the zip file and unzip it in a that you can add to your $PATH variable:

    -cd $KOBALT_HOME
    +cd yourLocation
     unzip kobalt-xxx.zip
     
    -

    - Note: Kobalt doesn't need any environment variable to run, the environment variable used above - is only here for clarity. -

    -

    2. Initialize your project

    -

    - Change to your project directory and call the kobaltw command with --init: -

    +

    2. Initialize your project

    +

    +Change to your project directory and call the kobaltw command with --init: +

     cd ~/java/project
    -$KOBALT_HOME/kobaltw --init java
    +kobaltw --init java
     
    -

    - This command will do two things: -

    -
      -
    1. Create a default kobalt/src/Build.kt suitable for a brand new Java project. -
    2. Install the Kobalt Wrapper in your current directory (a script called kobaltw) and a few additional files in the kobalt/wrapper directory. From now on, you can just use ./kobaltw to build and you can ignore $KOBALT_HOME. +

      +This command will do two things: +

      +
        +
      1. Create a default kobalt/src/Build.kt file based on what was found in your project.
      2. +
      3. Install the Kobalt Wrapper in your current directory (a script called kobaltw) and a few additional files in the kobalt/wrapper directory.

      +From now on, you can just use ./kobaltw to build and you can ignore the kobaltw on your path (this command is only useful for initializing projects). +

      +

      You can now attempt to build your project with Kobalt:

      @@ -76,6 +84,7 @@ You can now attempt to build your project with Kobalt:
       If your project follows a regular build structure (e.g. Maven's hierarchy), this should compile your file and create a .jar file. If not, you will have to make a few edits to your Build.kt.
       As of this writing, Kobalt supports Java and Kotlin projects.
       
      +
       

      3. Edit kobalt/src/Build.kt

      The build file generated by default might need some editing before you can build your project, so take a look at it and adjust whatever is necessary (e.g. package name, version, etc...)

      From a091734a5899194724cb6d850d61c1206f0bf475 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 23 Feb 2016 19:50:18 -0800 Subject: [PATCH 21/65] Forgot a word --- getting-started/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/getting-started/index.html b/getting-started/index.html index b0d9d4a..0ac6557 100644 --- a/getting-started/index.html +++ b/getting-started/index.html @@ -51,7 +51,7 @@ $ which kobaltw

      Manually

      -Download the zip file and unzip it in a that you can add to your $PATH variable: +Download the zip file and unzip it in a directory that you can add to your $PATH variable:

       cd yourLocation
      @@ -148,4 +148,4 @@ val jcommander = project {
       
      -
      \ No newline at end of file
      +
      
      From 134892b5149023448453bb3b75ddbb527afba2f9 Mon Sep 17 00:00:00 2001
      From: Cedric Beust 
      Date: Thu, 25 Feb 2016 23:09:36 +0400
      Subject: [PATCH 22/65] Document the "idea" template.
      
      ---
       getting-started/index.html | 54 ++++++++++++++++++++++++++++----------
       1 file changed, 40 insertions(+), 14 deletions(-)
      
      diff --git a/getting-started/index.html b/getting-started/index.html
      index 0ac6557..4387d21 100644
      --- a/getting-started/index.html
      +++ b/getting-started/index.html
      @@ -63,8 +63,20 @@ Change to your project directory and call the kobaltw command with
       

       cd ~/java/project
      -kobaltw --init java
      -
      +kobaltw --init java
      +to initialize a Java project, or +
      +cd ~/java/project
      +kobaltw --init kotlin
      +

      +to initialize a Kotlin project. +

      +
      +

      Note

      + + Kobalt supports projects with both Kotlin and Java sources. For such projects, + use either java or kotlin as the --init argument and refer to the mixed projects documentation for more details. +

      This command will do two things:

      @@ -75,18 +87,11 @@ This command will do two things:

      From now on, you can just use ./kobaltw to build and you can ignore the kobaltw on your path (this command is only useful for initializing projects).

      -

      -You can now attempt to build your project with Kobalt: -

      -
      -./kobaltw assemble
      -
      -If your project follows a regular build structure (e.g. Maven's hierarchy), this should compile your file and create a .jar file. If not, you will have to make a few edits to your Build.kt. -As of this writing, Kobalt supports Java and Kotlin projects. - -

      3. Edit kobalt/src/Build.kt

      +

      + If your project uses a standard folder structure, you can skip this section and try to build your project directly. +

      The build file generated by default might need some editing before you can build your project, so take a look at it and adjust whatever is necessary (e.g. package name, version, etc...)

      Here is the Build.kt for the JCommander project: @@ -116,15 +121,36 @@ val jcommander = project { publish = true } }

      +

      4. Build your project

      +

      + You can now attempt to build your project with Kobalt: +

      +
      +./kobaltw assemble
      +

      5. IDEA users: generate IDEA files

      +

      +If you are planning to use IDEA to work on your project, you can ask Kobalt to generate all the IDEA files necessary to import your project: +

      +
      +./kobaltw --init idea
      +
      -

      4. Sync your build file

      +
      +

      Note

      + + You need to have a valid Build.kt file for this command to work. +
      +

      + This will generate several files depending on the content of your build file. You can then launch IDEA and open this project directly. +

      +

      6. IDEA users: sync your build file

      If you're using Intellij IDEA, make sure you've installed the Kobalt plugin and then go to Kobalt -> Sync Build File. Once the build file is synchronized, the errors should disappear and you can now use all the regular functions of IDEA on Build.kt just like any other Kotlin files (auto completion, jump to symbol, etc...).

      -

      5. Next steps

      +

      7. Next steps

      From this point, you can either learn how to install the Kobalt IDEA plug-in or read Kobalt's documentation.

      From 7a9559e1ff8b69a5ae5e91c915870b579ad74b1d Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 26 Feb 2016 19:18:39 -0800 Subject: [PATCH 23/65] Typo. --- plug-ins/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plug-ins/index.html b/plug-ins/index.html index 53abcdc..56b7ff6 100644 --- a/plug-ins/index.html +++ b/plug-ins/index.html @@ -166,7 +166,7 @@ assembleFreeDebug

    BuildConfig

    - If you defined at least one variant defined, a special file called BuildConfig.java (or + If you have at least one variant defined in your build file, a special file called BuildConfig.java (or BuildConfig.kt) will be automatically generated.

    From 1a398913b4cc34a17996799e45a796d77407ad3d Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 27 Feb 2016 19:56:25 -0800 Subject: [PATCH 24/65] Clarify kobaltw. --- getting-started/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/getting-started/index.html b/getting-started/index.html index 4387d21..66e3cc1 100644 --- a/getting-started/index.html +++ b/getting-started/index.html @@ -85,7 +85,7 @@ This command will do two things:
  • Install the Kobalt Wrapper in your current directory (a script called kobaltw) and a few additional files in the kobalt/wrapper directory.
  • -From now on, you can just use ./kobaltw to build and you can ignore the kobaltw on your path (this command is only useful for initializing projects). +From now on, you can just use ./kobaltw to build and you can ignore the kobaltw on your path, which is only useful to install Kobalt on new projects. Since you will now build each project with its own ./kobaltw command, they will use their own version of Kobalt.

    3. Edit kobalt/src/Build.kt

    From f08ef2d5ab17bbd802148915e96d9f17a29018dc Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 27 Feb 2016 19:56:35 -0800 Subject: [PATCH 25/65] Document the java/kotlin templates. --- plug-ins/index.html | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/plug-ins/index.html b/plug-ins/index.html index 56b7ff6..478097f 100644 --- a/plug-ins/index.html +++ b/plug-ins/index.html @@ -116,6 +116,51 @@ Once you have at least one project configured, the plug-in lets you invoke the f
    Clean the project
    +

    Templates

    +

    + Both the Java and Kotlin plug-ins provide templates named respectively "java" and "kotlin". +

    +
    +$ ./kobaltw --listTemplates
    +Available templates
    +  Plug-in: Kobalt
    +    "java"              Generate a simple Java project
    +    "kotlin"            Generate a simple Kotlin project
    + +

    + They are both identical templates so we'll just look over the Kotlin one. +

    +

    + If you invoke ./kobaltw --init kotlin, the following will happen: +

    +
      +
    • If a kobalt/src/Build.kt build file doesn't exist, it will be created.
    • +
    • If no Kotlin (or Java) file is found under src, the template will create a simple + class with a main method and also a test class.
    • +
    +
    +$ ./kobaltw --init kotlin
    +Template "kotlin" installed
    +Now you can run either `./kobaltw test` or `./kobaltw run`
    +$ ./kobaltw test
    +----- example:test
    +===============================================
    +Command line suite
    +Total tests run: 1, Failures: 0, Skips: 0
    +===============================================
    +
    +All tests passed
    +BUILD SUCCESSFUL (5 seconds)
    +$ ./kobaltw run
    +----- example:run
    +Hello Java world from Kobalt
    +BUILD SUCCESSFUL (0 seconds)
    +
    + + + + +

    Variants

    Variants let you configure your project to generate different artifacts compiled from different sources depending on the variant you selected. From 0d19efa5742c63e4b2da516a95a634b068200b20 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 27 Feb 2016 20:00:04 -0800 Subject: [PATCH 26/65] Typo. --- plug-ins/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plug-ins/index.html b/plug-ins/index.html index 478097f..baf4606 100644 --- a/plug-ins/index.html +++ b/plug-ins/index.html @@ -152,8 +152,8 @@ Total tests run: 1, Failures: 0, Skips: 0 All tests passed BUILD SUCCESSFUL (5 seconds) $ ./kobaltw run ------ example:run -Hello Java world from Kobalt +-----s example:run +Hello Kotlin world from Kobalt BUILD SUCCESSFUL (0 seconds)

    From 02f8724fa225fed3688325adfbcb52ecfaa29abc Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 27 Feb 2016 20:01:21 -0800 Subject: [PATCH 27/65] Typo. --- plug-ins/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plug-ins/index.html b/plug-ins/index.html index baf4606..31e1f07 100644 --- a/plug-ins/index.html +++ b/plug-ins/index.html @@ -152,7 +152,7 @@ Total tests run: 1, Failures: 0, Skips: 0 All tests passed BUILD SUCCESSFUL (5 seconds) $ ./kobaltw run ------s example:run +----- example:run Hello Kotlin world from Kobalt BUILD SUCCESSFUL (0 seconds)
    From cedb6ea7f9f7d842ac385e63eef6a7d4b5c57664 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 27 Feb 2016 20:02:07 -0800 Subject: [PATCH 28/65] New lines. --- plug-ins/index.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plug-ins/index.html b/plug-ins/index.html index 31e1f07..97ed0e1 100644 --- a/plug-ins/index.html +++ b/plug-ins/index.html @@ -142,6 +142,7 @@ Available templates $ ./kobaltw --init kotlin Template "kotlin" installed Now you can run either `./kobaltw test` or `./kobaltw run` + $ ./kobaltw test ----- example:test =============================================== @@ -151,6 +152,7 @@ Total tests run: 1, Failures: 0, Skips: 0 All tests passed BUILD SUCCESSFUL (5 seconds) + $ ./kobaltw run ----- example:run Hello Kotlin world from Kobalt From 93f242ddd2a73301637f539647da17d8e230f9db Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 4 Mar 2016 16:48:32 -0800 Subject: [PATCH 29/65] Document new settings.xml . --- documentation/index.html | 59 +++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/documentation/index.html b/documentation/index.html index 3f45bd7..141f3f7 100644 --- a/documentation/index.html +++ b/documentation/index.html @@ -237,33 +237,42 @@ dependencies { You can create settings that will apply to all your Kobalt builds by creating a file in ~/kobalt/settings.xml:

    -
    +
     <kobalt-settings>
         <localRepo>/Users/beust/my-kobalt-repo</localRepo>
    -</kobalt-settings>
    -          
    -

    - Here is a list of the parameters you can configure: -

    - - - - - - - - - - - - - - - - - - -
    NameDefaultDescription
    localRepo~/.kobalt/repositoryWhere Kobalt stores all the downloaded dependencies.
    + <default-repos> + <repo>http://jcenter.com</repo> + <repo>http://example.com</repo> + </default-repos> +</kobalt-settings>
    +

    + Here is a list of the parameters you can configure: +

    + + + + + + + + + + + + + + + + + + + + + + + + +
    NameDefaultDescription
    localRepo~/.kobalt/repositoryWhere Kobalt stores all the downloaded dependencies.
    defaultReposDefault reposList of repos overriding the default ones that Kobalt uses.

    Templates

    From 51653e1a8265b1a41f6940a5cdcc23ce6fbd50a2 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 4 Mar 2016 17:21:40 -0800 Subject: [PATCH 30/65] Update doc. --- plug-in-development/index.html | 96 +++++++++++++++++++++------------- 1 file changed, 59 insertions(+), 37 deletions(-) diff --git a/plug-in-development/index.html b/plug-in-development/index.html index 9a89bcb..a54a451 100644 --- a/plug-in-development/index.html +++ b/plug-in-development/index.html @@ -123,9 +123,24 @@ class JavaBuildGenerator: ITemplateContributor {

    Type Description + + IAssemblyContributor + IContributor + + Plug-ins that want be invoked when the assemble task is called. + + + + + IBuildConfigContributor + IContributor + + Plug-ins that want to generate their own BuildConfig file. + + - IBuildConfigFieldContributor + IBuildConfigFieldContributor
    IInterceptor Plug-ins that want to add custom fields to the generated BuildConfig class. @@ -159,7 +174,7 @@ class JavaBuildGenerator: ITemplateContributor {
    ICompilerContributor IContributor - Plug-ins that know how to turn files into bytecodes should implement this interface. + Plug-ins that want be invoked when the compile task is called. @@ -184,6 +199,13 @@ class JavaBuildGenerator: ITemplateContributor { Plug-ins that know how to generate documentation out of source files should implement this interface. + + IMavenIdInterceptor + IInterceptor + + Plug-ins that need to rewrite Maven id's should implement this interface. + + IProjectContributor IContributor @@ -218,41 +240,41 @@ class JavaBuildGenerator: ITemplateContributor { - - - ISourceDirectoryInterceptor - IInterceptor - - Plug-ins that want to add, remove or alter the source directories should implement this interface. - - - - ITemplateContributor - IContributor - When invoked with --init followed by template names separated by commas, - Kobalt will invoke each of these contributors so they can generate their files. - Templates are useful to create projects from scratch with a minimal number of - files to get started. For example, the "java" template will generate a Build.kt - file suitable for a brand new Java project. - - - - - ITestRunnerContributor - IContributor - - Plug-ins that can operate when the "test" task gets invoked should implement that interface. - - - - - ITestSourceDirectoryContributor - IContributor - - - Plug-ins that add test source directories. - - + + + ISourceDirectoryInterceptor + IInterceptor + + Plug-ins that want to add, remove or alter the source directories should implement this interface. + + + + ITemplateContributor + IContributor + When invoked with --init followed by template names separated by commas, + Kobalt will invoke each of these contributors so they can generate their files. + Templates are useful to create projects from scratch with a minimal number of + files to get started. For example, the "java" template will generate a Build.kt + file suitable for a brand new Java project. + + + + + ITestRunnerContributor + IContributor + + Plug-ins that can operate when the "test" task gets invoked should implement that interface. + + + + + ITestSourceDirectoryContributor + IContributor + + + Plug-ins that add test source directories. + +

    Selection process

    From 6fbb484f1a266678dfbaa3217b2a9b9cbdc6e19d Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 8 Mar 2016 01:37:08 +0400 Subject: [PATCH 31/65] Indent. --- documentation/index.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/documentation/index.html b/documentation/index.html index 141f3f7..66de950 100644 --- a/documentation/index.html +++ b/documentation/index.html @@ -332,10 +332,10 @@ Available templates Plug-in: Kobalt "java" Generates a simple Java project "kotlin" Generates a simple Kotlin project - "kobaltPlugin" Generate a sample Kobalt plug-in project + "kobaltPlugin" Generate a sample Kobalt plug-in project Plug-in: Android - "androidJava" Generate a simple Android Java project< - "androidKotlin" Generate a simple Android Kotlin project + "androidJava" Generate a simple Android Java project + "androidKotlin" Generate a simple Android Kotlin project

    We see the same plug-ins we just reviewed and a new one provided by the Android plug-in called "android-java". The --plugins parameter expects a comma-separated list of plug-in From 1788aab18c765845ee7f6a53f507e7a540baa31e Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 10 Mar 2016 22:59:14 +0400 Subject: [PATCH 32/65] Update instructions. --- getting-started/index.html | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/getting-started/index.html b/getting-started/index.html index 66e3cc1..b3103b2 100644 --- a/getting-started/index.html +++ b/getting-started/index.html @@ -51,11 +51,13 @@ $ which kobaltw

    Manually

    -Download the zip file and unzip it in a directory that you can add to your $PATH variable: -

    +Download the zip file, unzip it and add that directory to your $PATH variable so that you can invoke the command kobaltw. +

     cd yourLocation
     unzip kobalt-xxx.zip
    +cd kobalt-xxx
    +export PATH=$PWD:$PATH
     

    2. Initialize your project

    From 1cf02d9763f31bb0dade0a2c075b3e13e3d419c3 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 19 Mar 2016 01:14:57 +0400 Subject: [PATCH 33/65] ~/.config/kobalt doc. --- documentation/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/index.html b/documentation/index.html index 66de950..7fde417 100644 --- a/documentation/index.html +++ b/documentation/index.html @@ -234,8 +234,8 @@ dependencies {

    Settings

    - You can create settings that will apply to all your Kobalt builds by creating - a file in ~/kobalt/settings.xml: + You can define settings that will apply to all your Kobalt builds by creating + the file ~/.config/kobalt/settings.xml:

     <kobalt-settings>
    
    From d0fbe176b5f1fa3fd0e23f4f30a3fc52a5cb0ffb Mon Sep 17 00:00:00 2001
    From: Cedric Beust 
    Date: Sat, 19 Mar 2016 08:38:59 -0700
    Subject: [PATCH 34/65] Typo for Homebrew.
    
    ---
     getting-started/index.html | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/getting-started/index.html b/getting-started/index.html
    index 66e3cc1..1761eab 100644
    --- a/getting-started/index.html
    +++ b/getting-started/index.html
    @@ -47,7 +47,7 @@
     
     $ brew install kobalt
     $ which kobaltw
    -/usr/local/bin/brew
    +/usr/local/bin/kobaltw

    Manually

    From c1771bb98f6c891cde64441fcb5b48dbcc71fb19 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 27 Mar 2016 18:33:16 -0700 Subject: [PATCH 35/65] Document Maven coordinates. --- documentation/index.html | 63 ++++++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/documentation/index.html b/documentation/index.html index 7fde417..30ebb4e 100644 --- a/documentation/index.html +++ b/documentation/index.html @@ -216,27 +216,54 @@ dependencies { } -

    - There are various kinds of dependencies: -

    -
    -
    compile
    -
    Used to compile your project.
    -
    runtime
    -
    Not used at compile time but passed to the JVM to run your application.
    -
    provided
    -
    Used at compile time but not used to run your application.
    -
    exclude
    -
    Exclude the given dependencies from the classpath. You can either - specify a versioned id (e.g. "groupId:artifactId:version") or a versionless one - ("groupId:artifactId:").
    -
    +

    Dependency types

    -

    Settings

    +

    + There are various kinds of dependencies: +

    +
    +
    compile
    +
    Used to compile your project.
    +
    runtime
    +
    Not used at compile time but passed to the JVM to run your application.
    +
    provided
    +
    Used at compile time but not used to run your application.
    +
    exclude
    +
    Exclude the given dependencies from the classpath. You can either + specify a versioned id (e.g. "groupId:artifactId:version") or a versionless one + ("groupId:artifactId:").
    +
    + +

    Dependency versions

    +

    +Kobalt lets you specify Maven coordinates in one line, such as "org.testng:testng:6.9.10". Note that Kobalt uses the Maven Coordinates defined in the Maven specification, which are a little bit different from the ones that Gradle uses. +

    +

    + The standard format for such coordinates, as explained in the link above, is: +

    +
    +groupId:artifactId:packaging:classifier:version

    - You can define settings that will apply to all your Kobalt builds by creating - the file ~/.config/kobalt/settings.xml: + packaging and classifier are optional and can be omitted. If version + is omitted, Kobalt will resolve the artifact to its latest version from all the specified repos. + Most of the time, you will only specify groupId, artifactId and version, but if you ever need to specify additional components such as packaging (sometimes referred to as "extension") or classifier, + please take note that these should appear before the version number.

    +

    + For example, here is a Maven coordinate specifying a classifier: +

    +
    +# No version, resolves to the latest
    +org.testng:testng:
    +# Specifies an extension and a qualifier
    +com.badlogicgames.gdx:gdx-platform:jar:natives-desktop:1.9.2
    + +

    Settings

    +

    + You can define settings that will apply to all your Kobalt builds by creating + the file ~/.config/kobalt/settings.xml: +

    +
     <kobalt-settings>
         <localRepo>/Users/beust/my-kobalt-repo</localRepo>
    
    From a46d28a42039bef40eed0d50674d34f268b03555 Mon Sep 17 00:00:00 2001
    From: Cedric Beust 
    Date: Sun, 27 Mar 2016 18:35:44 -0700
    Subject: [PATCH 36/65] Clarifications.
    
    ---
     documentation/index.html | 23 ++++++++++++-----------
     1 file changed, 12 insertions(+), 11 deletions(-)
    
    diff --git a/documentation/index.html b/documentation/index.html
    index 30ebb4e..d01b6d4 100644
    --- a/documentation/index.html
    +++ b/documentation/index.html
    @@ -241,20 +241,21 @@ Kobalt lets you specify Maven coordinates in one line, such as "org.testng
     

    The standard format for such coordinates, as explained in the link above, is:

    -
    +
     groupId:artifactId:packaging:classifier:version
    -

    - packaging and classifier are optional and can be omitted. If version - is omitted, Kobalt will resolve the artifact to its latest version from all the specified repos. - Most of the time, you will only specify groupId, artifactId and version, but if you ever need to specify additional components such as packaging (sometimes referred to as "extension") or classifier, - please take note that these should appear before the version number. -

    -

    - For example, here is a Maven coordinate specifying a classifier: -

    -
    +

    + packaging and classifier are optional and can be omitted. If version + is omitted, Kobalt will resolve the artifact to its latest version from all the specified repos. + Most of the time, you will only specify groupId, artifactId and version, but if you ever need to specify additional components such as packaging (sometimes referred to as "extension") or classifier, + please take note that these should appear before the version number. +

    +

    + For example, here is a Maven coordinate specifying a classifier: +

    +
     # No version, resolves to the latest
     org.testng:testng:
    +
     # Specifies an extension and a qualifier
     com.badlogicgames.gdx:gdx-platform:jar:natives-desktop:1.9.2
    From 66490e76b22396309f71eca47240148b872ae19b Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 27 Mar 2016 18:41:54 -0700 Subject: [PATCH 37/65] Clarifications 2. --- documentation/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/index.html b/documentation/index.html index d01b6d4..9123b18 100644 --- a/documentation/index.html +++ b/documentation/index.html @@ -250,7 +250,7 @@ groupId:artifactId:packaging:classifier:version
    please take note that these should appear before the version number.

    - For example, here is a Maven coordinate specifying a classifier: + Here are a few examples of valid Maven coordinates:

     # No version, resolves to the latest
    
    From 67ff327fd252bf23f8db9fb093d9181b91a6da25 Mon Sep 17 00:00:00 2001
    From: Cedric Beust 
    Date: Mon, 28 Mar 2016 17:59:41 -0700
    Subject: [PATCH 38/65] uploadBintray
    
    ---
     documentation/index.html | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/documentation/index.html b/documentation/index.html
    index 9123b18..55e56f9 100644
    --- a/documentation/index.html
    +++ b/documentation/index.html
    @@ -705,7 +705,7 @@ Now, all you need to do is to upload your package:
     

    -./kobaltw uploadJcenter
    +./kobaltw uploadBintray
     

    Profiles

    From f24a883b22bae4b2dde124545c3aa2107202c343 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 29 Mar 2016 22:12:25 -0800 Subject: [PATCH 39/65] Indenting. --- plug-in-development/index.html | 428 ++++++++++++++++----------------- 1 file changed, 214 insertions(+), 214 deletions(-) diff --git a/plug-in-development/index.html b/plug-in-development/index.html index a54a451..1d502bb 100644 --- a/plug-in-development/index.html +++ b/plug-in-development/index.html @@ -30,54 +30,54 @@ --> - -
    - - - -

    How to write a Kobalt plug-in

    - -
    -

    Tutorial

    -

    - If you are curious to get a quick feel for what a Kobalt plug-in looks like, I suggest you go read how to - write and publish a plug-in in ten minutes and then you can come back here - and keep reading. -

    + +
    + + + +

    How to write a Kobalt plug-in

    + +
    +

    Tutorial

    +

    +If you are curious to get a quick feel for what a Kobalt plug-in looks like, I suggest you go read how to +write and publish a plug-in in ten minutes and then you can come back here +and keep reading. +

    -

    Plug-in architecture

    -

    -

    - Plug-ins often produce files and data that other plug-ins need to use in order for a build to succeed. For example, - the Android plug-in needs to generate a file called R.java and then make this file available at - compile time by the Java or Kotlin (or any other language) plug-in. Since plug-ins have no idea about what other - plug-ins are currently enabled and running, they can't directly talk to each other so instead of calling into - Kobalt, Kobalt calls into them. This is done by declaring various "actors" that Kobalt will invoke whenever - it needs the information that your plug-in produced. This is a design pattern often referred to as the - "Hollywood Principle": "Don't call us, we'll call you". -

    -

    - These "actors" are exactly what the kobalt-plugin.xml file describes. This file informs Kobalt about - the various ways in which your plug-in participates in the build system by specifying 1) plug-ins, 2) contributors - or 3) interceptors. -

    -

    +

    Plug-in architecture

    +

    +

    +Plug-ins often produce files and data that other plug-ins need to use in order for a build to succeed. For example, +the Android plug-in needs to generate a file called R.java and then make this file available at +compile time by the Java or Kotlin (or any other language) plug-in. Since plug-ins have no idea about what other +plug-ins are currently enabled and running, they can't directly talk to each other so instead of calling into +Kobalt, Kobalt calls into them. This is done by declaring various "actors" that Kobalt will invoke whenever +it needs the information that your plug-in produced. This is a design pattern often referred to as the +"Hollywood Principle": "Don't call us, we'll call you". +

    +

    +These "actors" are exactly what the kobalt-plugin.xml file describes. This file informs Kobalt about +the various ways in which your plug-in participates in the build system by specifying 1) plug-ins, 2) contributors +or 3) interceptors. +

    +

    -

    Parts

    -

    -

      -
    • kobalt-plugin.xml. A file that describes all the components (called "plug-in actors") of your plug-in, such as contributors.
    • -
    • Directives. Kotlin functions that users of your plug-in can invoke in their build file, such as project or dependencies. These functions typically configure some data that your plug-in will later use to perform its functions.
    • -
    • Tasks. These tasks are invoked from the command line and ask your plug-ins to perform certain actions.
    • -
    • Properties. Plug-ins can export properties and read properties from other plug-ins.
    • -
    -

    - -

    kobalt-plugin.xml

    -

    - The kobalt-plugin.xml file (stored in META-INF in the jar file of your plug-in) is mandatory and describes all the actors of your plug-in. This file contains a list of class names, each of which is expected to implement at least one of IPluginActor's interfaces: -

    +

    Parts

    +

    +

      +
    • kobalt-plugin.xml. A file that describes all the components (called "plug-in actors") of your plug-in, such as contributors.
    • +
    • Directives. Kotlin functions that users of your plug-in can invoke in their build file, such as project or dependencies. These functions typically configure some data that your plug-in will later use to perform its functions.
    • +
    • Tasks. These tasks are invoked from the command line and ask your plug-ins to perform certain actions.
    • +
    • Properties. Plug-ins can export properties and read properties from other plug-ins.
    • +
    +

    + +

    kobalt-plugin.xml

    +

    +The kobalt-plugin.xml file (stored in META-INF in the jar file of your plug-in) is mandatory and describes all the actors of your plug-in. This file contains a list of class names, each of which is expected to implement at least one of IPluginActor's interfaces: +

     <plugin-actors>
       <class-name>com.beust.kobalt.plugin.java.JavaPlugin</class-name>
    @@ -276,19 +276,19 @@ class JavaBuildGenerator: ITemplateContributor {
    -

    Selection process

    -

    - Several plug-ins might want to contribute to a specific task where only one participant should be allowed, - such as running tests or generating documentation. Even the simple task of compiling should probably only - ever be performed by no more than one plug-in for a given project. Therefore, when comes the time to - compile a project, - Kobalt needs to find which plug-in is the most suitable for that task and pick it. In order to do that, - plug-ins that contribute to tasks that can only be performed by one candidate need to declare their - affinity to that task for a given project. -

    -

    - Contributors that want to participate in a selection process need to implement the following interface: -

    +

    Selection process

    +

    +Several plug-ins might want to contribute to a specific task where only one participant should be allowed, +such as running tests or generating documentation. Even the simple task of compiling should probably only +ever be performed by no more than one plug-in for a given project. Therefore, when comes the time to +compile a project, +Kobalt needs to find which plug-in is the most suitable for that task and pick it. In order to do that, +plug-ins that contribute to tasks that can only be performed by one candidate need to declare their +affinity to that task for a given project. +

    +

    +Contributors that want to participate in a selection process need to implement the following interface: +

     interface IProjectAffinity {
         /**
    @@ -356,19 +356,19 @@ public fun myConfig(init: Info.() -> Unit) = Info().apply {
         (Kobalt.findPlugin("my-plug-in") as MyPlugin).info = info
         this
     }
    -

    - Obviously, you can choose any kind of API to communicate between the directive and its plug-in. In the code - above, I chose to directly override the entire Info field, but you could instead choose to call - a function, just set one boolean instead of the whole object, etc... -

    -

    Tasks

    -

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

    -

    Static tasks

    -

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

    +

    +Obviously, you can choose any kind of API to communicate between the directive and its plug-in. In the code +above, I chose to directly override the entire Info field, but you could instead choose to call +a function, just set one boolean instead of the whole object, etc... +

    +

    Tasks

    +

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

    +

    Static tasks

    +

    +Static tasks are functions declared directly in your plug-in class 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 {
    @@ -376,96 +376,96 @@ 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. -

    -

    - 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 kobaltw 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.
    -
    alwaysRunAfter
    -
    A list of all the tasks that will always be run after this task if it's invoked.
    -
    -

    -

    - The difference between runAfter and alwaysRunAfter is subtle but important. runAfter - is just a declaration of dependency. It's basically the reverse of runBefore but it's useful in case - you are not the author of the task you want to run before (if you were, you would just use the runBefore - annotation on it). Since you can't say "a runBefore b" because you don't own task "a", - you say "b runAfter a". -

    -

    - For example, compileTest is declared as a runAfter for the task compile. - This means that it doesn't make sense to run compileTest unless compile has run first. - However, if a user invokes the task compile, they probably don't want to invoke compileTest, - so a dependency is exactly what we need here: invoking compileTest will trigger compile - but not the other way around. -

    -

    - However, there are times where you want to define a task that will always run after a given task. - For example, you could have a signJarFile task that should always be invoked if someone builds a jar - file. You don't expect users to invoke that target explicitly, but whenever they invoke the assemble - target, you want your signJarFile target to be invoked. When you want such a task to always be invoked - even if the user didn't explicitly request it, you should use alwaysRunAfter. - Note that there is no alwaysRunBefore annotation since runBefore - achieves the same functionality. -

    -

    - Here are a few different scenarios to illustrate how the three attributes work for the task exampleTask: -

    -

    - Result of the command ./kobaltw --dryRun compile -

    - - - - - - - - + +
    Configuration for exampleTaskResult
    runBefore = "compile" +

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

    +

    +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 kobaltw 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.
    +
    alwaysRunAfter
    +
    A list of all the tasks that will always be run after this task if it's invoked.
    +
    +

    +

    +The difference between runAfter and alwaysRunAfter is subtle but important. runAfter +is just a declaration of dependency. It's basically the reverse of runBefore but it's useful in case +you are not the author of the task you want to run before (if you were, you would just use the runBefore +annotation on it). Since you can't say "a runBefore b" because you don't own task "a", +you say "b runAfter a". +

    +

    +For example, compileTest is declared as a runAfter for the task compile. +This means that it doesn't make sense to run compileTest unless compile has run first. +However, if a user invokes the task compile, they probably don't want to invoke compileTest, +so a dependency is exactly what we need here: invoking compileTest will trigger compile +but not the other way around. +

    +

    +However, there are times where you want to define a task that will always run after a given task. +For example, you could have a signJarFile task that should always be invoked if someone builds a jar +file. You don't expect users to invoke that target explicitly, but whenever they invoke the assemble +target, you want your signJarFile target to be invoked. When you want such a task to always be invoked +even if the user didn't explicitly request it, you should use alwaysRunAfter. +Note that there is no alwaysRunBefore annotation since runBefore +achieves the same functionality. +

    +

    +Here are a few different scenarios to illustrate how the three attributes work for the task exampleTask: +

    +

    +Result of the command ./kobaltw --dryRun compile +

    + + + + + + + + - - - - + + + + - - - - + + + + - -
    Configuration for exampleTaskResult
    runBefore = "compile"
    kobalt-line-count:clean
     kobalt-line-count:exampleTask
     kobalt-line-count:compile
    -
    runAfter = "compile" -
    kobalt-line-count:clean
    +        
    runAfter = "compile" +
    kobalt-line-count:clean
     kobalt-line-count:compile
    -
    alwaysRunAfter = "compile" -
    kobalt-line-count:clean
    +        
    alwaysRunAfter = "compile" +
    kobalt-line-count:clean
     kobalt-line-count:compile
     kobalt-line-count:exampleTask
    -
    -

    Dynamic tasks

    -

    - Dynamic tasks are useful when you want your plug-in to generate one or several tasks that depend on - some other runtime information (therefore, you can't declare a method and put a @Task - annotation on it). Plug-ins declare dynamic tasks by implementing the ITaskContributor - intrface: -

    +
    +

    Dynamic tasks

    +

    +Dynamic tasks are useful when you want your plug-in to generate one or several tasks that depend on +some other runtime information (therefore, you can't declare a method and put a @Task +annotation on it). Plug-ins declare dynamic tasks by implementing the ITaskContributor +intrface: +

     interface ITaskContributor {
    -    fun tasksFor(context: KobaltContext) : List<DynamicTask>
    +fun tasksFor(context: KobaltContext) : List<DynamicTask>
     }
    -

    - For example: -

    +

    +For example: +

     override fun tasksFor(context: KobaltContext) = listOf(
         DynamicTask(
    @@ -476,15 +476,15 @@ override fun tasksFor(context: KobaltContext) = listOf(
                 println("Running dynamicTask")
                 TaskResult()
     }))
    -

    - DynamicTask mirrors the @Task attributes: name, description and - dependencies. The only addition is the closure parameter, which specifics the code that will - run if your task gets invoked. That closure needs to follow the same constraints that a @Task method - obeys: it takes a Project parameter and returns a TaskResult. -

    -

    - Once you have implemented ITaskContributor, you can see your dynamic task in the list of tasks and run it directly: -

    +

    +DynamicTask mirrors the @Task attributes: name, description and +dependencies. The only addition is the closure parameter, which specifics the code that will +run if your task gets invoked. That closure needs to follow the same constraints that a @Task method +obeys: it takes a Project parameter and returns a TaskResult. +

    +

    +Once you have implemented ITaskContributor, you can see your dynamic task in the list of tasks and run it directly: +

     $ ./kobaltw --tasks
       ===== kobalt-line-count =====
    @@ -493,32 +493,32 @@ $ ./kobaltw --tasks
     $ ./kobaltw dynamicTask
     Running dynamictask
     
    -

    Properties

    -

    - Properties are the mechanism that plug-ins can use to export values and also read values that other - plug-ins have exported. There are two kinds of properties that plug-ins can manipulate: -

    -
      -
    • Project properties: project-specific properties.
    • -
    • Plug-in properties: general properties that are applicable to no project - in particular.
    • -
    -

    Project properties

    -

    - Project instances have a property called projectProperties that is an - instance of the ProjectProperties class. Plugins can put and get values on this - object in order to store project specific properties. -

    -
    +

    Properties

    +

    +Properties are the mechanism that plug-ins can use to export values and also read values that other +plug-ins have exported. There are two kinds of properties that plug-ins can manipulate: +

    +
      +
    • Project properties: project-specific properties.
    • +
    • Plug-in properties: general properties that are applicable to no project + in particular.
    • +
    +

    Project properties

    +

    +Project instances have a property called projectProperties that is an +instance of the ProjectProperties class. Plugins can put and get values on this +object in order to store project specific properties. +

    +
     fun taskAssemble(project: Project) : TaskResult {
    -    project.projectProperties.put(PACKAGES, packages)
    +project.projectProperties.put(PACKAGES, packages)
     
    -

    Plug-in properties

    -

    - The PluginProperties instance can be found on the KobaltContext - object that your plug-in receives in its apply() method. Once you have an instance of this - class, you can read or write variables into it: -

    +

    Plug-in properties

    +

    +The PluginProperties instance can be found on the KobaltContext +object that your plug-in receives in its apply() method. Once you have an instance of this +class, you can read or write variables into it: +

     override fun apply(project: Project, context: KobaltContext) {
         // Export a property for other plug-ins to use
    @@ -527,33 +527,33 @@ override fun apply(project: Project, context: KobaltContext) {
         val sourceDir = context.pluginProperties.get("pluginName", "somePluginProperty")
     }
     
    -

    Documenting properties

    -

    - Plug-ins that define properties should annotate them with the @ExportedPluginProperty or - @ExportedProjectPropertyannotation: -

    +

    Documenting properties

    +

    + Plug-ins that define properties should annotate them with the @ExportedPluginProperty or + @ExportedProjectPropertyannotation: +

    -    companion object {
    -        @ExportedProjectProperty
    -        const val BUILD_DIR = "buildDir"
    +companion object {
    +@ExportedProjectProperty
    +const val BUILD_DIR = "buildDir"
     
    -
    - -
    -
    - - - - - - - - - -
    - \ No newline at end of file +
    + +
    +
    + + + + + + + + + +
    + \ No newline at end of file From 8f452d950be66a491d99c1e08cb4ac18714ff3a2 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 29 Mar 2016 22:12:41 -0800 Subject: [PATCH 40/65] Path update. --- getting-started/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/getting-started/index.html b/getting-started/index.html index e8df501..76f725f 100644 --- a/getting-started/index.html +++ b/getting-started/index.html @@ -51,13 +51,13 @@ $ which kobaltw

    Manually

    -Download the zip file, unzip it and add that directory to your $PATH variable so that you can invoke the command kobaltw. +Download the zip file, unzip it and add the bin directory to your $PATH variable so that you can invoke the command kobaltw:

     cd yourLocation
     unzip kobalt-xxx.zip
     cd kobalt-xxx
    -export PATH=$PWD:$PATH
    +export PATH=$PWD/bin:$PATH
     

    2. Initialize your project

    From e5289f0bace6e63df506401ba1eab2bb36c6476e Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 29 Mar 2016 22:28:17 -0800 Subject: [PATCH 41/65] Document plug-in development. --- plug-in-development/index.html | 45 ++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/plug-in-development/index.html b/plug-in-development/index.html index 1d502bb..acaf433 100644 --- a/plug-in-development/index.html +++ b/plug-in-development/index.html @@ -45,7 +45,52 @@ If you are curious to get a quick feel for what a Kobalt plug-in looks like, I s write and publish a plug-in in ten minutes and then you can come back here and keep reading.

    +

    Setting up IDEA

    +

    + 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: +

    +
    +fun main(argv: Array<String>) {
    +    com.beust.kobalt.main(argv)
    +}
    +
    +

    + In order for this code to compile, you will have to switch the dependency of your plug-in from + kobalt-plugin-api to just kobalt, which is the actual application (and which + therefore contains the main() entry point). +

    +
    +        // Normal dependency
    +        compile("com.beust:kobalt-plugin-api:$KOBALT_VERSION")
     
    +        // Development dependency
    +        compile("com.beust:kobalt:$KOBALT_VERSION")
    +
    +

    + You might find it convenient to leverage Kobalt's ability to use regular Kotlin variables to make things easier: +

    +
    +val dev = false
    +val kobaltDependency = if (dev) "kobalt" else "kobalt-plugin-api"
    +
    +val p = project {
    +    // ...
    +
    +    compile("com.beust:$kobaltDependency:$KOBALT_VERSION")
    +}
    +
    +

    + Then you can simply set the dev to true during development and back to false + when you are ready to publish your plug-in. + +

    +

    + Then resync your build file in IDEA and your main() function should now build and be launchable. + You can right click on that class file and select "Debug <your class name>", which will launch Kobalt + with your plug-in. You can set a breakpoint in one of your tasks or anywhere that gets invoked. Don't forget + to invoke this launch configuration with the regular parameters passed to Kobalt (e.g. "assemble"). +

    Plug-in architecture

    From 729205059e954e5ccacd4855922e338b9899a0ad Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 29 Mar 2016 22:49:19 -0800 Subject: [PATCH 42/65] More plug-in doc. --- plug-in-development/index.html | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/plug-in-development/index.html b/plug-in-development/index.html index acaf433..3c632d0 100644 --- a/plug-in-development/index.html +++ b/plug-in-development/index.html @@ -46,6 +46,7 @@ If you are curious to get a quick feel for what a Kobalt plug-in looks like, I s and keep reading.

    Setting up IDEA

    +

    Launch configuration

    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: @@ -91,6 +92,26 @@ val p = project { with your plug-in. You can set a breakpoint in one of your tasks or anywhere that gets invoked. Don't forget to invoke this launch configuration with the regular parameters passed to Kobalt (e.g. "assemble").

    +

    Local dependencies

    +

    + In the process of building your plug-in, you will probably be invoking it from test projects and since + you will be making changes to your plug-in and generating jar files often, you might find it more convenient + to have these test projects point to your local jar file instead of the Maven one (which would require you + to upload your plug-in all the time). For this, you might find the file() and homeDir + () directives convenient: +

    +
    +    // Regular dependency
    +    compile("com.example:myPlugin:0.1")
    +
    +    // Development dependency
    +    compile(file(homeDir("kotlin/myPlugin/kobaltBuild/libs/myPlugin-0.1.jar"))
    +
    +

    + With this latter configuration, simply build your plug-in to generate the jar file with ./kobaltw + assemble, switch to your test project and invoke Kobalt on it so that your plug-in will get invoked + and you should see the latest version of your code being invoked. +

    Plug-in architecture

    From 8d935dba2f81ddc6920797264431740664b98a47 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 30 Mar 2016 21:46:03 -0800 Subject: [PATCH 43/65] More documentation on properties. --- plug-in-development/index.html | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plug-in-development/index.html b/plug-in-development/index.html index 3c632d0..7995665 100644 --- a/plug-in-development/index.html +++ b/plug-in-development/index.html @@ -577,7 +577,13 @@ object in order to store project specific properties.

     fun taskAssemble(project: Project) : TaskResult {
    -project.projectProperties.put(PACKAGES, packages)
    +    project.projectProperties.put("packages", packages)
    +
    +

    + Another plug-in can then query this property as follows: +

    +
    +    val packages = project.projectProperties.put("packages")
     

    Plug-in properties

    From 7a7b6675b5be37bb725b18038b4e3f5150eb8b35 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 31 Mar 2016 21:50:47 -0800 Subject: [PATCH 44/65] Fix section. --- getting-started/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/getting-started/index.html b/getting-started/index.html index 76f725f..f2f2265 100644 --- a/getting-started/index.html +++ b/getting-started/index.html @@ -129,7 +129,7 @@ val jcommander = project {

     ./kobaltw assemble
    -

    5. IDEA users: generate IDEA files

    +

    5. IDEA users: generate IDEA files

    If you are planning to use IDEA to work on your project, you can ask Kobalt to generate all the IDEA files necessary to import your project:

    From 35f732c3b10bf194bd35d517dd6616d95ddc67f6 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 31 Mar 2016 21:50:56 -0800 Subject: [PATCH 45/65] Arrows. --- getting-started/index.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/getting-started/index.html b/getting-started/index.html index f2f2265..afb0aef 100644 --- a/getting-started/index.html +++ b/getting-started/index.html @@ -147,7 +147,8 @@ If you are planning to use IDEA to work on your project, you can ask Kobalt to g

    6. IDEA users: sync your build file

    - If you're using Intellij IDEA, make sure you've installed the Kobalt plugin and then go to Kobalt -> Sync Build File. Once the build file is synchronized, the errors should disappear + If you're using Intellij IDEA, make sure you've installed the Kobalt plugin and then go to Tools → Kobalt → Sync Build File. Once the build file is synchronized, the errors should + disappear and you can now use all the regular functions of IDEA on Build.kt just like any other Kotlin files (auto completion, jump to symbol, etc...).

    From 045ea91d3fe85e950dd5fea768501ea4c1acd751 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 31 Mar 2016 21:51:07 -0800 Subject: [PATCH 46/65] Menu update. --- idea-plug-in/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/idea-plug-in/index.html b/idea-plug-in/index.html index ba7b668..06a3971 100644 --- a/idea-plug-in/index.html +++ b/idea-plug-in/index.html @@ -72,7 +72,7 @@

    - Install it and restart IDEA. If the plug-in was correctly installed, you should see a new menu called "Kobalt" juste before the "Help" menu: + Install it and restart IDEA. If the plug-in was correctly installed, you should see a new menu called "Kobalt" in the "Tools" menu:

    From 09b0ca7c8e77cc8750ab659d39e4529a3fdfa6e0 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 31 Mar 2016 23:21:42 -0800 Subject: [PATCH 47/65] Document --noIncremental. --- documentation/index.html | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/documentation/index.html b/documentation/index.html index 55e56f9..8844b75 100644 --- a/documentation/index.html +++ b/documentation/index.html @@ -582,6 +582,14 @@ New versions found: Specify the log level. The default level is 1. Level 0 will quiet everything and 2 and 3 will display increasingly verbose output. + + --noIncremental + Boolean + false + Turn off incremental builds. + If this flag is specified, Kobalt will run all the tasks, even those that are incremental and would have + been skipped. + --plugins Comma-separated list of plugin id's From 0daf6782a903a776a278e4c25ea003f562ac8416 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 31 Mar 2016 23:22:55 -0800 Subject: [PATCH 48/65] Remove duplicate. --- documentation/index.html | 7 ------- 1 file changed, 7 deletions(-) diff --git a/documentation/index.html b/documentation/index.html index 8844b75..57a670e 100644 --- a/documentation/index.html +++ b/documentation/index.html @@ -611,13 +611,6 @@ New versions found: Display information about the given id. Display which repo this artifact can be found in and the whole graph of its dependencies. - - --resolve - Maven id
    (e.g. "com.beust:kobalt:0.228") - N/A - Display information about the given id. - Display which repo this artifact can be found in and the whole graph of its dependencies. - --tasks Boolean From b0e5923bf1c8ae6cd357ac6735f93300185f8ed6 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 31 Mar 2016 23:29:34 -0800 Subject: [PATCH 49/65] Fixes. --- documentation/index.html | 42 ++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/documentation/index.html b/documentation/index.html index 57a670e..2991f9c 100644 --- a/documentation/index.html +++ b/documentation/index.html @@ -517,8 +517,8 @@ Here are the options that you can pass to ./kobaltw: - - + + @@ -541,9 +541,9 @@ Here are the options that you can pass to ./kobaltw: - + - td> + - + @@ -583,7 +583,7 @@ New versions found: - + @@ -598,7 +598,7 @@ New versions found: - + @@ -611,20 +611,20 @@ New versions found: - - - - - - - - - - - - - - + + + + + + + + + + + + + +
    Use this option if you are trying to build a project whose Build.kt is not in kobalt/src.
    --checkVersions--checkVersions Booleanfalsefalse Display all the new versions of your dependencies. This option looks at all the dependencies found in your build file and then contacts all the Maven repositories in order to find out if any of these repos contains a newer version. If any are found, they are displayed:
    @@ -569,7 +569,7 @@ New versions found:
         
    The parameter to this argument is a list of template names separated by commas, e.g. "java,myProject". Each template will be invoked in order so they can generate their files.
    --listTemplates--listTemplates N/A List all the templates available.The default level is 1. Level 0 will quiet everything and 2 and 3 will display increasingly verbose output.
    --noIncremental--noIncremental Boolean false Turn off incremental builds.This is similar to specifying these plug-in id's in a build file except that no build file is needed.
    --pluginJarFiles--pluginJarFiles Comma-separated list of plugin jar files Specify the plug-ins to load.Display information about the given id. Display which repo this artifact can be found in and the whole graph of its dependencies.
    --tasksBooleanfalseList the tasks available.Note that the available tasks will vary depending on which projects are in your build file.
    --updateBooleanfalseUpdate Kobalt to the latest version available.Use this flag if Kobalt just notified you that a new version is available and you want to update. Another way of doing this is to edit kobalt/wrapper/kobalt-wrapper.properties manually.
    --tasksBooleanfalseList the tasks available.Note that the available tasks will vary depending on which projects are in your build file.
    --updateBooleanfalseUpdate Kobalt to the latest version available.Use this flag if Kobalt just notified you that a new version is available and you want to update. Another way of doing this is to edit kobalt/wrapper/kobalt-wrapper.properties manually.

    Testing

    From 617e0d8882426978b3d4ea83b0adbb425bad6036 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 10 Apr 2016 21:07:11 -0700 Subject: [PATCH 50/65] Document new settings. --- documentation/index.html | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/documentation/index.html b/documentation/index.html index 55e56f9..455d5bd 100644 --- a/documentation/index.html +++ b/documentation/index.html @@ -267,7 +267,7 @@ com.badlogicgames.gdx:gdx-platform:jar:natives-desktop:1.9.2
     <kobalt-settings>
    -    <localRepo>/Users/beust/my-kobalt-repo</localRepo>
    +    <local-repo>/Users/beust/my-kobalt-repo</local-repo>
         <default-repos>
             <repo>http://jcenter.com</repo>
             <repo>http://example.com</repo>
    @@ -291,15 +291,25 @@ com.badlogicgames.gdx:gdx-platform:jar:natives-desktop:1.9.2
    - localRepo - ~/.kobalt/repository - Where Kobalt stores all the downloaded dependencies. - - - defaultRepos + default-repos Default repos List of repos overriding the default ones that Kobalt uses. + + kobalt-compiler-version + 1.0.0 + The version of the Kotlin compiler that Kobalt uses. + + + kobalt-compiler-repo + None + The Maven repository where to find the compiler. By default, the compiler is looked up in the default repos (JCenter, Maven, ...). + + + local-repo + ~/.kobalt/repository + Where Kobalt stores all the downloaded dependencies. +

    Templates

    From 8c980772d5d93c131a9dd4215ee9fbc61b09e79e Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 18 Apr 2016 03:05:59 -0800 Subject: [PATCH 51/65] Update the task dependency section. --- plug-in-development/index.html | 51 ++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/plug-in-development/index.html b/plug-in-development/index.html index 7995665..094fe2b 100644 --- a/plug-in-development/index.html +++ b/plug-in-development/index.html @@ -436,7 +436,7 @@ Tasks are provided by plug-ins and can be invoked from the command line, e.g. @Task
    annotation. Here is an example:

    -@Task(name = "lineCount", description = "Count the lines", runBefore = arrayOf("compile"))
    +@Task(name = "lineCount", description = "Count the lines", dependsOn = arrayOf("compile"))
     fun lineCount(project: Project): TaskResult {
         // ...
         return TaskResult()
    @@ -452,36 +452,51 @@ The @Task annotation accepts the following attributes:
         
    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 kobaltw command.
    +
    dependsOn
    +
    A list of all the tasks that this task depends on.
    +
    reverseDependsOn
    +
    Make the following tasks depend on this task.
    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.
    -
    alwaysRunAfter
    -
    A list of all the tasks that will always be run after this task if it's invoked.

    -The difference between runAfter and alwaysRunAfter is subtle but important. runAfter -is just a declaration of dependency. It's basically the reverse of runBefore but it's useful in case -you are not the author of the task you want to run before (if you were, you would just use the runBefore -annotation on it). Since you can't say "a runBefore b" because you don't own task "a", -you say "b runAfter a". + Kobalt defines two different concepts for tasks: dependencies and orderings. And for each of this concept, + you can define the relation to go in one direction or the other.

    -For example, compileTest is declared as a runAfter for the task compile. + If your task cannot run until another task has run, you need to declare a dependency. Dependencies cause + additional tasks than those requested to be executed. For example, "assemble" depends on "compile", which means that whenever you invoke "assemble", "compile" + will be automatically run first. This is a dependency and it is controlled by "dependsOn" and + "reverseDependsOn". +

    +

    + Orderings, controlled by "runBefore" and "runAfter" merely specify an ordering + but do not pull new tasks in. This is how you tell Kobalt "In case task X is run, run my task before it + (or after)". But if task X doesn't run, your task will not be run either (unless it's explicitly requested + by the user). +

    +

    + The reverse direction attributes "reverseDependsOn" and "runAfter" are useful + when you want to declare a dependency/ordering on a task that you do not control, and that you can therefore + not modify. +

    +

    +

    +For example, compileTest is declared as "dependsOn" the task compile. This means that it doesn't make sense to run compileTest unless compile has run first. However, if a user invokes the task compile, they probably don't want to invoke compileTest, so a dependency is exactly what we need here: invoking compileTest will trigger compile but not the other way around.

    -However, there are times where you want to define a task that will always run after a given task. -For example, you could have a signJarFile task that should always be invoked if someone builds a jar -file. You don't expect users to invoke that target explicitly, but whenever they invoke the assemble -target, you want your signJarFile target to be invoked. When you want such a task to always be invoked -even if the user didn't explicitly request it, you should use alwaysRunAfter. -Note that there is no alwaysRunBefore annotation since runBefore -achieves the same functionality. +There are times where you want to define a task that will always run after a given task. +For example, you could have a "signJarFile" task that should always be invoked if someone builds a jar +file. You don't expect users to invoke that target explicitly, but whenever they invoke the "assemble" +target, you want your "signJarFile" target to be invoked. When you want such a task to always be invoked +even if the user didn't explicitly request it, you should use "reverseDependsOn".

    Here are a few different scenarios to illustrate how the three attributes work for the task exampleTask: @@ -510,7 +525,7 @@ kobalt-line-count:compile

    - alwaysRunAfter = "compile" + reverseDependsOn = "compile"
    kobalt-line-count:clean
     kobalt-line-count:compile
    @@ -537,7 +552,7 @@ override fun tasksFor(context: KobaltContext) = listOf(
         DynamicTask(
             name = "dynamicTask",
             description = "Description",
    -        alwaysRunAfter = listOf("compile"),
    +        reverseDependsOn = listOf("compile"),
             closure = { project: Project ->
                 println("Running dynamicTask")
                 TaskResult()
    
    From ed0248ce3f71335f55a4abeb0056f2c7872e47b0 Mon Sep 17 00:00:00 2001
    From: Cedric Beust 
    Date: Tue, 19 Apr 2016 05:04:20 -0800
    Subject: [PATCH 52/65] Clarify task dependencies.
    
    ---
     plug-in-development/index.html | 61 +++++++++++++++-------------------
     1 file changed, 26 insertions(+), 35 deletions(-)
    
    diff --git a/plug-in-development/index.html b/plug-in-development/index.html
    index 094fe2b..13d014d 100644
    --- a/plug-in-development/index.html
    +++ b/plug-in-development/index.html
    @@ -470,7 +470,7 @@ The @Task annotation accepts the following attributes:
         If your task cannot run until another task has run, you need to declare a dependency. Dependencies cause
         additional tasks than those requested to be executed. For example, "assemble" depends on "compile", which means that whenever you invoke "assemble", "compile"
         will be automatically run first. This is a dependency and it is controlled by "dependsOn" and
    -    "reverseDependsOn".
    +    "reverseDependsOn". You can see "reverseDependsOn" as a way to insert your task before an existing task.
     

    Orderings, controlled by "runBefore" and "runAfter" merely specify an ordering @@ -479,58 +479,49 @@ The @Task annotation accepts the following attributes: by the user).

    - The reverse direction attributes "reverseDependsOn" and "runAfter" are useful - when you want to declare a dependency/ordering on a task that you do not control, and that you can therefore - not modify. -

    -

    -

    -For example, compileTest is declared as "dependsOn" the task compile. -This means that it doesn't make sense to run compileTest unless compile has run first. -However, if a user invokes the task compile, they probably don't want to invoke compileTest, -so a dependency is exactly what we need here: invoking compileTest will trigger compile -but not the other way around. -

    -

    -There are times where you want to define a task that will always run after a given task. -For example, you could have a "signJarFile" task that should always be invoked if someone builds a jar -file. You don't expect users to invoke that target explicitly, but whenever they invoke the "assemble" -target, you want your "signJarFile" target to be invoked. When you want such a task to always be invoked -even if the user didn't explicitly request it, you should use "reverseDependsOn". -

    -

    -Here are a few different scenarios to illustrate how the three attributes work for the task exampleTask: +Here are a few different scenarios to illustrate how the three attributes work for the task example:

    Result of the command ./kobaltw --dryRun compile

    - + + - + - - - + + + + + + +
    Configuration for exampleTaskConfiguration for example ResultNote
    runBefore = "compile"dependsOn = "compile" -
    kobalt-line-count:clean
    -kobalt-line-count:exampleTask
    -kobalt-line-count:compile
    +
    clean
    +compile
    +example
    runAfter = "compile" -
    kobalt-line-count:clean
    -kobalt-line-count:compile
    + Make the "example" task depend on "compile".
    reverseDependsOn = "compile" -
    kobalt-line-count:clean
    -kobalt-line-count:compile
    -kobalt-line-count:exampleTask
    +
    clean
    +example
    +compile
    + Insert the "example" task before "compile". +
    runAfter = "compile" +
    clean
    +compile
    +
    + Make "example" run after "compile" but only if it's invoked explicitly. +

    Dynamic tasks

    From 7ce5c4e85a52e52a1d14619691f64a2819ee54bb Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 18 May 2016 23:23:15 -0800 Subject: [PATCH 53/65] Move a section around. --- home/index.html | 47 +++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/home/index.html b/home/index.html index 19de4d6..804cf4f 100644 --- a/home/index.html +++ b/home/index.html @@ -77,27 +77,6 @@

    Features

    -

    Build file auto-completion in your IDE

    -

    - Since Kobalt's build files are actual Kotlin files, not only can you leverage auto-completion - to write your build files but the full power of your IDEA is at your fingertips to write - these files in any way you see fit: using expressions, conditionals, classes, extension functions, - constants... The sky is the limit! -

    -

    - Kobalt uses Kotlin's type safe builder pattern to offer a DSL that's extremely similar to Gradle - and minimalistic while allowing you to switch to full Kotlin code whenever necessary. -

    -

    - Here is an example of the auto-completion dialog: -

    -

    - -

    -

    - And see the following section to get a feel for Kobalt's build file syntax. -

    -

    Clean, minimal syntax for build files

    For example, here is JCommander's entire build file: @@ -133,7 +112,31 @@ val jcommander = project {

    This build file also includes a directive to upload your artifacts to Bintray automatically.

    -

    Incremental tasks

    + + +

    Build file auto-completion in your IDE

    +

    + Since Kobalt's build files are actual Kotlin files, not only can you leverage auto-completion + to write your build files but the full power of your IDEA is at your fingertips to write + these files in any way you see fit: using expressions, conditionals, classes, extension functions, + constants... The sky is the limit! +

    +

    + Kobalt uses Kotlin's type safe builder pattern to offer a DSL that's extremely similar to Gradle + and minimalistic while allowing you to switch to full Kotlin code whenever necessary. +

    +

    + Here is an example of the auto-completion dialog: +

    +

    + +

    +

    + And see the following section to get a feel for Kobalt's build file syntax. +

    + + +

    Incremental tasks

    Most of Kobalt's core tasks are incremental, which means that if you run them without having changed anything, they will be skipped. The support for incremental tasks is also trivial to add for plug-in developers, which guarantees that your builds with Kobalt will always be as fast as they can be.

    From 39b9f785a046c0752845d420ab24acd1f6599d69 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 21 May 2016 09:34:23 -0700 Subject: [PATCH 54/65] Document variant dependencies. --- plug-ins/index.html | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/plug-ins/index.html b/plug-ins/index.html index 97ed0e1..8ee9956 100644 --- a/plug-ins/index.html +++ b/plug-ins/index.html @@ -180,7 +180,7 @@ BUILD SUCCESSFUL (0 seconds)
  • The build type.
  • - 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: + Product flavors usually contain 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") {
    @@ -210,6 +210,17 @@ 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".

    +

    + Variants can have they own dependencies{} section, which will be used only if this specific + variant is being compiled or assembled: +

    +
    +    productFlavor("debug") {
    +        dependencies {
    +            compile("joda-time:joda-time:2.9.3")
    +        }
    +    }
    +

    BuildConfig

    From 14867322fd9cf58c6d177a61650b4f2dc3fd5b90 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 23 May 2016 20:59:03 -0700 Subject: [PATCH 55/65] Minor fix. --- documentation/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/index.html b/documentation/index.html index d1fa715..a88a412 100644 --- a/documentation/index.html +++ b/documentation/index.html @@ -376,7 +376,7 @@ Available templates "androidKotlin" Generate a simple Android Kotlin project

    We see the same plug-ins we just reviewed and a new one provided by the Android plug-in called -"android-java". The --plugins parameter expects a comma-separated list of plug-in +"androidJava". The --plugins parameter expects a comma-separated list of plug-in id's and it acts as if you had specified these Maven id's in your Build.kt file. The reason why this parameter is useful is that typically, when you run a template, you don't have a build file yet since you are starting a project from scratch. From 8ff4a4c717a149baa0b5f9f50accbd9b77f331f3 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 29 May 2016 06:49:16 -0700 Subject: [PATCH 56/65] The "idea" template has been removed. --- getting-started/index.html | 5 ----- 1 file changed, 5 deletions(-) diff --git a/getting-started/index.html b/getting-started/index.html index afb0aef..14878f4 100644 --- a/getting-started/index.html +++ b/getting-started/index.html @@ -131,11 +131,6 @@ val jcommander = project { ./kobaltw assemble

    5. IDEA users: generate IDEA files

    -If you are planning to use IDEA to work on your project, you can ask Kobalt to generate all the IDEA files necessary to import your project: -

    -
    -./kobaltw --init idea
    -

    Note

    From 98dd80ecef197e313442ef52ba5eecd0e957d7d1 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 11 Jun 2016 08:33:24 -0700 Subject: [PATCH 57/65] Update the IDEA doc. --- getting-started/index.html | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/getting-started/index.html b/getting-started/index.html index 14878f4..287705b 100644 --- a/getting-started/index.html +++ b/getting-started/index.html @@ -129,23 +129,17 @@ val jcommander = project {

     ./kobaltw assemble
    -

    5. IDEA users: generate IDEA files

    +

    5. IDEA users: Import your project in IDEA

    -

    -

    Note

    - - You need to have a valid Build.kt file for this command to work. -

    - This will generate several files depending on the content of your build file. You can then launch IDEA and open this project directly. +You can now open your project in IDEA and if you have the Kobalt IDEA plug-in installed, you +will be asked whether you want to import that project as a Kobalt project.

    -

    6. IDEA users: sync your build file

    +

    6. IDEA users: Sync your build file

    - If you're using Intellij IDEA, make sure you've installed the Kobalt plugin and then go to Tools → Kobalt → Sync Build File. Once the build file is synchronized, the errors should - disappear - and you can now use all the regular functions of IDEA on Build.kt just like any other Kotlin - files (auto completion, jump to symbol, etc...). + Once your project has been imported as a Kobalt project in IDEA, bring up the Kobalt window (sideways on the + right side) and click the Sync icon, which will synchronize your build file with IDEA.

    7. Next steps

    From 9c00f7eaca04a080f5f085303eff55e0d39ad741 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 14 Jun 2016 22:45:55 -0800 Subject: [PATCH 58/65] Document native(). --- documentation/index.html | 59 ++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 23 deletions(-) diff --git a/documentation/index.html b/documentation/index.html index a88a412..6b3fe5e 100644 --- a/documentation/index.html +++ b/documentation/index.html @@ -216,6 +216,31 @@ dependencies { }
    +

    Dependency versions

    +

    + Kobalt lets you specify Maven coordinates in one line, such as "org.testng:testng:6.9.10". Note that Kobalt uses the Maven Coordinates defined in the Maven specification, which are a little bit different from the ones that Gradle uses. +

    +

    + The standard format for such coordinates, as explained in the link above, is: +

    +
    +groupId:artifactId:packaging:classifier:version
    +

    + packaging (e.g. "jar") and classifier (usually an arbitrary name) are optional and can be omitted. If version + is omitted, Kobalt will resolve the artifact to its latest version from all the specified repos. + Most of the time, you will only specify groupId, artifactId and version, but if you ever need to specify additional components such as packaging (sometimes referred to as "extension") or classifier, + please take note that these should appear before the version number. +

    +

    + Here are a few examples of valid Maven coordinates: +

    +
    +# No version, resolves to the latest
    +org.testng:testng:
    +
    +# Specifies an extension and a qualifier
    +com.badlogicgames.gdx:gdx-platform:jar:natives-desktop:1.9.2
    +

    Dependency types

    @@ -232,33 +257,21 @@ dependencies {

    Exclude the given dependencies from the classpath. You can either specify a versioned id (e.g. "groupId:artifactId:version") or a versionless one ("groupId:artifactId:").
    +
    native
    +
    Used to define native dependencies.
    -

    Dependency versions

    +
    Native dependencies

    -Kobalt lets you specify Maven coordinates in one line, such as "org.testng:testng:6.9.10". Note that Kobalt uses the Maven Coordinates defined in the Maven specification, which are a little bit different from the ones that Gradle uses. + Native dependencies will only be used when you invoke the run task on your project:

    -

    - The standard format for such coordinates, as explained in the link above, is: -

    -
    -groupId:artifactId:packaging:classifier:version
    -

    - packaging and classifier are optional and can be omitted. If version - is omitted, Kobalt will resolve the artifact to its latest version from all the specified repos. - Most of the time, you will only specify groupId, artifactId and version, but if you ever need to specify additional components such as packaging (sometimes referred to as "extension") or classifier, - please take note that these should appear before the version number. -

    -

    - Here are a few examples of valid Maven coordinates: -

    -
    -# No version, resolves to the latest
    -org.testng:testng:
    -
    -# Specifies an extension and a qualifier
    -com.badlogicgames.gdx:gdx-platform:jar:natives-desktop:1.9.2
    - +
    +dependencies {
    +    native("org.lwjgl.lwjgl:lwjgl-platform:jar:natives-windows:2.9.3",
    +           "org.lwjgl.lwjgl:lwjgl-platform:jar:natives-linux:2.9.3",
    +           "org.lwjgl.lwjgl:lwjgl-platform:jar:natives-osx:2.9.3"
    +        )
    +    }

    Settings

    You can define settings that will apply to all your Kobalt builds by creating From d12d7f91e9dcabce7131f47a601017b4382b3a44 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 15 Jun 2016 01:03:07 -0800 Subject: [PATCH 59/65] Clarify dependencies. --- plug-in-development/index.html | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plug-in-development/index.html b/plug-in-development/index.html index 13d014d..27b2562 100644 --- a/plug-in-development/index.html +++ b/plug-in-development/index.html @@ -474,9 +474,8 @@ The @Task annotation accepts the following attributes:

    Orderings, controlled by "runBefore" and "runAfter" merely specify an ordering - but do not pull new tasks in. This is how you tell Kobalt "In case task X is run, run my task before it - (or after)". But if task X doesn't run, your task will not be run either (unless it's explicitly requested - by the user). + but do not pull new tasks in. This is how you tell Kobalt "In case task the user asks for my task to run, + here is when it should be invoked", but your task will run only if it's explicitly invoked by the user.

    Here are a few different scenarios to illustrate how the three attributes work for the task example: From 3876816788de1b135049355813f23f9e13fc6afa Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 15 Jun 2016 01:05:59 -0800 Subject: [PATCH 60/65] Extra word --- plug-in-development/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plug-in-development/index.html b/plug-in-development/index.html index 27b2562..75aafde 100644 --- a/plug-in-development/index.html +++ b/plug-in-development/index.html @@ -474,7 +474,7 @@ The @Task annotation accepts the following attributes:

    Orderings, controlled by "runBefore" and "runAfter" merely specify an ordering - but do not pull new tasks in. This is how you tell Kobalt "In case task the user asks for my task to run, + but do not pull new tasks in. This is how you tell Kobalt "In case the user asks for my task to run, here is when it should be invoked", but your task will run only if it's explicitly invoked by the user.

    From b3a8d1a91c91379ef42f1ca0fe91566bed7e7bfc Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 25 Jun 2016 09:18:53 -0700 Subject: [PATCH 61/65] Document buildFileClasspath(). --- documentation/index.html | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/documentation/index.html b/documentation/index.html index a88a412..2889f88 100644 --- a/documentation/index.html +++ b/documentation/index.html @@ -191,6 +191,19 @@ fun taskCreateVersion(project: Project) : TaskResult { This tasks takes a template file and replaces all occurrences of the string "@version@" with the actual version of the project. Obviously, this task is very specific to TestNG's own build and it wasn't worth writing a plug-in ftor this. Note the attributes runBefore and runAfter, which specify when this task will run. You can find more information about tasks in the plug-in development section.

    +

    Build file classpath

    +

    + If you are writing code or an inline task in your build file that requires additional libraries, + you can specify these dependencies with the buildFileClasspath() directive, which accepts a list + of dependencies in parameters. Each of these dependencies will then be added to the classpath when + your build file is compiled and run: +

    +
    +// Build.kt
    +val bfc = buildFileClasspath("org.testng:testng:6.9.11")
    +val t = org.testng.TestNG()  // now legal
    +
    +

    Dependencies

    From 56ef02934cd206dc2c57ce5fcf08121a0e97390c Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 4 Jul 2016 11:15:53 -0700 Subject: [PATCH 62/65] Document ITaskContributor and IIncrementalTaskContributor. --- plug-in-development/index.html | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/plug-in-development/index.html b/plug-in-development/index.html index 75aafde..624f34c 100644 --- a/plug-in-development/index.html +++ b/plug-in-development/index.html @@ -251,6 +251,13 @@ class JavaBuildGenerator: ITemplateContributor { Plug-ins that need to add flags to the compiler. + + IIncrementalTaskContributor + IContributor + + Plug-ins that implement this interface provide incremental tasks. + + ICompilerInterceptor IInterceptor @@ -314,6 +321,13 @@ class JavaBuildGenerator: ITemplateContributor { Plug-ins that want to add, remove or alter the source directories should implement this interface. + + ITaskContributor + IContributor + + Plug-ins that implement this interface provide tasks. + + ITemplateContributor IContributor From eeacf3a97de0a48af2198830371aa8c3e37cf6ab Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 5 Jul 2016 15:26:10 -0700 Subject: [PATCH 63/65] Typo. --- plug-in-development/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plug-in-development/index.html b/plug-in-development/index.html index 624f34c..a051701 100644 --- a/plug-in-development/index.html +++ b/plug-in-development/index.html @@ -409,7 +409,7 @@ Users can now specify the following in their build file:

     // Build.kt
    -ort.com.example.plugin.myConfig
    +import.com.example.plugin.myConfig
     myConfig {
         publish = true
     }
    From 64559988d99b4c636a25ae83a6534afafe5239a2 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 6 Jul 2016 00:43:54 -0800 Subject: [PATCH 64/65] Update IDEA doc. --- idea-plug-in/index.html | 29 +++++++++++++++++++++-------- pics/kobalt-import-1.png | Bin 0 -> 30587 bytes pics/kobalt-import-2.png | Bin 0 -> 42925 bytes pics/kobalt-main-window.png | Bin 0 -> 39994 bytes 4 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 pics/kobalt-import-1.png create mode 100644 pics/kobalt-import-2.png create mode 100644 pics/kobalt-main-window.png diff --git a/idea-plug-in/index.html b/idea-plug-in/index.html index 06a3971..7f93119 100644 --- a/idea-plug-in/index.html +++ b/idea-plug-in/index.html @@ -64,7 +64,7 @@

    How to install and use the Kobalt IDEA plug-in

    -

    Installation

    +

    Installation

    Open the "Plugins" section of the IDEA preferences and find the "Kobalt" plug-in.

    @@ -72,13 +72,26 @@

    - Install it and restart IDEA. If the plug-in was correctly installed, you should see a new menu called "Kobalt" in the "Tools" menu: + Install it and restart IDEA. Next time you open a project with a Build.kt build file in it, IDEA + will offer to import it as a Kobalt project.

    -

    - +

    + +

    +

    + +

    + +

    +Once you accept, a new window will be available on the right +side of your main IDEA window. Clicking it will reveal the whole Kobalt window. +You can then click on the Sync icon in the upper left corner to update your dependencies:

    -

    Features

    +

    + +

    +

    Features

    The Kobalt IDEA plug-in offers the following features:

      @@ -86,7 +99,7 @@
    • Automatic completion of Build.kt

    -

    Synchronization of build files

    +

    Synchronization of build files

    The plug-in will locate your kobalt/src/Build.kt file and automatically update your project's libraries and dependencies to reflect it. For example, suppose you have the following dependencies: @@ -140,7 +153,7 @@ dependencies {

    -

    Auto completion of Build.kt

    +

    Auto completion of Build.kt

    The plug-in will automatically turn on auto-completion of your kobalt/src/Build.kt file. Once this is @@ -165,7 +178,7 @@ val lc = lineCount { -

    Source code and bug reports

    +

    Source code and bug reports

    The source code can be found on github. If you need to report a bug, please make sure you include the log file, which you can find under diff --git a/pics/kobalt-import-1.png b/pics/kobalt-import-1.png new file mode 100644 index 0000000000000000000000000000000000000000..d7ca8d7deeff779a82a89104fbf116e8360e3d46 GIT binary patch literal 30587 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 literal 0 HcmV?d00001 diff --git a/pics/kobalt-import-2.png b/pics/kobalt-import-2.png new file mode 100644 index 0000000000000000000000000000000000000000..1ffe193c5f8e199a88b4294c12cec04afb953be9 GIT binary patch literal 42925 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 O{H|#mTq)LsJ^Tlx3$4BY literal 0 HcmV?d00001 diff --git a/pics/kobalt-main-window.png b/pics/kobalt-main-window.png new file mode 100644 index 0000000000000000000000000000000000000000..712b010ae28259c2e90d1099b1317f8a45ca6f7e GIT binary patch literal 39994 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 JYjeLl{{pT{zmNa` literal 0 HcmV?d00001 From f909f13e7aa9f68354fc059c5b88d35e8a59c33b Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 7 Jul 2016 05:44:07 -0700 Subject: [PATCH 65/65] Clarify doc. --- plug-ins/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plug-ins/index.html b/plug-ins/index.html index 8ee9956..fc29f04 100644 --- a/plug-ins/index.html +++ b/plug-ins/index.html @@ -452,7 +452,7 @@ assemble {

    install

    - 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. + The install section lets you specify how the artifacts get installed. If you don't specify any install directive, then the install task will install your artifacts in the lib directory by default.

         install {