use of com.google.devtools.build.lib.vfs.RootedPath in project bazel by bazelbuild.
the class PackageFunction method compute.
@Override
public SkyValue compute(SkyKey key, Environment env) throws PackageFunctionException, InterruptedException {
PackageIdentifier packageId = (PackageIdentifier) key.argument();
SkyKey packageLookupKey = PackageLookupValue.key(packageId);
PackageLookupValue packageLookupValue;
try {
packageLookupValue = (PackageLookupValue) env.getValueOrThrow(packageLookupKey, BuildFileNotFoundException.class, InconsistentFilesystemException.class);
} catch (BuildFileNotFoundException e) {
throw new PackageFunctionException(e, Transience.PERSISTENT);
} catch (InconsistentFilesystemException e) {
// This error is not transient from the perspective of the PackageFunction.
throw new PackageFunctionException(new NoSuchPackageException(packageId, e.getMessage(), e), Transience.PERSISTENT);
}
if (packageLookupValue == null) {
return null;
}
if (!packageLookupValue.packageExists()) {
switch(packageLookupValue.getErrorReason()) {
case NO_BUILD_FILE:
case DELETED_PACKAGE:
throw new PackageFunctionException(new BuildFileNotFoundException(packageId, packageLookupValue.getErrorMsg()), Transience.PERSISTENT);
case INVALID_PACKAGE_NAME:
throw new PackageFunctionException(new InvalidPackageNameException(packageId, packageLookupValue.getErrorMsg()), Transience.PERSISTENT);
default:
// We should never get here.
throw new IllegalStateException();
}
}
if (packageId.equals(Label.EXTERNAL_PACKAGE_IDENTIFIER)) {
return getExternalPackage(env, packageLookupValue.getRoot());
}
WorkspaceNameValue workspaceNameValue = (WorkspaceNameValue) env.getValue(WorkspaceNameValue.key());
if (workspaceNameValue == null) {
return null;
}
String workspaceName = workspaceNameValue.maybeGetName();
if (workspaceName == null) {
throw new PackageFunctionException(new BuildFileContainsErrorsException(Label.EXTERNAL_PACKAGE_IDENTIFIER), Transience.PERSISTENT);
}
RootedPath buildFileRootedPath = packageLookupValue.getRootedPath(packageId);
FileValue buildFileValue = null;
Path buildFilePath = buildFileRootedPath.asPath();
String replacementContents = null;
if (!isDefaultsPackage(packageId)) {
buildFileValue = getBuildFileValue(env, buildFileRootedPath);
if (buildFileValue == null) {
return null;
}
} else {
replacementContents = PrecomputedValue.DEFAULTS_PACKAGE_CONTENTS.get(env);
if (replacementContents == null) {
return null;
}
}
RuleVisibility defaultVisibility = PrecomputedValue.DEFAULT_VISIBILITY.get(env);
if (defaultVisibility == null) {
return null;
}
SkyKey astLookupKey = ASTFileLookupValue.key(preludeLabel);
ASTFileLookupValue astLookupValue = null;
try {
astLookupValue = (ASTFileLookupValue) env.getValueOrThrow(astLookupKey, ErrorReadingSkylarkExtensionException.class, InconsistentFilesystemException.class);
} catch (ErrorReadingSkylarkExtensionException | InconsistentFilesystemException e) {
throw new PackageFunctionException(new NoSuchPackageException(packageId, "Error encountered while reading the prelude file: " + e.getMessage()), Transience.PERSISTENT);
}
if (astLookupValue == null) {
return null;
}
// The prelude file doesn't have to exist. If not, we substitute an empty statement list.
List<Statement> preludeStatements = astLookupValue.lookupSuccessful() ? astLookupValue.getAST().getStatements() : ImmutableList.<Statement>of();
CacheEntryWithGlobDeps<Package.Builder> packageBuilderAndGlobDeps = loadPackage(workspaceName, replacementContents, packageId, buildFilePath, buildFileValue, defaultVisibility, preludeStatements, packageLookupValue.getRoot(), env);
if (packageBuilderAndGlobDeps == null) {
return null;
}
Package.Builder pkgBuilder = packageBuilderAndGlobDeps.value;
pkgBuilder.buildPartial();
try {
// Since the Skyframe dependencies we request below in
// markDependenciesAndPropagateFilesystemExceptions are requested independently of
// the ones requested here in
// handleLabelsCrossingSubpackagesAndPropagateInconsistentFilesystemExceptions, we don't
// bother checking for missing values and instead piggyback on the env.missingValues() call
// for the former. This avoids a Skyframe restart.
handleLabelsCrossingSubpackagesAndPropagateInconsistentFilesystemExceptions(packageLookupValue.getRoot(), packageId, pkgBuilder, env);
} catch (InternalInconsistentFilesystemException e) {
packageFunctionCache.invalidate(packageId);
throw new PackageFunctionException(e.toNoSuchPackageException(), e.isTransient() ? Transience.TRANSIENT : Transience.PERSISTENT);
}
Set<SkyKey> globKeys = packageBuilderAndGlobDeps.globDepKeys;
Map<Label, Path> subincludes = pkgBuilder.getSubincludes();
boolean packageShouldBeConsideredInError;
try {
packageShouldBeConsideredInError = markDependenciesAndPropagateFilesystemExceptions(env, globKeys, subincludes, packageId, pkgBuilder.containsErrors());
} catch (InternalInconsistentFilesystemException e) {
packageFunctionCache.invalidate(packageId);
throw new PackageFunctionException(e.toNoSuchPackageException(), e.isTransient() ? Transience.TRANSIENT : Transience.PERSISTENT);
}
if (env.valuesMissing()) {
return null;
}
Event.replayEventsOn(env.getListener(), pkgBuilder.getEvents());
if (packageShouldBeConsideredInError) {
pkgBuilder.setContainsErrors();
}
Package pkg = pkgBuilder.finishBuild();
// We know this SkyFunction will not be called again, so we can remove the cache entry.
packageFunctionCache.invalidate(packageId);
packageFactory.afterDoneLoadingPackage(pkg);
return new PackageValue(pkg);
}
use of com.google.devtools.build.lib.vfs.RootedPath in project bazel by bazelbuild.
the class PackageLookupFunction method computeExternalPackageLookupValue.
/**
* Gets a PackageLookupValue from a different Bazel repository.
*
* <p>To do this, it looks up the "external" package and finds a path mapping for the repository
* name.
*/
private PackageLookupValue computeExternalPackageLookupValue(SkyKey skyKey, Environment env, PackageIdentifier packageIdentifier) throws PackageLookupFunctionException, InterruptedException {
PackageIdentifier id = (PackageIdentifier) skyKey.argument();
SkyKey repositoryKey = RepositoryValue.key(id.getRepository());
RepositoryValue repositoryValue;
try {
repositoryValue = (RepositoryValue) env.getValueOrThrow(repositoryKey, NoSuchPackageException.class, IOException.class, EvalException.class);
if (repositoryValue == null) {
return null;
}
} catch (NoSuchPackageException | IOException | EvalException e) {
throw new PackageLookupFunctionException(new BuildFileNotFoundException(id, e.getMessage()), Transience.PERSISTENT);
}
// This checks for the build file names in the correct precedence order.
for (BuildFileName buildFileName : buildFilesByPriority) {
PathFragment buildFileFragment = id.getPackageFragment().getChild(buildFileName.getFilename());
RootedPath buildFileRootedPath = RootedPath.toRootedPath(repositoryValue.getPath(), buildFileFragment);
FileValue fileValue = getFileValue(buildFileRootedPath, env, packageIdentifier);
if (fileValue == null) {
return null;
}
if (fileValue.isFile()) {
return PackageLookupValue.success(repositoryValue.getPath(), buildFileName);
}
}
return PackageLookupValue.NO_BUILD_FILE_VALUE;
}
use of com.google.devtools.build.lib.vfs.RootedPath in project bazel by bazelbuild.
the class PackageLookupFunction method getPackageLookupValue.
private PackageLookupValue getPackageLookupValue(Environment env, Path packagePathEntry, PackageIdentifier packageIdentifier, BuildFileName buildFileName) throws InterruptedException, PackageLookupFunctionException {
PathFragment buildFileFragment = buildFileName.getBuildFileFragment(packageIdentifier);
RootedPath buildFileRootedPath = RootedPath.toRootedPath(packagePathEntry, buildFileFragment);
if (crossRepositoryLabelViolationStrategy == CrossRepositoryLabelViolationStrategy.ERROR) {
// Is this path part of a local repository?
RootedPath currentPath = RootedPath.toRootedPath(packagePathEntry, buildFileFragment.getParentDirectory());
SkyKey repositoryLookupKey = LocalRepositoryLookupValue.key(currentPath);
// TODO(jcater): Consider parallelizing these lookups.
LocalRepositoryLookupValue localRepository;
try {
localRepository = (LocalRepositoryLookupValue) env.getValueOrThrow(repositoryLookupKey, ErrorDeterminingRepositoryException.class);
if (localRepository == null) {
return null;
}
} catch (ErrorDeterminingRepositoryException e) {
// TODO(katre): Improve the error message given here.
throw new PackageLookupFunctionException(new BuildFileNotFoundException(packageIdentifier, "Unable to determine the local repository for directory " + currentPath.asPath().getPathString()), Transience.PERSISTENT);
}
if (localRepository.exists() && !localRepository.getRepository().equals(packageIdentifier.getRepository())) {
// TODO(jcater): Work out the correct package name for this error message.
return PackageLookupValue.invalidPackageName("Package crosses into repository " + localRepository.getRepository().getName());
}
// There's no local repository, keep going.
} else {
// Future-proof against adding future values to CrossRepositoryLabelViolationStrategy.
Preconditions.checkState(crossRepositoryLabelViolationStrategy == CrossRepositoryLabelViolationStrategy.IGNORE, crossRepositoryLabelViolationStrategy);
}
// Check for the existence of the build file.
FileValue fileValue = getFileValue(buildFileRootedPath, env, packageIdentifier);
if (fileValue == null) {
return null;
}
if (fileValue.isFile()) {
return PackageLookupValue.success(buildFileRootedPath.getRoot(), buildFileName);
}
return PackageLookupValue.NO_BUILD_FILE_VALUE;
}
use of com.google.devtools.build.lib.vfs.RootedPath in project bazel by bazelbuild.
the class ActionMetadataHandler method fileValueFromArtifact.
@VisibleForTesting
static FileValue fileValueFromArtifact(Artifact artifact, @Nullable FileStatusWithDigest statNoFollow, @Nullable TimestampGranularityMonitor tsgm) throws IOException {
Path path = artifact.getPath();
RootedPath rootedPath = RootedPath.toRootedPath(artifact.getRoot().getPath(), artifact.getRootRelativePath());
if (statNoFollow == null) {
statNoFollow = FileStatusWithDigestAdapter.adapt(path.statIfFound(Symlinks.NOFOLLOW));
if (statNoFollow == null) {
return FileValue.value(rootedPath, FileStateValue.NONEXISTENT_FILE_STATE_NODE, rootedPath, FileStateValue.NONEXISTENT_FILE_STATE_NODE);
}
}
Path realPath = path;
// done by the latter.
if (statNoFollow.isSymbolicLink()) {
realPath = path.resolveSymbolicLinks();
// file that's not in a symlink cycle.
if (realPath.equals(path)) {
throw new IOException("symlink cycle");
}
}
RootedPath realRootedPath = RootedPath.toRootedPathMaybeUnderRoot(realPath, ImmutableList.of(artifact.getRoot().getPath()));
FileStateValue fileStateValue;
FileStateValue realFileStateValue;
try {
fileStateValue = FileStateValue.createWithStatNoFollow(rootedPath, statNoFollow, tsgm);
// TODO(bazel-team): consider avoiding a 'stat' here when the symlink target hasn't changed
// and is a source file (since changes to those are checked separately).
realFileStateValue = realPath.equals(path) ? fileStateValue : FileStateValue.create(realRootedPath, tsgm);
} catch (InconsistentFilesystemException e) {
throw new IOException(e);
}
return FileValue.value(rootedPath, fileStateValue, realRootedPath, realFileStateValue);
}
use of com.google.devtools.build.lib.vfs.RootedPath in project bazel by bazelbuild.
the class ProcessPackageDirectory method getSubdirDeps.
private Iterable<SkyKey> getSubdirDeps(DirectoryListingValue dirListingValue, RootedPath rootedPath, RepositoryName repositoryName, Set<PathFragment> excludedPaths) {
Path root = rootedPath.getRoot();
PathFragment rootRelativePath = rootedPath.getRelativePath();
boolean followSymlinks = shouldFollowSymlinksWhenTraversing(dirListingValue.getDirents());
List<SkyKey> childDeps = new ArrayList<>();
for (Dirent dirent : dirListingValue.getDirents()) {
Type type = dirent.getType();
if (type != Type.DIRECTORY && (type != Type.SYMLINK || !followSymlinks)) {
// rise to infinite directory trees are diagnosed by FileValue.
continue;
}
String basename = dirent.getName();
if (rootRelativePath.equals(PathFragment.EMPTY_FRAGMENT) && PathPackageLocator.DEFAULT_TOP_LEVEL_EXCLUDES.contains(basename)) {
continue;
}
PathFragment subdirectory = rootRelativePath.getRelative(basename);
// If this subdirectory is one of the excluded paths, don't recurse into it.
if (excludedPaths.contains(subdirectory)) {
continue;
}
// If we have an excluded path that isn't below this subdirectory, we shouldn't pass that
// excluded path to our evaluation of the subdirectory, because the exclusion can't
// possibly match anything beneath the subdirectory.
//
// For example, if we're currently evaluating directory "a", are looking at its subdirectory
// "a/b", and we have an excluded path "a/c/d", there's no need to pass the excluded path
// "a/c/d" to our evaluation of "a/b".
//
// This strategy should help to get more skyframe sharing. Consider the example above. A
// subsequent request of "a/b/...", without any excluded paths, will be a cache hit.
//
// TODO(bazel-team): Replace the excludedPaths set with a trie or a SortedSet for better
// efficiency.
ImmutableSet<PathFragment> excludedSubdirectoriesBeneathThisSubdirectory = PathFragment.filterPathsStartingWith(excludedPaths, subdirectory);
RootedPath subdirectoryRootedPath = RootedPath.toRootedPath(root, subdirectory);
childDeps.add(skyKeyTransformer.makeSkyKey(repositoryName, subdirectoryRootedPath, excludedSubdirectoriesBeneathThisSubdirectory));
}
return childDeps;
}
Aggregations