aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/skyframe
diff options
context:
space:
mode:
authorGravatar kchodorow <kchodorow@google.com>2017-07-11 18:12:55 +0200
committerGravatar László Csomor <laszlocsomor@google.com>2017-07-11 18:26:24 +0200
commit937350211dcd55a4714ec32ebbf33fffcc42cdf2 (patch)
tree77f2cb3d5b6c4fe1e66691a3f0bc4041593168c4 /src/main/java/com/google/devtools/build/lib/skyframe
parenta334363a500fb9df953fe2c70184ee013ff77ccb (diff)
Resolve references to @main-repo//foo to //foo
Bazel was creating an dummy external repository for @main-repo, which doesn't work with package paths and will cause conflicts once @main-repo//foo and //foo refer to the same path. This adds a "soft pull" option to WorkspaceNameFunction: it can either parse the entire WORKSPACE file to find the name or just the first section. That way PackageLookupFunction can find the repository name without causing a circular dependency. This should have no change of behavior and is already tested in https://github.com/bazelbuild/bazel/blob/master/src/test/shell/bazel/workspace_test.sh#L176. PiperOrigin-RevId: 161536466
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/skyframe')
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java15
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceNameFunction.java39
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceNameValue.java43
3 files changed, 63 insertions, 34 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java
index c0a115ad6c..d264cea205 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java
@@ -18,6 +18,7 @@ import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelValidator;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
+import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.packages.BuildFileNotFoundException;
import com.google.devtools.build.lib.packages.ErrorDeterminingRepositoryException;
import com.google.devtools.build.lib.packages.NoSuchPackageException;
@@ -294,8 +295,20 @@ public class PackageLookupFunction implements SkyFunction {
private PackageLookupValue computeExternalPackageLookupValue(
SkyKey skyKey, Environment env, PackageIdentifier packageIdentifier)
throws PackageLookupFunctionException, InterruptedException {
+ // Check if this is the main repository.
PackageIdentifier id = (PackageIdentifier) skyKey.argument();
- SkyKey repositoryKey = RepositoryValue.key(id.getRepository());
+ RepositoryName repositoryName = id.getRepository();
+ WorkspaceNameValue workspaceNameValue = (WorkspaceNameValue)
+ env.getValue(WorkspaceNameValue.firstChunk());
+ if (workspaceNameValue == null) {
+ return null;
+ }
+ if (repositoryName.strippedName().equals(workspaceNameValue.getName())) {
+ return (PackageLookupValue) env.getValue(PackageLookupValue.key(
+ PackageIdentifier.createInMainRepo(id.getPackageFragment())));
+ }
+ // Otherwise look up the repository.
+ SkyKey repositoryKey = RepositoryValue.key(repositoryName);
RepositoryValue repositoryValue;
try {
repositoryValue = (RepositoryValue) env.getValueOrThrow(
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceNameFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceNameFunction.java
index 9284f5c2e9..4582572c4a 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceNameFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceNameFunction.java
@@ -14,9 +14,11 @@
package com.google.devtools.build.lib.skyframe;
import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.packages.BuildFileContainsErrorsException;
import com.google.devtools.build.lib.packages.NoSuchPackageException;
import com.google.devtools.build.lib.packages.Package;
+import com.google.devtools.build.lib.vfs.RootedPath;
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyFunctionException;
import com.google.devtools.build.skyframe.SkyKey;
@@ -34,18 +36,47 @@ public class WorkspaceNameFunction implements SkyFunction {
@Nullable
public SkyValue compute(SkyKey skyKey, Environment env)
throws InterruptedException, WorkspaceNameFunctionException {
- SkyKey externalPackageKey = PackageValue.key(Label.EXTERNAL_PACKAGE_IDENTIFIER);
- PackageValue externalPackageValue = (PackageValue) env.getValue(externalPackageKey);
- if (externalPackageValue == null) {
+ boolean firstChunk = (boolean) skyKey.argument();
+ Package externalPackage = firstChunk ? firstChunk(env) : parseFullPackage(env);
+ if (externalPackage == null) {
return null;
}
- Package externalPackage = externalPackageValue.getPackage();
if (externalPackage.containsErrors()) {
+ Event.replayEventsOn(env.getListener(), externalPackage.getEvents());
throw new WorkspaceNameFunctionException();
}
return WorkspaceNameValue.withName(externalPackage.getWorkspaceName());
}
+ /**
+ * This just examines the first chunk of the WORKSPACE file to avoid circular dependencies and
+ * overeager invalidation during package loading.
+ */
+ private Package firstChunk(Environment env) throws InterruptedException {
+ SkyKey packageLookupKey = PackageLookupValue.key(Label.EXTERNAL_PACKAGE_IDENTIFIER);
+ PackageLookupValue packageLookupValue = (PackageLookupValue) env.getValue(packageLookupKey);
+ if (packageLookupValue == null) {
+ return null;
+ }
+ RootedPath workspacePath = packageLookupValue.getRootedPath(Label.EXTERNAL_PACKAGE_IDENTIFIER);
+
+ SkyKey workspaceKey = WorkspaceFileValue.key(workspacePath);
+ WorkspaceFileValue value = (WorkspaceFileValue) env.getValue(workspaceKey);
+ if (value == null) {
+ return null;
+ }
+ return value.getPackage();
+ }
+
+ private Package parseFullPackage(Environment env) throws InterruptedException {
+ SkyKey externalPackageKey = PackageValue.key(Label.EXTERNAL_PACKAGE_IDENTIFIER);
+ PackageValue externalPackageValue = (PackageValue) env.getValue(externalPackageKey);
+ if (externalPackageValue == null) {
+ return null;
+ }
+ return externalPackageValue.getPackage();
+ }
+
@Override
@Nullable
public String extractTag(SkyKey skyKey) {
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceNameValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceNameValue.java
index 4da943b6ab..98fe8b2416 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceNameValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceNameValue.java
@@ -28,9 +28,6 @@ import java.util.Objects;
* the WORKSPACE file.
*/
public class WorkspaceNameValue implements SkyValue {
- private static final SkyKey KEY =
- LegacySkyKey.create(SkyFunctions.WORKSPACE_NAME, DummyArgument.INSTANCE);
-
private final String workspaceName;
private WorkspaceNameValue(String workspaceName) {
@@ -44,9 +41,21 @@ public class WorkspaceNameValue implements SkyValue {
return workspaceName;
}
- /** Returns the (singleton) {@link SkyKey} for {@link WorkspaceNameValue}s. */
+ /** Returns the {@link SkyKey} for {@link WorkspaceNameValue}s. */
public static SkyKey key() {
- return KEY;
+ return createKey(false);
+ }
+
+ /**
+ * Returns the {@link SkyKey} for a less-aggressive {@link WorkspaceNameValue} query, when
+ * we don't want to parse the whole WORKSPACE file.
+ */
+ public static SkyKey firstChunk() {
+ return createKey(true);
+ }
+
+ private static SkyKey createKey(boolean firstChunk) {
+ return LegacySkyKey.create(SkyFunctions.WORKSPACE_NAME, firstChunk);
}
/** Returns a {@link WorkspaceNameValue} for a workspace with the given name. */
@@ -72,28 +81,4 @@ public class WorkspaceNameValue implements SkyValue {
public String toString() {
return String.format("WorkspaceNameValue[name=%s]", workspaceName);
}
-
- /** Singleton class used as the {@link SkyKey#argument} for {@link WorkspaceNameValue#key}. */
- public static final class DummyArgument {
- static final int HASHCODE = DummyArgument.class.getCanonicalName().hashCode();
- public static final DummyArgument INSTANCE = new DummyArgument();
-
- private DummyArgument() {
- }
-
- @Override
- public boolean equals(Object obj) {
- return obj instanceof DummyArgument;
- }
-
- @Override
- public int hashCode() {
- return HASHCODE;
- }
-
- @Override
- public String toString() {
- return "#";
- }
- }
}