Set workspace name for http_file, http_jar, and maven_jar

Fixes #1166.

While I was here, I also:

* Renamed the implementations of Decompressor to show that they are
Decompressors, not SkyFunctions (they used to be, it's confusing to have them
still have the -Function suffix).
* Added a unit test and moved the testing target to the rule/repository
subdirectory, since it was a good chance to break off a tiny chunk of the
monolithic BUILD file in lib/.

--
MOS_MIGRATED_REVID=121306165
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/DecompressorValue.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/DecompressorValue.java
index 0d5ee8f..9343bbd 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/DecompressorValue.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/DecompressorValue.java
@@ -41,15 +41,8 @@
 
   @Override
   public boolean equals(Object other) {
-    if (this == other) {
-      return true;
-    }
-
-    if (!(other instanceof DecompressorValue)) {
-      return false;
-    }
-
-    return directory.equals(((DecompressorValue) other).directory);
+    return this == other || other instanceof DecompressorValue
+        && directory.equals(((DecompressorValue) other).directory);
   }
 
   @Override
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/FileFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/FileDecompressor.java
similarity index 88%
rename from src/main/java/com/google/devtools/build/lib/bazel/repository/FileFunction.java
rename to src/main/java/com/google/devtools/build/lib/bazel/repository/FileDecompressor.java
index 0392e2d..9031d4b 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/FileFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/FileDecompressor.java
@@ -20,10 +20,10 @@
 /**
  * Creates a repository for a random file.
  */
