Skip to content

Commit

Permalink
Use preloader for worker process and introduce kotlin_test rule (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
pcj authored May 26, 2017
1 parent 44a0f3f commit c998eb5
Show file tree
Hide file tree
Showing 8 changed files with 211 additions and 67 deletions.
75 changes: 57 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
<table><tr>
<td><img src="https://github.com/pubref/rules_protobuf/blob/master/images/bazel.png" width="120"/></td>
<td><img src="https://kotlinlang.org/assets/images/open-graph/kotlin_250x250.png" width="120"/></td>
</tr><tr>
<td>Bazel</td>
<td>Kotlin</td>
</tr></table>

# Kotlin Rules for Bazel
[![Build Status](https://travis-ci.org/pubref/rules_kotlin.svg?branch=master)](https://travis-ci.org/pubref/rules_kotlin)

Expand All @@ -9,6 +17,7 @@ These rules are for building [Kotlin][kotlin] source with with
1. [kotlin_repositories](#kotlin_repositories)
1. [kotlin_library](#kotlin_library)
1. [kotlin_binary](#kotlin_binary)
1. [kotlin_test](#kotlin_test)

## Workspace rules

Expand All @@ -18,7 +27,7 @@ Add the following to your `WORKSPACE` file:
git_repository(
name = "org_pubref_rules_kotlin",
remote = "https://github.com/pubref/rules_kotlin.git",
tag = "v0.3.0", # update as needed
tag = "v0.3.1", # update as needed
)

load("@org_pubref_rules_kotlin//kotlin:rules.bzl", "kotlin_repositories")
Expand All @@ -40,7 +49,7 @@ dagger (used to build the `KotlinCompiler` bazel worker).
Add the following to your BUILD file:

```python
load("@org_pubref_rules_kotlin//kotlin:rules.bzl", "kotlin_library", "kotlin_binary")
load("@org_pubref_rules_kotlin//kotlin:rules.bzl", "kotlin_library")
```

### kotlin_library
Expand Down Expand Up @@ -95,18 +104,18 @@ android_binary(
| `srcs` | `label_list` | Kotlin source files `*.kt` |
| `deps` | `label_list` | List of `kotlin_library` targets |
| `java_deps` | `label_list` | List of java provider targets (`java_library`, `java_import`, `...`) |
| `android_deps` | `label_list` | List of android provider targets (`android_library`) |
| `jars` | `label_list` | List of jar file targets (`*.jar`) |
| `x_opts` | `string_list` | List of additional `-X` options to `kotlinc` |
| `plugin_opts` | `string_dict` | List of additional `-P` options to `kotlinc` |
| `use_worker` | `boolean` | Assign to `False` to disable the use of [bazel workers](https://bazel.build/blog/2015/12/10/java-workers.html). |


### kotlin_binary

A `kotlin_binary` rule takes the same arguments as a `kotlin_library`,
plus a required `main_class` argument (the name of the compiled kotlin
class to run, in java package notation). This class should have a
`fun main(...)` entrypoint. Example:
A `kotlin_binary` macro takes the same arguments as a
`kotlin_library`, plus a required `main_class` argument (the name of
the compiled kotlin class to run, in java package notation). This
class should have a `fun main(...)` entrypoint. Example:

```python
kotlin_binary(
Expand All @@ -128,6 +137,8 @@ Target :main_kt_deploy.jar up-to-date:
$ java -jar ./bazel-bin/.../main_kt_deploy.jar
```

> The `kotlin-runtime.jar` is implicitly included by the `kotlin_binary` rule.
#### kotlin_binary attributes

Includes all `kotlin_library` attributes as well as:
Expand All @@ -137,25 +148,52 @@ Includes all `kotlin_library` attributes as well as:
| `main_class` | `string` | Main class to run with the `kotlin_binary` rule |


### kotlin_test

The `kotlin_test` rule is nearly identical the `kotlin_binary` rule
(other than calling `java_test` internally rather than `java_binary`).


```python
kotlin_test(
name = "main_kt_test",
test_class = "examples.helloworld.MainKtTest",
srcs = ["MainKtTest.kt"],
size = "small",
deps = [
":rules",
],
java_deps = [
"@junit4//jar",
],
)
```

```sh
$ bazel test :main_kt_test.jar
```

> The `kotlin-test.jar` is implicitly included by the `kotlin_test` rule.
### kotlin_compile

The `kotlin_compile` rule runs the `kotlinc` tool to generate a `.jar`
file from a list of kotlin source files. The `kotlin_library` rule
(actually, macro) calls this internally and then makes the jarfile
available to other java rules via a `java_import` rule.
> TL;DR; You most likely do not need to interact with the
> `kotlin_compile` rule directly.
In summary, you most likely do not need to interact with the
`kotlin_compile` rule directly.
The `kotlin_compile` rule runs the kotlin compiler to generate a
`.jar` file from a list of kotlin source files. The `kotlin_library`
rule calls this internally and then makes the jarfile available to
other java rules via a `java_import` rule.

# Summary

That's it! Hopefully these rules with make it easy to mix kotlin and
traditional java code in your projects and take advantage of bazel's
approach to fast, repeatable, and reliable builds.

> Note: if you have a bunch of maven (central) dependencies, consider
> [rules_maven](https://github.com/pubref/rules_maven) for taming the
> issue of transitive dependencies with your java/kotlin projects.
> Note: Consider [rules_maven](https://github.com/pubref/rules_maven)
> for handling transitive maven dependencies with your java/kotlin
> projects.
## Examples

Expand All @@ -167,13 +205,14 @@ $ cd rules_kotlin
$ bazel query //... --output label_kind
$ bazel run examples/helloworld:main_kt
$ bazel run examples/helloworld:main_java
$ bazel test examples/helloworld:main_test
$ bazel test examples/helloworld:main_kt_test
```

## TODO

1. Implement a `kotlin_test` rule.
1. Proper `data` and runfiles support.
2. Android support.
2. Proper android support.
4. kapt support.
3. Incremental compilation.

Expand Down
16 changes: 15 additions & 1 deletion examples/helloworld/BUILD
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package(default_visibility = ["//visibility:public"])

load("//kotlin:rules.bzl", "kotlin_library", "kotlin_binary")
load("//kotlin:rules.bzl", "kotlin_library", "kotlin_binary", "kotlin_test")


# A kotlin binary that depends on another kotlin rule (using kotlin
Expand Down Expand Up @@ -52,6 +52,20 @@ java_test(
]
)

# A kotlin test rule that depends on a kotlin rule
kotlin_test(
name = "main_kt_test",
test_class = "examples.helloworld.MainKtTest",
srcs = ["MainKtTest.kt"],
size = "small",
deps = [
":rules",
],
java_deps = [
"@junit4//jar",
],
)

# Included to test dependent java providers
java_library(
name = "guava",
Expand Down
13 changes: 13 additions & 0 deletions examples/helloworld/MainKtTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package examples.helloworld

import kotlin.test.assertEquals
import org.junit.Test

public class MainKtTest {

@Test fun testRuleName(): Unit {
val rule = KotlinLibraryRule("foo", emptyList(), emptyList())
assertEquals("foo", rule.name)
}

}
14 changes: 14 additions & 0 deletions java/org/pubref/rules/kotlin/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ java_binary(
visibility = ["//visibility:public"],
deps = [
":compiler",
":preloader",
"//java/io/bazel/rules/closure:BazelWorker",
"//java/io/bazel/rules/closure/program",
"@com_google_dagger",
Expand All @@ -27,3 +28,16 @@ java_library(
"@com_github_jetbrains_kotlin//:compiler",
],
)

java_library(
name = "preloader",
srcs = [
"KotlinPreloader.java",
],
visibility = ["//visibility:public"],
deps = [
"//java/io/bazel/rules/closure/program",
"@com_google_guava",
"@com_github_jetbrains_kotlin//:preloader",
],
)
39 changes: 39 additions & 0 deletions java/org/pubref/rules/kotlin/KotlinPreloader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2017 PubRef.org. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.pubref.rules.kotlin;

import com.google.common.collect.Iterables;
import io.bazel.rules.closure.program.CommandLineProgram;
import org.jetbrains.kotlin.preloading.Preloader;

/**
* CommandLineProgram Wrapper for the Kotlin Preloader.
*/
public final class KotlinPreloader implements CommandLineProgram {

@Override
public Integer apply(Iterable<String> args) {
try {
Preloader.main(Iterables.toArray(args, String.class));
return 0;
} catch (Exception ex) {
ex.printStackTrace();
return 1;
}
}

}
2 changes: 2 additions & 0 deletions java/org/pubref/rules/kotlin/KotlinWorker.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public Integer apply(Iterable<String> args) {
switch (head) {
case "KotlinCompiler":
return new KotlinCompiler().apply(tail);
case "KotlinPreloader":
return new KotlinPreloader().apply(tail);
default:
output.println(
"\nERROR: First flag to KotlinWorker should be specific compiler to run, "
Expand Down
12 changes: 12 additions & 0 deletions kotlin/kotlin_repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,22 @@ java_import(
name = "runtime",
jars = ["lib/kotlin-runtime.jar"],
)
java_import(
name = "stdlib",
jars = ["lib/kotlin-stdlib.jar"],
)
java_import(
name = "compiler",
jars = ["lib/kotlin-compiler.jar"],
)
java_import(
name = "preloader",
jars = ["lib/kotlin-preloader.jar"],
)
java_import(
name = "test",
jars = ["lib/kotlin-test.jar"],
)
sh_binary(
name = "kotlin",
srcs = ["bin/kotlin"],
Expand Down
Loading

0 comments on commit c998eb5

Please sign in to comment.