static FileStateValue create(RootedPath rootedPath, @Nullable TimestampGranularityMonitor tsgm) throws InconsistentFilesystemException, IOException { Path path = rootedPath.asPath(); // Stat, but don't throw an exception for the common case of a nonexistent file. This still // throws an IOException in case any other IO error is encountered. FileStatus stat = path.statIfFound(Symlinks.NOFOLLOW); if (stat == null) { return NONEXISTENT_FILE_STATE_NODE; } return createWithStatNoFollow(rootedPath, FileStatusWithDigestAdapter.adapt(stat), tsgm); }
static FileStateValue createWithStatNoFollow( RootedPath rootedPath, FileStatusWithDigest statNoFollow, @Nullable TimestampGranularityMonitor tsgm) throws InconsistentFilesystemException, IOException { Path path = rootedPath.asPath(); if (statNoFollow.isFile()) { return statNoFollow.isSpecialFile() ? SpecialFileStateValue.fromStat(statNoFollow, tsgm) : RegularFileStateValue.fromPath(path, statNoFollow, tsgm); } else if (statNoFollow.isDirectory()) { return DIRECTORY_FILE_STATE_NODE; } else if (statNoFollow.isSymbolicLink()) { return new SymlinkFileStateValue(path.readSymbolicLinkUnchecked()); } throw new InconsistentFilesystemException( "according to stat, existing path " + path + " is " + "neither a file nor directory nor symlink."); }
/** * If this instance is configured with DEPEND_ON_EXTERNAL_PKG and rootedPath is a file that isn't * under a package root then this adds a dependency on the //external package. If the action is * ERROR_OUT, it will throw an error instead. */ public void maybeHandleExternalFile(RootedPath rootedPath, SkyFunction.Environment env) throws FileOutsidePackageRootsException { if (isInternal(rootedPath, pkgLocator.get())) { return; } externalFileSeen = true; if (externalFileAction == ExternalFileAction.ERROR_OUT) { throw new FileOutsidePackageRootsException(rootedPath); } // The outputBase may be null if we're not actually running a build. Path outputBase = pkgLocator.get().getOutputBase(); if (outputBase != null && !rootedPath .asPath() .startsWith(pkgLocator.get().getOutputBase().getRelative(Label.EXTERNAL_PATH_PREFIX))) { return; } // For files that are under $OUTPUT_BASE/external, add a dependency on the //external package // so that if the WORKSPACE file changes, the File/DirectoryStateValue will be re-evaluated. // // Note that: // - We don't add a dependency on the parent directory at the package root boundary, so // the only transitive dependencies from files inside the package roots to external files // are through symlinks. So the upwards transitive closure of external files is small. // - The only way other than external repositories for external source files to get into the // skyframe graph in the first place is through symlinks outside the package roots, which we // neither want to encourage nor optimize for since it is not common. So the set of external // files is small. PackageValue pkgValue = (PackageValue) env.getValue(PackageValue.key(Label.EXTERNAL_PACKAGE_IDENTIFIER)); if (pkgValue == null) { return; } Preconditions.checkState(!pkgValue.getPackage().containsErrors()); }