-public class FileFunction extends JarFunction {
-  public static final Decompressor INSTANCE = new FileFunction();
+public class FileDecompressor extends JarDecompressor {
+  public static final Decompressor INSTANCE = new FileDecompressor();
 
-  private FileFunction() {
+  private FileDecompressor() {
   }
 
   @Override
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/HttpFileFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/HttpFileFunction.java
index bd5b733..25216ed 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/HttpFileFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/HttpFileFunction.java
@@ -32,7 +32,7 @@
     boolean executable = (mapper.has("executable", Type.BOOLEAN)
         && mapper.get("executable", Type.BOOLEAN));
     return DecompressorDescriptor.builder()
-        .setDecompressor(FileFunction.INSTANCE)
+        .setDecompressor(FileDecompressor.INSTANCE)
         .setTargetKind(rule.getTargetKind())
         .setTargetName(rule.getName())
         .setArchivePath(downloadPath)
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/HttpJarFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/HttpJarFunction.java
index 4233158..a09ee1c 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/HttpJarFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/HttpJarFunction.java
@@ -27,7 +27,7 @@
   protected DecompressorDescriptor getDescriptor(Rule rule, Path downloadPath, Path outputDirectory)
       throws RepositoryFunctionException {
     return DecompressorDescriptor.builder()
-        .setDecompressor(JarFunction.INSTANCE)
+        .setDecompressor(JarDecompressor.INSTANCE)
         .setTargetKind(rule.getTargetKind())
         .setTargetName(rule.getName())
         .setArchivePath(downloadPath)
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/JarFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/JarDecompressor.java
similarity index 87%
rename from src/main/java/com/google/devtools/build/lib/bazel/repository/JarFunction.java
rename to src/main/java/com/google/devtools/build/lib/bazel/repository/JarDecompressor.java
index 048c507..cfd7aef 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/JarFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/JarDecompressor.java
@@ -16,6 +16,7 @@
 
 import com.google.common.base.Joiner;
 import com.google.devtools.build.lib.bazel.repository.DecompressorValue.Decompressor;
+import com.google.devtools.build.lib.rules.repository.RepositoryFunction;
 import com.google.devtools.build.lib.rules.repository.RepositoryFunction.RepositoryFunctionException;
 import com.google.devtools.build.lib.vfs.FileSystemUtils;
 import com.google.devtools.build.lib.vfs.Path;
@@ -29,10 +30,10 @@
 /**
  * Creates a repository for a jar file.
  */
-public class JarFunction implements Decompressor {
-  public static final Decompressor INSTANCE = new JarFunction();
+public class JarDecompressor implements Decompressor {
+  public static final Decompressor INSTANCE = new JarDecompressor();
 
-  protected JarFunction() {
+  protected JarDecompressor() {
   }
 
   /**
@@ -50,10 +51,8 @@
     try {
       FileSystemUtils.createDirectoryAndParents(descriptor.repositoryPath());
       // external/some-name/WORKSPACE.
-      Path workspaceFile = descriptor.repositoryPath().getRelative("WORKSPACE");
-      FileSystemUtils.writeContent(workspaceFile, Charset.forName("UTF-8"), String.format(
-          "# DO NOT EDIT: automatically generated WORKSPACE file for %s rule %s\n",
-          descriptor.targetKind(), descriptor.targetName()));
+      RepositoryFunction.createWorkspaceFile(
+          descriptor.repositoryPath(), descriptor.targetKind(), descriptor.targetName());
       // external/some-name/jar.
       Path jarDirectory = descriptor.repositoryPath().getRelative(getPackageName());
       FileSystemUtils.createDirectoryAndParents(jarDirectory);
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/MavenJarFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/MavenJarFunction.java
index f3dbb06..c8a826f 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/MavenJarFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/MavenJarFunction.java
@@ -139,7 +139,7 @@
 
     // Add a WORKSPACE file & BUILD file to the Maven jar.
     Path result = DecompressorValue.decompress(DecompressorDescriptor.builder()
-        .setDecompressor(JarFunction.INSTANCE)
+        .setDecompressor(JarDecompressor.INSTANCE)
         .setTargetKind(MavenJarRule.NAME)
         .setTargetName(downloader.getName())
         .setArchivePath(repositoryJar)
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/NewGitRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/NewGitRepositoryFunction.java
index 96f2b2b..2bf1f18 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/NewGitRepositoryFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/NewGitRepositoryFunction.java
@@ -39,7 +39,7 @@
 
     createDirectory(outputDirectory, rule);
     GitCloner.clone(rule, outputDirectory, env.getListener());
-    createWorkspaceFile(outputDirectory, rule);
+    createWorkspaceFile(outputDirectory, rule.getTargetKind(), rule.getName());
     buildFileHandler.finishBuildFile(outputDirectory);
 
     return RepositoryDirectoryValue.create(outputDirectory);
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/NewHttpArchiveFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/NewHttpArchiveFunction.java
index 815e41d..71e34f6 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/NewHttpArchiveFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/NewHttpArchiveFunction.java
@@ -75,7 +75,7 @@
         .build());
 
     // Finally, write WORKSPACE and BUILD files.
-    createWorkspaceFile(decompressed, rule);
+    createWorkspaceFile(decompressed, rule.getTargetKind(), rule.getName());
     buildFileHandler.finishBuildFile(outputDirectory);
 
     return RepositoryDirectoryValue.create(outputDirectory);
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryFunction.java
index 397b013..08015a2 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryFunction.java
@@ -140,7 +140,7 @@
     }
 
     if (!outputDirectory.getRelative("WORKSPACE").exists()) {
-      createWorkspaceFile(outputDirectory, rule);
+      createWorkspaceFile(outputDirectory, rule.getTargetKind(), rule.getName());
     }
 
     return RepositoryDirectoryValue.create(outputDirectory);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/NewLocalRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/NewLocalRepositoryFunction.java
index 66942f3..eb77b57 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/repository/NewLocalRepositoryFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/repository/NewLocalRepositoryFunction.java
@@ -91,7 +91,7 @@
         throw new RepositoryFunctionException(e, SkyFunctionException.Transience.TRANSIENT);
       }
     }
-    createWorkspaceFile(outputDirectory, rule);
+    createWorkspaceFile(outputDirectory, rule.getTargetKind(), rule.getName());
 
     return RepositoryDirectoryValue.createWithSourceDirectory(outputDirectory, directoryValue);
   }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java
index d9c0b0b..d3f5982 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java
@@ -175,17 +175,18 @@
     }
 
     // Add x/WORKSPACE.
-    createWorkspaceFile(repositoryDirectory, rule);
+    createWorkspaceFile(repositoryDirectory, rule.getTargetKind(), rule.getName());
     return repositoryDirectory;
   }
 
-  protected void createWorkspaceFile(Path repositoryDirectory, Rule rule)
+  public static void createWorkspaceFile(
+      Path repositoryDirectory, String ruleKind, String ruleName)
       throws RepositoryFunctionException {
     try {
       Path workspaceFile = repositoryDirectory.getRelative("WORKSPACE");
       FileSystemUtils.writeContent(workspaceFile, Charset.forName("UTF-8"),
           String.format("# DO NOT EDIT: automatically generated WORKSPACE file for %s\n"
-              + "workspace(name = \"%s\")", rule, rule.getName()));
+              + "workspace(name = \"%s\")\n", ruleKind, ruleName));
     } catch (IOException e) {
       throw new RepositoryFunctionException(e, Transience.TRANSIENT);
     }
diff --git a/src/test/java/com/google/devtools/build/lib/BUILD b/src/test/java/com/google/devtools/build/lib/BUILD
index 3960aa7..7887b3b 100644
--- a/src/test/java/com/google/devtools/build/lib/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/BUILD
@@ -1,3 +1,7 @@
+package(
+    default_visibility = ["//src/test/java/com/google/devtools/build/lib:__subpackages__"],
+)
+
 # This should correspond to the list of "EMBEDDED_TOOLS" in TestConstants.java.bazel.
 filegroup(
     name = "embedded_scripts",
@@ -979,36 +983,6 @@
 )
 
 java_test(
-    name = "repository-rules-tests",
-    srcs = glob(["rules/repository/*.java"]),
-    tags = ["rules"],
-    test_class = "com.google.devtools.build.lib.AllTests",
-    deps = [
-        ":analysis_testutil",
-        ":testutil",
-        "//src/main/java/com/google/devtools/build/lib:bazel-main",
-        "//src/main/java/com/google/devtools/build/lib:build-base",
-        "//src/main/java/com/google/devtools/build/lib:cmdline",
-        "//src/main/java/com/google/devtools/build/lib:common",
-        "//src/main/java/com/google/devtools/build/lib:packages-internal",
-        "//src/main/java/com/google/devtools/build/lib:runtime",
-        "//src/main/java/com/google/devtools/build/lib:util",
-        "//src/main/java/com/google/devtools/build/lib:vfs",
-        "//src/main/java/com/google/devtools/build/lib/actions",
-        "//src/main/java/com/google/devtools/build/lib/rules/cpp",
-        "//src/main/java/com/google/devtools/build/skyframe",
-        "//src/test/java/com/google/devtools/build/lib:actions_testutil",
-        "//src/test/java/com/google/devtools/build/lib:packages_testutil",
-        "//third_party:guava",
-        "//third_party:jsr305",
-        "//third_party:junit4",
-        "//third_party:mockito",
-        "//third_party:truth",
-        "//third_party/protobuf",
-    ],
-)
-
-java_test(
     name = "bazel-rules-tests",
     srcs = glob([
         "bazel/rules/**/*.java",
diff --git a/src/test/java/com/google/devtools/build/lib/rules/repository/BUILD b/src/test/java/com/google/devtools/build/lib/rules/repository/BUILD
new file mode 100644
index 0000000..1d7724f
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/rules/repository/BUILD
@@ -0,0 +1,29 @@
+java_test(
+    name = "RepositoryTests",
+    srcs = glob(["*.java"]),
+    tags = ["rules"],
+    test_class = "com.google.devtools.build.lib.AllTests",
+    deps = [
+        "//src/main/java/com/google/devtools/build/lib:bazel-main",
+        "//src/main/java/com/google/devtools/build/lib:bazel-repository",
+        "//src/main/java/com/google/devtools/build/lib:build-base",
+        "//src/main/java/com/google/devtools/build/lib:cmdline",
+        "//src/main/java/com/google/devtools/build/lib:common",
+        "//src/main/java/com/google/devtools/build/lib:packages-internal",
+        "//src/main/java/com/google/devtools/build/lib:runtime",
+        "//src/main/java/com/google/devtools/build/lib:util",
+        "//src/main/java/com/google/devtools/build/lib:vfs",
+        "//src/main/java/com/google/devtools/build/lib/actions",
+        "//src/main/java/com/google/devtools/build/lib/rules/cpp",
+        "//src/main/java/com/google/devtools/build/skyframe",
+        "//src/test/java/com/google/devtools/build/lib:analysis_testutil",
+        "//src/test/java/com/google/devtools/build/lib:packages_testutil",
+        "//src/test/java/com/google/devtools/build/lib:testutil",
+        "//third_party:guava",
+        "//third_party:jsr305",
+        "//third_party:junit4",
+        "//third_party:mockito",
+        "//third_party:truth",
+        "//third_party/protobuf",
+    ],
+)
diff --git a/src/test/java/com/google/devtools/build/lib/rules/repository/JarDecompressorTest.java b/src/test/java/com/google/devtools/build/lib/rules/repository/JarDecompressorTest.java
new file mode 100644
index 0000000..8526402
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/rules/repository/JarDecompressorTest.java
@@ -0,0 +1,61 @@
+// 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.
+
+package com.google.devtools.build.lib.rules.repository;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.devtools.build.lib.bazel.repository.DecompressorDescriptor;
+import com.google.devtools.build.lib.bazel.repository.DecompressorValue;
+import com.google.devtools.build.lib.bazel.repository.JarDecompressor;
+import com.google.devtools.build.lib.testutil.Scratch;
+import com.google.devtools.build.lib.vfs.FileSystemUtils;
+import com.google.devtools.build.lib.vfs.Path;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests expanding external jars into external repositories.
+ */
+@RunWith(JUnit4.class)
+public class JarDecompressorTest {
+  private DecompressorDescriptor.Builder descriptorBuilder;
+
+  @Before
+  public void setUpFs() throws Exception {
+    Scratch fs = new Scratch();
+    Path dir = fs.dir("/whatever/external/tester");
+    Path jar = fs.file("/foo.jar", "I'm a jar");
+    FileSystemUtils.createDirectoryAndParents(dir);
+    descriptorBuilder = DecompressorDescriptor.builder()
+        .setDecompressor(JarDecompressor.INSTANCE)
+        .setTargetName("tester")
+        .setTargetKind("http_jar rule")
+        .setRepositoryPath(dir)
+        .setArchivePath(jar);
+  }
+
+  @Test
+  public void testWorkspaceGen() throws Exception {
+    Path outputDir = DecompressorValue.decompress(descriptorBuilder.build());
+    assertThat(outputDir.exists()).isTrue();
+    String workspaceContent = new String(
+        FileSystemUtils.readContentAsLatin1(outputDir.getRelative("WORKSPACE")));
+    assertThat(workspaceContent).contains("workspace(name = \"tester\")");
+  }
+
+}
diff --git a/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryFunctionTest.java b/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryFunctionTest.java
index cbc65dd..3cc0a84 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryFunctionTest.java
@@ -91,8 +91,7 @@
         "    name = 'abc',",
         "    path = '/a/b/c',",
         ")");
-    TestingRepositoryFunction repositoryFunction = new TestingRepositoryFunction();
-    repositoryFunction.createWorkspaceFile(rootDirectory, rule);
+    RepositoryFunction.createWorkspaceFile(rootDirectory, rule.getTargetKind(), rule.getName());
     String workspaceContent = new String(
         FileSystemUtils.readContentAsLatin1(rootDirectory.getRelative("WORKSPACE")));
     assertThat(workspaceContent).contains("workspace(name = \"abc\")");