aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--site/docs/external.md129
-rw-r--r--src/main/java/BUILD14
-rw-r--r--src/main/java/com/google/devtools/build/workspace/BUILD10
-rw-r--r--src/main/java/com/google/devtools/build/workspace/WorkspaceFileGenerator.java45
-rw-r--r--src/main/java/com/google/devtools/build/workspace/maven/BUILD29
-rw-r--r--src/main/java/com/google/devtools/build/workspace/maven/Resolver.java105
-rw-r--r--src/main/java/com/google/devtools/build/workspace/maven/Rule.java45
-rw-r--r--src/test/java/BUILD11
-rw-r--r--src/test/shell/bazel/BUILD9
-rwxr-xr-xsrc/test/shell/bazel/testenv.sh1
-rwxr-xr-xsrc/test/shell/bazel/workspace_path_test.sh31
-rwxr-xr-xsrc/test/shell/bazel/workspace_test.sh100
-rw-r--r--third_party/BUILD5
-rw-r--r--third_party/README.md12
14 files changed, 510 insertions, 36 deletions
diff --git a/site/docs/external.md b/site/docs/external.md
new file mode 100644
index 0000000000..95278984a3
--- /dev/null
+++ b/site/docs/external.md
@@ -0,0 +1,129 @@
+---
+layout: documentation
+---
+
+# Working with external dependencies
+
+Bazel is designed to have absolutely everything needed for a build, from source
+code to libraries to compilers, under one directory (the build root). This is
+impractical for some version control systems and goes against how many existing
+projects are structured. Thus, Bazel has a system for pulling in dependencies
+from outside of the build root.
+
+External dependencies can be specified in a _WORKSPACE_ file in the build root.
+This _WORKSPACE_ file uses the same Python-like syntax of BUILD files, but
+allows a different set of rules.
+
+## Fetching dependencies
+
+By default, external dependencies are fetched as needed during `bazel build`. If
+you would like to disable this behavior or prefetch dependencies, use
+[`bazel fetch`](http://bazel.io/docs/bazel-user-manual.html#fetch).
+
+## Transitive dependencies
+
+Bazel only reads dependencies listed in your build root's _WORKSPACE_ file. This
+means that if your project (_A_) depends on another project (_B_) which list a
+dependency on project _C_ in its _WORKSPACE_ file, you'll have to add both _B_
+and _C_ to your project's _WORKSPACE_ file. This can balloon the _WORKSPACE_
+file size, but hopefully limits the chances of having one library include _C_
+at version 1.0 and another include _C_ at 2.0.
+
+# Converting existing projects
+
+To convert a Maven project, first run the `generate_workspace` tool:
+
+```bash
+$ bazel run src/main/java/com/google/devtools/build/workspace:generate_workspace /path/to/your/maven/project >> WORKSPACE
+```
+
+This will parse the _pom.xml_ file and discover project dependencies. All of
+these dependencies will be written in
+[`maven_jar`](http://bazel.io/docs/build-encyclopedia.html#maven_jar) format to
+stdout, which can be redirected or copied to the _WORKSPACE_ file.
+
+At the moment, `generate_workspace` will only include direct dependencies.
+
+You will still need to manually add these libraries as dependencies of your
+`java_` targets.
+
+# Types of external dependencies
+
+There are a few basic types of external dependencies that can be created.
+
+## Combining Bazel projects
+
+If you have a second Bazel project that you'd like to use targets from, you can
+use
+[`local_repository`](http://bazel.io/docs/build-encyclopedia.html#local_repository)
+or [`http_archive`](http://bazel.io/docs/build-encyclopedia.html#http_archive)
+to symlink it from the local filesystem or download it (respectively).
+
+For example, suppose you are working on a project, _my-project/_, and you want
+to depend on targets from your coworker's project, _coworkers-project/_. Both
+projects use Bazel, so you can add your coworker's project as an external
+dependency and then use any targets your coworker has defined from your own
+BUILD files. You would add the following to _my\_project/WORKSPACE_:
+
+```python
+local_repository(
+ name = "coworkers-project",
+ path = "/path/to/coworkers-project",
+)
+```
+
+If your coworker has a target `//foo:bar`, your project can refer to it as
+`@coworkers-project//foo:bar`.
+
+## Depending on non-Bazel projects
+
+Rules prefixed with `new_` (e.g.,
+[`new_local_repository`](http://bazel.io/docs/build-encyclopedia.html#new_local_repository)
+and [`new_http_archive`](http://bazel.io/docs/build-encyclopedia.html#new_http_archive)
+allow you to create targets from projects that do not use Bazel.
+
+For example, suppose you are working on a project, _my-project/_, and you want
+to depend on your coworker's project, _coworkers-project/_. Your coworker's
+project uses `make` to build, but you'd like to depend on one of the .so files
+it generates. To do so, add the following to _my\_project/WORKSPACE_:
+
+```python
+new_local_repository(
+ name = "coworkers-project",
+ path = "/path/to/coworkers-project",
+ build_file = "coworker.BUILD",
+)
+```
+
+`build_file` specifies a BUILD file to overlay on the existing project, for
+example:
+
+```python
+java_library(
+ name = "some-lib",
+ srcs = glob(["**"]),
+ visibility = ["//visibility:public"],
+)
+```
+
+You can then depend on `@coworkers-project//:some-lib` from your project's BUILD
+files.
+
+# Caching of external dependencies
+
+Bazel caches external dependencies and only re-downloads or updates them when
+the _WORKSPACE_ file changes. If the _WORKSPACE_ file does not change, Bazel
+assumes that the external dependencies have not changed, either. This can cause
+unexpected results, especially with local repositories.
+
+For instance, in the example above, suppose that _my-project/_ has a target that
+depends on `@coworkers-project//:a`, which you build. Then you change to
+_coworkers-project/_ and pull the latest updates to their library, which changes
+the behavior of `@coworkers-project//:a`. If you go back to _my-project/_ and
+build your target again, it will assume `@coworkers-project//:a` is already
+up-to-date and reuse the cached library (instead of realizing that the sources
+have changed and, thus, rebuilding).
+
+To avoid this situation, prefer remote repositories to local ones and do not
+manually change the files in _\[output\_base\]/external_. If you change a file
+in _\[output\_base\]/external_, rerun `bazel fetch ...` to update the cache.
diff --git a/src/main/java/BUILD b/src/main/java/BUILD
index 0d0bda354c..19fc52d502 100644
--- a/src/main/java/BUILD
+++ b/src/main/java/BUILD
@@ -87,6 +87,18 @@ java_library(
)
java_library(
+ name = "events",
+ srcs = glob(["com/google/devtools/build/lib/events/*.java"]),
+ deps = [
+ ":common",
+ ":concurrent",
+ ":vfs",
+ "//third_party:guava",
+ "//third_party:jsr305",
+ ],
+)
+
+java_library(
name = "bazel-core",
srcs = glob(
[
@@ -102,7 +114,6 @@ java_library(
"com/google/devtools/build/lib/skyframe/**",
"com/google/devtools/build/lib/webstatusserver/**/*.java",
"com/google/devtools/build/lib/analysis/**",
- "com/google/devtools/build/lib/events/**",
"com/google/devtools/build/lib/rules/**",
"com/google/devtools/build/lib/syntax/**",
"com/google/devtools/build/docgen/**/*.java",
@@ -139,6 +150,7 @@ java_library(
":collect",
":common",
":concurrent",
+ ":events",
":options",
":shell",
":unix",
diff --git a/src/main/java/com/google/devtools/build/workspace/BUILD b/src/main/java/com/google/devtools/build/workspace/BUILD
new file mode 100644
index 0000000000..c0f35dd653
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/workspace/BUILD
@@ -0,0 +1,10 @@
+java_binary(
+ name = "generate_workspace",
+ srcs = ["WorkspaceFileGenerator.java"],
+ main_class = "com.google.devtools.build.workspace.WorkspaceFileGenerator",
+ visibility = ["//visibility:public"],
+ deps = [
+ "//src/main/java:events",
+ "//src/main/java/com/google/devtools/build/workspace/maven",
+ ],
+)
diff --git a/src/main/java/com/google/devtools/build/workspace/WorkspaceFileGenerator.java b/src/main/java/com/google/devtools/build/workspace/WorkspaceFileGenerator.java
new file mode 100644
index 0000000000..8561910d7f
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/workspace/WorkspaceFileGenerator.java
@@ -0,0 +1,45 @@
+// Copyright 2015 Google Inc. 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.
+
+package com.google.devtools.build.workspace;
+
+import com.google.devtools.build.lib.events.Event;
+import com.google.devtools.build.lib.events.StoredEventHandler;
+import com.google.devtools.build.workspace.maven.Resolver;
+
+import java.io.File;
+
+/**
+ * Generates a WORKSPACE file for Bazel from other types of dependency trackers.
+ */
+public class WorkspaceFileGenerator {
+
+ public static void main(String[] args) {
+ String directory;
+ if (args.length == 1) {
+ directory = args[0];
+ } else {
+ directory = System.getProperty("user.dir");
+ }
+ StoredEventHandler handler = new StoredEventHandler();
+ Resolver connector = new Resolver(new File(directory), handler);
+ connector.writeDependencies(System.out);
+ if (handler.hasErrors()) {
+ for (Event event : handler.getEvents()) {
+ System.err.println(event);
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/com/google/devtools/build/workspace/maven/BUILD b/src/main/java/com/google/devtools/build/workspace/maven/BUILD
new file mode 100644
index 0000000000..3b0e2f5330
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/workspace/maven/BUILD
@@ -0,0 +1,29 @@
+java_library(
+ name = "maven",
+ srcs = [
+ "Resolver.java",
+ ],
+ visibility = [
+ "//src/main/java/com/google/devtools/build/workspace:__pkg__",
+ "//src/test/java/com/google/devtools/build/workspace:__pkg__",
+ ],
+ runtime_deps = [
+ "//third_party:maven_model",
+ "//third_party:plexus_interpolation",
+ "//third_party:plexus_utils",
+ ],
+ deps = [
+ ":rule",
+ "//src/main/java:events",
+ "//third_party:aether",
+ "//third_party:guava",
+ "//third_party:maven_model",
+ "//third_party:plexus_component_annotations",
+ ],
+)
+
+java_library(
+ name = "rule",
+ srcs = ["Rule.java"],
+ deps = ["//third_party:auto_value"],
+)
diff --git a/src/main/java/com/google/devtools/build/workspace/maven/Resolver.java b/src/main/java/com/google/devtools/build/workspace/maven/Resolver.java
new file mode 100644
index 0000000000..2f79cf1e0f
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/workspace/maven/Resolver.java
@@ -0,0 +1,105 @@
+// Copyright 2015 Google Inc. 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.
+
+package com.google.devtools.build.workspace.maven;
+
+import com.google.devtools.build.lib.events.Event;
+import com.google.devtools.build.lib.events.EventHandler;
+import com.google.devtools.build.lib.events.EventKind;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Repository;
+import org.apache.maven.model.building.DefaultModelBuilderFactory;
+import org.apache.maven.model.building.DefaultModelBuildingRequest;
+import org.apache.maven.model.building.DefaultModelProcessor;
+import org.apache.maven.model.building.ModelBuildingException;
+import org.apache.maven.model.building.ModelBuildingResult;
+import org.apache.maven.model.io.DefaultModelReader;
+import org.apache.maven.model.locator.DefaultModelLocator;
+import org.eclipse.aether.collection.CollectRequest;
+import org.eclipse.aether.repository.RemoteRepository;
+
+import java.io.File;
+import java.io.PrintStream;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Resolves Maven dependencies.
+ */
+public class Resolver {
+ private final File projectDirectory;
+ private final Map<String, Rule> deps;
+ private final EventHandler handler;
+
+ public Resolver(File projectDirectory, EventHandler handler) {
+ this.projectDirectory = projectDirectory;
+ deps = new HashMap<String, Rule>();
+ this.handler = handler;
+ }
+
+ /**
+ * Find the pom.xml, parse it, and write the equivalent WORKSPACE file to the provided
+ * outputStream.
+ */
+ public void writeDependencies(PrintStream outputStream) {
+ resolveDependencies();
+ for (Rule rule : deps.values()) {
+ outputStream.println(rule.toString() + "\n");
+ }
+ }
+
+ private void resolveDependencies() {
+ DefaultModelProcessor processor = new DefaultModelProcessor();
+ processor.setModelLocator(new DefaultModelLocator());
+ processor.setModelReader(new DefaultModelReader());
+ File pom = processor.locatePom(projectDirectory);
+
+ DefaultModelBuilderFactory factory = new DefaultModelBuilderFactory();
+ DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
+ request.setPomFile(pom);
+ Model model = null;
+ try {
+ ModelBuildingResult result = factory.newInstance().build(request);
+ model = result.getEffectiveModel();
+ } catch (ModelBuildingException e) {
+ System.err.println("Unable to resolve Maven model from " + pom + ": " + e.getMessage());
+ return;
+ }
+
+ CollectRequest collectRequest = new CollectRequest();
+ for (Repository repo : model.getRepositories()) {
+ collectRequest.addRepository(
+ new RemoteRepository.Builder(repo.getId(), repo.getName(), repo.getUrl()).build());
+ }
+
+ for (org.apache.maven.model.Dependency dependency : model.getDependencies()) {
+ Rule rule = Rule.create(
+ dependency.getArtifactId(), dependency.getGroupId(), dependency.getVersion());
+ if (deps.containsKey(rule.name())) {
+ Rule existingDependency = deps.get(rule.name());
+ // Check that the versions are the same.
+ if (!existingDependency.version().equals(dependency.getVersion())) {
+ handler.handle(new Event(EventKind.ERROR, null, dependency.getGroupId() + ":"
+ + dependency.getArtifactId() + " already processed for version "
+ + existingDependency.version() + " but " + model + " wants version "
+ + dependency.getVersion() + ", ignoring."));
+ }
+ // If it already exists at the right version, we're done.
+ } else {
+ deps.put(rule.name(), rule);
+ // TODO(kchodorow): fetch transitive dependencies.
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/workspace/maven/Rule.java b/src/main/java/com/google/devtools/build/workspace/maven/Rule.java
new file mode 100644
index 0000000000..3c680dfe07
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/workspace/maven/Rule.java
@@ -0,0 +1,45 @@
+// Copyright 2015 Google Inc. 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.
+
+package com.google.devtools.build.workspace.maven;
+
+import com.google.auto.value.AutoValue;
+
+/**
+ * A struct representing the fields of maven_jar to be written to the WORKSPACE file.
+ */
+@AutoValue
+public abstract class Rule {
+ static Rule create(String artifactId, String groupId, String version) {
+ return new AutoValue_Rule(artifactId, groupId, version);
+ }
+
+ abstract String artifactId();
+ abstract String groupId();
+ abstract String version();
+
+ String name() {
+ return (groupId() + "/" + artifactId()).replaceAll("\\.", "/");
+ }
+
+ @Override
+ public String toString() {
+ return "maven_jar(\n"
+ + " name = \"" + name() + "\",\n"
+ + " artifact_id = \"" + artifactId() + "\",\n"
+ + " group_id = \"" + groupId() + "\",\n"
+ + " version = \"" + version() + "\",\n"
+ + ")";
+ }
+}
diff --git a/src/test/java/BUILD b/src/test/java/BUILD
index 56bdf892ee..5d14e87049 100644
--- a/src/test/java/BUILD
+++ b/src/test/java/BUILD
@@ -5,6 +5,7 @@ java_library(
deps = [
"//src/main/java:bazel-core",
"//src/main/java:collect",
+ "//src/main/java:events",
"//src/main/java:vfs",
"//third_party:guava",
"//third_party:guava-testlib",
@@ -25,6 +26,7 @@ java_test(
"//src/main/java:bazel-core",
"//src/main/java:collect",
"//src/main/java:concurrent",
+ "//src/main/java:events",
"//src/main/java:vfs",
"//third_party:guava",
"//third_party:guava-testlib",
@@ -64,6 +66,7 @@ java_library(
":testutil",
"//src/main/java:bazel-core",
"//src/main/java:concurrent",
+ "//src/main/java:events",
"//src/main/java:shell",
"//src/main/java:vfs",
"//third_party:guava",
@@ -119,6 +122,7 @@ java_test(
"//src/main/java:bazel-core",
"//src/main/java:collect",
"//src/main/java:concurrent",
+ "//src/main/java:events",
"//src/main/java:options",
"//src/main/java:shell",
"//src/main/java:unix",
@@ -166,6 +170,7 @@ java_library(
":testutil",
"//src/main/java:bazel-core",
"//src/main/java:concurrent",
+ "//src/main/java:events",
"//src/main/java:options",
"//src/main/java:vfs",
"//third_party:guava",
@@ -191,6 +196,7 @@ java_test(
"//src/main/java:bazel-core",
"//src/main/java:collect",
"//src/main/java:concurrent",
+ "//src/main/java:events",
"//src/main/java:options",
"//src/main/java:vfs",
"//third_party:guava",
@@ -222,6 +228,7 @@ java_library(
"//src/main/java:bazel-core",
"//src/main/java:collect",
"//src/main/java:concurrent",
+ "//src/main/java:events",
"//src/main/java:options",
"//src/main/java:vfs",
"//src/main/protobuf:proto_extra_actions_base",
@@ -342,6 +349,7 @@ java_test(
":testutil",
"//src/main/java:bazel-core",
"//src/main/java:collect",
+ "//src/main/java:events",
"//src/main/java:vfs",
"//third_party:guava",
"//third_party:guava-testlib",
@@ -360,6 +368,7 @@ java_library(
":foundations_testutil",
":testutil",
"//src/main/java:bazel-core",
+ "//src/main/java:events",
"//src/main/java:options",
"//src/main/java:vfs",
"//src/main/protobuf:proto_extra_actions_base",
@@ -385,6 +394,7 @@ java_test(
":test_runner",
":testutil",
"//src/main/java:bazel-core",
+ "//src/main/java:events",
"//src/main/java:vfs",
"//third_party:guava",
"//third_party:guava-testlib",
@@ -447,6 +457,7 @@ java_test(
"//src/main/java:bazel-core",
"//src/main/java:collect",
"//src/main/java:concurrent",
+ "//src/main/java:events",
"//src/main/java:vfs",
"//third_party:guava",
"//third_party:guava-testlib",
diff --git a/src/test/shell/bazel/BUILD b/src/test/shell/bazel/BUILD
index 44c7306c13..94ac78c2f7 100644
--- a/src/test/shell/bazel/BUILD
+++ b/src/test/shell/bazel/BUILD
@@ -104,6 +104,15 @@ sh_test(
)
sh_test(
+ name = "workspace_test",
+ srcs = ["workspace_test.sh"],
+ data = [
+ ":test-deps",
+ "//src/main/java/com/google/devtools/build/workspace:generate_workspace",
+ ],
+)
+
+sh_test(
name = "bazel_sandboxing_test",
srcs = ["bazel_sandboxing_test.sh"],
data = [":test-deps"],
diff --git a/src/test/shell/bazel/testenv.sh b/src/test/shell/bazel/testenv.sh
index 4f1f3d8202..a275ad5667 100755
--- a/src/test/shell/bazel/testenv.sh
+++ b/src/test/shell/bazel/testenv.sh
@@ -26,6 +26,7 @@ source "${TEST_SRCDIR}/src/test/shell/unittest.bash" || \
# Bazel
bazel_tree="${TEST_SRCDIR}/src/test/shell/bazel/doc-srcs.zip"
bazel_path="${TEST_SRCDIR}/src"
+bazel_data="${TEST_SRCDIR}"
# Java
jdk_dir="${TEST_SRCDIR}/external/local-jdk"
diff --git a/src/test/shell/bazel/workspace_path_test.sh b/src/test/shell/bazel/workspace_path_test.sh
deleted file mode 100755
index ae76bc325b..0000000000
--- a/src/test/shell/bazel/workspace_path_test.sh
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2015 Google Inc. 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 test environment
-source $(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/test-setup.sh \
- || { echo "test-setup.sh not found!" >&2; exit 1; }
-
-function test_path_with_spaces() {
- ws="a b"
- mkdir "$ws"
- cd "$ws"
- touch WORKSPACE
-
- bazel info &> $TEST_log && fail "Info succeeeded"
- bazel help &> $TEST_log || fail "Help failed"
-}
-
-run_suite "workspace tests"
diff --git a/src/test/shell/bazel/workspace_test.sh b/src/test/shell/bazel/workspace_test.sh
new file mode 100755
index 0000000000..0fd3f15bce
--- /dev/null
+++ b/src/test/shell/bazel/workspace_test.sh
@@ -0,0 +1,100 @@
+#!/bin/bash
+#
+# Copyright 2015 Google Inc. 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 test environment
+source $(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/test-setup.sh \
+ || { echo "test-setup.sh not found!" >&2; exit 1; }
+
+export JAVA_RUNFILES=$TEST_SRCDIR
+
+function test_path_with_spaces() {
+ ws="a b"
+ mkdir "$ws"
+ cd "$ws"
+ touch WORKSPACE
+
+ bazel info &> $TEST_log && fail "Info succeeeded"
+ bazel help &> $TEST_log || fail "Help failed"
+}
+
+function write_pom() {
+ cat > pom.xml <<EOF
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>com.mycompany.app</groupId>
+ <artifactId>my-app</artifactId>
+ <version>1</version>
+ <packaging>pom</packaging>
+ <modules>
+ <module>my-module</module>
+ </modules>
+ <dependencies>
+ <dependency>
+ <groupId>com.y.z</groupId>
+ <artifactId>x</artifactId>
+ <version>3.2.1</version>
+ </dependency>
+ </dependencies>
+</project>
+EOF
+}
+
+function test_minimal_pom() {
+ write_pom
+
+ ${bazel_data}/src/main/java/com/google/devtools/build/workspace/generate_workspace &> $TEST_log || \
+ fail "generating workspace failed"
+ expect_log "artifact_id = \"x\","
+ expect_log "group_id = \"com.y.z\","
+ expect_log "version = \"3.2.1\","
+}
+
+function test_parent_pom_inheritence() {
+ write_pom
+ mkdir my-module
+ cat > my-module/pom.xml <<EOF
+<project>
+ <parent>
+ <groupId>com.mycompany.app</groupId>
+ <artifactId>my-app</artifactId>
+ <version>1</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>com.mycompany.app</groupId>
+ <artifactId>my-module</artifactId>
+ <version>1</version>
+ <dependencies>
+ <dependency>
+ <groupId>com.z.w</groupId>
+ <artifactId>x</artifactId>
+ <version>1.2.3</version>
+ </dependency>
+ </dependencies>
+</project>
+EOF
+
+ ${bazel_data}/src/main/java/com/google/devtools/build/workspace/generate_workspace my-module &> $TEST_log || \
+ fail "generating workspace failed"
+ expect_log "name = \"com/y/z/x\","
+ expect_log "artifact_id = \"x\","
+ expect_log "group_id = \"com.y.z\","
+ expect_log "version = \"3.2.1\","
+ expect_log "name = \"com/z/w/x\","
+ expect_log "group_id = \"com.z.w\","
+ expect_log "version = \"1.2.3\","
+}
+
+run_suite "workspace tests"
diff --git a/third_party/BUILD b/third_party/BUILD
index ecca1450c8..9053f85d39 100644
--- a/third_party/BUILD
+++ b/third_party/BUILD
@@ -203,6 +203,11 @@ java_import(
)
java_import(
+ name = "plexus_component_annotations",
+ jars = ["plexus_component_annotations/plexus-component-annotations-1.6.jar"],
+)
+
+java_import(
name = "plexus_interpolation",
jars = ["plexus_interpolation/plexus-interpolation-1.22.jar"],
)
diff --git a/third_party/README.md b/third_party/README.md
index 908486e242..e858cb9a65 100644
--- a/third_party/README.md
+++ b/third_party/README.md
@@ -154,14 +154,20 @@ a minimal set of extra dependencies.
* License: Apache License 2.0
-[plexus_interpolation](http://plexus.codehaus.org/plexus-components/plexus-interpolation/)
+[plexus_component_annotations](http://mvnrepository.com/artifact/org.codehaus.plexus/plexus-component-annotations)
+----------------------
+
+* Version: 1.6
+* License: Apache License 2.0
+
+[plexus_interpolation](http://mvnrepository.com/artifact/org.codehaus.plexus/plexus-interpolation)
----------------------
* Version: 1.22
* License: Apache License 2.0
-[plexus_utils](http://plexus.codehaus.org/plexus-utils/)
+[plexus_utils](http://mvnrepository.com/artifact/org.codehaus.plexus/plexus-utils)
--------------
* Version: 3.0.21
@@ -197,5 +203,3 @@ Testing
* Version: 0.24
* License: Apache License 2.0
-
-