Make Rule know about the name of the workspace it is in.
This is needed for taking the runfiles prefix from the WORKSPACE file instead of hardcoding it.
--
MOS_MIGRATED_REVID=87347883
diff --git a/src/main/java/com/google/devtools/build/lib/packages/ExternalPackage.java b/src/main/java/com/google/devtools/build/lib/packages/ExternalPackage.java
index ac4920c..6f7b243 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/ExternalPackage.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/ExternalPackage.java
@@ -34,7 +34,6 @@
*/
public class ExternalPackage extends Package {
- private String workspaceName;
private Map<RepositoryName, Rule> repositoryMap;
ExternalPackage() {
@@ -42,13 +41,6 @@
}
/**
- * Returns the name for this repository.
- */
- public String getWorkspaceName() {
- return workspaceName;
- }
-
- /**
* Returns a description of the repository with the given name, or null if there's no such
* repository.
*/
@@ -77,7 +69,7 @@
}
/**
- * Checks if the label is bound, i.e., starts with //external:.
+ * Checks if the label is bound, i.e., starts with {@code //external:}.
*/
public static boolean isBoundLabel(Label label) {
return label.getPackageName().equals("external");
@@ -89,7 +81,6 @@
*/
public static class Builder
extends AbstractBuilder<ExternalPackage, Builder> {
- private String workspaceName;
private Map<Label, Binding> bindMap = Maps.newHashMap();
private Map<RepositoryName, Rule> repositoryMap = Maps.newHashMap();
@@ -106,7 +97,6 @@
@Override
public ExternalPackage build() {
- pkg.workspaceName = workspaceName;
pkg.repositoryMap = ImmutableMap.copyOf(repositoryMap);
return super.build();
}
@@ -114,8 +104,10 @@
/**
* Sets the name for this repository.
*/
- public void setWorkspaceName(String name) {
- workspaceName = name;
+ @Override
+ public Builder setWorkspaceName(String workspaceName) {
+ pkg.workspaceName = workspaceName;
+ return this;
}
public void addBinding(Label label, Binding binding) {
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Package.java b/src/main/java/com/google/devtools/build/lib/packages/Package.java
index a2216e0..fd48e5d 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/Package.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Package.java
@@ -24,6 +24,7 @@
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
+import com.google.devtools.build.lib.Constants;
import com.google.devtools.build.lib.collect.CollectionUtils;
import com.google.devtools.build.lib.collect.ImmutableSortedKeyMap;
import com.google.devtools.build.lib.events.Event;
@@ -33,7 +34,6 @@
import com.google.devtools.build.lib.packages.License.DistributionType;
import com.google.devtools.build.lib.packages.PackageDeserializer.PackageDeserializationException;
import com.google.devtools.build.lib.packages.PackageFactory.Globber;
-
import com.google.devtools.build.lib.syntax.FuncallExpression;
import com.google.devtools.build.lib.syntax.Label;
import com.google.devtools.build.lib.syntax.Label.SyntaxException;
@@ -103,6 +103,12 @@
private Path packageDirectory;
/**
+ * The name of the workspace this package is in. Used as a prefix for the runfiles directory.
+ * This can be set in the WORKSPACE file. This must be a valid target name.
+ */
+ protected String workspaceName = Constants.RUNFILES_PREFIX;
+
+ /**
* The root of the source tree in which this package was found. It is an invariant that
* {@code sourceRoot.getRelative(name).equals(packageDirectory)}.
*/
@@ -545,6 +551,16 @@
}
/**
+ * Returns this package's workspace name.
+ *
+ * <p>Package-private to encourage callers to get their workspace name from a rule, not a
+ * package.</p>
+ */
+ String getWorkspaceName() {
+ return workspaceName;
+ }
+
+ /**
* Returns the features specified in the <code>package()</code> declaration.
*/
public ImmutableSet<String> getFeatures() {
@@ -826,7 +842,7 @@
protected Map<Label, EnvironmentGroup> environmentGroups = new HashMap<>();
protected Map<Label, Path> subincludes = null;
- protected ImmutableList<Label> skylarkFileDependencies = null;
+ protected ImmutableList<Label> skylarkFileDependencies = ImmutableList.of();
/**
* True iff the "package" function has already been called in this package.
@@ -942,6 +958,14 @@
}
/**
+ * Uses the workspace name from {@code //external} to set this package's workspace name.
+ */
+ B setWorkspaceName(String workspaceName) {
+ pkg.workspaceName = workspaceName;
+ return self();
+ }
+
+ /**
* Returns whether the "package" function has been called yet
*/
public boolean isPackageFunctionUsed() {
diff --git a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
index c8b6710..0cfdf0a 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
@@ -897,17 +897,18 @@
* <p>Executes {@code globber.onCompletion()} on completion and executes
* {@code globber.onInterrupt()} on an {@link InterruptedException}.
*/
- private Package.LegacyBuilder createPackage(PackageIdentifier packageId, Path buildFile,
- List<Statement> preludeStatements, ParserInputSource inputSource,
- Map<PathFragment, SkylarkEnvironment> imports, ImmutableList<Label> skylarkFileDependencies,
- CachingPackageLocator locator, RuleVisibility defaultVisibility, Globber globber)
+ private Package.LegacyBuilder createPackage(ExternalPackage externalPkg,
+ PackageIdentifier packageId, Path buildFile, List<Statement> preludeStatements,
+ ParserInputSource inputSource, Map<PathFragment, SkylarkEnvironment> imports,
+ ImmutableList<Label> skylarkFileDependencies, CachingPackageLocator locator,
+ RuleVisibility defaultVisibility, Globber globber)
throws InterruptedException {
StoredEventHandler localReporter = new StoredEventHandler();
Preprocessor.Result preprocessingResult = preprocess(packageId, buildFile, inputSource, globber,
localReporter);
- return createPackageFromPreprocessingResult(packageId, buildFile, preprocessingResult,
- localReporter.getEvents(), preludeStatements, imports, skylarkFileDependencies, locator,
- defaultVisibility, globber);
+ return createPackageFromPreprocessingResult(externalPkg, packageId, buildFile,
+ preprocessingResult, localReporter.getEvents(), preludeStatements, imports,
+ skylarkFileDependencies, locator, defaultVisibility, globber);
}
/**
@@ -918,7 +919,8 @@
* {@code globber.onInterrupt()} on an {@link InterruptedException}.
*/
// Used outside of bazel!
- public Package.LegacyBuilder createPackageFromPreprocessingResult(PackageIdentifier packageId,
+ public Package.LegacyBuilder createPackageFromPreprocessingResult(Package externalPkg,
+ PackageIdentifier packageId,
Path buildFile,
Preprocessor.Result preprocessingResult,
Iterable<Event> preprocessingEvents,
@@ -947,7 +949,7 @@
prefetchGlobs(packageId, buildFileAST, preprocessingResult.preprocessed,
buildFile, globber, defaultVisibility, makeEnv);
return evaluateBuildFile(
- packageId, buildFileAST, buildFile, globber,
+ externalPkg, packageId, buildFileAST, buildFile, globber,
Iterables.concat(preprocessingEvents, localReporter.getEvents()),
defaultVisibility, preprocessingResult.containsErrors,
preprocessingResult.containsTransientErrors, makeEnv, imports, skylarkFileDependencies);
@@ -965,9 +967,8 @@
*/
@VisibleForTesting
public Package createPackageForTesting(PackageIdentifier packageId,
- Path buildFile,
- CachingPackageLocator locator,
- EventHandler eventHandler) throws NoSuchPackageException, InterruptedException {
+ Path buildFile, CachingPackageLocator locator, EventHandler eventHandler)
+ throws NoSuchPackageException, InterruptedException {
String error = LabelValidator.validatePackageName(
packageId.getPackageFragment().getPathString());
if (error != null) {
@@ -978,11 +979,11 @@
if (inputSource == null) {
throw new BuildFileContainsErrorsException(packageId.toString(), "IOException occured");
}
- Package result = createPackage(packageId, buildFile,
- ImmutableList.<Statement>of(), inputSource,
- ImmutableMap.<PathFragment, SkylarkEnvironment>of(),
- ImmutableList.<Label>of(),
- locator, ConstantRuleVisibility.PUBLIC,
+
+ Package result = createPackage((new ExternalPackage.Builder(
+ buildFile.getRelative("WORKSPACE"))).build(), packageId, buildFile,
+ ImmutableList.<Statement>of(), inputSource, ImmutableMap.<PathFragment,
+ SkylarkEnvironment>of(), ImmutableList.<Label>of(), locator, ConstantRuleVisibility.PUBLIC,
createLegacyGlobber(buildFile.getParentDirectory(), packageId, locator)).build();
Event.replayEventsOn(eventHandler, result.getEvents());
return result;
@@ -1135,8 +1136,8 @@
* @see PackageFactory#PackageFactory
*/
@VisibleForTesting // used by PackageFactoryApparatus
- public Package.LegacyBuilder evaluateBuildFile(PackageIdentifier packageId,
- BuildFileAST buildFileAST, Path buildFilePath, Globber globber,
+ public Package.LegacyBuilder evaluateBuildFile(Package externalPkg,
+ PackageIdentifier packageId, BuildFileAST buildFileAST, Path buildFilePath, Globber globber,
Iterable<Event> pastEvents, RuleVisibility defaultVisibility, boolean containsError,
boolean containsTransientError, MakeEnvironment.Builder pkgMakeEnv,
Map<PathFragment, SkylarkEnvironment> imports,
@@ -1154,11 +1155,12 @@
// "defaultVisibility" comes from the command line. Let's give the BUILD file a chance to
// set default_visibility once, be reseting the PackageBuilder.defaultVisibilitySet flag.
.setDefaultVisibilitySet(false)
- .setSkylarkFileDependencies(skylarkFileDependencies);
+ .setSkylarkFileDependencies(skylarkFileDependencies)
+ .setWorkspaceName(externalPkg.getWorkspaceName());
Event.replayEventsOn(eventHandler, pastEvents);
- // Stuff that closes over the package context:
+ // Stuff that closes over the package context:`
PackageContext context = new PackageContext(pkgBuilder, globber, eventHandler);
buildPkgEnv(pkgEnv, packageId.toString(), pkgMakeEnv, context, ruleFactory);
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Rule.java b/src/main/java/com/google/devtools/build/lib/packages/Rule.java
index cff91f6..23ceb9f 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/Rule.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Rule.java
@@ -147,6 +147,8 @@
private final FuncallExpression ast; // may be null
+ private final String workspaceName;
+
// Initialized in the call to populateOutputFiles.
private List<OutputFile> outputFiles;
private ListMultimap<String, OutputFile> outputFileMap;
@@ -160,6 +162,7 @@
this.attributeMap = new RawAttributeMapper(pkg, ruleClass, label, attributes);
this.containsErrors = false;
this.ast = ast;
+ this.workspaceName = pkg.getWorkspaceName();
}
void setVisibility(RuleVisibility visibility) {
@@ -186,6 +189,13 @@
this.containsErrors = true;
}
+ /**
+ * Returns the name of the workspace that this rule is in.
+ */
+ public String getWorkspaceName() {
+ return workspaceName;
+ }
+
@Override
public Label getLabel() {
return attributeMap.getLabel();