aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--WORKSPACE8
-rw-r--r--tools/build_defs/scala/README.md35
-rw-r--r--tools/build_defs/scala/scala.bzl108
-rw-r--r--tools/build_defs/scala/test/BUILD13
-rw-r--r--tools/build_defs/scala/test/HelloLib.scala12
-rw-r--r--tools/build_defs/scala/test/HelloLibTest.scala16
6 files changed, 152 insertions, 40 deletions
diff --git a/WORKSPACE b/WORKSPACE
index ebe5700f2f..1cb41a8e00 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -52,3 +52,11 @@ new_http_archive(
url = "http://downloads.typesafe.com/scala/2.11.7/scala-2.11.7.tgz",
build_file = "tools/build_defs/scala/scala.BUILD",
)
+
+# only used for the scala test rule
+http_file(
+ name = "scalatest",
+ url = "https://oss.sonatype.org/content/groups/public/org/scalatest/scalatest_2.11/2.2.6/scalatest_2.11-2.2.6.jar",
+ sha256 = "f198967436a5e7a69cfd182902adcfbcb9f2e41b349e1a5c8881a2407f615962",
+)
+
diff --git a/tools/build_defs/scala/README.md b/tools/build_defs/scala/README.md
index c2db304035..1bf99809aa 100644
--- a/tools/build_defs/scala/README.md
+++ b/tools/build_defs/scala/README.md
@@ -5,17 +5,18 @@
<ul>
<li><a href="#scala_library">scala_library/scala_macro_library</a></li>
<li><a href="#scala_binary">scala_binary</a></li>
+ <li><a href="#scala_test">scala_test</a></li>
</ul>
</div>
## Overview
This rule is used for building [Scala][scala] projects with Bazel. There are
-currently three rules, `scala_library`, `scala_macro_library` and
-`scala_binary`. More features will be added in the future, e.g. `scala_test`.
+currently four rules, `scala_library`, `scala_macro_library`, `scala_binary`
+and `scala_test`.
-In order to use this build rule, you must add the following to your WORKSPACE
-file:
+In order to use `scala_library`, `scala_macro_library`, and `scala_binary`,
+you must add the following to your WORKSPACE file:
```python
new_http_archive(
name = "scala",
@@ -26,6 +27,16 @@ new_http_archive(
)
```
+In addition, in order to use `scala_test`, you must add the following to your
+WORKSPACE file:
+```python
+http_file(
+ name = "scalatest",
+ url = "https://oss.sonatype.org/content/groups/public/org/scalatest/scalatest_2.11/2.2.6/scalatest_2.11-2.2.6.jar",
+ sha256 = "f198967436a5e7a69cfd182902adcfbcb9f2e41b349e1a5c8881a2407f615962",
+)
+```
+
[scala]: http://www.scala-lang.org/
<a name="scala_library"></a>
@@ -234,3 +245,19 @@ A `scala_binary` requires a `main_class` attribute.
</tr>
</tbody>
</table>
+
+<a name="scala_test"></a>
+## scala_test
+
+```python
+scala_test(name, srcs, suites, deps, data, main_class, resources, scalacopts, jvm_flags)
+```
+
+`scala_test` generates a Scala executable which runs unit test suites written
+using the `scalatest` library. It may depend on `scala_library`,
+`scala_macro_library` and `java_library` rules.
+
+A `scala_test` requires a `suites` attribute, specifying the fully qualified
+(canonical) names of the test suites to run. In a future version, we might
+investigate lifting this requirement.
+
diff --git a/tools/build_defs/scala/scala.bzl b/tools/build_defs/scala/scala.bzl
index 488d526cbd..10ac1aec22 100644
--- a/tools/build_defs/scala/scala.bzl
+++ b/tools/build_defs/scala/scala.bzl
@@ -85,9 +85,10 @@ def _write_manifest(ctx):
def _write_launcher(ctx, jars):
content = """#!/bin/bash
cd $0.runfiles
-java -cp {cp} {name} "$@"
+{java} -cp {cp} {name} "$@"
"""
content = content.format(
+ java=ctx.file._java.path,
name=ctx.attr.main_class,
deploy_jar=ctx.outputs.jar.path,
cp=":".join([j.short_path for j in jars]))
@@ -95,6 +96,27 @@ java -cp {cp} {name} "$@"
output=ctx.outputs.executable,
content=content)
+def _args_for_suites(suites):
+ args = ["-o"]
+ for suite in suites:
+ args.extend(["-s", suite])
+ return args
+
+def _write_test_launcher(ctx, jars):
+ content = """#!/bin/bash
+cd $0.runfiles
+{java} -cp {cp} {name} {args} "$@"
+"""
+ content = content.format(
+ java=ctx.file._java.path,
+ name=ctx.attr.main_class,
+ args=' '.join(_args_for_suites(ctx.attr.suites)),
+ deploy_jar=ctx.outputs.jar.path,
+ cp=":".join([j.short_path for j in jars]))
+ ctx.file_action(
+ output=ctx.outputs.executable,
+ content=content)
+
def _collect_comp_run_jars(ctx):
compile_jars = set()
runtime_jars = set()
@@ -140,43 +162,60 @@ def _scala_macro_library_impl(ctx):
interface_jar_files=cjars,
runfiles=runfiles)
-def _scala_binary_impl(ctx):
- (cjars, rjars) = _collect_comp_run_jars(ctx)
+# Common code shared by all scala binary implementations.
+def _scala_binary_common(ctx, cjars, rjars):
_write_manifest(ctx)
_compile(ctx, cjars, False)
- rjars += [ctx.outputs.jar, ctx.file._scalalib]
- _write_launcher(ctx, rjars)
-
runfiles = ctx.runfiles(
- files = list(rjars) + [ctx.outputs.executable],
+ files = list(rjars) + [ctx.outputs.executable] + [ctx.file._java] + ctx.files._jdk,
collect_data = True)
return struct(
files=set([ctx.outputs.executable]),
runfiles=runfiles)
+def _scala_binary_impl(ctx):
+ (cjars, rjars) = _collect_comp_run_jars(ctx)
+ cjars += [ctx.file._scalareflect]
+ rjars += [ctx.outputs.jar, ctx.file._scalalib, ctx.file._scalareflect]
+ _write_launcher(ctx, rjars)
+ return _scala_binary_common(ctx, cjars, rjars)
+
+def _scala_test_impl(ctx):
+ (cjars, rjars) = _collect_comp_run_jars(ctx)
+ cjars += [ctx.file._scalareflect, ctx.file._scalatest, ctx.file._scalaxml]
+ rjars += [ctx.outputs.jar, ctx.file._scalalib, ctx.file._scalareflect, ctx.file._scalatest, ctx.file._scalaxml]
+ _write_test_launcher(ctx, rjars)
+ return _scala_binary_common(ctx, cjars, rjars)
+
_implicit_deps = {
"_ijar": attr.label(executable=True, default=Label("//tools/defaults:ijar"), single_file=True, allow_files=True),
"_scalac": attr.label(executable=True, default=Label("@scala//:bin/scalac"), single_file=True, allow_files=True),
"_scalalib": attr.label(default=Label("@scala//:lib/scala-library.jar"), single_file=True, allow_files=True),
+ "_scalaxml": attr.label(default=Label("@scala//:lib/scala-xml_2.11-1.0.4.jar"), single_file=True, allow_files=True),
"_scalasdk": attr.label(default=Label("@scala//:sdk"), allow_files=True),
+ "_scalareflect": attr.label(default=Label("@scala//:lib/scala-reflect.jar"), single_file=True, allow_files=True),
"_jar": attr.label(executable=True, default=Label("@bazel_tools//tools/jdk:jar"), single_file=True, allow_files=True),
"_jdk": attr.label(default=Label("//tools/defaults:jdk"), allow_files=True),
}
+# Common attributes reused across multiple rules.
+_common_attrs = {
+ "srcs": attr.label_list(
+ allow_files=_scala_filetype,
+ non_empty=True),
+ "deps": attr.label_list(),
+ "data": attr.label_list(allow_files=True, cfg=DATA_CFG),
+ "resources": attr.label_list(allow_files=True),
+ "scalacopts":attr.string_list(),
+ "jvm_flags": attr.string_list(),
+}
+
scala_library = rule(
implementation=_scala_library_impl,
attrs={
"main_class": attr.string(),
- "srcs": attr.label_list(
- allow_files=_scala_filetype,
- non_empty=True),
- "deps": attr.label_list(),
- "data": attr.label_list(allow_files=True, cfg=DATA_CFG),
- "resources": attr.label_list(allow_files=True),
- "scalacopts": attr.string_list(),
- "jvm_flags": attr.string_list(),
- } + _implicit_deps,
+ } + _implicit_deps + _common_attrs,
outputs={
"jar": "%{name}_deploy.jar",
"ijar": "%{name}_ijar.jar",
@@ -188,16 +227,8 @@ scala_macro_library = rule(
implementation=_scala_macro_library_impl,
attrs={
"main_class": attr.string(),
- "srcs": attr.label_list(
- allow_files=_scala_filetype,
- non_empty=True),
- "deps": attr.label_list(),
- "data": attr.label_list(allow_files=True, cfg=DATA_CFG),
- "resources": attr.label_list(allow_files=True),
- "scalacopts": attr.string_list(),
- "jvm_flags": attr.string_list(),
"_scala-reflect": attr.label(default=Label("@scala//:lib/scala-reflect.jar"), single_file=True, allow_files=True),
- } + _implicit_deps,
+ } + _implicit_deps + _common_attrs,
outputs={
"jar": "%{name}_deploy.jar",
"manifest": "%{name}_MANIFEST.MF",
@@ -208,18 +239,27 @@ scala_binary = rule(
implementation=_scala_binary_impl,
attrs={
"main_class": attr.string(mandatory=True),
- "srcs": attr.label_list(
- allow_files=_scala_filetype,
- non_empty=True),
- "deps": attr.label_list(),
- "data": attr.label_list(allow_files=True, cfg=DATA_CFG),
- "resources": attr.label_list(allow_files=True),
- "scalacopts":attr.string_list(),
- "jvm_flags": attr.string_list(),
- } + _implicit_deps,
+ "_java": attr.label(executable=True, default=Label("@bazel_tools//tools/jdk:java"), single_file=True, allow_files=True),
+ } + _implicit_deps + _common_attrs,
+ outputs={
+ "jar": "%{name}_deploy.jar",
+ "manifest": "%{name}_MANIFEST.MF",
+ },
+ executable=True,
+)
+
+scala_test = rule(
+ implementation=_scala_test_impl,
+ attrs={
+ "main_class": attr.string(default="org.scalatest.tools.Runner"),
+ "suites": attr.string_list(),
+ "_scalatest": attr.label(executable=True, default=Label("@scalatest//file"), single_file=True, allow_files=True),
+ "_java": attr.label(executable=True, default=Label("@bazel_tools//tools/jdk:java"), single_file=True, allow_files=True),
+ } + _implicit_deps + _common_attrs,
outputs={
"jar": "%{name}_deploy.jar",
"manifest": "%{name}_MANIFEST.MF",
},
executable=True,
+ test=True,
)
diff --git a/tools/build_defs/scala/test/BUILD b/tools/build_defs/scala/test/BUILD
index 4000e0c57d..6f77bb4376 100644
--- a/tools/build_defs/scala/test/BUILD
+++ b/tools/build_defs/scala/test/BUILD
@@ -33,6 +33,19 @@ scala_library(
],
)
+scala_test(
+ name = "HelloLibTest",
+ size = "medium", # Not a macro, can pass test-specific attributes.
+ srcs = ["HelloLibTest.scala"],
+ suites = [
+ "scala.test.ScalaSuite",
+ "scala.test.JavaSuite",
+ ],
+ deps = [
+ ":HelloLib",
+ ],
+)
+
scala_library(
name = "OtherLib",
srcs = ["OtherLib.scala"],
diff --git a/tools/build_defs/scala/test/HelloLib.scala b/tools/build_defs/scala/test/HelloLib.scala
index 88db4546ac..a1fef111da 100644
--- a/tools/build_defs/scala/test/HelloLib.scala
+++ b/tools/build_defs/scala/test/HelloLib.scala
@@ -2,7 +2,15 @@ package scala.test
object HelloLib {
def printMessage(arg: String) {
- println(arg + " " + OtherLib.getMessage())
- println(arg + " " + OtherJavaLib.getMessage())
+ println(getOtherLibMessage(arg))
+ println(getOtherJavaLibMessage(arg))
+ }
+
+ def getOtherLibMessage(arg: String) : String = {
+ arg + " " + OtherLib.getMessage()
+ }
+
+ def getOtherJavaLibMessage(arg: String) : String = {
+ arg + " " + OtherJavaLib.getMessage()
}
}
diff --git a/tools/build_defs/scala/test/HelloLibTest.scala b/tools/build_defs/scala/test/HelloLibTest.scala
new file mode 100644
index 0000000000..7f5cb5f9b7
--- /dev/null
+++ b/tools/build_defs/scala/test/HelloLibTest.scala
@@ -0,0 +1,16 @@
+package scala.test
+
+import org.scalatest._
+
+class ScalaSuite extends FlatSpec {
+ "HelloLib" should "call scala" in {
+ assert(HelloLib.getOtherLibMessage("hello").equals("hello scala!"))
+ }
+}
+
+class JavaSuite extends FlatSpec {
+ "HelloLib" should "call java" in {
+ assert(HelloLib.getOtherJavaLibMessage("hello").equals("hello java!"))
+ }
+}
+