aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Kristina Chodorow <kchodorow@google.com>2015-10-08 17:38:35 +0000
committerGravatar Kristina Chodorow <kchodorow@google.com>2015-10-09 14:40:04 +0000
commitcca07bce5c7574950128ec7c9ad77fbd32ca1dbe (patch)
treec1a926f646f72ab235a226e426892fb0bd1633e6 /src
parent0f1b041c23e7cc3a2af4bb47a6cd1f3a331b5a4f (diff)
Add executable option to http_file
This also simplifies the decompressor code a bit and actually adds lib/bazel/repository tests to a test rule. Fixes #497. RELNOTES[NEW]: http_file can specify "executable" to make the downloaded file runnable. -- MOS_MIGRATED_REVID=104975488
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/DecompressorDescriptor.java149
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/DecompressorValue.java114
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/HttpArchiveFunction.java11
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/HttpFileFunction.java14
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/HttpJarFunction.java8
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/JarFunction.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/MavenJarFunction.java10
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/NewHttpArchiveFunction.java9
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/TarGzFunction.java1
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/ZipFunction.java1
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidHttpToolsRepositoryFunction.java10
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/workspace/HttpFileRule.java7
-rw-r--r--src/test/java/BUILD22
-rw-r--r--src/test/java/com/google/devtools/build/lib/bazel/repository/DecompressorValueTest.java59
-rwxr-xr-xsrc/test/shell/bazel/external_integration_test.sh14
15 files changed, 311 insertions, 122 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/DecompressorDescriptor.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/DecompressorDescriptor.java
new file mode 100644
index 0000000000..11263d456a
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/DecompressorDescriptor.java
@@ -0,0 +1,149 @@
+// 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.
+
+package com.google.devtools.build.lib.bazel.repository;
+
+import com.google.common.base.Optional;
+import com.google.devtools.build.lib.vfs.Path;
+
+import java.util.Objects;
+
+import javax.annotation.Nullable;
+
+/**
+ * Description of an archive to be decompressed for use in a SkyKey.
+ * TODO(bazel-team): this should be an autovalue class.
+ */
+public class DecompressorDescriptor {
+ private final String targetKind;
+ private final String targetName;
+ private final Path archivePath;
+ private final Path repositoryPath;
+ private final Optional<String> prefix;
+ private final boolean executable;
+
+ private DecompressorDescriptor(
+ String targetKind, String targetName, Path archivePath, Path repositoryPath,
+ @Nullable String prefix, boolean executable) {
+ this.targetKind = targetKind;
+ this.targetName = targetName;
+ this.archivePath = archivePath;
+ this.repositoryPath = repositoryPath;
+ this.prefix = Optional.fromNullable(prefix);
+ this.executable = executable;
+ }
+
+ public String targetKind() {
+ return targetKind;
+ }
+
+ public String targetName() {
+ return targetName;
+ }
+
+ public Path archivePath() {
+ return archivePath;
+ }
+
+ public Path repositoryPath() {
+ return repositoryPath;
+ }
+
+ public Optional<String> prefix() {
+ return prefix;
+ }
+
+ public boolean executable() {
+ return executable;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+
+ if (!(other instanceof DecompressorDescriptor)) {
+ return false;
+ }
+
+ DecompressorDescriptor descriptor = (DecompressorDescriptor) other;
+ return Objects.equals(targetKind, descriptor.targetKind)
+ && Objects.equals(targetName, descriptor.targetName)
+ && Objects.equals(archivePath, descriptor.archivePath)
+ && Objects.equals(repositoryPath, descriptor.repositoryPath)
+ && Objects.equals(prefix, descriptor.prefix)
+ && Objects.equals(executable, descriptor.executable);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(targetKind, targetName, archivePath, repositoryPath, prefix);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Builder for describing the file to be decompressed. The fields set will depend on the type
+ * of file.
+ */
+ public static class Builder {
+ private String targetKind;
+ private String targetName;
+ private Path archivePath;
+ private Path repositoryPath;
+ private String prefix;
+ private boolean executable;
+
+ private Builder() {
+ }
+
+ public DecompressorDescriptor build() {
+ return new DecompressorDescriptor(
+ targetKind, targetName, archivePath, repositoryPath, prefix, executable);
+ }
+
+ public Builder setTargetKind(String targetKind) {
+ this.targetKind = targetKind;
+ return this;
+ }
+
+ public Builder setTargetName(String targetName) {
+ this.targetName = targetName;
+ return this;
+ }
+
+ public Builder setArchivePath(Path archivePath) {
+ this.archivePath = archivePath;
+ return this;
+ }
+
+ public Builder setRepositoryPath(Path repositoryPath) {
+ this.repositoryPath = repositoryPath;
+ return this;
+ }
+
+ public Builder setPrefix(String prefix) {
+ this.prefix = prefix;
+ return this;
+ }
+
+ public Builder setExecutable(boolean executable) {
+ this.executable = executable;
+ return this;
+ }
+ }
+}
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 544247be4d..27b4db7894 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
@@ -14,15 +14,13 @@
package com.google.devtools.build.lib.bazel.repository;
-import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.build.skyframe.SkyFunctionName;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import java.io.IOException;
-import java.util.Objects;
-
-import javax.annotation.Nullable;
/**
* The contents of decompressed archive.
@@ -57,111 +55,27 @@ public class DecompressorValue implements SkyValue {
return directory.hashCode();
}
- public static SkyKey fileKey(
- String targetKind, String targetName, Path archivePath, Path repositoryPath) {
- return new SkyKey(
- FileFunction.NAME,
- new DecompressorDescriptor(targetKind, targetName, archivePath, repositoryPath));
- }
-
- public static SkyKey jarKey(
- String targetKind, String targetName, Path archivePath, Path repositoryPath) {
- return new SkyKey(JarFunction.NAME,
- new DecompressorDescriptor(targetKind, targetName, archivePath, repositoryPath));
+ public static SkyKey key(SkyFunctionName skyFunctionName, DecompressorDescriptor descriptor) {
+ Preconditions.checkNotNull(descriptor.archivePath());
+ return new SkyKey(skyFunctionName, descriptor);
}
- public static SkyKey key(
- String targetKind, String targetName, Path archivePath, Path repositoryPath)
- throws IOException {
- return key(targetKind, targetName, archivePath, repositoryPath, null);
+ public static SkyKey key(DecompressorDescriptor descriptor) throws IOException {
+ Preconditions.checkNotNull(descriptor.archivePath());
+ return key(getSkyFunctionName(descriptor.archivePath()), descriptor);
}
- public static SkyKey key(
- String targetKind, String targetName, Path archivePath, Path repositoryPath,
- @Nullable String prefix)
- throws IOException {
+ private static SkyFunctionName getSkyFunctionName(Path archivePath) throws IOException {
String baseName = archivePath.getBaseName();
-
- DecompressorDescriptor descriptor =
- new DecompressorDescriptor(targetKind, targetName, archivePath, repositoryPath, prefix);
-
if (baseName.endsWith(".zip") || baseName.endsWith(".jar") || baseName.endsWith(".war")) {
- return new SkyKey(ZipFunction.NAME, descriptor);
+ return ZipFunction.NAME;
} else if (baseName.endsWith(".tar.gz") || baseName.endsWith(".tgz")) {
- return new SkyKey(TarGzFunction.NAME, descriptor);
+ return TarGzFunction.NAME;
} else {
- throw new IOException(
- String.format("Expected %s %s to create file with a .zip, .jar, .war, .tar.gz, or .tgz"
- + " suffix (got %s)", targetKind, targetName, archivePath));
+ throw new IOException(String.format(
+ "Expected a file with a .zip, .jar, .war, .tar.gz, or .tgz suffix (got %s)",
+ archivePath));
}
}
- /**
- * Description of an archive to be decompressed for use in a SkyKey.
- * TODO(bazel-team): this should be an autovalue class.
- */
- public static class DecompressorDescriptor {
- private final String targetKind;
- private final String targetName;
- private final Path archivePath;
- private final Path repositoryPath;
- private final Optional<String> prefix;
-
- private DecompressorDescriptor(String targetKind, String targetName, Path archivePath,
- Path repositoryPath) {
- this(targetKind, targetName, archivePath, repositoryPath, null);
- }
-
- private DecompressorDescriptor(String targetKind, String targetName, Path archivePath,
- Path repositoryPath, @Nullable String prefix) {
- this.targetKind = targetKind;
- this.targetName = targetName;
- this.archivePath = archivePath;
- this.repositoryPath = repositoryPath;
- this.prefix = Optional.fromNullable(prefix);
- }
-
- public String targetKind() {
- return targetKind;
- }
-
- public String targetName() {
- return targetName;
- }
-
- public Path archivePath() {
- return archivePath;
- }
-
- public Path repositoryPath() {
- return repositoryPath;
- }
-
- public Optional<String> prefix() {
- return prefix;
- }
-
- @Override
- public boolean equals(Object other) {
- if (this == other) {
- return true;
- }
-
- if (!(other instanceof DecompressorDescriptor)) {
- return false;
- }
-
- DecompressorDescriptor descriptor = (DecompressorDescriptor) other;
- return targetKind.equals(descriptor.targetKind)
- && targetName.equals(descriptor.targetName)
- && archivePath.equals(descriptor.archivePath)
- && repositoryPath.equals(descriptor.repositoryPath)
- && prefix.equals(descriptor.prefix);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(targetKind, targetName, archivePath, repositoryPath, prefix);
- }
- }
}
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/HttpArchiveFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/HttpArchiveFunction.java
index f6fd03c0c6..824aa4add8 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/HttpArchiveFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/HttpArchiveFunction.java
@@ -79,8 +79,7 @@ public class HttpArchiveFunction extends RepositoryFunction {
}
DecompressorValue value = (DecompressorValue) env.getValueOrThrow(
- decompressorValueKey(rule, downloadValue.getPath(), outputDirectory),
- IOException.class);
+ decompressorValueKey(rule, downloadValue.getPath(), outputDirectory), IOException.class);
if (value == null) {
return null;
}
@@ -93,8 +92,12 @@ public class HttpArchiveFunction extends RepositoryFunction {
protected SkyKey decompressorValueKey(Rule rule, Path downloadPath, Path outputDirectory)
throws IOException {
- return DecompressorValue.key(
- rule.getTargetKind(), rule.getName(), downloadPath, outputDirectory);
+ return DecompressorValue.key(DecompressorDescriptor.builder()
+ .setTargetKind(rule.getTargetKind())
+ .setTargetName(rule.getName())
+ .setArchivePath(downloadPath)
+ .setRepositoryPath(outputDirectory)
+ .build());
}
@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 2645d54573..5621a0690c 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
@@ -17,7 +17,9 @@ package com.google.devtools.build.lib.bazel.repository;
import com.google.devtools.build.lib.analysis.RuleDefinition;
import com.google.devtools.build.lib.bazel.rules.workspace.HttpFileRule;
import com.google.devtools.build.lib.cmdline.PackageIdentifier.RepositoryName;
+import com.google.devtools.build.lib.packages.AggregatingAttributeMapper;
import com.google.devtools.build.lib.packages.Rule;
+import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.skyframe.SkyFunctionException;
import com.google.devtools.build.skyframe.SkyFunctionName;
@@ -44,8 +46,16 @@ public class HttpFileFunction extends HttpArchiveFunction {
@Override
protected SkyKey decompressorValueKey(Rule rule, Path downloadPath, Path outputDirectory)
throws IOException {
- return DecompressorValue.fileKey(
- rule.getTargetKind(), rule.getName(), downloadPath, outputDirectory);
+ AggregatingAttributeMapper mapper = AggregatingAttributeMapper.of(rule);
+ boolean executable = (mapper.has("executable", Type.BOOLEAN)
+ && mapper.get("executable", Type.BOOLEAN));
+ return DecompressorValue.key(FileFunction.NAME, DecompressorDescriptor.builder()
+ .setTargetKind(rule.getTargetKind())
+ .setTargetName(rule.getName())
+ .setArchivePath(downloadPath)
+ .setRepositoryPath(outputDirectory)
+ .setExecutable(executable)
+ .build());
}
@Override
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 6653d481c5..9cbd4f6049 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
@@ -44,8 +44,12 @@ public class HttpJarFunction extends HttpArchiveFunction {
@Override
protected SkyKey decompressorValueKey(Rule rule, Path downloadPath, Path outputDirectory)
throws IOException {
- return DecompressorValue.jarKey(
- rule.getTargetKind(), rule.getName(), downloadPath, outputDirectory);
+ return DecompressorValue.key(JarFunction.NAME, DecompressorDescriptor.builder()
+ .setTargetKind(rule.getTargetKind())
+ .setTargetName(rule.getName())
+ .setArchivePath(downloadPath)
+ .setRepositoryPath(outputDirectory)
+ .build());
}
@Override
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/JarFunction.java
index e0c63a63f1..d432717765 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/JarFunction.java
@@ -15,7 +15,6 @@
package com.google.devtools.build.lib.bazel.repository;
import com.google.common.base.Joiner;
-import com.google.devtools.build.lib.bazel.repository.DecompressorValue.DecompressorDescriptor;
import com.google.devtools.build.lib.bazel.repository.RepositoryFunction.RepositoryFunctionException;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
@@ -76,6 +75,9 @@ public class JarFunction implements SkyFunction {
+ " rule "
+ descriptor.targetName(),
createBuildFile(baseName));
+ if (descriptor.executable()) {
+ descriptor.archivePath().chmod(0755);
+ }
} catch (IOException e) {
throw new RepositoryFunctionException(new IOException(
"Error auto-creating jar repo structure: " + e.getMessage()), Transience.TRANSIENT);
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 16b4fb650c..b74fc1fff6 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
@@ -124,9 +124,13 @@ public class MavenJarFunction extends HttpArchiveFunction {
// Add a WORKSPACE file & BUILD file to the Maven jar.
DecompressorValue value;
try {
- value = (DecompressorValue) env.getValueOrThrow(DecompressorValue.jarKey(
- MavenJarRule.NAME, downloader.getName(), repositoryJar,
- outputDirectoryValue.realRootedPath().asPath()), IOException.class);
+ value = (DecompressorValue) env.getValueOrThrow(DecompressorValue.key(
+ JarFunction.NAME, DecompressorDescriptor.builder()
+ .setTargetKind(MavenJarRule.NAME)
+ .setTargetName(downloader.getName())
+ .setArchivePath(repositoryJar)
+ .setRepositoryPath(outputDirectoryValue.realRootedPath().asPath()).build()),
+ IOException.class);
if (value == null) {
return null;
}
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 87688c76f7..1ee640c989 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
@@ -86,8 +86,13 @@ public class NewHttpArchiveFunction extends HttpArchiveFunction {
prefix = mapper.get("strip_prefix", Type.STRING);
}
decompressed = (DecompressorValue) env.getValueOrThrow(
- DecompressorValue.key(rule.getTargetKind(), rule.getName(),
- downloadedFileValue.getPath(), outputDirectory, prefix), IOException.class);
+ DecompressorValue.key(DecompressorDescriptor.builder()
+ .setTargetKind(rule.getTargetKind())
+ .setTargetName(rule.getName())
+ .setArchivePath(downloadedFileValue.getPath())
+ .setRepositoryPath(outputDirectory)
+ .setPrefix(prefix)
+ .build()), IOException.class);
if (decompressed == null) {
return null;
}
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/TarGzFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/TarGzFunction.java
index 6bdd4ac0fd..2bc8248036 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/TarGzFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/TarGzFunction.java
@@ -15,7 +15,6 @@
package com.google.devtools.build.lib.bazel.repository;
import com.google.common.base.Optional;
-import com.google.devtools.build.lib.bazel.repository.DecompressorValue.DecompressorDescriptor;
import com.google.devtools.build.lib.bazel.repository.RepositoryFunction.RepositoryFunctionException;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/ZipFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/ZipFunction.java
index 9f938c34d8..158026acbd 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/ZipFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/ZipFunction.java
@@ -15,7 +15,6 @@
package com.google.devtools.build.lib.bazel.repository;
import com.google.common.base.Optional;
-import com.google.devtools.build.lib.bazel.repository.DecompressorValue.DecompressorDescriptor;
import com.google.devtools.build.lib.bazel.repository.RepositoryFunction.RepositoryFunctionException;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidHttpToolsRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidHttpToolsRepositoryFunction.java
index cab437d208..c1c640c357 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidHttpToolsRepositoryFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidHttpToolsRepositoryFunction.java
@@ -15,6 +15,7 @@
package com.google.devtools.build.lib.bazel.rules.android;
import com.google.devtools.build.lib.analysis.RuleDefinition;
+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.HttpDownloadFunction;
import com.google.devtools.build.lib.bazel.repository.HttpDownloadValue;
@@ -77,8 +78,13 @@ public class AndroidHttpToolsRepositoryFunction extends RepositoryFunction {
return null;
}
- DecompressorValue value = (DecompressorValue) env.getValueOrThrow(DecompressorValue.key(
- rule.getTargetKind(), rule.getName(), downloadValue.getPath(), outputDirectory),
+ DecompressorValue value = (DecompressorValue) env.getValueOrThrow(
+ DecompressorValue.key(DecompressorDescriptor.builder()
+ .setTargetKind(rule.getTargetKind())
+ .setTargetName(rule.getName())
+ .setArchivePath(downloadValue.getPath())
+ .setRepositoryPath(outputDirectory)
+ .build()),
IOException.class);
if (value == null) {
return null;
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/workspace/HttpFileRule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/workspace/HttpFileRule.java
index 3c12a1fa23..0d68d82d3b 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/workspace/HttpFileRule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/workspace/HttpFileRule.java
@@ -15,6 +15,7 @@
package com.google.devtools.build.lib.bazel.rules.workspace;
import static com.google.devtools.build.lib.packages.Attribute.attr;
+import static com.google.devtools.build.lib.syntax.Type.BOOLEAN;
import static com.google.devtools.build.lib.syntax.Type.STRING;
import com.google.devtools.build.lib.analysis.RuleDefinition;
@@ -48,6 +49,12 @@ public class HttpFileRule implements RuleDefinition {
<p>This must match the SHA-256 of the file downloaded.</p>
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */
.add(attr("sha256", STRING).mandatory())
+ /* <!-- #BLAZE_RULE(http_file).ATTRIBUTE(executable) -->
+ If the downloaded file should be made executable. Defaults to False.
+ ${SYNOPSIS}
+
+ <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
+ .add(attr("executable", BOOLEAN))
.setWorkspaceOnly()
.build();
}
diff --git a/src/test/java/BUILD b/src/test/java/BUILD
index b27b2dcec5..6c7fc3415c 100644
--- a/src/test/java/BUILD
+++ b/src/test/java/BUILD
@@ -725,6 +725,28 @@ java_test(
)
java_test(
+ name = "repository_test",
+ srcs = glob([
+ "com/google/devtools/build/lib/bazel/repository/*.java",
+ ]),
+ args = ["com.google.devtools.build.lib.AllTests"],
+ tags = ["rules"],
+ deps = [
+ ":foundations_testutil",
+ ":test_runner",
+ ":testutil",
+ "//src/main/java:bazel-core",
+ "//src/main/java:collect",
+ "//src/main/java:vfs",
+ "//third_party:guava",
+ "//third_party:guava-testlib",
+ "//third_party:jsr305",
+ "//third_party:junit4",
+ "//third_party:truth",
+ ],
+)
+
+java_test(
name = "sandbox-tests",
srcs = glob(["com/google/devtools/build/lib/sandbox/*.java"]),
args = ["com.google.devtools.build.lib.AllTests"],
diff --git a/src/test/java/com/google/devtools/build/lib/bazel/repository/DecompressorValueTest.java b/src/test/java/com/google/devtools/build/lib/bazel/repository/DecompressorValueTest.java
new file mode 100644
index 0000000000..3f3e5e42d6
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/bazel/repository/DecompressorValueTest.java
@@ -0,0 +1,59 @@
+// 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.
+
+package com.google.devtools.build.lib.bazel.repository;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+
+import com.google.devtools.build.lib.vfs.FileSystem;
+import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.IOException;
+
+/**
+ * Tests for {@link DecompressorValue}.
+ */
+@RunWith(JUnit4.class)
+public class DecompressorValueTest {
+
+ private FileSystem fs = new InMemoryFileSystem();
+
+ @Test
+ public void testKnownFileExtensionsDoNotThrow() throws Exception {
+ Path path = fs.getPath("/foo/.external-repositories/some-repo/bar.zip");
+ DecompressorValue.key(DecompressorDescriptor.builder().setArchivePath(path).build());
+ path = fs.getPath("/foo/.external-repositories/some-repo/bar.jar");
+ DecompressorValue.key(DecompressorDescriptor.builder().setArchivePath(path).build());
+ path = fs.getPath("/foo/.external-repositories/some-repo/bar.baz.zip");
+ DecompressorValue.key(DecompressorDescriptor.builder().setArchivePath(path).build());
+ }
+
+ @Test
+ public void testUnknownFileExtensionsThrow() throws Exception {
+ Path zipPath = fs.getPath("/foo/.external-repositories/some-repo/bar.baz");
+ try {
+ DecompressorValue.key(DecompressorDescriptor.builder().setArchivePath(zipPath).build());
+ fail(".baz isn't a valid suffix");
+ } catch (IOException expected) {
+ assertThat(expected.getMessage()).contains("Expected a file with a .zip, .jar,");
+ }
+ }
+
+}
diff --git a/src/test/shell/bazel/external_integration_test.sh b/src/test/shell/bazel/external_integration_test.sh
index 0bdb243623..816d5f60ce 100755
--- a/src/test/shell/bazel/external_integration_test.sh
+++ b/src/test/shell/bazel/external_integration_test.sh
@@ -336,14 +336,17 @@ EOF
# Tests downloading a file and using it as a dependency.
function test_http_download() {
local test_file=$TEST_TMPDIR/toto
- echo "Tra-la!" >$test_file
+ cat > $test_file <<EOF
+#!/bin/bash
+echo "Tra-la!"
+EOF
local sha256=$(sha256sum $test_file | cut -f 1 -d ' ')
serve_file $test_file
cd ${WORKSPACE_DIR}
cat > WORKSPACE <<EOF
http_file(name = 'toto', url = 'http://localhost:$nc_port/toto',
- sha256 = '$sha256')
+ sha256 = '$sha256', executable = True)
EOF
mkdir -p test
@@ -357,11 +360,14 @@ EOF
cat > test/test.sh <<EOF
#!/bin/bash
-cat external/toto/file/toto
+echo "symlink:"
+ls -l external/toto/file
+echo "dest:"
+ls -l \$(readlink -f external/toto/file/toto)
+external/toto/file/toto
EOF
chmod +x test/test.sh
- bazel fetch //test || fail "Fetch failed"
bazel run //test >& $TEST_log || echo "Expected run to succeed"
kill_nc
expect_log "Tra-la!"