Skip to content

Commit

Permalink
Implementation of maven_jar rule in Skylark.
Browse files Browse the repository at this point in the history
**Experimental**

This is an initial implementation of the maven_jar rule in Skylark, targeted at
the FRs in issue #1410.

Implemented a wrapper around the maven binary to pull dependencies from
remote repositories into a directory under {output_base}/external.

Attributes `name`, `artifact`, `repository`, `sha1` have been implemented,
but not `server`.

Caveat: this rule assumes that the Maven dependency is installed in the
system. Hence, the maven_skylark_test integration tests are tagged with
"manual" and commented out because the Bazel CI isn't configured with
the Maven binary yet.

Added a serve_not_found helper for 404 response tests.

Usage:

```
load("@bazel_tools//tools/build_defs/repo:maven_rules.bzl", "maven_jar")

maven_jar(
    name = "com_google_guava_guava",
    artifact = "com.google.guava:guava:18.0",
    sha1 = "cce0823396aa693798f8882e64213b1772032b09",
    repository = "http://uk.maven.org/maven2",
)
```

With regards to server, there are some limitations with retrieving a
maven_server's attribute at Loading Phase without the use of hacky macros
(issue #1704), and even if macros are used, the maven_server is not treated as
an actual dependency by maven_jar. There is a test (`test_unimplemented_server_attr`)
to ensure that the error message to shown to users if they use the server
attribute with this rule.

--
Change-Id: I167f9d13835c30be971928b4cc60167a8e396893
Reviewed-on: https://bazel-review.googlesource.com/c/5770
MOS_MIGRATED_REVID=133971809
  • Loading branch information
jin authored and laszlocsomor committed Sep 23, 2016
1 parent 296ffbd commit 3f0d3b6
Show file tree
Hide file tree
Showing 7 changed files with 601 additions and 20 deletions.
5 changes: 5 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,8 @@ bind(name = "xcrunwrapper", actual = "@bazel_tools//tools/objc:xcrunwrapper")

bind(name = "protobuf/java_runtime", actual = "//third_party/protobuf:protobuf")
bind(name = "protobuf/javalite_runtime", actual = "//third_party/protobuf:protobuf-lite")

# For Skylark tests at //src/test/shell/bazel:maven_skylark_test
# Uncomment the following lines, and the test in src/test/shell/bazel/BUILD to run it.
# load("//tools/build_defs/repo:maven_rules.bzl", "maven_dependency_plugin")
# maven_dependency_plugin()
12 changes: 12 additions & 0 deletions src/test/shell/bazel/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,18 @@ sh_test(
data = [":test-deps"],
)

# To run this test, ensure that the maven_dependency_plugin() in WORKSPACE is uncommented as well.
sh_test(
name = "maven_skylark_test",
size = "medium",
srcs = ["maven_skylark_test.sh"],
data = [
":test-deps",
"@m2//:files",
],
tags = ["manual"],
)

sh_test(
name = "generate_workspace_test",
size = "large",
Expand Down
10 changes: 1 addition & 9 deletions src/test/shell/bazel/external_integration_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -349,15 +349,7 @@ EOF
}

function test_http_404() {
http_response=$TEST_TMPDIR/http_response
cat > $http_response <<EOF
HTTP/1.0 404 Not Found
Help, I'm lost!
EOF
nc_port=$(pick_random_unused_tcp_port) || exit 1
nc_l $nc_port < $http_response &
nc_pid=$!
serve_not_found "Help, I'm lost!"

cd ${WORKSPACE_DIR}
cat > WORKSPACE <<EOF
Expand Down
194 changes: 194 additions & 0 deletions src/test/shell/bazel/maven_skylark_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
#!/bin/bash
#
# Copyright 2016 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.
#
# Test the Skylark implementation of the maven_jar() rule.

# Load test environment
src=$(cd "$(dirname ${BASH_SOURCE[0]})" && pwd)
source $src/test-setup.sh \
|| { echo "test-setup.sh not found!" >&2; exit 1; }
source $src/remote_helpers.sh \
|| { echo "remote_helpers.sh not found!" >&2; exit 1; }

function setup_zoo() {
mkdir -p zoo
cat > zoo/BUILD <<EOF
java_binary(
name = "ball-pit",
srcs = ["BallPit.java"],
main_class = "BallPit",
deps = ["//external:mongoose"],
)
EOF

cat > zoo/BallPit.java <<EOF
import carnivore.Mongoose;
public class BallPit {
public static void main(String args[]) {
Mongoose.frolic();
}
}
EOF
}

function tear_down() {
shutdown_server
}

function test_maven_jar_skylark() {
setup_zoo
version="1.21"
serve_artifact com.example.carnivore carnivore $version

cat > WORKSPACE <<EOF
load("@bazel_tools//tools/build_defs/repo:maven_rules.bzl", "maven_jar")
maven_jar(
name = 'endangered',
artifact = "com.example.carnivore:carnivore:$version",
repository = 'http://localhost:$fileserver_port/',
sha1 = '$sha1',
local_repository = "@m2//:BUILD",
)
# Make use of the pre-downloaded maven-dependency-plugin because there's no
# internet connection at this stage.
local_repository(
name = "m2",
path = "$TEST_SRCDIR/m2",
)
bind(name = 'mongoose', actual = '@endangered//jar')
EOF

bazel run //zoo:ball-pit >& $TEST_log || fail "Expected run to succeed"
expect_log "Tra-la!"
}

# Same as test_maven_jar, except omit sha1 implying "we don't care".
function test_maven_jar_no_sha1_skylark() {
setup_zoo
version="1.22"
serve_artifact com.example.carnivore carnivore $version

cat > WORKSPACE <<EOF
load("@bazel_tools//tools/build_defs/repo:maven_rules.bzl", "maven_jar")
maven_jar(
name = 'endangered',
artifact = "com.example.carnivore:carnivore:$version",
repository = 'http://localhost:$fileserver_port/',
local_repository = "@m2//:BUILD",
)
local_repository(
name = "m2",
path = "$TEST_SRCDIR/m2",
)
bind(name = 'mongoose', actual = '@endangered//jar')
EOF

bazel run //zoo:ball-pit >& $TEST_log || fail "Expected run to succeed"
expect_log "Tra-la!"
}

function test_maven_jar_404_skylark() {
setup_zoo
version="1.23"
serve_not_found

cat > WORKSPACE <<EOF
load("@bazel_tools//tools/build_defs/repo:maven_rules.bzl", "maven_jar")
maven_jar(
name = 'endangered',
artifact = "com.example.carnivore:carnivore:$version",
repository = 'http://localhost:$nc_port/',
local_repository = "@m2//:BUILD",
)
local_repository(
name = "m2",
path = "$TEST_SRCDIR/m2",
)
bind(name = 'mongoose', actual = '@endangered//jar')
EOF

bazel clean --expunge
bazel build //zoo:ball-pit >& $TEST_log && echo "Expected build to fail"
kill_nc
expect_log "Failed to fetch Maven dependency"
}

function test_maven_jar_mismatched_sha1_skylark() {
setup_zoo
version="1.24"
serve_artifact com.example.carnivore carnivore 1.24

wrong_sha1="0123456789012345678901234567890123456789"
cat > WORKSPACE <<EOF
load("@bazel_tools//tools/build_defs/repo:maven_rules.bzl", "maven_jar")
maven_jar(
name = 'endangered',
artifact = "com.example.carnivore:carnivore:1.24",
repository = 'http://localhost:$fileserver_port/',
sha1 = '$wrong_sha1',
local_repository = "@m2//:BUILD",
)
local_repository(
name = "m2",
path = "$TEST_SRCDIR/m2",
)
bind(name = 'mongoose', actual = '@endangered//jar')
EOF

bazel fetch //zoo:ball-pit >& $TEST_log && echo "Expected fetch to fail"
expect_log "has SHA-1 of $sha1, does not match expected SHA-1 ($wrong_sha1)"
}

function test_unimplemented_server_attr_skylark() {
setup_zoo
version="1.25"
serve_jar

cat > WORKSPACE <<EOF
load("@bazel_tools//tools/build_defs/repo:maven_rules.bzl", "maven_jar")
maven_jar(
name = 'endangered',
artifact = "com.example.carnivore:carnivore:$version",
server = "attr_not_implemented",
local_repository = "@m2//:BUILD"
)
local_repository(
name = "m2",
path = "$TEST_SRCDIR/m2",
)
bind(name = 'mongoose', actual = '@endangered//jar')
EOF

bazel build //zoo:ball-pit >& $TEST_log && echo "Expected build to fail"
kill_nc
expect_log "specifies a 'server' attribute which is currently not supported."
}

run_suite "maven skylark tests"
15 changes: 4 additions & 11 deletions src/test/shell/bazel/maven_test.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash
#
# Copyright 2015 The Bazel Authors. All rights reserved.
# Copyright 2016 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.
Expand Down Expand Up @@ -87,14 +87,8 @@ EOF

function test_maven_jar_404() {
setup_zoo
http_response=$TEST_TMPDIR/http_response
cat > $http_response <<EOF
HTTP/1.0 404 Not Found
serve_not_found

EOF
nc_port=$(pick_random_unused_tcp_port) || exit 1
nc_l $nc_port < $http_response &
nc_pid=$!
cat > WORKSPACE <<EOF
maven_jar(
name = 'endangered',
Expand All @@ -112,21 +106,20 @@ EOF

function test_maven_jar_mismatched_sha1() {
setup_zoo
serve_jar
serve_artifact com.example.carnivore carnivore 1.23

wrong_sha1="0123456789012345678901234567890123456789"
cat > WORKSPACE <<EOF
maven_jar(
name = 'endangered',
artifact = "com.example.carnivore:carnivore:1.23",
repository = 'http://localhost:$nc_port/',
repository = 'http://localhost:$fileserver_port/',
sha1 = '$wrong_sha1',
)
bind(name = 'mongoose', actual = '@endangered//jar')
EOF

bazel fetch //zoo:ball-pit >& $TEST_log && echo "Expected fetch to fail"
kill_nc
expect_log "has SHA-1 of $sha1, does not match expected SHA-1 ($wrong_sha1)"
}

Expand Down
15 changes: 15 additions & 0 deletions src/test/shell/bazel/remote_helpers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,21 @@ EOF
redirect_pid=$!
}

# Serves a HTTP 404 Not Found response with an optional parameter for the
# response body.
function serve_not_found() {
RESPONSE_BODY=${1:-}
http_response=$TEST_TMPDIR/http_response
cat > $http_response <<EOF
HTTP/1.0 404 Not Found
$RESPONSE_BODY
EOF
nc_port=$(pick_random_unused_tcp_port) || exit 1
nc_l $nc_port < $http_response &
nc_pid=$!
}

# Waits for the SimpleHTTPServer to actually start up before the test is run.
# Otherwise the entire test can run before the server starts listening for
# connections, which causes flakes.
Expand Down
Loading

0 comments on commit 3f0d3b6

Please sign in to comment.