aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/WorkspaceResolver.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/WorkspaceResolver.java')
-rw-r--r--src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/WorkspaceResolver.java148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/WorkspaceResolver.java b/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/WorkspaceResolver.java
new file mode 100644
index 0000000000..1adadb83c5
--- /dev/null
+++ b/src/tools/generate_workspace/src/main/java/com/google/devtools/build/workspace/WorkspaceResolver.java
@@ -0,0 +1,148 @@
+// 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.workspace;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Sets;
+import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
+import com.google.devtools.build.lib.bazel.BazelMain;
+import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
+import com.google.devtools.build.lib.cmdline.RepositoryName;
+import com.google.devtools.build.lib.events.Event;
+import com.google.devtools.build.lib.events.EventHandler;
+import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.packages.AggregatingAttributeMapper;
+import com.google.devtools.build.lib.packages.AttributeMap;
+import com.google.devtools.build.lib.packages.Package;
+import com.google.devtools.build.lib.packages.PackageFactory.EnvironmentExtension;
+import com.google.devtools.build.lib.packages.RuleClassProvider;
+import com.google.devtools.build.lib.packages.Target;
+import com.google.devtools.build.lib.packages.WorkspaceFactory;
+import com.google.devtools.build.lib.runtime.BlazeModule;
+import com.google.devtools.build.lib.runtime.BlazeRuntime;
+import com.google.devtools.build.lib.syntax.Mutability;
+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;
+import org.apache.maven.model.resolution.UnresolvableModelException;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Finds the transitive dependencies of a WORKSPACE file.
+ */
+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;
+
+ WorkspaceResolver(Resolver resolver, EventHandler handler) {
+ this.resolver = resolver;
+ this.handler = handler;
+ ConfiguredRuleClassProvider.Builder ruleClassBuilder =
+ new ConfiguredRuleClassProvider.Builder();
+ List<BlazeModule> blazeModules = BlazeRuntime.createModules(BazelMain.BAZEL_MODULES);
+ ImmutableList.Builder<EnvironmentExtension> environmentExtensions = ImmutableList.builder();
+ for (BlazeModule blazeModule : blazeModules) {
+ blazeModule.initializeRuleClasses(ruleClassBuilder);
+ environmentExtensions.add(blazeModule.getPackageEnvironmentExtension());
+ }
+ this.ruleClassProvider = ruleClassBuilder.build();
+ this.environmentExtensions = environmentExtensions.build();
+ }
+
+ /**
+ * Converts the WORKSPACE file content into an ExternalPackage.
+ */
+ public Package parse(Path workspacePath) {
+ resolver.addHeader(workspacePath.getPathString());
+ Package.LegacyBuilder builder =
+ Package.newExternalPackageBuilder(workspacePath, ruleClassProvider.getRunfilesPrefix());
+ try (Mutability mutability = Mutability.create("External Package %s", workspacePath)) {
+ new WorkspaceFactory(builder, ruleClassProvider, environmentExtensions, mutability)
+ .parse(ParserInputSource.create(workspacePath));
+ } catch (IOException | InterruptedException e) {
+ handler.handle(Event.error(Location.fromFile(workspacePath), e.getMessage()));
+ }
+
+ return builder.build();
+ }
+
+ /**
+ * Calculates transitive dependencies of the given //external package.
+ */
+ public void resolveTransitiveDependencies(Package externalPackage) {
+ Location location = Location.fromFile(externalPackage.getFilename());
+ for (Target target : externalPackage.getTargets()) {
+ // Targets are //external:foo.
+ if (target.getTargetKind().startsWith("maven_jar ")) {
+ RepositoryName repositoryName;
+ try {
+ repositoryName = RepositoryName.create("@" + target.getName());
+ } catch (LabelSyntaxException e) {
+ handler.handle(Event.error(location, "Invalid repository name for " + target + ": "
+ + e.getMessage()));
+ return;
+ }
+ com.google.devtools.build.lib.packages.Rule workspaceRule =
+ externalPackage.getRule(repositoryName.strippedName());
+
+ DefaultModelResolver modelResolver = resolver.getModelResolver();
+ AttributeMap attributeMap = AggregatingAttributeMapper.of(workspaceRule);
+ Rule rule;
+ try {
+ 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;
+ }
+ if (attributeMap.isAttributeValueExplicitlySpecified("repository")) {
+ modelResolver.addUserRepository(attributeMap.get("repository", Type.STRING));
+ rule.setRepository(attributeMap.get("repository", Type.STRING), handler);
+ }
+ if (attributeMap.isAttributeValueExplicitlySpecified("sha1")) {
+ rule.setSha1(attributeMap.get("sha1", Type.STRING));
+ } else {
+ rule.setSha1(resolver.downloadSha1(rule));
+ }
+
+ ModelSource modelSource;
+ try {
+ modelSource = modelResolver.resolveModel(
+ rule.groupId(), rule.artifactId(), rule.version());
+ } catch (UnresolvableModelException e) {
+ handler.handle(Event.error(
+ "Could not resolve model for " + target + ": " + e.getMessage()));
+ continue;
+ }
+ resolver.addRootDependency(rule);
+ resolver.resolveEffectiveModel(modelSource, Sets.<String>newHashSet(), rule);
+ } else if (!target.getTargetKind().startsWith("bind")
+ && !target.getTargetKind().startsWith("source ")) {
+ handler.handle(Event.warn(location, "Cannot fetch transitive dependencies for " + target
+ + " yet, skipping"));
+ }
+ }
+ }
+}