aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/GenerateWorkspace.java26
-rw-r--r--src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/GenerateWorkspaceOptions.java13
-rw-r--r--src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/WorkspaceResolver.java (renamed from src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/Resolver.java)10
-rw-r--r--src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/maven/BUILD1
-rw-r--r--src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/maven/DefaultModelResolver.java39
-rw-r--r--src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/maven/Resolver.java56
-rw-r--r--src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/maven/Rule.java31
-rw-r--r--src/tools/generate_workspace/src/test/java/com/google/devtools/build/workspace/maven/BUILD1
-rw-r--r--src/tools/generate_workspace/src/test/java/com/google/devtools/build/workspace/maven/RuleTest.java2
9 files changed, 126 insertions, 53 deletions
diff --git a/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/GenerateWorkspace.java b/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/GenerateWorkspace.java
index e06f067d60..84bbc0b6eb 100644
--- a/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/GenerateWorkspace.java
+++ b/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/GenerateWorkspace.java
@@ -23,6 +23,7 @@ import com.google.devtools.build.lib.vfs.FileSystem;
import com.google.devtools.build.lib.vfs.JavaIoFileSystem;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.UnixFileSystem;
+import com.google.devtools.build.workspace.maven.Resolver;
import com.google.devtools.common.options.OptionsParser;
import java.io.File;
@@ -41,14 +42,16 @@ public class GenerateWorkspace {
private final EventHandler handler;
private final FileSystem fileSystem;
- private final com.google.devtools.build.workspace.maven.Resolver resolver;
+ private final Resolver resolver;
private final Path outputDir;
public static void main(String[] args) {
OptionsParser parser = OptionsParser.newOptionsParser(GenerateWorkspaceOptions.class);
parser.parseAndExitUponError(args);
GenerateWorkspaceOptions options = parser.getOptions(GenerateWorkspaceOptions.class);
- if (options.mavenProjects.isEmpty() && options.bazelProjects.isEmpty()) {
+ if (options.mavenProjects.isEmpty()
+ && options.bazelProjects.isEmpty()
+ && options.artifacts.isEmpty()) {
printUsage(parser);
return;
}
@@ -56,6 +59,7 @@ public class GenerateWorkspace {
GenerateWorkspace workspaceFileGenerator = new GenerateWorkspace(options.outputDir);
workspaceFileGenerator.generateFromWorkspace(options.bazelProjects);
workspaceFileGenerator.generateFromPom(options.mavenProjects);
+ workspaceFileGenerator.generateFromArtifacts(options.artifacts);
if (!workspaceFileGenerator.hasErrors()) {
workspaceFileGenerator.writeResults();
}
@@ -66,11 +70,11 @@ public class GenerateWorkspace {
}
private static void printUsage(OptionsParser parser) {
- System.out.println("Usage: generate_workspace (-b PATH|-m PATH)+ [-o PATH]\n\n"
+ System.out.println("Usage: generate_workspace (-b PATH|-m PATH|-a coord)+ [-o PATH]\n\n"
+ "Generates a WORKSPACE file from the given projects and a BUILD file with a rule that "
- + "contains all of the transitive dependencies. At least one bazel_project or "
- + "maven_project must be specified. If output_dir is not specified, the generated files "
- + "will be written to a temporary directory.\n");
+ + "contains all of the transitive dependencies. At least one bazel_project, "
+ + "maven_project, or artifact coordinate must be specified. If output_dir is not "
+ + "specified, the generated files will be written to a temporary directory.\n");
System.out.println(parser.describeOptions(Collections.<String, String>emptyMap(),
OptionsParser.HelpVerbosity.LONG));
}
@@ -78,7 +82,7 @@ public class GenerateWorkspace {
private GenerateWorkspace(String outputDir) {
this.handler = new EventHandler();
this.fileSystem = getFileSystem();
- this.resolver = new com.google.devtools.build.workspace.maven.Resolver(handler);
+ this.resolver = new Resolver(handler);
if (outputDir.isEmpty()) {
this.outputDir = fileSystem.getPath(Files.createTempDir().toString());
} else {
@@ -93,7 +97,7 @@ public class GenerateWorkspace {
private void generateFromWorkspace(List<String> projects) {
for (String project : projects) {
- Resolver workspaceResolver = new Resolver(resolver, handler);
+ WorkspaceResolver workspaceResolver = new WorkspaceResolver(resolver, handler);
Path projectPath = fileSystem.getPath(getAbsolute(project));
Package externalPackage = workspaceResolver.parse(projectPath.getRelative("WORKSPACE"));
workspaceResolver.resolveTransitiveDependencies(externalPackage);
@@ -106,6 +110,12 @@ public class GenerateWorkspace {
}
}
+ private void generateFromArtifacts(List<String> artifacts) {
+ for (String artifactCoord : artifacts) {
+ resolver.resolveArtifact(artifactCoord);
+ }
+ }
+
private String getAbsolute(String path) {
return Paths.get(System.getProperty("user.dir")).resolve(path).toString();
}
diff --git a/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/GenerateWorkspaceOptions.java b/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/GenerateWorkspaceOptions.java
index 935df95345..7e9011bd0d 100644
--- a/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/GenerateWorkspaceOptions.java
+++ b/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/GenerateWorkspaceOptions.java
@@ -36,6 +36,7 @@ public class GenerateWorkspaceOptions extends OptionsBase {
abbrev = 'b',
help = "Directory contains a Bazel project.",
allowMultiple = true,
+ category = "input",
defaultValue = ""
)
public List<String> bazelProjects;
@@ -45,15 +46,27 @@ public class GenerateWorkspaceOptions extends OptionsBase {
abbrev = 'm',
help = "Directory containing a Maven project.",
allowMultiple = true,
+ category = "input",
defaultValue = ""
)
public List<String> mavenProjects;
@Option(
+ name = "artifact",
+ abbrev = 'a',
+ help = "Maven artifact coordinates (e.g. groupId:artifactId:version).",
+ allowMultiple = true,
+ category = "input",
+ defaultValue = ""
+ )
+ public List<String> artifacts;
+
+ @Option(
name = "output_dir",
abbrev = 'o',
help = "Output directory to store the WORKSPACE and BUILD files. If unspecified, a temporary"
+ " directory is used.",
+ category = "output",
defaultValue = ""
)
public String outputDir;
diff --git a/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/Resolver.java b/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/WorkspaceResolver.java
index 2d95c4bd58..1adadb83c5 100644
--- a/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/Resolver.java
+++ b/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/WorkspaceResolver.java
@@ -37,6 +37,8 @@ import com.google.devtools.build.lib.syntax.ParserInputSource;
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.workspace.maven.DefaultModelResolver;
+import com.google.devtools.build.workspace.maven.Resolver;
+import com.google.devtools.build.workspace.maven.Resolver.InvalidArtifactCoordinateException;
import com.google.devtools.build.workspace.maven.Rule;
import org.apache.maven.model.building.ModelSource;
@@ -48,14 +50,14 @@ import java.util.List;
/**
* Finds the transitive dependencies of a WORKSPACE file.
*/
-public class Resolver {
+public class WorkspaceResolver {
private final RuleClassProvider ruleClassProvider;
private final ImmutableList<EnvironmentExtension> environmentExtensions;
private final EventHandler handler;
private final com.google.devtools.build.workspace.maven.Resolver resolver;
- Resolver(com.google.devtools.build.workspace.maven.Resolver resolver, EventHandler handler) {
+ WorkspaceResolver(Resolver resolver, EventHandler handler) {
this.resolver = resolver;
this.handler = handler;
ConfiguredRuleClassProvider.Builder ruleClassBuilder =
@@ -110,8 +112,8 @@ public class Resolver {
AttributeMap attributeMap = AggregatingAttributeMapper.of(workspaceRule);
Rule rule;
try {
- rule = new Rule(attributeMap.get("artifact", Type.STRING));
- } catch (Rule.InvalidRuleException e) {
+ rule = new Rule(Resolver.getArtifact(attributeMap.get("artifact", Type.STRING)));
+ } catch (InvalidArtifactCoordinateException e) {
handler.handle(Event.error(location, "Couldn't get attribute: " + e.getMessage()));
return;
}
diff --git a/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/maven/BUILD b/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/maven/BUILD
index 94517fd18e..be51073317 100644
--- a/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/maven/BUILD
+++ b/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/maven/BUILD
@@ -17,6 +17,7 @@ java_library(
":rule",
"//src/main/java/com/google/devtools/build/lib:events",
"//src/main/java/com/google/devtools/build/lib:maven-connector",
+ "//third_party:aether",
"//third_party:guava",
"//third_party:jsr305",
"//third_party:maven_model",
diff --git a/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/maven/DefaultModelResolver.java b/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/maven/DefaultModelResolver.java
index 395d619e60..d00d714506 100644
--- a/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/maven/DefaultModelResolver.java
+++ b/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/maven/DefaultModelResolver.java
@@ -26,6 +26,7 @@ import org.apache.maven.model.building.ModelSource;
import org.apache.maven.model.building.UrlModelSource;
import org.apache.maven.model.resolution.ModelResolver;
import org.apache.maven.model.resolution.UnresolvableModelException;
+import org.eclipse.aether.artifact.Artifact;
import java.io.IOException;
import java.net.HttpURLConnection;
@@ -42,26 +43,30 @@ import java.util.Set;
public class DefaultModelResolver implements ModelResolver {
private final Set<Repository> repositories;
- private final Map<String, ModelSource> artifactToUrl;
+ private final Map<String, ModelSource> ruleNameToModelSource;
public DefaultModelResolver() {
repositories = Sets.newHashSet();
repositories.add(MavenConnector.getMavenCentral());
- artifactToUrl = Maps.newHashMap();
+ ruleNameToModelSource = Maps.newHashMap();
}
private DefaultModelResolver(
- Set<Repository> repositories, Map<String, ModelSource> artifactToRepository) {
+ Set<Repository> repositories, Map<String, ModelSource> ruleNameToModelSource) {
this.repositories = repositories;
- this.artifactToUrl = artifactToRepository;
+ this.ruleNameToModelSource = ruleNameToModelSource;
}
+ public ModelSource resolveModel(Artifact artifact) throws UnresolvableModelException {
+ return resolveModel(artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion());
+ }
+
@Override
public ModelSource resolveModel(String groupId, String artifactId, String version)
throws UnresolvableModelException {
- String artifact = Rule.name(groupId, artifactId);
- if (artifactToUrl.containsKey(artifact)) {
- return artifactToUrl.get(artifact);
+ String ruleName = Rule.name(groupId, artifactId);
+ if (ruleNameToModelSource.containsKey(ruleName)) {
+ return ruleNameToModelSource.get(ruleName);
}
for (Repository repository : repositories) {
UrlModelSource modelSource = getModelSource(
@@ -72,13 +77,13 @@ public class DefaultModelResolver implements ModelResolver {
}
// TODO(kchodorow): use Java 8 features to make this a one-liner.
- List<String> urls = Lists.newArrayList();
+ List<String> attemptedUrls = Lists.newArrayList();
for (Repository repository : repositories) {
- urls.add(repository.getUrl());
+ attemptedUrls.add(repository.getUrl());
}
throw new UnresolvableModelException("Could not find any repositories that knew how to "
+ "resolve " + groupId + ":" + artifactId + ":" + version + " (checked "
- + Joiner.on(", ").join(urls) + ")", groupId, artifactId, version);
+ + Joiner.on(", ").join(attemptedUrls) + ")", groupId, artifactId, version);
}
// TODO(kchodorow): make this work with local repositories.
@@ -94,7 +99,7 @@ public class DefaultModelResolver implements ModelResolver {
+ "-" + version + ".pom");
if (pomFileExists(urlUrl)) {
UrlModelSource urlModelSource = new UrlModelSource(urlUrl);
- artifactToUrl.put(Rule.name(groupId, artifactId), urlModelSource);
+ ruleNameToModelSource.put(Rule.name(groupId, artifactId), urlModelSource);
return urlModelSource;
}
} catch (MalformedURLException e) {
@@ -121,22 +126,26 @@ public class DefaultModelResolver implements ModelResolver {
return false;
}
+ // For compatibility with older versions of ModelResolver which don't have this method,
+ // don't add @Override.
public ModelSource resolveModel(Parent parent) throws UnresolvableModelException {
return resolveModel(parent.getGroupId(), parent.getArtifactId(), parent.getVersion());
}
- @Override
+ // For compatibility with older versions of ModelResolver which don't have this method,
+ // don't add @Override.
public void addRepository(Repository repository) {
repositories.add(repository);
}
+ @Override
public void addRepository(Repository repository, boolean replace) {
addRepository(repository);
}
@Override
public ModelResolver newCopy() {
- return new DefaultModelResolver(repositories, artifactToUrl);
+ return new DefaultModelResolver(repositories, ruleNameToModelSource);
}
/**
@@ -152,8 +161,8 @@ public class DefaultModelResolver implements ModelResolver {
public boolean putModelSource(String groupId, String artifactId, ModelSource modelSource) {
String key = Rule.name(groupId, artifactId);
- if (!artifactToUrl.containsKey(key)) {
- artifactToUrl.put(key, modelSource);
+ if (!ruleNameToModelSource.containsKey(key)) {
+ ruleNameToModelSource.put(key, modelSource);
return true;
}
return false;
diff --git a/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/maven/Resolver.java b/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/maven/Resolver.java
index bbc9e52993..d379deca5e 100644
--- a/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/maven/Resolver.java
+++ b/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/maven/Resolver.java
@@ -21,6 +21,7 @@ import com.google.common.io.CharStreams;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventHandler;
+import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.apache.maven.model.Parent;
import org.apache.maven.model.Repository;
@@ -40,6 +41,8 @@ import org.apache.maven.model.management.DefaultPluginManagementInjector;
import org.apache.maven.model.plugin.DefaultPluginConfigurationExpander;
import org.apache.maven.model.profile.DefaultProfileSelector;
import org.apache.maven.model.resolution.UnresolvableModelException;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.artifact.DefaultArtifact;
import java.io.File;
import java.io.IOException;
@@ -59,6 +62,31 @@ import javax.annotation.Nullable;
* Resolves Maven dependencies.
*/
public class Resolver {
+
+ /**
+ * Exception thrown if an artifact coordinate could not be parsed.
+ */
+ public static class InvalidArtifactCoordinateException extends Exception {
+ InvalidArtifactCoordinateException(String message) {
+ super(message);
+ }
+ }
+
+ public static Artifact getArtifact(String atrifactCoords)
+ throws InvalidArtifactCoordinateException {
+ try {
+ return new DefaultArtifact(atrifactCoords);
+ } catch (IllegalArgumentException e) {
+ throw new InvalidArtifactCoordinateException(e.getMessage());
+ }
+ }
+
+ public static Artifact getArtifact(Dependency dependency)
+ throws InvalidArtifactCoordinateException {
+ return getArtifact(dependency.getGroupId() + ":" + dependency.getArtifactId() + ":"
+ + dependency.getVersion());
+ }
+
private static final String COMPILE_SCOPE = "compile";
private final EventHandler handler;
@@ -110,6 +138,7 @@ public class Resolver {
}
outputStream.println(" ],");
outputStream.println(")");
+ outputStream.println();
}
}
@@ -148,6 +177,27 @@ public class Resolver {
}
/**
+ * Resolves an artifact as a root of a dependency graph.
+ */
+ public void resolveArtifact(String artifactCoord) {
+ Artifact artifact;
+ ModelSource modelSource;
+ try {
+ artifact = getArtifact(artifactCoord);
+ modelSource = modelResolver.resolveModel(artifact);
+ } catch (UnresolvableModelException | InvalidArtifactCoordinateException e) {
+ handler.handle(Event.error(e.getMessage()));
+ return;
+ }
+
+ addHeader(artifactCoord);
+ Rule rule = new Rule(artifact);
+ addRootDependency(rule);
+ deps.put(rule.name(), rule); // add the artifact rule to the workspace
+ resolveEffectiveModel(modelSource, Sets.<String>newHashSet(), rule);
+ }
+
+ /**
* Resolves all dependencies from a given "model source," which could be either a URL or a local
* file.
* @return the model.
@@ -171,7 +221,7 @@ public class Resolver {
modelResolver.addRepository(repo);
}
- for (org.apache.maven.model.Dependency dependency : model.getDependencies()) {
+ for (Dependency dependency : model.getDependencies()) {
if (!dependency.getScope().equals(COMPILE_SCOPE)) {
continue;
}
@@ -182,7 +232,7 @@ public class Resolver {
continue;
}
try {
- Rule artifactRule = new Rule(dependency);
+ Rule artifactRule = new Rule(getArtifact(dependency), dependency.getExclusions());
HashSet<String> localDepExclusions = new HashSet<>(exclusions);
localDepExclusions.addAll(artifactRule.getExclusions());
@@ -205,7 +255,7 @@ public class Resolver {
} else {
rootDependencies.add(artifactRule);
}
- } catch (UnresolvableModelException | Rule.InvalidRuleException e) {
+ } catch (UnresolvableModelException | InvalidArtifactCoordinateException e) {
handler.handle(Event.error("Could not resolve dependency " + dependency.getGroupId()
+ ":" + dependency.getArtifactId() + ":" + dependency.getVersion() + ": "
+ e.getMessage()));
diff --git a/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/maven/Rule.java b/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/maven/Rule.java
index 8f14523a41..13698f364c 100644
--- a/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/maven/Rule.java
+++ b/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/maven/Rule.java
@@ -20,11 +20,10 @@ import com.google.devtools.build.lib.bazel.repository.MavenConnector;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventHandler;
-import org.apache.maven.model.Dependency;
import org.apache.maven.model.Exclusion;
import org.eclipse.aether.artifact.Artifact;
-import org.eclipse.aether.artifact.DefaultArtifact;
+import java.util.List;
import java.util.Objects;
import java.util.Set;
@@ -32,6 +31,7 @@ import java.util.Set;
* A struct representing the fields of maven_jar to be written to the WORKSPACE file.
*/
public final class Rule implements Comparable<Rule> {
+
private final Artifact artifact;
private final Set<String> parents;
private final Set<String> exclusions;
@@ -39,24 +39,20 @@ public final class Rule implements Comparable<Rule> {
private String repository;
private String sha1;
- public Rule(String artifactStr) throws InvalidRuleException {
- try {
- this.artifact = new DefaultArtifact(artifactStr);
- } catch (IllegalArgumentException e) {
- throw new InvalidRuleException(e.getMessage());
- }
+ public Rule(Artifact artifact) {
+ this.artifact = artifact;
this.parents = Sets.newHashSet();
this.dependencies = Sets.newTreeSet();
this.exclusions = Sets.newHashSet();
this.repository = MavenConnector.MAVEN_CENTRAL_URL;
}
- public Rule(Dependency dependency) throws InvalidRuleException {
- this(dependency.getGroupId() + ":" + dependency.getArtifactId() + ":"
- + dependency.getVersion());
+ public Rule(Artifact artifact, List<Exclusion> exclusions) {
+ this(artifact);
- for (Exclusion exclusion : dependency.getExclusions()) {
- exclusions.add(String.format("%s:%s", exclusion.getGroupId(), exclusion.getArtifactId()));
+ for (Exclusion exclusion : exclusions) {
+ String coord = String.format("%s:%s", exclusion.getGroupId(), exclusion.getArtifactId());
+ this.exclusions.add(coord);
}
}
@@ -190,13 +186,4 @@ public final class Rule implements Comparable<Rule> {
public int compareTo(Rule o) {
return name().compareTo(o.name());
}
-
- /**
- * Exception thrown if the rule could not be created.
- */
- public static class InvalidRuleException extends Exception {
- InvalidRuleException(String message) {
- super(message);
- }
- }
}
diff --git a/src/tools/generate_workspace/src/test/java/com/google/devtools/build/workspace/maven/BUILD b/src/tools/generate_workspace/src/test/java/com/google/devtools/build/workspace/maven/BUILD
index 919502fef7..edce307ff2 100644
--- a/src/tools/generate_workspace/src/test/java/com/google/devtools/build/workspace/maven/BUILD
+++ b/src/tools/generate_workspace/src/test/java/com/google/devtools/build/workspace/maven/BUILD
@@ -3,6 +3,7 @@ java_test(
srcs = ["RuleTest.java"],
deps = [
"//src/main/java/com/google/devtools/build/lib:events",
+ "//src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/maven",
"//src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/maven:rule",
"//third_party:junit4",
"//third_party:truth",
diff --git a/src/tools/generate_workspace/src/test/java/com/google/devtools/build/workspace/maven/RuleTest.java b/src/tools/generate_workspace/src/test/java/com/google/devtools/build/workspace/maven/RuleTest.java
index 18cd687862..2782aba7da 100644
--- a/src/tools/generate_workspace/src/test/java/com/google/devtools/build/workspace/maven/RuleTest.java
+++ b/src/tools/generate_workspace/src/test/java/com/google/devtools/build/workspace/maven/RuleTest.java
@@ -38,7 +38,7 @@ public class RuleTest {
@Test
public void testUrl() throws Exception {
- Rule rule = new Rule("foo:bar:1.2.3");
+ Rule rule = new Rule(Resolver.getArtifact("foo:bar:1.2.3"));
assertThat(rule.getUrl())
.isEqualTo("https://repo1.maven.org/maven2/foo/bar/1.2.3/bar-1.2.3.pom");
rule.setRepository("http://myrepo.com/foo/bar/1.2.3/bar-1.2.3.pom", handler);