Make generate_workspace also generate a BUILD file with transitive deps

Fixes #89.

--
MOS_MIGRATED_REVID=98832811
diff --git a/site/docs/external.md b/site/docs/external.md
index 84c5423..583aaab 100644
--- a/site/docs/external.md
+++ b/site/docs/external.md
@@ -42,40 +42,52 @@
 files) or Maven projects (i.e., _pom.xml_ files).  For example:
 
 ```bash
-$ bazel run src/main/java/com/google/devtools/build/workspace:generate_workspace \
+$ bazel run src/main/java/com/google/devtools/build/workspace:generate_workspace -- \
 >    --maven_project=/path/to/my/project \
 >    --bazel_project=/path/to/skunkworks \
 >    --bazel_project=/path/to/teleporter/project
-# --------------------
-# The following dependencies were calculated from:
-# /path/to/my/project/pom.xml
-# /path/to/skunkworks/WORKSPACE
-# /path/to/teleporter/project/WORKSPACE
-
-
-# com.example.some-project:a:1.2.3
-# com.example.another-project:b:3.2.1 wanted version 2.4
-maven_jar(
-    name = "javax/servlet/servlet-api",
-    artifact = "javax.servlet:servlet-api:2.5",
-)
-
-[Other dependencies]
-# --------------------
-
-WARNING /path/to/my/project/pom.xml:1: javax.servlet:servlet-api already processed for version 2.5 but com.example.another-project:b:3.2.1 wants version 2.4, ignoring.
+Wrote:
+/tmp/1437415510621-0/2015-07-20-14-05-10.WORKSPACE
+/tmp/1437415510621-0/2015-07-20-14-05-10.BUILD
 ```
-Everything after the second `--------------------` is printed to stderr, not
-stdout. This is where any errors or warnings are printed. You may need to edit
-the versions that `generate_workspace` automatically chooses for the artifacts.
+
+The _WORKSPACE_ file contains the transitive dependencies of given projects. The
+_BUILD_ file contains a single target, `transitive-deps`, that contains all of
+the dependencies. You can copy these files to your project and add
+`transitive-deps` as a dependency of your `java_` targets in _BUILD_ files.
 
 If you specify multiple Bazel or Maven projects, they will all be combined into
 one _WORKSPACE_ file (e.g., if the Bazel project depends on junit and the Maven
 project also depends on junit, junit will only appear once as a dependency in
 the output).
 
-Once these `maven_jar`s have been added to your _WORKSPACE_ file, you will still
-need to add the jars as dependencies of your `java_` targets in _BUILD_ files.
+You may wish to curate the generated _WORKSPACE_ file to ensure it is using the
+correct version of each dependency. If several different versions of an artifact
+are requested (by different libraries that depend on it), then
+`generate_workspace` chooses a version and annotates the `maven_jar` with the
+other versions requested, for example:
+
+```python
+# org.springframework:spring:2.5.6
+# javax.mail:mail:1.4
+# httpunit:httpunit:1.6 wanted version 1.0.2
+# org.springframework:spring-support:2.0.2 wanted version 1.0.2
+# org.slf4j:nlog4j:1.2.24 wanted version 1.0.2
+maven_jar(
+    name = "javax/activation/activation",
+    artifact = "javax.activation:activation:1.1",
+)
+```
+
+This indicates that `org.springframework:spring:2.5.6`, `javax.mail:mail:1.4`,
+`httpunit:httpunit:1.6`, `org.springframework:spring-support:2.0.2`, and
+`org.slf4j:nlog4j:1.2.24` all depend on javax.activation. However, two of these
+libraries wanted version 1.1 and three of them wanted 1.0.2. The _WORkSPACE_
+file is using version 1.1, but that might not be the right version to use.
+
+You may also want to break `transitive-deps` into smaller targets, as it is
+unlikely that all of your targets depend on the transitive closure of your
+maven jars.
 
 # Types of external dependencies
 
diff --git a/src/main/java/com/google/devtools/build/workspace/GenerateWorkspace.java b/src/main/java/com/google/devtools/build/workspace/GenerateWorkspace.java
index 7b05c4a..9e64efe 100644
--- a/src/main/java/com/google/devtools/build/workspace/GenerateWorkspace.java
+++ b/src/main/java/com/google/devtools/build/workspace/GenerateWorkspace.java
@@ -14,6 +14,7 @@
 
 package com.google.devtools.build.workspace;
 
+import com.google.common.io.Files;
 import com.google.devtools.build.lib.events.Event;
 import com.google.devtools.build.lib.events.StoredEventHandler;
 import com.google.devtools.build.lib.packages.ExternalPackage;
@@ -24,8 +25,13 @@
 import com.google.devtools.build.lib.vfs.UnixFileSystem;
 import com.google.devtools.common.options.OptionsParser;
 
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
 import java.nio.file.Paths;
