aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Kristina Chodorow <kchodorow@google.com>2016-01-29 15:04:31 +0000
committerGravatar Kristina Chodorow <kchodorow@google.com>2016-01-29 15:36:36 +0000
commit734e7f7b63c9c00a6aaa60769481a11bc4f76346 (patch)
treed51ce64080b580a98540ef7fd16b5ec5369d9e22 /src
parentf9f2e10dcbbf0efade6a9c9cf21dd3dde8e55f6b (diff)
Parse the workspace name when a repository is loaded
Moved RepositoryValue to RepositoryDirectoryValue so that it could be cached (and not re-downloaded) even if the WorkspaceAST caused a Skyframe restart (as mentioned in https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java#L130-L133). -- MOS_MIGRATED_REVID=113358489
Diffstat (limited to 'src')
-rwxr-xr-xsrc/create_embedded_tools.sh4
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java19
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/GitRepositoryFunction.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/HttpArchiveFunction.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/MavenJarFunction.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/Package.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/pkgcache/PathPackageLocator.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/repository/LocalRepositoryFunction.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDirectoryValue.java94
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java19
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryLoaderFunction.java83
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/EnvironmentBackedRecursivePackageProvider.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/GraphBackedRecursivePackageProvider.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternFunction.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/RepositoryValue.java65
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceASTValue.java2
-rw-r--r--src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java1
-rw-r--r--src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisMock.java7
20 files changed, 250 insertions, 87 deletions
diff --git a/src/create_embedded_tools.sh b/src/create_embedded_tools.sh
index dfd34193e1..6f296f6e76 100755
--- a/src/create_embedded_tools.sh
+++ b/src/create_embedded_tools.sh
@@ -44,7 +44,9 @@ for i in $*; do
cp "$i" "${PACKAGE_DIR}/${OUTPUT_PATH}"
done
-touch "${PACKAGE_DIR}/WORKSPACE"
+cat > "${PACKAGE_DIR}/WORKSPACE" <<EOF
+workspace(name = "bazel_tools")
+EOF
mkdir -p "${PACKAGE_DIR}/tools/defaults"
touch "${PACKAGE_DIR}/tools/defaults/BUILD"
for i in $(find "${PACKAGE_DIR}" -name BUILD.tools); do
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java b/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java
index 9c83d70c89..0befcba0e8 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java
@@ -48,10 +48,11 @@ import com.google.devtools.build.lib.rules.repository.LocalRepositoryRule;
import com.google.devtools.build.lib.rules.repository.NewLocalRepositoryFunction;
import com.google.devtools.build.lib.rules.repository.NewLocalRepositoryRule;
import com.google.devtools.build.lib.rules.repository.RepositoryDelegatorFunction;
+import com.google.devtools.build.lib.rules.repository.RepositoryDirectoryValue;
import com.google.devtools.build.lib.rules.repository.RepositoryFunction;
+import com.google.devtools.build.lib.rules.repository.RepositoryLoaderFunction;
import com.google.devtools.build.lib.runtime.BlazeCommand;
import com.google.devtools.build.lib.runtime.BlazeModule;
-import com.google.devtools.build.lib.skyframe.RepositoryValue;
import com.google.devtools.build.lib.skyframe.SkyFunctions;
import com.google.devtools.build.lib.skyframe.SkyValueDirtinessChecker;
import com.google.devtools.build.lib.util.Clock;
@@ -105,8 +106,9 @@ public class BazelRepositoryModule extends BlazeModule {
}
/**
- * A dirtiness checker that always dirties {@link RepositoryValue}s so that if they were produced
- * in a {@code --nofetch} build, they are re-created no subsequent {@code --fetch} builds.
+ * A dirtiness checker that always dirties {@link RepositoryDirectoryValue}s so that if they were
+ * produced in a {@code --nofetch} build, they are re-created no subsequent {@code --fetch}
+ * builds.
*
* <p>The alternative solution would be to reify the value of the flag as a Skyframe value.
*/
@@ -114,7 +116,7 @@ public class BazelRepositoryModule extends BlazeModule {
new SkyValueDirtinessChecker() {
@Override
public boolean applies(SkyKey skyKey) {
- return skyKey.functionName().equals(SkyFunctions.REPOSITORY);
+ return skyKey.functionName().equals(SkyFunctions.REPOSITORY_DIRECTORY);
}
@Override
@@ -125,7 +127,7 @@ public class BazelRepositoryModule extends BlazeModule {
@Override
public DirtyResult check(
SkyKey skyKey, SkyValue skyValue, @Nullable TimestampGranularityMonitor tsgm) {
- RepositoryValue repositoryValue = (RepositoryValue) skyValue;
+ RepositoryDirectoryValue repositoryValue = (RepositoryDirectoryValue) skyValue;
return repositoryValue.isFetchingDelayed()
? DirtyResult.dirty(skyValue)
: DirtyResult.notDirty(skyValue);
@@ -166,11 +168,12 @@ public class BazelRepositoryModule extends BlazeModule {
public ImmutableMap<SkyFunctionName, SkyFunction> getSkyFunctions(BlazeDirectories directories) {
ImmutableMap.Builder<SkyFunctionName, SkyFunction> builder = ImmutableMap.builder();
- // Create the delegator everything flows through.
- builder.put(SkyFunctions.REPOSITORY,
- new RepositoryDelegatorFunction(directories, repositoryHandlers, isFetch));
+ // Create the repository function everything flows through.
+ builder.put(SkyFunctions.REPOSITORY, new RepositoryLoaderFunction());
// Helper SkyFunctions.
+ builder.put(SkyFunctions.REPOSITORY_DIRECTORY,
+ new RepositoryDelegatorFunction(directories, repositoryHandlers, isFetch));
builder.put(MavenServerFunction.NAME, new MavenServerFunction(directories));
return builder.build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/GitRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/GitRepositoryFunction.java
index 66ef6bcb14..7ba85c6a40 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/GitRepositoryFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/GitRepositoryFunction.java
@@ -17,8 +17,8 @@ package com.google.devtools.build.lib.bazel.repository;
import com.google.devtools.build.lib.analysis.RuleDefinition;
import com.google.devtools.build.lib.bazel.rules.workspace.GitRepositoryRule;
import com.google.devtools.build.lib.packages.Rule;
+import com.google.devtools.build.lib.rules.repository.RepositoryDirectoryValue;
import com.google.devtools.build.lib.rules.repository.RepositoryFunction;
-import com.google.devtools.build.lib.skyframe.RepositoryValue;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.skyframe.SkyFunction.Environment;
@@ -42,7 +42,7 @@ public class GitRepositoryFunction extends RepositoryFunction {
throws SkyFunctionException {
createDirectory(outputDirectory, rule);
GitCloner.clone(rule, outputDirectory, env.getListener());
- return RepositoryValue.create(outputDirectory);
+ return RepositoryDirectoryValue.create(outputDirectory);
}
protected void createDirectory(Path path, Rule rule)
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/HttpArchiveFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/HttpArchiveFunction.java
index 5f5628aa3b..5158bc6212 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/HttpArchiveFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/HttpArchiveFunction.java
@@ -18,8 +18,8 @@ import com.google.devtools.build.lib.analysis.RuleDefinition;
import com.google.devtools.build.lib.bazel.rules.workspace.HttpArchiveRule;
import com.google.devtools.build.lib.packages.AggregatingAttributeMapper;
import com.google.devtools.build.lib.packages.Rule;
+import com.google.devtools.build.lib.rules.repository.RepositoryDirectoryValue;
import com.google.devtools.build.lib.rules.repository.RepositoryFunction;
-import com.google.devtools.build.lib.skyframe.RepositoryValue;
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
@@ -61,7 +61,7 @@ public class HttpArchiveFunction extends RepositoryFunction {
Path downloadedPath = HttpDownloader.download(rule, outputDirectory, env.getListener());
DecompressorValue.decompress(getDescriptor(rule, downloadedPath, outputDirectory));
- return RepositoryValue.create(outputDirectory);
+ return RepositoryDirectoryValue.create(outputDirectory);
}
protected DecompressorDescriptor getDescriptor(Rule rule, Path downloadPath, Path outputDirectory)
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 83a7ed1b77..1bbe61ffa2 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
@@ -26,8 +26,8 @@ import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.packages.AggregatingAttributeMapper;
import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.Rule;
+import com.google.devtools.build.lib.rules.repository.RepositoryDirectoryValue;
import com.google.devtools.build.lib.rules.repository.RepositoryFunction;
-import com.google.devtools.build.lib.skyframe.RepositoryValue;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.util.Fingerprint;
@@ -142,7 +142,7 @@ public class MavenJarFunction extends HttpArchiveFunction {
.setTargetName(downloader.getName())
.setArchivePath(repositoryJar)
.setRepositoryPath(outputDirectory).build());
- return RepositoryValue.create(result);
+ return RepositoryDirectoryValue.create(result);
}
/**
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 1cfb443936..c861bfe4f2 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
@@ -484,7 +484,7 @@ public class Package {
* <p>Package-private to encourage callers to get their workspace name from a rule, not a
* package.</p>
*/
- String getWorkspaceName() {
+ public String getWorkspaceName() {
return workspaceName;
}
diff --git a/src/main/java/com/google/devtools/build/lib/pkgcache/PathPackageLocator.java b/src/main/java/com/google/devtools/build/lib/pkgcache/PathPackageLocator.java
index f14b954978..93a5e01357 100644
--- a/src/main/java/com/google/devtools/build/lib/pkgcache/PathPackageLocator.java
+++ b/src/main/java/com/google/devtools/build/lib/pkgcache/PathPackageLocator.java
@@ -105,8 +105,8 @@ public class PathPackageLocator implements Serializable {
"External package '%s' needs to be loaded but this PathPackageLocator instance does not "
+ "support external packages", packageIdentifier));
// This works only to some degree, because it relies on the presence of the repository under
- // $OUTPUT_BASE/external, which is created by the appropriate RepositoryValue. This is true
- // for the invocation in GlobCache, but not for the locator.getBuildFileForPackage()
+ // $OUTPUT_BASE/external, which is created by the appropriate RepositoryDirectoryValue. This
+ // is true for the invocation in GlobCache, but not for the locator.getBuildFileForPackage()
// invocation in Parser#include().
Path buildFile = outputBase.getRelative(
packageIdentifier.getPathFragment()).getRelative("BUILD");
diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/LocalRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/LocalRepositoryFunction.java
index 400783e1b4..d37204379e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/repository/LocalRepositoryFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/repository/LocalRepositoryFunction.java
@@ -18,7 +18,6 @@ import com.google.devtools.build.lib.analysis.RuleDefinition;
import com.google.devtools.build.lib.packages.AggregatingAttributeMapper;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.skyframe.FileValue;
-import com.google.devtools.build.lib.skyframe.RepositoryValue;
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.vfs.FileSystem;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
@@ -71,7 +70,7 @@ public class LocalRepositoryFunction extends RepositoryFunction {
new IOException(rule + " must specify an existing directory"), Transience.TRANSIENT);
}
- return RepositoryValue.create(outputDirectory);
+ return RepositoryDirectoryValue.create(outputDirectory);
}
@Override
diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java
index 903fc63eb2..e83433b082 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java
@@ -22,7 +22,6 @@ import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.rules.repository.RepositoryFunction.RepositoryFunctionException;
import com.google.devtools.build.lib.skyframe.FileValue;
-import com.google.devtools.build.lib.skyframe.RepositoryValue;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
@@ -116,7 +115,7 @@ public class RepositoryDelegatorFunction implements SkyFunction {
// NB: This returns the wrong repository value for non-local new_* repository functions.
// This should sort itself out automatically once the ExternalFilesHelper refactoring is
// finally submitted.
- return RepositoryValue.create(repoRootValue.realRootedPath().asPath());
+ return RepositoryDirectoryValue.create(repoRootValue.realRootedPath().asPath());
}
if (isFetch.get()) {
@@ -156,7 +155,7 @@ public class RepositoryDelegatorFunction implements SkyFunction {
+ "run the build without the '--nofetch' command line option.",
rule.getName())));
- return RepositoryValue.fetchingDelayed(repoRootValue.realRootedPath().asPath());
+ return RepositoryDirectoryValue.fetchingDelayed(repoRootValue.realRootedPath().asPath());
}
@Override
diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDirectoryValue.java b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDirectoryValue.java
new file mode 100644
index 0000000000..6b43297e58
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDirectoryValue.java
@@ -0,0 +1,94 @@
+// Copyright 2014 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.lib.rules.repository;
+
+import com.google.common.base.Objects;
+import com.google.devtools.build.lib.cmdline.RepositoryName;
+import com.google.devtools.build.lib.skyframe.SkyFunctions;
+import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.build.skyframe.SkyKey;
+import com.google.devtools.build.skyframe.SkyValue;
+
+/**
+ * A local view of an external repository.
+ */
+public class RepositoryDirectoryValue implements SkyValue {
+ private final Path path;
+ private final boolean fetchingDelayed;
+
+ private RepositoryDirectoryValue(Path path, boolean fetchingDelayed) {
+ this.path = path;
+ this.fetchingDelayed = fetchingDelayed;
+ }
+
+ /**
+ * Creates an immutable external repository.
+ */
+ public static RepositoryDirectoryValue create(Path repositoryDirectory) {
+ return new RepositoryDirectoryValue(repositoryDirectory, false);
+ }
+
+ /**
+ * Creates a value that represents a repository whose fetching has been delayed by a
+ * {@code --nofetch} command line option.
+ */
+ public static RepositoryDirectoryValue fetchingDelayed(Path repositoryDirectory) {
+ return new RepositoryDirectoryValue(repositoryDirectory, true);
+ }
+
+ /**
+ * Returns the path to the directory containing the repository's contents. This directory is
+ * guaranteed to exist. It may contain a full Bazel repository (with a WORKSPACE file,
+ * directories, and BUILD files) or simply contain a file (or set of files) for, say, a jar from
+ * Maven.
+ */
+ public Path getPath() {
+ return path;
+ }
+
+ public boolean isFetchingDelayed() {
+ return fetchingDelayed;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+
+ if (other instanceof RepositoryDirectoryValue) {
+ RepositoryDirectoryValue otherValue = (RepositoryDirectoryValue) other;
+ return path.equals(otherValue.path);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(path);
+ }
+
+ @Override
+ public String toString() {
+ return path.getPathString();
+ }
+
+ /**
+ * Creates a key from the given repository name.
+ */
+ public static SkyKey key(RepositoryName repository) {
+ return new SkyKey(SkyFunctions.REPOSITORY_DIRECTORY, repository);
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java
index f5fdd79e5e..fbf079c85b 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java
@@ -32,7 +32,6 @@ import com.google.devtools.build.lib.skyframe.FileSymlinkException;
import com.google.devtools.build.lib.skyframe.FileValue;
import com.google.devtools.build.lib.skyframe.InconsistentFilesystemException;
import com.google.devtools.build.lib.skyframe.PackageValue;
-import com.google.devtools.build.lib.skyframe.RepositoryValue;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.util.Fingerprint;
@@ -77,11 +76,11 @@ import javax.annotation.Nullable;
* repository has never been fetched, Bazel errors out for lack of a better option. This is
* implemented using
* {@link com.google.devtools.build.lib.bazel.BazelRepositoryModule#REPOSITORY_VALUE_CHECKER} and
- * a flag in {@link RepositoryValue} that tells Bazel whether the value in Skyframe is stale
- * according to the value of {@code --nofetch} or not.
+ * a flag in {@link RepositoryDirectoryValue} that tells Bazel whether the value in Skyframe is
+ * stale according to the value of {@code --nofetch} or not.
*
- * <p>When a rule in the WORKSPACE file is changed, the corresponding {@link RepositoryValue} is
- * invalidated using the usual Skyframe route.
+ * <p>When a rule in the WORKSPACE file is changed, the corresponding
+ * {@link RepositoryDirectoryValue} is invalidated using the usual Skyframe route.
*/
public abstract class RepositoryFunction {
/**
@@ -244,7 +243,7 @@ public abstract class RepositoryFunction {
}
}
- protected RepositoryValue writeBuildFile(Path repositoryDirectory, String contents)
+ protected RepositoryDirectoryValue writeBuildFile(Path repositoryDirectory, String contents)
throws RepositoryFunctionException {
Path buildFilePath = repositoryDirectory.getRelative("BUILD");
try {
@@ -253,7 +252,7 @@ public abstract class RepositoryFunction {
throw new RepositoryFunctionException(e, Transience.TRANSIENT);
}
- return RepositoryValue.create(repositoryDirectory);
+ return RepositoryDirectoryValue.create(repositoryDirectory);
}
protected FileValue getBuildFileValue(Rule rule, Environment env)
@@ -307,11 +306,11 @@ public abstract class RepositoryFunction {
* @throws RepositoryFunctionException if the BUILD file specified does not exist or cannot be
* linked.
*/
- protected RepositoryValue symlinkBuildFile(FileValue buildFileValue, Path outputDirectory)
- throws RepositoryFunctionException {
+ protected RepositoryDirectoryValue symlinkBuildFile(
+ FileValue buildFileValue, Path outputDirectory) throws RepositoryFunctionException {
Path buildFilePath = outputDirectory.getRelative("BUILD");
createSymbolicLink(buildFilePath, buildFileValue.realRootedPath().asPath());
- return RepositoryValue.create(outputDirectory);
+ return RepositoryDirectoryValue.create(outputDirectory);
}
@VisibleForTesting
diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryLoaderFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryLoaderFunction.java
new file mode 100644
index 0000000000..2753346aac
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryLoaderFunction.java
@@ -0,0 +1,83 @@
+// Copyright 2016 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.lib.rules.repository;
+
+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.Location;
+import com.google.devtools.build.lib.skyframe.PackageValue;
+import com.google.devtools.build.lib.skyframe.RepositoryValue;
+import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.build.lib.vfs.PathFragment;
+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;
+import com.google.devtools.build.skyframe.SkyValue;
+
+import javax.annotation.Nullable;
+
+/**
+ * Creates a local or remote repository and checks its WORKSPACE file.
+ */
+public class RepositoryLoaderFunction implements SkyFunction {
+ @Nullable
+ @Override
+ public SkyValue compute(SkyKey skyKey, Environment env)
+ throws SkyFunctionException, InterruptedException {
+ // This cannot be combined with {@link RepositoryDelegatorFunction}. RDF fetches the
+ // repository and must not have a Skyframe restart after writing it (otherwise the repository
+ // would be re-downloaded).
+ RepositoryName nameFromRule = (RepositoryName) skyKey.argument();
+ SkyKey repositoryKey = RepositoryDirectoryValue.key(nameFromRule);
+ RepositoryDirectoryValue repository = (RepositoryDirectoryValue) env.getValue(repositoryKey);
+ if (repository == null) {
+ return null;
+ }
+
+ SkyKey workspaceKey = PackageValue.workspaceKey(
+ RootedPath.toRootedPath(repository.getPath(), new PathFragment("WORKSPACE")));
+ PackageValue workspacePackage = (PackageValue) env.getValue(workspaceKey);
+ if (workspacePackage == null) {
+ return null;
+ }
+
+ RepositoryName workspaceName;
+ try {
+ String workspaceNameStr = workspacePackage.getPackage().getWorkspaceName();
+ workspaceName = workspaceNameStr.isEmpty()
+ ? RepositoryName.create("") : RepositoryName.create("@" + workspaceNameStr);
+ } catch (LabelSyntaxException e) {
+ throw new IllegalStateException(e);
+ }
+
+ if (!workspaceName.isDefault() && !nameFromRule.equals(workspaceName)) {
+ Path workspacePath = repository.getPath().getRelative("WORKSPACE");
+ env.getListener().handle(Event.warn(Location.fromFile(workspacePath),
+ "Workspace name in " + workspacePath + " (" + workspaceName + ") does not match name "
+ + " given in the repository's definition (" + nameFromRule + "), this will cause "
+ + " a build error in future versions."));
+ }
+
+ return new RepositoryValue(nameFromRule, repository);
+ }
+
+ @Nullable
+ @Override
+ public String extractTag(SkyKey skyKey) {
+ return null;
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/EnvironmentBackedRecursivePackageProvider.java b/src/main/java/com/google/devtools/build/lib/skyframe/EnvironmentBackedRecursivePackageProvider.java
index a388389141..8045c59c96 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/EnvironmentBackedRecursivePackageProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/EnvironmentBackedRecursivePackageProvider.java
@@ -29,6 +29,7 @@ import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.pkgcache.PathPackageLocator;
import com.google.devtools.build.lib.pkgcache.RecursivePackageProvider;
+import com.google.devtools.build.lib.rules.repository.RepositoryDirectoryValue;
import com.google.devtools.build.lib.util.Preconditions;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
@@ -122,8 +123,8 @@ public final class EnvironmentBackedRecursivePackageProvider implements Recursiv
if (repository.isDefault()) {
roots.addAll(packageLocator.getPathEntries());
} else {
- RepositoryValue repositoryValue =
- (RepositoryValue) env.getValue(RepositoryValue.key(repository));
+ RepositoryDirectoryValue repositoryValue =
+ (RepositoryDirectoryValue) env.getValue(RepositoryDirectoryValue.key(repository));
if (repositoryValue == null) {
throw new MissingDepException();
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/GraphBackedRecursivePackageProvider.java b/src/main/java/com/google/devtools/build/lib/skyframe/GraphBackedRecursivePackageProvider.java
index 60221ad319..8c0e56cf0e 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/GraphBackedRecursivePackageProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/GraphBackedRecursivePackageProvider.java
@@ -37,6 +37,7 @@ import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.pkgcache.PathPackageLocator;
import com.google.devtools.build.lib.pkgcache.RecursivePackageProvider;
+import com.google.devtools.build.lib.rules.repository.RepositoryDirectoryValue;
import com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternKey;
import com.google.devtools.build.lib.util.Preconditions;
import com.google.devtools.build.lib.vfs.Path;
@@ -172,8 +173,8 @@ public final class GraphBackedRecursivePackageProvider implements RecursivePacka
if (repository.isDefault()) {
roots.addAll(pkgPath.getPathEntries());
} else {
- RepositoryValue repositoryValue =
- (RepositoryValue) graph.getValue(RepositoryValue.key(repository));
+ RepositoryDirectoryValue repositoryValue =
+ (RepositoryDirectoryValue) graph.getValue(RepositoryDirectoryValue.key(repository));
if (repositoryValue == null) {
// If this key doesn't exist, the repository is outside the universe, so we return
// "nothing".
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternFunction.java
index 781c0015df..2261b77878 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternFunction.java
@@ -32,6 +32,7 @@ import com.google.devtools.build.lib.pkgcache.FilteringPolicies;
import com.google.devtools.build.lib.pkgcache.FilteringPolicy;
import com.google.devtools.build.lib.pkgcache.PathPackageLocator;
import com.google.devtools.build.lib.pkgcache.TargetPatternResolverUtil;
+import com.google.devtools.build.lib.rules.repository.RepositoryDirectoryValue;
import com.google.devtools.build.lib.skyframe.EnvironmentBackedRecursivePackageProvider.MissingDepException;
import com.google.devtools.build.lib.util.BatchCallback;
import com.google.devtools.build.lib.util.BatchCallback.NullCallback;
@@ -225,8 +226,8 @@ public class PrepareDepsOfPatternFunction implements SkyFunction {
if (repository.isDefault()) {
roots.addAll(pkgPath.getPathEntries());
} else {
- RepositoryValue repositoryValue =
- (RepositoryValue) env.getValue(RepositoryValue.key(repository));
+ RepositoryDirectoryValue repositoryValue =
+ (RepositoryDirectoryValue) env.getValue(RepositoryDirectoryValue.key(repository));
if (repositoryValue == null) {
throw new MissingDepException();
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/RepositoryValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/RepositoryValue.java
index e647b817b2..2f8da11aa2 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/RepositoryValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/RepositoryValue.java
@@ -1,4 +1,4 @@
-// Copyright 2014 The Bazel Authors. All rights reserved.
+// Copyright 2016 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.
@@ -16,49 +16,31 @@ package com.google.devtools.build.lib.skyframe;
import com.google.common.base.Objects;
import com.google.devtools.build.lib.cmdline.RepositoryName;
+import com.google.devtools.build.lib.rules.repository.RepositoryDirectoryValue;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
/**
- * A local view of an external repository.
+ * A repository's name and directory.
*/
public class RepositoryValue implements SkyValue {
- private final Path path;
- private final boolean fetchingDelayed;
-
- private RepositoryValue(Path path, boolean fetchingDelayed) {
- this.path = path;
- this.fetchingDelayed = fetchingDelayed;
- }
-
- /**
- * Creates an immutable external repository.
- */
- public static RepositoryValue create(Path repositoryDirectory) {
- return new RepositoryValue(repositoryDirectory, false);
- }
+ private final RepositoryName repositoryName;
+ private final RepositoryDirectoryValue repositoryDirectory;
/**
- * Creates a value that represents a repository whose fetching has been delayed by a
- * {@code --nofetch} command line option.
+ * Creates a repository with a given name in a certain directory.
*/
- public static RepositoryValue fetchingDelayed(Path repositoryDirectory) {
- return new RepositoryValue(repositoryDirectory, true);
+ public RepositoryValue(RepositoryName repositoryName, RepositoryDirectoryValue repository) {
+ this.repositoryName = repositoryName;
+ this.repositoryDirectory = repository;
}
/**
- * Returns the path to the directory containing the repository's contents. This directory is
- * guaranteed to exist. It may contain a full Bazel repository (with a WORKSPACE file,
- * directories, and BUILD files) or simply contain a file (or set of files) for, say, a jar from
- * Maven.
+ * Returns the path to the repository.
*/
public Path getPath() {
- return path;
- }
-
- public boolean isFetchingDelayed() {
- return fetchingDelayed;
+ return repositoryDirectory.getPath();
}
@Override
@@ -66,28 +48,21 @@ public class RepositoryValue implements SkyValue {
if (this == other) {
return true;
}
-
- if (other instanceof RepositoryValue) {
- RepositoryValue otherValue = (RepositoryValue) other;
- return path.equals(otherValue.path);
+ if (other == null || getClass() != other.getClass()) {
+ return false;
}
- return false;
- }
- @Override
- public int hashCode() {
- return Objects.hashCode(path);
+ RepositoryValue that = (RepositoryValue) other;
+ return Objects.equal(repositoryName, that.repositoryName)
+ && Objects.equal(repositoryDirectory, that.repositoryDirectory);
}
@Override
- public String toString() {
- return path.getPathString();
+ public int hashCode() {
+ return Objects.hashCode(repositoryName, repositoryDirectory);
}
- /**
- * Creates a key from the given repository name.
- */
- public static SkyKey key(RepositoryName repository) {
- return new SkyKey(SkyFunctions.REPOSITORY, repository);
+ static SkyKey key(RepositoryName repositoryName) {
+ return new SkyKey(SkyFunctions.REPOSITORY, repositoryName);
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java
index 277b627c9f..ed3508f060 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java
@@ -96,6 +96,8 @@ public final class SkyFunctions {
public static final SkyFunctionName WORKSPACE_FILE = SkyFunctionName.create("WORKSPACE_FILE");
public static final SkyFunctionName COVERAGE_REPORT = SkyFunctionName.create("COVERAGE_REPORT");
public static final SkyFunctionName REPOSITORY = SkyFunctionName.create("REPOSITORY");
+ public static final SkyFunctionName REPOSITORY_DIRECTORY =
+ SkyFunctionName.create("REPOSITORY_DIRECTORY");
public static final SkyFunctionName WORKSPACE_AST = SkyFunctionName.create("WORKSPACE_AST");
public static Predicate<SkyKey> isSkyFunction(final SkyFunctionName functionName) {
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceASTValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceASTValue.java
index 022541d04f..96f42dfa71 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceASTValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceASTValue.java
@@ -35,7 +35,7 @@ public class WorkspaceASTValue implements SkyValue {
return ast;
}
- public SkyKey key(RootedPath path) {
+ public static SkyKey key(RootedPath path) {
return new SkyKey(SkyFunctions.WORKSPACE_AST, path);
}
}
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java b/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java
index 2d7a0ad293..c1da7d3361 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java
@@ -75,6 +75,7 @@ public final class BazelAnalysisMock extends AnalysisMock {
"bind(name = 'tools/python', actual='//tools/python')"));
config.overwrite("WORKSPACE", workspaceContents.toArray(new String[workspaceContents.size()]));
+ config.create("/bazel_tools_workspace/WORKSPACE", "workspace(name = 'bazel_tools')");
config.create(
"/bazel_tools_workspace/tools/jdk/BUILD",
"package(default_visibility=['//visibility:public'])",
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisMock.java b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisMock.java
index b42b4aae23..2d7c39078a 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisMock.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisMock.java
@@ -23,6 +23,7 @@ import com.google.devtools.build.lib.rules.repository.LocalRepositoryFunction;
import com.google.devtools.build.lib.rules.repository.LocalRepositoryRule;
import com.google.devtools.build.lib.rules.repository.RepositoryDelegatorFunction;
import com.google.devtools.build.lib.rules.repository.RepositoryFunction;
+import com.google.devtools.build.lib.rules.repository.RepositoryLoaderFunction;
import com.google.devtools.build.lib.skyframe.SkyFunctions;
import com.google.devtools.build.lib.testutil.TestConstants;
import com.google.devtools.build.lib.vfs.Path;
@@ -80,9 +81,11 @@ public abstract class AnalysisMock {
ImmutableMap<String, RepositoryFunction> repositoryHandlers = ImmutableMap.of(
LocalRepositoryRule.NAME, localRepositoryFunction);
- return ImmutableMap.<SkyFunctionName, SkyFunction>of(
+ return ImmutableMap.of(
+ SkyFunctions.REPOSITORY_DIRECTORY,
+ new RepositoryDelegatorFunction(directories, repositoryHandlers, new AtomicBoolean(true)),
SkyFunctions.REPOSITORY,
- new RepositoryDelegatorFunction(directories, repositoryHandlers, new AtomicBoolean(true)));
+ new RepositoryLoaderFunction());
}
public static class Delegate extends AnalysisMock {