| # 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. |
| |
| load("//tools/build_rules:deprecation.bzl", "deprecated") |
| |
| def warning(rule): |
| print(deprecated( |
| "groovy", |
| rule, |
| "@bazel_tools//tools/build_defs/groovy:groovy.bzl", |
| "@io_bazel_rules_groovy//groovy:groovy.bzl")) |
| |
| def _groovy_jar_impl(ctx): |
| """Creates a .jar file from Groovy sources. Users should rely on |
| groovy_library instead of using this rule directly. |
| """ |
| warning("groovy_jar") |
| class_jar = ctx.outputs.class_jar |
| build_output = class_jar.path + ".build_output" |
| |
| # Extract all transitive dependencies |
| # TODO(bazel-team): get transitive dependencies from other groovy libraries |
| all_deps = set(ctx.files.deps) |
| for this_dep in ctx.attr.deps: |
| if hasattr(this_dep, "java"): |
| all_deps += this_dep.java.transitive_runtime_deps |
| |
| # Set up the output directory and set JAVA_HOME |
| cmd = "rm -rf %s\n" % build_output |
| cmd += "mkdir -p %s\n" % build_output |
| cmd += "export JAVA_HOME=external/local_jdk\n" |
| |
| # Set GROOVY_HOME by scanning through the groovy SDK to find the license file, |
| # which should be at the root of the SDK. |
| for file in ctx.files._groovysdk: |
| if file.basename == "CLI-LICENSE.txt": |
| cmd += "export GROOVY_HOME=%s\n" % file.dirname |
| break |
| |
| # Compile all files in srcs with groovyc |
| cmd += "$GROOVY_HOME/bin/groovyc %s -d %s %s\n" % ( |
| "-cp " + ":".join([dep.path for dep in all_deps]) if len(all_deps) != 0 else "", |
| build_output, |
| " ".join([src.path for src in ctx.files.srcs]), |
| ) |
| |
| # Discover all of the generated class files and write their paths to a file. |
| # Run the paths through sed to trim out everything before the package root so |
| # that the paths match how they should look in the jar file. |
| cmd += "find . -name '*.class' | sed 's:^./%s/::' > %s/class_list\n" % ( |
| build_output, |
| build_output, |
| ) |
| |
| # Create a jar file using the discovered paths |
| cmd += "root=`pwd`\n" |
| cmd += "cd %s; $root/%s Cc ../%s @class_list\n" % ( |
| build_output, |
| ctx.executable._zipper.path, |
| class_jar.basename, |
| ) |
| cmd += "cd $root\n" |
| |
| # Clean up temporary output |
| cmd += "rm -rf %s" % build_output |
| |
| # Execute the command |
| ctx.action( |
| inputs = ( |
| ctx.files.srcs |
| + list(all_deps) |
| + ctx.files._groovysdk |
| + ctx.files._jdk |
| + ctx.files._zipper), |
| outputs = [class_jar], |
| mnemonic = "Groovyc", |
| command = "set -e;" + cmd, |
| use_default_shell_env = True, |
| ) |
| |
| _groovy_jar = rule( |
| attrs = { |
| "srcs": attr.label_list( |
| non_empty = True, |
| allow_files = FileType([".groovy"]), |
| ), |
| "deps": attr.label_list( |
| mandatory = False, |
| allow_files = FileType([".jar"]), |
| ), |
| "_groovysdk": attr.label( |
| default = Label("//external:groovy-sdk"), |
| ), |
| "_jdk": attr.label( |
| default = Label("//tools/defaults:jdk"), |
| ), |
| "_zipper": attr.label( |
| default = Label("@bazel_tools//tools/zip:zipper"), |
| executable = True, |
| single_file = True, |
| ), |
| }, |
| outputs = { |
| "class_jar": "lib%{name}.jar", |
| }, |
| implementation = _groovy_jar_impl, |
| ) |
| |
| def groovy_library(name, srcs=[], deps=[], **kwargs): |
| """Rule analagous to java_library that accepts .groovy sources instead of |
| .java sources. The result is wrapped in a java_import so that java rules may |
| depend on it. |
| """ |
| warning("groovy_library") |
| _groovy_jar( |
| name = name + "-impl", |
| srcs = srcs, |
| deps = deps, |
| ) |
| native.java_import( |
| name = name, |
| jars = [name + "-impl"], |
| deps = deps, |
| **kwargs |
| ) |
| |
| def groovy_and_java_library(name, srcs=[], deps=[], **kwargs): |
| """Accepts .groovy and .java srcs to create a groovy_library and a |
| java_library. The groovy_library will depend on the java_library, so the |
| Groovy code may reference the Java code but not vice-versa. |
| """ |
| warning("groovy_and_java_library") |
| groovy_deps = deps |
| jars = [] |
| |
| # Put all .java sources in a java_library |
| java_srcs = [src for src in srcs if src.endswith(".java")] |
| if java_srcs: |
| native.java_library( |
| name = name + "-java", |
| srcs = java_srcs, |
| deps = deps, |
| ) |
| groovy_deps += [name + "-java"] |
| jars += ["lib" + name + "-java.jar"] |
| |
| # Put all .groovy sources in a groovy_library depending on the java_library |
| groovy_srcs = [src for src in srcs if src.endswith(".groovy")] |
| if groovy_srcs: |
| _groovy_jar( |
| name = name + "-groovy", |
| srcs = groovy_srcs, |
| deps = groovy_deps, |
| ) |
| jars += ["lib" + name + "-groovy.jar"] |
| |
| # Output a java_import combining both libraries |
| native.java_import( |
| name = name, |
| jars = jars, |
| deps = deps, |
| **kwargs |
| ) |
| |
| def groovy_binary(name, main_class, srcs=[], deps=[], **kwargs): |
| """Rule analagous to java_binary that accepts .groovy sources instead of .java |
| sources. |
| """ |
| warning("groovy_binary") |
| all_deps = deps + ["//external:groovy"] |
| if srcs: |
| groovy_library( |
| name = name + "-lib", |
| srcs = srcs, |
| deps = deps, |
| ) |
| all_deps += [name + "-lib"] |
| |
| native.java_binary( |
| name = name, |
| main_class = main_class, |
| runtime_deps = all_deps, |
| **kwargs |
| ) |
| |
| def path_to_class(path): |
| if path.startswith("src/test/groovy/"): |
| return path[len("src/test/groovy/") : path.index(".groovy")].replace('/', '.') |
| elif path.startswith("src/test/java/"): |
| return path[len("src/test/java/") : path.index(".groovy")].replace('/', '.') |
| else: |
| fail("groovy_test sources must be under src/test/java or src/test/groovy") |
| |
| def _groovy_test_impl(ctx): |
| warning("groovy_test") |
| # Collect jars from the Groovy sdk |
| groovy_sdk_jars = [file |
| for file in ctx.files._groovysdk |
| if file.basename.endswith(".jar") |
| ] |
| |
| # Extract all transitive dependencies |
| all_deps = set(ctx.files.deps + ctx.files._implicit_deps + groovy_sdk_jars) |
| for this_dep in ctx.attr.deps: |
| if hasattr(this_dep, 'java'): |
| all_deps += this_dep.java.transitive_runtime_deps |
| |
| # Infer a class name from each src file |
| classes = [path_to_class(src.path) for src in ctx.files.srcs] |
| |
| # Write a file that executes JUnit on the inferred classes |
| cmd = "external/local_jdk/bin/java %s -cp %s org.junit.runner.JUnitCore %s\n" % ( |
| " ".join(ctx.attr.jvm_flags), |
| ":".join([dep.short_path for dep in all_deps]), |
| " ".join(classes), |
| ) |
| ctx.file_action( |
| output = ctx.outputs.executable, |
| content = cmd |
| ) |
| |
| # Return all dependencies needed to run the tests |
| return struct( |
| runfiles=ctx.runfiles(files=list(all_deps) + ctx.files.data + ctx.files._jdk), |
| ) |
| |
| _groovy_test = rule( |
| attrs = { |
| "srcs": attr.label_list( |
| mandatory = True, |
| allow_files = FileType([".groovy"]), |
| ), |
| "deps": attr.label_list(allow_files = FileType([".jar"])), |
| "data": attr.label_list(allow_files = True), |
| "jvm_flags": attr.string_list(), |
| "_groovysdk": attr.label( |
| default = Label("//external:groovy-sdk"), |
| ), |
| "_jdk": attr.label( |
| default = Label("//tools/defaults:jdk"), |
| ), |
| "_implicit_deps": attr.label_list(default = [ |
| Label("//external:junit"), |
| ]), |
| }, |
| test = True, |
| implementation = _groovy_test_impl, |
| ) |
| |
| def groovy_test( |
| name, |
| deps=[], |
| srcs=[], |
| data=[], |
| resources=[], |
| jvm_flags=[], |
| size="medium", |
| tags=[]): |
| # Create an extra jar to hold the resource files if any were specified |
| all_deps = deps |
| if resources: |
| native.java_library( |
| name = name + "-resources", |
| resources = resources, |
| ) |
| all_deps += [name + "-resources"] |
| |
| _groovy_test( |
| name = name, |
| size = size, |
| tags = tags, |
| srcs = srcs, |
| deps = all_deps, |
| data = data, |
| jvm_flags = jvm_flags, |
| ) |
| |
| def groovy_junit_test( |
| name, |
| tests, |
| deps=[], |
| groovy_srcs=[], |
| java_srcs=[], |
| data=[], |
| resources=[], |
| jvm_flags=[], |
| size="small", |
| tags=[]): |
| warning("groovy_junit_test") |
| groovy_lib_deps = deps + ["//external:junit"] |
| test_deps = deps + ["//external:junit"] |
| |
| if len(tests) == 0: |
| fail("Must provide at least one file in tests") |
| |
| # Put all Java sources into a Java library |
| if java_srcs: |
| native.java_library( |
| name = name + "-javalib", |
| srcs = java_srcs, |
| deps = deps + ["//external:junit"], |
| ) |
| groovy_lib_deps += [name + "-javalib"] |
| test_deps += [name + "-javalib"] |
| |
| # Put all tests and Groovy sources into a Groovy library |
| groovy_library( |
| name = name + "-groovylib", |
| srcs = tests + groovy_srcs, |
| deps = groovy_lib_deps, |
| ) |
| test_deps += [name + "-groovylib"] |
| |
| # Create a groovy test |
| groovy_test( |
| name = name, |
| deps = test_deps, |
| srcs = tests, |
| data = data, |
| resources = resources, |
| jvm_flags = jvm_flags, |
| size = size, |
| tags = tags, |
| ) |
| |
| def spock_test( |
| name, |
| specs, |
| deps=[], |
| groovy_srcs=[], |
| java_srcs=[], |
| data=[], |
| resources=[], |
| jvm_flags=[], |
| size="small", |
| tags=[]): |
| warning("spock_test") |
| groovy_lib_deps = deps + [ |
| "//external:junit", |
| "//external:spock", |
| ] |
| test_deps = deps + [ |
| "//external:junit", |
| "//external:spock", |
| ] |
| |
| if len(specs) == 0: |
| fail("Must provide at least one file in specs") |
| |
| # Put all Java sources into a Java library |
| if java_srcs: |
| native.java_library( |
| name = name + "-javalib", |
| srcs = java_srcs, |
| deps = deps + [ |
| "//external:junit", |
| "//external:spock", |
| ], |
| ) |
| groovy_lib_deps += [name + "-javalib"] |
| test_deps += [name + "-javalib"] |
| |
| # Put all specs and Groovy sources into a Groovy library |
| groovy_library( |
| name = name + "-groovylib", |
| srcs = specs + groovy_srcs, |
| deps = groovy_lib_deps, |
| ) |
| test_deps += [name + "-groovylib"] |
| |
| # Create a groovy test |
| groovy_test( |
| name = name, |
| deps = test_deps, |
| srcs = specs, |
| data = data, |
| resources = resources, |
| jvm_flags = jvm_flags, |
| size = size, |
| tags = tags, |
| ) |
| |
| def groovy_repositories(): |
| warning("groovy_repositories") |
| native.new_http_archive( |
| name = "groovy_sdk_artifact", |
| url = "http://dl.bintray.com/groovy/maven/apache-groovy-binary-2.4.4.zip", |
| sha256 = "a7cc1e5315a14ea38db1b2b9ce0792e35174161141a6a3e2ef49b7b2788c258c", |
| build_file_content = """ |
| filegroup( |
| name = "sdk", |
| srcs = glob(["groovy-2.4.4/**"], exclude_directories=0), |
| visibility = ["//visibility:public"], |
| ) |
| java_import( |
| name = "groovy", |
| jars = ["groovy-2.4.4/lib/groovy-2.4.4.jar"], |
| visibility = ["//visibility:public"], |
| ) |
| """, |
| ) |
| native.bind( |
| name = "groovy-sdk", |
| actual = "@groovy_sdk_artifact//:sdk", |
| ) |
| native.bind( |
| name = "groovy", |
| actual = "@groovy_sdk_artifact//:groovy", |
| ) |
| |
| native.maven_jar( |
| name = "junit_artifact", |
| artifact = "junit:junit:4.12", |
| ) |
| native.bind( |
| name = "junit", |
| actual = "@junit_artifact//jar", |
| ) |
| |
| native.maven_jar( |
| name = "spock_artifact", |
| artifact = "org.spockframework:spock-core:0.7-groovy-2.0", |
| ) |
| native.bind( |
| name = "spock", |
| actual = "@spock_artifact//jar", |
| ) |