diff options
-rw-r--r-- | WORKSPACE | 8 | ||||
-rw-r--r-- | tools/build_defs/scala/README.md | 35 | ||||
-rw-r--r-- | tools/build_defs/scala/scala.bzl | 108 | ||||
-rw-r--r-- | tools/build_defs/scala/test/BUILD | 13 | ||||
-rw-r--r-- | tools/build_defs/scala/test/HelloLib.scala | 12 | ||||
-rw-r--r-- | tools/build_defs/scala/test/HelloLibTest.scala | 16 |
6 files changed, 152 insertions, 40 deletions
@@ -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!")) + } +} + |