diff options
author | 2016-11-03 15:20:48 +0000 | |
---|---|---|
committer | 2016-11-03 16:12:22 +0000 | |
commit | 38e54ac14e69113e9790ce9a526784e0f18e4b6e (patch) | |
tree | 345bec2131dd53d2496e95b9c26b1309c413c081 /src | |
parent | 614fdc3c7fbcc2656e48d6ea9e0c0749cf5c57ce (diff) |
Implemented repository caching for native maven_jar rules.
GITHUB: #1752
--
MOS_MIGRATED_REVID=138072464
Diffstat (limited to 'src')
4 files changed, 124 insertions, 10 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/MavenDownloader.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/MavenDownloader.java index da9653672a..264173ef8f 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/repository/MavenDownloader.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/MavenDownloader.java @@ -27,6 +27,7 @@ import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.vfs.Path; import java.io.IOException; import java.util.Map; +import java.util.StringJoiner; import javax.annotation.Nullable; import org.apache.maven.settings.Server; import org.eclipse.aether.RepositorySystem; @@ -77,14 +78,32 @@ public class MavenDownloader extends HttpDownloader { MavenServerValue serverValue) throws IOException, EvalException { this.name = name; this.outputDirectory = outputDirectory; + + String url = serverValue.getUrl(); + Server server = serverValue.getServer(); + + Artifact artifact; String artifactId = mapper.get("artifact", Type.STRING); String sha1 = mapper.isAttributeValueExplicitlySpecified("sha1") ? mapper.get("sha1", Type.STRING) : null; if (sha1 != null && !KeyType.SHA1.isValid(sha1)) { throw new IOException("Invalid SHA-1 for maven_jar " + name + ": '" + sha1 + "'"); } - String url = serverValue.getUrl(); - Server server = serverValue.getServer(); + try { + artifact = new DefaultArtifact(artifactId); + } catch (IllegalArgumentException e) { + throw new IOException(e.getMessage()); + } + + boolean isCaching = repositoryCache.isEnabled() && KeyType.SHA1.isValid(sha1); + + if (isCaching) { + Path downloadPath = getDownloadDestination(artifact); + Path cachedDestination = repositoryCache.get(sha1, downloadPath, KeyType.SHA1); + if (cachedDestination != null) { + return cachedDestination; + } + } MavenConnector connector = new MavenConnector(outputDirectory.getPathString()); RepositorySystem system = connector.newRepositorySystem(); @@ -95,12 +114,7 @@ public class MavenDownloader extends HttpDownloader { .setAuthentication(new MavenAuthentication(server)) .build(); ArtifactRequest artifactRequest = new ArtifactRequest(); - Artifact artifact; - try { - artifact = new DefaultArtifact(artifactId); - } catch (IllegalArgumentException e) { - throw new IOException(e.getMessage()); - } + artifactRequest.setArtifact(artifact); artifactRequest.setRepositories(ImmutableList.of(repository)); @@ -116,9 +130,25 @@ public class MavenDownloader extends HttpDownloader { if (!Strings.isNullOrEmpty(sha1)) { RepositoryCache.assertFileChecksum(sha1, downloadPath, KeyType.SHA1); } + + if (isCaching) { + repositoryCache.put(sha1, downloadPath, KeyType.SHA1); + } return downloadPath; } + private Path getDownloadDestination(Artifact artifact) { + String groupIdPath = artifact.getGroupId().replace('.', '/'); + String artifactId = artifact.getArtifactId(); + String version = artifact.getVersion(); + String filename = artifactId + '-' + version + '.' + artifact.getExtension(); + + StringJoiner joiner = new StringJoiner("/"); + joiner.add(groupIdPath).add(artifactId).add(version).add(filename); + + return outputDirectory.getRelative(joiner.toString()); + } + private static class MavenAuthentication implements Authentication { private final Map<String, String> authenticationInfo; 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 67fc61cdeb..f5a86e22e8 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 @@ -28,6 +28,7 @@ import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.skyframe.SkyFunction.Environment; import com.google.devtools.build.skyframe.SkyFunctionException.Transience; import com.google.devtools.build.skyframe.SkyValue; + import java.io.IOException; /** diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/cache/RepositoryCache.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/cache/RepositoryCache.java index da7c0cd045..595e0cb991 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/repository/cache/RepositoryCache.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/cache/RepositoryCache.java @@ -135,6 +135,7 @@ public class RepositoryCache { + "Please delete the directory " + cacheEntry + " and try again."); } + FileSystemUtils.createDirectoryAndParents(targetPath.getParentDirectory()); FileSystemUtils.copyFile(cacheValue, targetPath); return targetPath; diff --git a/src/test/shell/bazel/bazel_repository_cache_test.sh b/src/test/shell/bazel/bazel_repository_cache_test.sh index dc563220f6..e503d683a8 100755 --- a/src/test/shell/bazel/bazel_repository_cache_test.sh +++ b/src/test/shell/bazel/bazel_repository_cache_test.sh @@ -71,6 +71,40 @@ EOF touch BUILD } +function setup_maven_repository() { + 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 + + serve_artifact com.example.carnivore carnivore 1.23 + + cat > WORKSPACE <<EOF +maven_jar( + name = 'endangered', + artifact = "com.example.carnivore:carnivore:1.23", + repository = 'http://localhost:$fileserver_port/', + sha1 = '$sha1', +) +bind(name = 'mongoose', actual = '@endangered//jar') +EOF +} + # Test downloading a file from a repository. # This creates a simple repository containing: # @@ -326,7 +360,7 @@ EOF expect_log "All external dependencies fetched successfully" } -function test_load_skylark_download_fail_without_cache() { +function test_skylark_download_fail_without_cache() { setup_skylark_repository cat >test.bzl <<EOF @@ -379,7 +413,7 @@ EOF expect_log "All external dependencies fetched successfully" } -function test_load_skylark_download_and_extract_fail_without_cache() { +function test_skylark_download_and_extract_fail_without_cache() { setup_skylark_repository cat >test.bzl <<EOF @@ -407,4 +441,52 @@ EOF expect_log "Error downloading" } +function test_maven_jar_exists_in_cache() { + setup_maven_repository + + bazel fetch --experimental_repository_cache="$repo_cache_dir" //zoo:ball-pit >& $TEST_log \ + || echo "Expected fetch to succeed" + + if [ ! -f $repo_cache_dir/content_addressable/sha1/$sha1/file ]; then + fail "the file was not cached successfully" + fi +} + +function test_load_cached_value_maven_jar() { + setup_maven_repository + + bazel fetch --experimental_repository_cache="$repo_cache_dir" //zoo:ball-pit >& $TEST_log \ + || echo "Expected fetch to succeed" + + # Kill the server + shutdown_server + bazel clean --expunge + + # Fetch again + bazel fetch --experimental_repository_cache="$repo_cache_dir" //zoo:ball-pit >& $TEST_log \ + || echo "Expected fetch to succeed" + + expect_log "All external dependencies fetched successfully" +} + +function test_maven_jar_fail_without_cache() { + setup_maven_repository + + bazel fetch --experimental_repository_cache="$repo_cache_dir" //zoo:ball-pit >& $TEST_log \ + || echo "Expected fetch to succeed" + + # Kill the server + shutdown_server + bazel clean --expunge + + # Clean the repository cache + rm -rf "$repo_cache_dir" + + # Fetch again + bazel fetch --experimental_repository_cache="$repo_cache_dir" //zoo:ball-pit >& $TEST_log \ + && echo "Expected fetch to fail" + + expect_log "Failed to fetch Maven dependency" +} + run_suite "repository cache tests" |