diff --git a/.bazelrc.travis b/.bazelrc.travis index 657602435..e3fcfe4d6 100644 --- a/.bazelrc.travis +++ b/.bazelrc.travis @@ -17,8 +17,8 @@ build --verbose_failures # runs stuff in a container, and since Travis already runs its script # in a container (unless you require sudo in your .travis.yml) this # fails to run tests. -build --spawn_strategy=standalone --genrule_strategy=standalone --strategy=Scalac=worker --strategy=ScroogeRule=worker --worker_max_instances=3 -test --test_strategy=standalone +build --strategy=Scalac=worker --strategy=ScroogeRule=worker --worker_max_instances=3 +#test --test_strategy=standalone # Below this line, .travis.yml will cat the default bazelrc. # This is needed so Bazel starts with the base workspace in its diff --git a/README.md b/README.md index 8dfa7bc8b..26cc0915d 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@
  • scala_library/scala_macro_library
  • scala_binary
  • scala_test
  • +
  • scalapb_proto_library
  • @@ -467,10 +468,20 @@ thrift_library(name, srcs, deps, absolute_prefix, absolute_prefixes) + ## scalapb_proto_library +You first need to add the following to your WORKSPACE file: + +```python +load("@io_bazel_rules_scala//scala_proto:scala_proto.bzl", "scala_proto_repositories") +scala_proto_repositories() +``` + +Then you can import `scalapb_proto_library` in any BUILD file like this: + ```python -load("//scala_proto:scala_proto.bzl", "scalapb_proto_library") +load("@io_bazel_rules_scala//scala_proto:scala_proto.bzl", "scalapb_proto_library") scalapb_proto_library(name, deps, with_grpc, with_java, with_flat_package, with_single_line_to_string) ``` @@ -498,7 +509,7 @@ generated by the [ScalaPB compiler](https://github.com/scalapb/ScalaPB). deps

    List of labels, required

    -

    List of proto dependencies that this target depends on. Must be of type proto_library

    +

    List of dependencies for this target. Must either be of type proto_library or java_proto_library (allowed only if with_java is enabled)

    @@ -512,7 +523,7 @@ generated by the [ScalaPB compiler](https://github.com/scalapb/ScalaPB). with_java

    boolean; optional (default False)

    -

    Enables generation of converters to and from java protobuf bindings

    +

    Enables generation of converters to and from java protobuf bindings. If you set this to True make sure that you pass the corresponding java_proto_library target in deps

    diff --git a/WORKSPACE b/WORKSPACE index c2ce2261a..51a65fffa 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -56,14 +56,14 @@ maven_jar( http_archive( name = "com_google_protobuf", - urls = ["https://github.com/google/protobuf/archive/b4b0e304be5a68de3d0ee1af9b286f958750f5e4.zip"], - strip_prefix = "protobuf-b4b0e304be5a68de3d0ee1af9b286f958750f5e4", - sha256 = "ff771a662fb6bd4d3cc209bcccedef3e93980a49f71df1e987f6afa3bcdcba3a", + urls = ["https://github.com/google/protobuf/archive/b04e5cba356212e4e8c66c61bbe0c3a20537c5b9.zip"], + strip_prefix = "protobuf-b04e5cba356212e4e8c66c61bbe0c3a20537c5b9", + sha256 = "cf4a434ac3a83040e9f65be92e153d00d075d8cd25e3f6c6d8670879f5796aa0", ) http_archive( name = "com_google_protobuf_java", - urls = ["https://github.com/google/protobuf/archive/b4b0e304be5a68de3d0ee1af9b286f958750f5e4.zip"], - strip_prefix = "protobuf-b4b0e304be5a68de3d0ee1af9b286f958750f5e4", - sha256 = "ff771a662fb6bd4d3cc209bcccedef3e93980a49f71df1e987f6afa3bcdcba3a", + urls = ["https://github.com/google/protobuf/archive/b04e5cba356212e4e8c66c61bbe0c3a20537c5b9.zip"], + strip_prefix = "protobuf-b04e5cba356212e4e8c66c61bbe0c3a20537c5b9", + sha256 = "cf4a434ac3a83040e9f65be92e153d00d075d8cd25e3f6c6d8670879f5796aa0", ) diff --git a/scala/scala.bzl b/scala/scala.bzl index 2f0caebdd..e875b2b28 100644 --- a/scala/scala.bzl +++ b/scala/scala.bzl @@ -15,6 +15,7 @@ """Rules for supporting the Scala language.""" load("//specs2:specs2_junit.bzl", "specs2_junit_dependencies") +load(":scala_cross_version.bzl", "scala_version", "scala_mvn_artifact") _jar_filetype = FileType([".jar"]) _java_filetype = FileType([".java"]) _scala_filetype = FileType([".scala"]) @@ -66,7 +67,7 @@ def _adjust_resources_path(path, resource_strip_prefix): def _add_resources_cmd(ctx): res_cmd = [] for f in ctx.files.resources: - c_dir, res_path = _adjust_resources_path(f.path, ctx.attr.resource_strip_prefix) + c_dir, res_path = _adjust_resources_path(f.short_path, ctx.attr.resource_strip_prefix) target_path = res_path if target_path[0] == "/": target_path = target_path[1:] @@ -197,6 +198,7 @@ PrintCompileTime: {print_compile_time} ResourceDests: {resource_dest} ResourceJars: {resource_jars} ResourceSrcs: {resource_src} +ResourceShortPaths: {resource_short_paths} ResourceStripPrefix: {resource_strip_prefix} ScalacOpts: {scala_opts} SourceJars: {srcjars} @@ -218,8 +220,9 @@ DependencyAnalyzerMode: {dependency_analyzer_mode} srcjars=",".join([f.path for f in all_srcjars]), java_files=",".join([f.path for f in java_srcs]), resource_src=",".join([f.path for f in ctx.files.resources]), + resource_short_paths=",".join([f.short_path for f in ctx.files.resources]), resource_dest=",".join( - [_adjust_resources_path_by_default_prefixes(f.path)[1] for f in ctx.files.resources] + [_adjust_resources_path_by_default_prefixes(f.short_path)[1] for f in ctx.files.resources] ), resource_strip_prefix=ctx.attr.resource_strip_prefix, resource_jars=",".join([f.path for f in ctx.files.resource_jars]), @@ -390,15 +393,20 @@ def _write_launcher(ctx, rjars, main_class, jvm_flags, args="", wrapper_preamble javabin = "%s/%s" % (runfiles_root, ctx.executable._java.short_path) template = ctx.attr._java_stub_template.files.to_list()[0] + exec_str = "" + if wrapper_preamble == "": + exec_str = "exec " + wrapper = ctx.new_file(ctx.label.name + "_wrapper.sh") ctx.file_action( output = wrapper, content = """#!/bin/bash {preamble} -{javabin} "$@" {args} +{exec_str}{javabin} "$@" {args} """.format( preamble=wrapper_preamble, + exec_str=exec_str, javabin=javabin, args=args, ), @@ -514,7 +522,7 @@ def _collect_jars_when_dependency_analyzer_is_on(dep_targets): jars2labels = jars2labels, transitive_compile_jars = transitive_compile_jars) -def _collect_jars(dep_targets, dependency_analyzer_is_off = True): +def collect_jars(dep_targets, dependency_analyzer_is_off = True): """Compute the runtime and compile-time dependencies from the given targets""" # noqa if dependency_analyzer_is_off: @@ -542,10 +550,10 @@ def _collect_jars_from_common_ctx(ctx, extra_deps = [], extra_runtime_deps = []) # Get jars from deps auto_deps = [ctx.attr._scalalib, ctx.attr._scalareflect] - deps_jars = _collect_jars(ctx.attr.deps + auto_deps + extra_deps, dependency_analyzer_is_off) + deps_jars = collect_jars(ctx.attr.deps + auto_deps + extra_deps, dependency_analyzer_is_off) (cjars, transitive_rjars, jars2labels, transitive_compile_jars) = (deps_jars.compile_jars, deps_jars.transitive_runtime_jars, deps_jars.jars2labels, deps_jars.transitive_compile_jars) - runtime_dep_jars = _collect_jars(ctx.attr.runtime_deps + extra_runtime_deps, dependency_analyzer_is_off) + runtime_dep_jars = collect_jars(ctx.attr.runtime_deps + extra_runtime_deps, dependency_analyzer_is_off) transitive_rjars += runtime_dep_jars.transitive_runtime_jars if not dependency_analyzer_is_off: @@ -556,7 +564,7 @@ def _collect_jars_from_common_ctx(ctx, extra_deps = [], extra_runtime_deps = []) def _format_full_jars_for_intellij_plugin(full_jars): return [struct (class_jar = jar, ijar = None) for jar in full_jars] -def _create_java_provider(ctx, scalaattr, transitive_compile_time_jars): +def create_java_provider(ctx, scalaattr, transitive_compile_time_jars): # This is needed because Bazel >=0.6.0 requires ctx.actions and a Java # toolchain. Fortunately, the same change that added this requirement also # added this field to the Java provider so we can use it to test which @@ -610,7 +618,7 @@ def _lib(ctx, non_macro_lib): # Add information from exports (is key that AFTER all build actions/runfiles analysis) # Since after, will not show up in deploy_jar or old jars runfiles # Notice that compile_jars is intentionally transitive for exports - exports_jars = _collect_jars(ctx.attr.exports) + exports_jars = collect_jars(ctx.attr.exports) next_cjars += exports_jars.compile_jars transitive_rjars += exports_jars.transitive_runtime_jars @@ -631,7 +639,7 @@ def _lib(ctx, non_macro_lib): transitive_exports = [] #needed by intellij plugin ) - java_provider = _create_java_provider(ctx, scalaattr, jars.transitive_compile_jars) + java_provider = create_java_provider(ctx, scalaattr, jars.transitive_compile_jars) return struct( files = depset([ctx.outputs.jar]), # Here is the default output @@ -695,7 +703,7 @@ def _scala_binary_common(ctx, cjars, rjars, transitive_compile_time_jars, jars2l transitive_exports = [] #needed by intellij plugin ) - java_provider = _create_java_provider(ctx, scalaattr, transitive_compile_time_jars) + java_provider = create_java_provider(ctx, scalaattr, transitive_compile_time_jars) return struct( files=depset([ctx.outputs.executable]), @@ -772,7 +780,7 @@ def _scala_test_impl(ctx): jars.transitive_compile_jars, jars.jars2labels) # _scalatest is an http_jar, so its compile jar is run through ijar # however, contains macros, so need to handle separately - scalatest_jars = _collect_jars([ctx.attr._scalatest]).transitive_runtime_jars + scalatest_jars = collect_jars([ctx.attr._scalatest]).transitive_runtime_jars cjars += scalatest_jars transitive_rjars += scalatest_jars @@ -973,17 +981,6 @@ scala_repl = rule( fragments = ["java"] ) -def scala_version(): - """return the scala version for use in maven coordinates""" - return "2.12" - -def scala_mvn_artifact(artifact): - gav = artifact.split(":") - groupid = gav[0] - artifactid = gav[1] - version = gav[2] - return "%s:%s_%s:%s" % (groupid, artifactid, scala_version(), version) - SCALA_BUILD_FILE = """ # scala.BUILD java_import( diff --git a/scala/scala_cross_version.bzl b/scala/scala_cross_version.bzl new file mode 100644 index 000000000..56043db38 --- /dev/null +++ b/scala/scala_cross_version.bzl @@ -0,0 +1,28 @@ +# Copyright 2015 The Bazel Authors. 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. + +"""Helper functions for Scala cross-version support. Encapsulates the logic +of abstracting over Scala major version (2.11, 2.12, etc) for dependency +resolution.""" + +def scala_version(): + """return the scala version for use in maven coordinates""" + return "2.12" + +def scala_mvn_artifact(artifact): + gav = artifact.split(":") + groupid = gav[0] + artifactid = gav[1] + version = gav[2] + return "%s:%s_%s:%s" % (groupid, artifactid, scala_version(), version) diff --git a/scala_proto/scala_proto.bzl b/scala_proto/scala_proto.bzl index be52f6c10..55d7c5ac1 100644 --- a/scala_proto/scala_proto.bzl +++ b/scala_proto/scala_proto.bzl @@ -1,5 +1,8 @@ load("//scala:scala.bzl", - "scala_library") + "scala_mvn_artifact", + "scala_library", + "collect_jars", + "create_java_provider") def scala_proto_repositories(): native.maven_server( @@ -21,7 +24,7 @@ def scala_proto_repositories(): native.maven_jar( name = "scala_proto_rules_scalapb_plugin", - artifact = "com.trueaccord.scalapb:compilerplugin_2.12:0.6.5", + artifact = scala_mvn_artifact("com.trueaccord.scalapb:compilerplugin:0.6.5"), sha1 = "d119bb24e976dacae8f55a678a027d59bc50ffac", server = "scala_proto_deps_maven_server", ) @@ -33,7 +36,7 @@ def scala_proto_repositories(): native.maven_jar( name = "scala_proto_rules_protoc_bridge", - artifact = "com.trueaccord.scalapb:protoc-bridge_2.12:0.3.0-M1", + artifact = scala_mvn_artifact("com.trueaccord.scalapb:protoc-bridge:0.3.0-M1"), sha1 = "1de84a8176cf0192b68b2873364e26cb4da61a7a", server = "scala_proto_deps_maven_server", ) @@ -45,7 +48,7 @@ def scala_proto_repositories(): native.maven_jar( name = "scala_proto_rules_scalapbc", - artifact = "com.trueaccord.scalapb:scalapbc_2.12:0.6.5", + artifact = scala_mvn_artifact("com.trueaccord.scalapb:scalapbc:0.6.5"), sha1 = "7dd00d1d5b03be9879194bf917738d69b0126fab", server = "scala_proto_deps_maven_server", ) @@ -57,7 +60,7 @@ def scala_proto_repositories(): native.maven_jar( name = "scala_proto_rules_scalapb_runtime", - artifact = "com.trueaccord.scalapb:scalapb-runtime_2.12:0.6.5", + artifact = scala_mvn_artifact("com.trueaccord.scalapb:scalapb-runtime:0.6.5"), sha1 = "5375ad64f0cc26b8e8a9377811f9b97645d24bac", server = "scala_proto_deps_maven_server", ) @@ -69,7 +72,7 @@ def scala_proto_repositories(): native.maven_jar( name = "scala_proto_rules_scalapb_runtime_grpc", - artifact = "com.trueaccord.scalapb:scalapb-runtime-grpc_2.12:0.6.5", + artifact = scala_mvn_artifact("com.trueaccord.scalapb:scalapb-runtime-grpc:0.6.5"), sha1 = "64885c5d96be6ecdfccdb27ca2bdef3ed9ce9fb4", server = "scala_proto_deps_maven_server", ) @@ -81,7 +84,7 @@ def scala_proto_repositories(): native.maven_jar( name = "scala_proto_rules_scalapb_lenses", - artifact = "com.trueaccord.lenses:lenses_2.12:0.4.12", + artifact = scala_mvn_artifact("com.trueaccord.lenses:lenses:0.4.12"), sha1 = "d97d2958814bcfe2f19e1ed2f0f03fd9da5a3961", server = "scala_proto_deps_maven_server", ) @@ -93,7 +96,7 @@ def scala_proto_repositories(): native.maven_jar( name = "scala_proto_rules_scalapb_fastparse", - artifact = "com.lihaoyi:fastparse_2.12:0.4.4", + artifact = scala_mvn_artifact("com.lihaoyi:fastparse:0.4.4"), sha1 = "aaf2048f9c6223220eac28c9b6a442f27ba83c55", server = "scala_proto_deps_maven_server", ) @@ -308,12 +311,26 @@ def scala_proto_repositories(): ) def _colon_paths(data): - return ':'.join([f.path for f in data]) + return ':'.join(["{root},{path}".format(root=f.owner.workspace_root, path=f.path) for f in data]) def _gen_proto_srcjar_impl(ctx): acc_imports = depset() + + proto_deps, java_proto_lib_deps = [], [] for target in ctx.attr.deps: - acc_imports += target.proto.transitive_sources + if hasattr(target, 'proto'): + proto_deps.append(target) + acc_imports += target.proto.transitive_sources + else: + java_proto_lib_deps.append(target) + + if not ctx.attr.with_java and len(java_proto_lib_deps) > 0: + fail("cannot have java_proto_library dependencies with with_java is False") + + if ctx.attr.with_java and len(java_proto_lib_deps) == 0: + fail("must have a java_proto_library dependency if with_java is True") + + deps_jars = collect_jars(java_proto_lib_deps) # Command line args to worker cannot be empty so using padding flags = ["-"] @@ -345,7 +362,15 @@ def _gen_proto_srcjar_impl(ctx): srcjarsattr = struct( srcjar = ctx.outputs.srcjar, ) + scalaattr = struct( + outputs = None, + compile_jars = deps_jars.compile_jars, + transitive_runtime_jars = deps_jars.transitive_runtime_jars, + ) + java_provider = create_java_provider(ctx, scalaattr, depset()) return struct( + scala = scalaattr, + providers = [java_provider], srcjars=srcjarsattr, extra_information=[struct( srcjars=srcjarsattr, @@ -357,7 +382,7 @@ scalapb_proto_srcjar = rule( attrs={ "deps": attr.label_list( mandatory=True, - allow_rules=["proto_library"] + allow_rules=["proto_library", "java_proto_library"] ), "with_grpc": attr.bool(default=False), "with_java": attr.bool(default=False), @@ -414,7 +439,7 @@ Example: Args: name: A unique name for this rule - deps: Proto library targets that this rule depends on (must be of type proto_library) + deps: Proto library or java proto library (if with_java is True) targets that this rule depends on with_grpc: Enables generation of grpc service bindings for services defined in deps with_java: Enables generation of converters to and from java protobuf bindings with_flat_package: When true, ScalaPB will not append the protofile base name to the package name @@ -446,19 +471,9 @@ def scalapb_proto_library( external_deps = list(SCALAPB_DEPS + GRPC_DEPS if (with_grpc) else SCALAPB_DEPS) - if with_java: - java_proto_lib = name + "_java_lib" - native.java_proto_library( - name = java_proto_lib, - deps = deps, - visibility = visibility, - ) - external_deps.append(java_proto_lib) - scala_library( name = name, - srcs = [srcjar], - deps = external_deps, + deps = [srcjar] + external_deps, exports = external_deps, visibility = visibility, ) diff --git a/specs2/specs2.bzl b/specs2/specs2.bzl index 45c4558c5..039abecef 100644 --- a/specs2/specs2.bzl +++ b/specs2/specs2.bzl @@ -1,38 +1,42 @@ +load("//scala:scala_cross_version.bzl", + "scala_mvn_artifact", + ) + def specs2_version(): return "3.8.8" def specs2_repositories(): native.maven_jar( name = "io_bazel_rules_scala_org_specs2_specs2_core", - artifact = "org.specs2:specs2-core_2.12:" + specs2_version(), + artifact = scala_mvn_artifact("org.specs2:specs2-core:" + specs2_version()), sha1 = "86cb72427e64e1423edcbf082e8767a60493bbcc", ) native.bind(name = 'io_bazel_rules_scala/dependency/specs2/specs2_core', actual = '@io_bazel_rules_scala_org_specs2_specs2_core//jar') native.maven_jar( name = "io_bazel_rules_scala_org_specs2_specs2_common", - artifact = "org.specs2:specs2-common_2.12:" + specs2_version(), + artifact = scala_mvn_artifact("org.specs2:specs2-common:" + specs2_version()), sha1 = "83bd14fb54f81a886901fa7ed136bcf887322440", ) native.bind(name = 'io_bazel_rules_scala/dependency/specs2/specs2_common', actual = '@io_bazel_rules_scala_org_specs2_specs2_common//jar') native.maven_jar( name = "io_bazel_rules_scala_org_specs2_specs2_matcher", - artifact = "org.specs2:specs2-matcher_2.12:" + specs2_version(), + artifact = scala_mvn_artifact("org.specs2:specs2-matcher:" + specs2_version()), sha1 = "921d9ef6bf98c3e5a59d535e1139b5522625d6ba", ) native.bind(name = 'io_bazel_rules_scala/dependency/specs2/specs2_matcher', actual = '@io_bazel_rules_scala_org_specs2_specs2_matcher//jar') native.maven_jar( name = "io_bazel_rules_scala_org_scalaz_scalaz_effect", - artifact = "org.scalaz:scalaz-effect_2.12:7.2.7", + artifact = scala_mvn_artifact("org.scalaz:scalaz-effect:7.2.7"), sha1 = "5d0bbd74323d8c7467cde95dcdc298eb3d9dcdb1", ) native.bind(name = 'io_bazel_rules_scala/dependency/scalaz/scalaz_effect', actual = '@io_bazel_rules_scala_org_scalaz_scalaz_effect//jar') native.maven_jar( name = "io_bazel_rules_scala_org_scalaz_scalaz_core", - artifact = "org.scalaz:scalaz-core_2.12:7.2.7", + artifact = scala_mvn_artifact("org.scalaz:scalaz-core:7.2.7"), sha1 = "ee06c07e856bad6ce112b2a5b96e1df1609ad57f", ) native.bind(name = 'io_bazel_rules_scala/dependency/scalaz/scalaz_core', actual = '@io_bazel_rules_scala_org_scalaz_scalaz_core//jar') diff --git a/specs2/specs2_junit.bzl b/specs2/specs2_junit.bzl index 6046f6c36..b3083354b 100644 --- a/specs2/specs2_junit.bzl +++ b/specs2/specs2_junit.bzl @@ -1,4 +1,5 @@ load("//specs2:specs2.bzl", "specs2_repositories", "specs2_dependencies", "specs2_version") +load("//scala:scala_cross_version.bzl", "scala_mvn_artifact") load("//junit:junit.bzl", "junit_repositories") def specs2_junit_repositories(): @@ -7,7 +8,7 @@ def specs2_junit_repositories(): # Aditional dependencies for specs2 junit runner native.maven_jar( name = "io_bazel_rules_scala_org_specs2_specs2_junit_2_12", - artifact = "org.specs2:specs2-junit_2.12:" + specs2_version(), + artifact = scala_mvn_artifact("org.specs2:specs2-junit:" + specs2_version()), sha1 = "aa6af850ccd428673add3840652cdd8e82791391", ) native.bind(name = 'io_bazel_rules_scala/dependency/specs2/specs2_junit', actual = '@io_bazel_rules_scala_org_specs2_specs2_junit_2_12//jar') diff --git a/src/java/io/bazel/rulesscala/scalac/BUILD b/src/java/io/bazel/rulesscala/scalac/BUILD index e56aebcc5..a27f34a9f 100644 --- a/src/java/io/bazel/rulesscala/scalac/BUILD +++ b/src/java/io/bazel/rulesscala/scalac/BUILD @@ -4,6 +4,7 @@ java_binary( "CompileOptions.java", "ScalaCInvoker.java", "ScalacProcessor.java", + "Resource.java", ], main_class = "io.bazel.rulesscala.scalac.ScalaCInvoker", # this probably should be set globally for the entire rules_scala diff --git a/src/java/io/bazel/rulesscala/scalac/CompileOptions.java b/src/java/io/bazel/rulesscala/scalac/CompileOptions.java index 64d9c3c6c..eaa80a699 100644 --- a/src/java/io/bazel/rulesscala/scalac/CompileOptions.java +++ b/src/java/io/bazel/rulesscala/scalac/CompileOptions.java @@ -17,7 +17,7 @@ public class CompileOptions { final public String ijarOutput; final public String ijarCmdPath; final public String[] javaFiles; - final public Map resourceFiles; + final public Map resourceFiles; final public String resourceStripPrefix; final public String[] resourceJars; final public String[] directJars; @@ -62,15 +62,23 @@ public CompileOptions(List args) { currentTarget = getOrElse(argMap, "CurrentTarget", "NA"); } - private static Map getResources(Map args) { + private static Map getResources(Map args) { String[] keys = getCommaList(args, "ResourceSrcs"); - String[] vals = getCommaList(args, "ResourceDests"); - if (keys.length != vals.length) - throw new RuntimeException(String.format("mismatch in resources: keys: %s vals: %s", + String[] dests = getCommaList(args, "ResourceDests"); + String[] shortPaths = getCommaList(args, "ResourceShortPaths"); + + if (keys.length != dests.length) + throw new RuntimeException(String.format("mismatch in resources: keys: %s dests: %s", getOrEmpty(args, "ResourceSrcs"), getOrEmpty(args, "ResourceDests"))); - HashMap res = new HashMap(); + + if (keys.length != shortPaths.length) + throw new RuntimeException(String.format("mismatch in resources: keys: %s shortPaths: %s", + getOrEmpty(args, "ResourceSrcs"), getOrEmpty(args, "ResourceShortPaths"))); + + HashMap res = new HashMap(); for(int idx = 0; idx < keys.length; idx++) { - res.put(keys[idx], vals[idx]); + Resource resource = new Resource(dests[idx], shortPaths[idx]); + res.put(keys[idx], resource); } return res; } diff --git a/src/java/io/bazel/rulesscala/scalac/Resource.java b/src/java/io/bazel/rulesscala/scalac/Resource.java new file mode 100644 index 000000000..a8db9dbc3 --- /dev/null +++ b/src/java/io/bazel/rulesscala/scalac/Resource.java @@ -0,0 +1,11 @@ +package io.bazel.rulesscala.scalac; + +public class Resource { + public final String destination; + public final String shortPath; + + public Resource(String destination, String shortPath) { + this.destination = destination; + this.shortPath = shortPath; + } +} diff --git a/src/java/io/bazel/rulesscala/scalac/ScalacProcessor.java b/src/java/io/bazel/rulesscala/scalac/ScalacProcessor.java index 78d904cc3..00c632ce2 100644 --- a/src/java/io/bazel/rulesscala/scalac/ScalacProcessor.java +++ b/src/java/io/bazel/rulesscala/scalac/ScalacProcessor.java @@ -275,11 +275,13 @@ public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOEx } } private static void copyResources( - Map resources, + Map resources, String resourceStripPrefix, Path dest) throws IOException { - for(Entry e : resources.entrySet()) { + for(Entry e : resources.entrySet()) { Path source = Paths.get(e.getKey()); + Resource resource = e.getValue(); + Path shortPath = Paths.get(resource.shortPath); String dstr; // Check if we need to modify resource destination path if (!"".equals(resourceStripPrefix)) { @@ -292,9 +294,9 @@ private static void copyResources( * from the Source Path and use that as the new destination path * Refer Bazel -> BazelJavaRuleClasses.java#L227 for details */ - dstr = getResourcePath(source, resourceStripPrefix); + dstr = getResourcePath(shortPath, resourceStripPrefix); } else { - dstr = e.getValue(); + dstr = resource.destination; } if (dstr.charAt(0) == '/') dstr = dstr.substring(1); Path target = dest.resolve(dstr); diff --git a/src/scala/scripts/ScalaPBGenerator.scala b/src/scala/scripts/ScalaPBGenerator.scala index ad6ce2db5..6e5fdc722 100644 --- a/src/scala/scripts/ScalaPBGenerator.scala +++ b/src/scala/scripts/ScalaPBGenerator.scala @@ -39,7 +39,25 @@ class ScalaPBGenerator extends Processor { def processRequest(args: java.util.List[String]) { val jarOutput = args.get(0) - val protoFiles = args.get(1).split(':').toList + val parsedProtoFiles = args.get(1).split(':').toList.map { rootAndFile => + val parsed = rootAndFile.split(',') + val root = parsed(0) + val file = if (root.isEmpty) { + parsed(1) + } else { + parsed(1).substring(root.length + 1) + } + (file, Paths.get(root, file).toString) + } + // This will map the absolute path of a given proto file + // to a relative path that does not contain the repo prefix. + // This is to match the expected behavior of + // proto_library and java_proto_library where proto files + // can import other proto files using only the relative path + val imports = parsedProtoFiles.map { case (relPath, absolutePath) => + s"-I${relPath}=${absolutePath}" + } + val protoFiles = parsedProtoFiles.map(_._2) val flagOpt = args.get(2) match { case "-" => None case s => Some(s.drop(2)) @@ -48,7 +66,7 @@ class ScalaPBGenerator extends Processor { val tmp = Paths.get(Option(System.getProperty("java.io.tmpdir")).getOrElse("/tmp")) val scalaPBOutput = Files.createTempDirectory(tmp, "bazelscalapb") val flagPrefix = flagOpt.map(_ + ":").getOrElse("") - val scalaPBArgs = s"--scala_out=${flagPrefix}${scalaPBOutput}" :: protoFiles + val scalaPBArgs = s"--scala_out=${flagPrefix}${scalaPBOutput}" :: (imports ++ protoFiles) val config = ScalaPBC.processArgs(scalaPBArgs.toArray) val code = ProtocBridge.runWithGenerators( protoc = a => com.github.os72.protocjar.Protoc.runProtoc(config.version +: a.toArray), diff --git a/test/BUILD b/test/BUILD index cb5062f84..a5abca636 100644 --- a/test/BUILD +++ b/test/BUILD @@ -166,7 +166,8 @@ scala_library( "//test/data:more.txt", "//test/data:foo.txt", "//test/src/main/resources/scala/test:more-hellos", - "//test/src/main/resources/scala/test:more-byes" + "//test/src/main/resources/scala/test:more-byes", + "//test/src/main/resources/scala/test:generated-hello", ], resource_strip_prefix = "test/", ) diff --git a/test/proto/BUILD b/test/proto/BUILD index 99a7cacf3..c21da8c61 100644 --- a/test/proto/BUILD +++ b/test/proto/BUILD @@ -28,9 +28,14 @@ scalapb_proto_library( visibility = ["//visibility:public"], ) +java_proto_library( + name = "test_proto_java_lib", + deps = [":test2", "//test/proto2:test"], +) + scalapb_proto_library( name = "test_proto_java_conversions", - deps = [":test2", "//test/proto2:test"], + deps = [":test2", "//test/proto2:test", ":test_proto_java_lib"], with_java = True, with_flat_package = True, visibility = ["//visibility:public"], diff --git a/test/src/main/resources/scala/test/BUILD b/test/src/main/resources/scala/test/BUILD index cd3f6cfa7..df2e639f9 100644 --- a/test/src/main/resources/scala/test/BUILD +++ b/test/src/main/resources/scala/test/BUILD @@ -1 +1,8 @@ exports_files(["byes", "hellos", "hellos-and-byes.jar", "more-byes", "more-hellos"]) + +genrule( + name = "generated-hello", + outs = ["generated-hello.txt"], + cmd = "echo 'hello' > $@", + visibility = ["//visibility:public"], +) diff --git a/test/src/main/scala/scala/test/ResourcesStripScalaBinary.scala b/test/src/main/scala/scala/test/ResourcesStripScalaBinary.scala index 7f161db15..c36e7bffe 100644 --- a/test/src/main/scala/scala/test/ResourcesStripScalaBinary.scala +++ b/test/src/main/scala/scala/test/ResourcesStripScalaBinary.scala @@ -19,5 +19,6 @@ object ResourcesStripScalaBinary { ResourcesStripScalaLib.getGreetings foreach println ResourcesStripScalaLib.getFarewells foreach println ResourcesStripScalaLib.getData foreach println + ResourcesStripScalaLib.getGeneratedHello foreach println } } diff --git a/test/src/main/scala/scala/test/ResourcesStripScalaLib.scala b/test/src/main/scala/scala/test/ResourcesStripScalaLib.scala index 2ddacb829..6ebdc70e7 100644 --- a/test/src/main/scala/scala/test/ResourcesStripScalaLib.scala +++ b/test/src/main/scala/scala/test/ResourcesStripScalaLib.scala @@ -21,6 +21,8 @@ object ResourcesStripScalaLib { def getData = get("/data/more.txt") + def getGeneratedHello = get("/src/main/resources/scala/test/generated-hello.txt") + private def get(s: String): List[String] = scala.io.Source .fromInputStream(getClass.getResourceAsStream(s)) diff --git a/tut_rule/tut.bzl b/tut_rule/tut.bzl index 076d97ac4..a2e9d592d 100644 --- a/tut_rule/tut.bzl +++ b/tut_rule/tut.bzl @@ -1,4 +1,5 @@ load("//scala:scala.bzl", "scala_binary") +load("//scala:scala_cross_version.bzl", "scala_mvn_artifact") def tut_repositories(): native.maven_server( @@ -8,7 +9,7 @@ def tut_repositories(): native.maven_jar( name = "io_bazel_rules_scala_org_tpolecat_tut_core", - artifact = "org.tpolecat:tut-core_2.12:0.4.8", + artifact = scala_mvn_artifact("org.tpolecat:tut-core:0.4.8"), sha1 = "b68b5a52474bf249d1156f5002033498054b813c", server = "tut_repositories_maven_server", ) diff --git a/twitter_scrooge/twitter_scrooge.bzl b/twitter_scrooge/twitter_scrooge.bzl index 762144771..ea9a32da7 100644 --- a/twitter_scrooge/twitter_scrooge.bzl +++ b/twitter_scrooge/twitter_scrooge.bzl @@ -4,7 +4,8 @@ load("//scala:scala.bzl", "scala_mvn_artifact", "scala_library", "write_manifest", - "collect_srcjars") + "collect_srcjars", + "collect_jars") def twitter_scrooge(): native.maven_server( @@ -177,7 +178,7 @@ def _gen_scrooge_srcjar_impl(ctx): arguments=["--jvm_flag=%s" % flag for flag in ctx.attr.jvm_flags] + ["@" + argfile.path], ) - deps_jars = _collect_jars(ctx.attr.deps) + deps_jars = collect_jars(ctx.attr.deps) scalaattr = struct( outputs = None, @@ -201,22 +202,6 @@ def _gen_scrooge_srcjar_impl(ctx): )], ) -# TODO(twigg): Use the one in scala.bzl? -def _collect_jars(targets): - compile_jars = depset() - transitive_runtime_jars = depset() - - for target in targets: - if java_common.provider in target: - java_provider = target[java_common.provider] - compile_jars += java_provider.compile_jars - transitive_runtime_jars += java_provider.transitive_runtime_jars - - return struct( - compile_jars = compile_jars, - transitive_runtime_jars = transitive_runtime_jars, - ) - scrooge_scala_srcjar = rule( _gen_scrooge_srcjar_impl, attrs={