aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build
diff options
context:
space:
mode:
authorGravatar juliexxia <juliexxia@google.com>2017-08-23 19:32:49 +0200
committerGravatar Damien Martin-Guillerez <dmarting@google.com>2017-08-24 13:58:50 +0200
commit7a7c41d7d342cd427e74f091b55690eed13e280d (patch)
tree9dff41110751ad6e1a0b0a12e15a11e8d8f8e9ac /src/main/java/com/google/devtools/build
parent49bb72377153fc208708267f90791644f389bd31 (diff)
Pull maven -src jars when available alongside jars re:
https://github.com/bazelbuild/bazel/issues/308 RELNOTES: None. PiperOrigin-RevId: 166219871
Diffstat (limited to 'src/main/java/com/google/devtools/build')
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/JarDecompressor.java88
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/MavenDownloader.java102
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/MavenJarFunction.java31
3 files changed, 169 insertions, 52 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/JarDecompressor.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/JarDecompressor.java
index 703c4a32dd..26286adef0 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/JarDecompressor.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/JarDecompressor.java
@@ -15,6 +15,7 @@
package com.google.devtools.build.lib.bazel.repository;
import com.google.common.base.Joiner;
+import com.google.common.base.Optional;
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;
@@ -34,34 +35,46 @@ public class JarDecompressor implements Decompressor {
protected JarDecompressor() {
}
- /**
- * The .jar can be used compressed, so this just exposes it in a way Bazel can use.
- *
- * <p>It moves the jar from some-name/x/y/z/foo.jar to some-name/jar/foo.jar and creates a
- * BUILD.bazel file containing one entry: the .jar.
- */
@Override
@Nullable
public Path decompress(DecompressorDescriptor descriptor) throws RepositoryFunctionException {
- // Example: archiveFile is external/some-name/foo.jar.
- String baseName = descriptor.archivePath().getBaseName();
+ return decompressWithSrcjar(descriptor, Optional.absent());
+ }
+ /**
+ * The jar (and srcjar if available) can be used compressed, so this just exposes them in a way
+ * Bazel can use.
+ *
+ * <p>It moves the jar(s) from some-name/x/y/z/foo.jar to some-name/jar/foo.jar and creates a
+ * BUILD.bazel file containing only the jar(s).
+ */
+ public Path decompressWithSrcjar(
+ DecompressorDescriptor descriptor, Optional<DecompressorDescriptor> srcjarDescriptor)
+ throws RepositoryFunctionException {
try {
+ // external/some-name/
FileSystemUtils.createDirectoryAndParents(descriptor.repositoryPath());
- // external/some-name/WORKSPACE.
+ // external/some-name/WORKSPACE
RepositoryFunction.createWorkspaceFile(
descriptor.repositoryPath(), descriptor.targetKind(), descriptor.targetName());
- // external/some-name/jar.
+ // external/some-name/jar/
Path jarDirectory = descriptor.repositoryPath().getRelative(getPackageName());
FileSystemUtils.createDirectoryAndParents(jarDirectory);
- // external/some-name/repository/jar/foo.jar is a symbolic link to the jar in
- // external/some-name.
- Path jarSymlink = jarDirectory.getRelative(baseName);
- if (!jarSymlink.exists()) {
- jarSymlink.createSymbolicLink(descriptor.archivePath());
- }
- // external/some-name/repository/jar/BUILD.bazel defines the //jar target.
+ // external/some-name/jar/BUILD.bazel defines the //jar target.
Path buildFile = jarDirectory.getRelative("BUILD.bazel");
+
+ // Example: get foo.jar from external/some-name/foo.jar.
+ String baseName = descriptor.archivePath().getBaseName();
+ makeSymlink(descriptor);
+ String buildFileContents;
+ if (srcjarDescriptor.isPresent()) {
+ String srcjarBaseName = srcjarDescriptor.get().archivePath().getBaseName();
+ makeSymlink(srcjarDescriptor.get());
+ buildFileContents = createBuildFileWithSrcjar(baseName, srcjarBaseName);
+ } else {
+ buildFileContents = createBuildFile(baseName);
+ }
+
FileSystemUtils.writeLinesAs(
buildFile,
Charset.forName("UTF-8"),
@@ -69,7 +82,7 @@ public class JarDecompressor implements Decompressor {
+ descriptor.targetKind()
+ " rule "
+ descriptor.targetName(),
- createBuildFile(baseName));
+ buildFileContents);
if (descriptor.executable()) {
descriptor.archivePath().chmod(0755);
}
@@ -80,6 +93,25 @@ public class JarDecompressor implements Decompressor {
return descriptor.repositoryPath();
}
+ /*
+ * Links some-name/x/y/z/foo.jar to some-name/jar/foo.jar (represented by {@code descriptor}
+ */
+ protected void makeSymlink(DecompressorDescriptor descriptor) throws RepositoryFunctionException {
+ try {
+ Path jarDirectory = descriptor.repositoryPath().getRelative(getPackageName());
+ // external/some-name/jar/foo.jar is a symbolic link to the jar in
+ // external/some-name.
+ Path jarSymlink = jarDirectory.getRelative(descriptor.archivePath().getBaseName());
+ if (!jarSymlink.exists()) {
+ jarSymlink.createSymbolicLink(descriptor.archivePath());
+ }
+ } catch (IOException e) {
+ throw new RepositoryFunctionException(
+ new IOException("Error auto-creating jar repo structure: " + e.getMessage()),
+ Transience.TRANSIENT);
+ }
+ }
+
protected String getPackageName() {
return "jar";
}
@@ -99,4 +131,24 @@ public class JarDecompressor implements Decompressor {
" visibility = ['//visibility:public']",
")");
}
+
+ protected String createBuildFileWithSrcjar(String baseName, String srcjarBaseName) {
+ return Joiner.on("\n")
+ .join(
+ "java_import(",
+ " name = 'jar',",
+ " jars = ['" + baseName + "'],",
+ " srcjar = '" + srcjarBaseName + "',",
+ " visibility = ['//visibility:public']",
+ ")",
+ "",
+ "filegroup(",
+ " name = 'file',",
+ " srcs = [",
+ " '" + baseName + "',",
+ " '" + srcjarBaseName + "',",
+ " ],",
+ " visibility = ['//visibility:public']",
+ ")");
+ }
}
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 264173ef8f..e663a80499 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
@@ -14,6 +14,7 @@
package com.google.devtools.build.lib.bazel.repository;
+import com.google.common.base.Optional;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -72,9 +73,10 @@ public class MavenDownloader extends HttpDownloader {
}
/**
- * Download the Maven artifact to the output directory. Returns the path to the jar.
+ * Download the Maven artifact to the output directory. Returns the path to the jar (and the
+ * srcjar if available).
*/
- public Path download(String name, WorkspaceAttributeMapper mapper, Path outputDirectory,
+ public JarPaths download(String name, WorkspaceAttributeMapper mapper, Path outputDirectory,
MavenServerValue serverValue) throws IOException, EvalException {
this.name = name;
this.outputDirectory = outputDirectory;
@@ -82,59 +84,73 @@ public class MavenDownloader extends HttpDownloader {
String url = serverValue.getUrl();
Server server = serverValue.getServer();
+ // Initialize maven artifacts
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 artifactCoords = 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 + "'");
+ }
+
try {
- artifact = new DefaultArtifact(artifactId);
+ artifact = new DefaultArtifact(artifactCoords);
} 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;
+ return new JarPaths(cachedDestination, Optional.absent());
}
}
+ // Setup env for fetching jars
MavenConnector connector = new MavenConnector(outputDirectory.getPathString());
RepositorySystem system = connector.newRepositorySystem();
RepositorySystemSession session = connector.newRepositorySystemSession(system);
+ RemoteRepository repository =
+ new RemoteRepository.Builder(name, MavenServerValue.DEFAULT_ID, url)
+ .setAuthentication(new MavenAuthentication(server))
+ .build();
- RemoteRepository repository = new RemoteRepository.Builder(
- name, MavenServerValue.DEFAULT_ID, url)
- .setAuthentication(new MavenAuthentication(server))
- .build();
- ArtifactRequest artifactRequest = new ArtifactRequest();
-
- artifactRequest.setArtifact(artifact);
- artifactRequest.setRepositories(ImmutableList.of(repository));
-
+ // Try fetching jar.
+ final Path jarDownload;
try {
- ArtifactResult artifactResult = system.resolveArtifact(session, artifactRequest);
- artifact = artifactResult.getArtifact();
+ artifact = downloadArtifact(artifact, repository, session, system);
} catch (ArtifactResolutionException e) {
throw new IOException("Failed to fetch Maven dependency: " + e.getMessage());
}
- Path downloadPath = outputDirectory.getRelative(artifact.getFile().getAbsolutePath());
+ // Try also fetching srcjar.
+ Artifact artifactWithSrcs = srcjarCoords(artifact);
+ try {
+ artifactWithSrcs = downloadArtifact(artifactWithSrcs, repository, session, system);
+ } catch (ArtifactResolutionException e) {
+ // Intentionally ignored - missing srcjar is not an error.
+ }
+
+ jarDownload = outputDirectory.getRelative(artifact.getFile().getAbsolutePath());
// Verify checksum.
if (!Strings.isNullOrEmpty(sha1)) {
- RepositoryCache.assertFileChecksum(sha1, downloadPath, KeyType.SHA1);
+ RepositoryCache.assertFileChecksum(sha1, jarDownload, KeyType.SHA1);
}
if (isCaching) {
- repositoryCache.put(sha1, downloadPath, KeyType.SHA1);
+ repositoryCache.put(sha1, jarDownload, KeyType.SHA1);
+ }
+
+ if (artifactWithSrcs.getFile() != null) {
+ Path srcjarDownload =
+ outputDirectory.getRelative(artifactWithSrcs.getFile().getAbsolutePath());
+ return new JarPaths(jarDownload, Optional.fromNullable(srcjarDownload));
+ } else {
+ return new JarPaths(jarDownload, Optional.absent());
}
- return downloadPath;
}
private Path getDownloadDestination(Artifact artifact) {
@@ -149,6 +165,40 @@ public class MavenDownloader extends HttpDownloader {
return outputDirectory.getRelative(joiner.toString());
}
+ private Artifact srcjarCoords(Artifact jar) {
+ return new DefaultArtifact(
+ jar.getGroupId(), jar.getArtifactId(), "sources", jar.getExtension(), jar.getVersion());
+ }
+
+ /*
+ * Set up request for and resolve (retrieve to local repo) artifact
+ */
+ private Artifact downloadArtifact(
+ Artifact artifact,
+ RemoteRepository repository,
+ RepositorySystemSession session,
+ RepositorySystem system)
+ throws ArtifactResolutionException {
+ ArtifactRequest artifactRequest = new ArtifactRequest();
+ artifactRequest.setArtifact(artifact);
+ artifactRequest.setRepositories(ImmutableList.of(repository));
+ ArtifactResult artifactResult = system.resolveArtifact(session, artifactRequest);
+ return artifactResult.getArtifact();
+ }
+
+ /*
+ * Class for packaging srcjar and jar paths together when srcjar is available.
+ */
+ static class JarPaths {
+ final Path jar;
+ @Nullable final Optional<Path> srcjar;
+
+ private JarPaths(Path jar, Optional<Path> srcjar) {
+ this.jar = jar;
+ this.srcjar = srcjar;
+ }
+ }
+
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 907227e959..45aa2bab6f 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
@@ -14,9 +14,11 @@
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.analysis.BlazeDirectories;
import com.google.devtools.build.lib.analysis.RuleDefinition;
+import com.google.devtools.build.lib.bazel.repository.MavenDownloader.JarPaths;
import com.google.devtools.build.lib.bazel.rules.workspace.MavenJarRule;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.rules.repository.RepositoryDirectoryValue;
@@ -98,7 +100,7 @@ public class MavenJarFunction extends HttpArchiveFunction {
if (env.valuesMissing()) {
return null;
}
-
+
Path outputDir = getExternalRepositoryDirectory(directories).getRelative(rule.getName());
return createOutputTree(rule, outputDir, serverValue);
}
@@ -110,10 +112,11 @@ public class MavenJarFunction extends HttpArchiveFunction {
createDirectory(outputDirectory);
String name = rule.getName();
- Path repositoryJar;
+ final JarPaths repositoryJars;
try {
- repositoryJar = mavenDownloader.download(
- name, WorkspaceAttributeMapper.of(rule), outputDirectory, serverValue);
+ repositoryJars =
+ mavenDownloader.download(
+ name, WorkspaceAttributeMapper.of(rule), outputDirectory, serverValue);
} catch (IOException e) {
throw new RepositoryFunctionException(e, Transience.TRANSIENT);
} catch (EvalException e) {
@@ -121,13 +124,25 @@ public class MavenJarFunction extends HttpArchiveFunction {
}
// Add a WORKSPACE file & BUILD file to the Maven jar.
- Path result = DecompressorValue.decompress(DecompressorDescriptor.builder()
+ DecompressorDescriptor jar = getDescriptorBuilder(name, repositoryJars.jar, outputDirectory);
+ DecompressorDescriptor srcjar =
+ repositoryJars.srcjar.isPresent()
+ ? getDescriptorBuilder(name, repositoryJars.srcjar.get(), outputDirectory)
+ : null;
+ JarDecompressor decompressor = (JarDecompressor) jar.getDecompressor();
+ Path result = decompressor.decompressWithSrcjar(jar, Optional.fromNullable(srcjar));
+ return RepositoryDirectoryValue.builder().setPath(result);
+ }
+
+ private DecompressorDescriptor getDescriptorBuilder(String name, Path jar, Path outputDirectory)
+ throws RepositoryFunctionException, InterruptedException {
+ return DecompressorDescriptor.builder()
.setDecompressor(JarDecompressor.INSTANCE)
.setTargetKind(MavenJarRule.NAME)
.setTargetName(name)
- .setArchivePath(repositoryJar)
- .setRepositoryPath(outputDirectory).build());
- return RepositoryDirectoryValue.builder().setPath(result);
+ .setArchivePath(jar)
+ .setRepositoryPath(outputDirectory)
+ .build();
}
/**