+import java.text.SimpleDateFormat;
 import java.util.Collections;
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -49,7 +55,13 @@
     GenerateWorkspace workspaceFileGenerator = new GenerateWorkspace();
     workspaceFileGenerator.generateFromWorkspace(options.bazelProjects);
     workspaceFileGenerator.generateFromPom(options.mavenProjects);
-    workspaceFileGenerator.print();
+    if (!workspaceFileGenerator.hasErrors()) {
+      workspaceFileGenerator.writeResults();
+    }
+    workspaceFileGenerator.cleanup();
+    if (workspaceFileGenerator.hasErrors()) {
+      System.exit(1);
+    }
   }
 
   private static void printUsage(OptionsParser parser) {
@@ -91,10 +103,33 @@
     return Paths.get(System.getProperty("user.dir")).resolve(path).toString();
   }
 
-  private void print() {
-    resolver.writeDependencies(System.out);
-    resolver.cleanup();
+  /**
+   * Returns if there were any errors generating the WORKSPACE and BUILD files.
+   */
+  private boolean hasErrors() {
+    return handler.hasErrors();
+  }
 
+  private void writeResults() {
+    String date = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date());
+    File tempDir = Files.createTempDir();
+    File workspaceFile = new File(tempDir + "/" + date + ".WORKSPACE");
+    File buildFile = new File(tempDir + "/" + date + ".BUILD");
+    try (PrintStream workspaceStream = new PrintStream(workspaceFile);
+         PrintStream buildStream = new PrintStream(buildFile)) {
+      resolver.writeWorkspace(workspaceStream);
+      resolver.writeBuild(buildStream);
+    } catch (IOException e) {
+      handler.handle(Event.error(
+          "Could not write WORKSPACE and BUILD files to " + tempDir + ": " + e.getMessage()));
+      return;
+    }
+
+    System.err.println("Wrote:\n" + workspaceFile + "\n" + buildFile);
+  }
+
+  private void cleanup() {
+    resolver.cleanup();
     for (Event event : handler.getEvents()) {
       System.err.println(event);
     }
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
index 2ffd1b0..aa6b878 100644
--- a/src/main/java/com/google/devtools/build/workspace/maven/Resolver.java
+++ b/src/main/java/com/google/devtools/build/workspace/maven/Resolver.java
@@ -73,17 +73,35 @@
   /**
    * Writes all resolved dependencies in WORKSPACE file format to the outputStream.
    */
-  public void writeDependencies(PrintStream outputStream) {
-    outputStream.println("# --------------------\n"
-        + "# The following dependencies were calculated from:");
+  public void writeWorkspace(PrintStream outputStream) {
+    writeHeader(outputStream);
+    for (Rule rule : deps.values()) {
+      outputStream.println(rule + "\n");
+    }
+  }
+
+  /**
+   * Write library rules to depend on the transitive closure of all of these rules.
+   */
+  public void writeBuild(PrintStream outputStream) {
+    writeHeader(outputStream);
+    outputStream.println("java_library(");
+    outputStream.println("    name = \"transitive-deps\",");
+    outputStream.println("    visibility = [\"//visibility:public\"],");
+    outputStream.println("    exports = [");
+    for (Rule rule : deps.values()) {
+      outputStream.println("        \"@" + rule.name() + "//jar\",");
+    }
+    outputStream.println("    ],");
+    outputStream.println(")");
+  }
+
+  private void writeHeader(PrintStream outputStream) {
+    outputStream.println("# The following dependencies were calculated from:");
     for (String header : headers) {
       outputStream.println("# " + header);
     }
     outputStream.print("\n\n");
-    for (Rule rule : deps.values()) {
-      outputStream.println(rule + "\n");
-    }
-    outputStream.println("# --------------------\n");
   }
 
   public void addHeader(String header) {
diff --git a/src/test/shell/bazel/workspace_test.sh b/src/test/shell/bazel/workspace_test.sh
index 5519435..51abf7f 100755
--- a/src/test/shell/bazel/workspace_test.sh
+++ b/src/test/shell/bazel/workspace_test.sh
@@ -58,7 +58,6 @@
 EOF
 
   bazel build @x//:x || fail "build failed"
-  ls -l $(bazel info execution_root)/external/x/
   assert_contains "bye" bazel-genfiles/out
 }
 
@@ -73,67 +72,4 @@
   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 \
-    --maven_project=$(pwd) &> $TEST_log || fail "generating workspace failed"
-  expect_log "artifact = \"com.y.z:x: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 \
-    --maven_project=$(pwd)/my-module &> $TEST_log || \
-    fail "generating workspace failed"
-  expect_log "name = \"com/y/z/x\","
-  expect_log "artifact = \"com.y.z:x:3.2.1\","
-  expect_log "name = \"com/z/w/x\","
-  expect_log "artifact = \"com.z.w:x:1.2.3\","
-}
-
 run_suite "workspace tests"