private void GetPathProducers(AbsolutePath path) { Dictionary <AbsolutePath, DirectoryArtifact> directories = new Dictionary <AbsolutePath, DirectoryArtifact>(); foreach (var directory in PipGraph.AllSealDirectories) { directories[directory.Path] = directory; } var latest = PipGraph.TryGetLatestFileArtifactForPath(path); if (!latest.IsValid) { m_writer.WriteLine("No declared file producers"); } else { for (int i = 0; i <= latest.RewriteCount; i++) { var producerId = PipGraph.TryGetProducer(new FileArtifact(path, i)); if (producerId.IsValid) { m_writer.WriteLine("File Producer: ({0})", i); m_producers.Add(producerId); m_writer.WriteLine(GetDescription(GetPip(producerId))); m_writer.WriteLine(); } } } while (path.IsValid) { DirectoryArtifact containingDirectory; if (directories.TryGetValue(path, out containingDirectory)) { var directoryNode = PipGraph.GetSealedDirectoryNode(containingDirectory); var sealDirectory = (SealDirectory)GetPip(directoryNode); if (sealDirectory.Kind == SealDirectoryKind.Opaque) { m_writer.WriteLine("Directory Producer:"); m_producers.Add(PipGraph.GetProducer(containingDirectory)); m_writer.WriteLine(GetDescription(GetPip(PipGraph.GetProducer(containingDirectory)))); m_writer.WriteLine("Directory: " + GetDescription(sealDirectory)); m_writer.WriteLine(); } } path = path.GetParent(PathTable); } }
/// <summary> /// Gets the existence of a path for the given file system view mode if set /// </summary> private bool TryGetKnownPathExistence(AbsolutePath path, FileSystemViewMode mode, out PathExistence existence) { if (mode == FileSystemViewMode.FullGraph || mode == FileSystemViewMode.Output) { if (ExistsInGraphFileSystem(PipGraph.TryGetLatestFileArtifactForPath(path), mode)) { existence = PathExistence.ExistsAsFile; return(true); } } // For graph file systems, we query the path existence cache for existence of directories. Files are tracked // by the pip graph. For dynamic files, we need to check PathExistenceCache. existence = PathExistence.Nonexistent; FileSystemEntry entry; return(PathExistenceCache.TryGetValue(path, out entry) && entry.TryGetExistence(mode, out existence)); }
public IEnumerable <AbsolutePath> EnumeratePipGraphFilesUnderDirectory(AbsolutePath directory) { foreach (var path in PipGraph.EnumerateImmediateChildPaths(directory)) { var latestFile = PipGraph.TryGetLatestFileArtifactForPath(path); if (latestFile.IsValid) { if (latestFile.IsSourceFile) { yield return(path); } continue; } foreach (var childPath in EnumeratePipGraphFilesUnderDirectory(path)) { yield return(childPath); } } }
private ObjectInfo AnalyzePathInfo(AnalyzePath ap) { var props = new List <Property>() { new Property("Path", ap.Path) }; var latestFileArtifact = PipGraph.TryGetLatestFileArtifactForPath(ap.Path); if (latestFileArtifact.IsValid) { props.Add(new Property("LastestFileArtifact", latestFileArtifact)); } var dirArtifact = PipGraph.TryGetDirectoryArtifactForPath(ap.Path); if (dirArtifact.IsValid) { props.Add(new Property("DirectoryArtifact", dirArtifact)); } return(new ObjectInfo(props)); }
/// <summary> /// Queries the existence and members of a directory in the specified file system mode /// </summary> public Possible <PathExistence> TryEnumerateDirectory(AbsolutePath path, FileSystemViewMode mode, Action <string, AbsolutePath, PathExistence> handleEntry, bool cachePathExistence = true) { FileSystemEntry entry; PathExistence existence; if (PathExistenceCache.TryGetValue(path, out entry) && entry.TryGetExistence(mode, out existence)) { if (existence == PathExistence.Nonexistent) { return(existence); } if (existence == PathExistence.ExistsAsFile) { bool isDirectorySymlinkOrJunction = false; if (entry.HasFlag(FileSystemEntryFlags.CheckedIsDirectorySymlink)) { isDirectorySymlinkOrJunction = entry.HasFlag(FileSystemEntryFlags.IsDirectorySymlink); } else { isDirectorySymlinkOrJunction = FileUtilities.IsDirectorySymlinkOrJunction(path.ToString(PathTable)); PathExistenceCache.AddOrUpdate(path, false, (key, data) => { throw Contract.AssertFailure("Entry should already be added for path"); }, (key, data, oldValue) => oldValue.SetFlag( FileSystemEntryFlags.CheckedIsDirectorySymlink | (isDirectorySymlinkOrJunction ? FileSystemEntryFlags.IsDirectorySymlink : FileSystemEntryFlags.None))); } if (!isDirectorySymlinkOrJunction) { return(existence); } } // For graph file systems, directory members can be determined by overlaying path table with existence state in-memory // For real file system, this same is true if the directory has already been enumerated if (mode != FileSystemViewMode.Real || ((entry.Flags & FileSystemEntryFlags.IsRealFileSystemEnumerated) != 0)) { foreach (var childPathValue in PathTable.EnumerateImmediateChildren(path.Value)) { var childPath = new AbsolutePath(childPathValue); PathExistence childExistence; if (TryGetKnownPathExistence(childPath, mode, out childExistence) && childExistence != PathExistence.Nonexistent) { var entryName = childPath.GetName(PathTable).ToString(PathTable.StringTable); handleEntry(entryName, childPath, childExistence); } } return(existence); } } if (mode == FileSystemViewMode.Real) { var handleDirectoryEntry = new Action <string, FileAttributes>((entryName, entryAttributes) => { // Reparse points are always treated as files. Otherwise, honor the directory attribute to determine // existence var childExistence = (entryAttributes & FileAttributes.ReparsePoint) != 0 ? PathExistence.ExistsAsFile : (entryAttributes & FileAttributes.Directory) != 0 ? PathExistence.ExistsAsDirectory : PathExistence.ExistsAsFile; var childPath = path.Combine(PathTable, entryName); childExistence = GetOrAddExistence(childPath, mode, childExistence, updateParents: false); // NOTE: Because we are caching file system state in memory, it is possible that the existence state of // files does not match the state from the file system. if (childExistence != PathExistence.Nonexistent) { handleEntry(entryName, childPath, childExistence); } }); Counters.IncrementCounter(FileSystemViewCounters.RealFileSystemEnumerations); if (cachePathExistence) { Possible <PathExistence> possibleExistence; using (Counters.StartStopwatch(FileSystemViewCounters.RealFileSystemEnumerationsDuration)) { possibleExistence = LocalDiskFileSystem.TryEnumerateDirectoryAndTrackMembership( path, handleDirectoryEntry, // This method is called during observed input processing. Currently, we simply include all entries. // TODO: In the future, we may want to restrict it based on pip's untracked scopes/paths. shouldIncludeEntry: null /* include all entries */); } if (possibleExistence.Succeeded) { existence = GetOrAddExistence(path, mode, possibleExistence.Result); PathExistenceCache.AddOrUpdate(path, false, (key, data) => { throw Contract.AssertFailure("Entry should already be added for path"); }, (key, data, oldValue) => oldValue.SetFlag(FileSystemEntryFlags.IsRealFileSystemEnumerated)); return(existence); } return(possibleExistence); } using (Counters.StartStopwatch(FileSystemViewCounters.RealFileSystemEnumerationsDuration)) { var possibleFingerprintResult = DirectoryMembershipTrackingFingerprinter.ComputeFingerprint( path.Expand(PathTable).ExpandedPath, handleEntry: handleDirectoryEntry); return(possibleFingerprintResult.Succeeded ? new Possible <PathExistence>(possibleFingerprintResult.Result.PathExistence) : new Possible <PathExistence>(possibleFingerprintResult.Failure)); } } else if (ExistsInGraphFileSystem(PipGraph.TryGetLatestFileArtifactForPath(path), mode)) { return(PathExistence.ExistsAsFile); } return(PathExistence.Nonexistent); }
/// <summary> /// Queries the existence and members of a directory in the specified file system mode /// </summary> public Possible <PathExistence> TryEnumerateDirectory(AbsolutePath path, FileSystemViewMode mode, Action <string, AbsolutePath, PathExistence> handleEntry, bool cachePathExistence = true) { FileSystemEntry entry; PathExistence existence; if (PathExistenceCache.TryGetValue(path, out entry) && entry.TryGetExistence(mode, out existence)) { if (existence != PathExistence.ExistsAsDirectory) { return(existence); } // For graph file systems, directory members can be determined by overlaying path table with existence state in-memory // For real file system, this same is true if the directory has already been enumerated if (mode != FileSystemViewMode.Real || ((entry.Flags & FileSystemEntryFlags.IsRealFileSystemEnumerated) != 0)) { foreach (var childPathValue in PathTable.EnumerateImmediateChildren(path.Value)) { var childPath = new AbsolutePath(childPathValue); PathExistence childExistence; if (TryGetKnownPathExistence(childPath, mode, out childExistence) && childExistence != PathExistence.Nonexistent) { var entryName = childPath.GetName(PathTable).ToString(PathTable.StringTable); handleEntry(entryName, childPath, childExistence); } } return(existence); } } if (mode == FileSystemViewMode.Real) { var handleDirectoryEntry = new Action <string, FileAttributes>((entryName, entryAttributes) => { var childExistence = (entryAttributes & FileAttributes.Directory) != 0 ? PathExistence.ExistsAsDirectory : PathExistence.ExistsAsFile; var childPath = path.Combine(PathTable, entryName); childExistence = GetOrAddExistence(childPath, mode, childExistence, updateParents: false); // NOTE: Because we are caching file system state in memory, it is possible that the existence state of // files does not match the state from the file system. if (childExistence != PathExistence.Nonexistent) { handleEntry(entryName, childPath, childExistence); } }); Counters.IncrementCounter(FileSystemViewCounters.RealFileSystemEnumerations); if (cachePathExistence) { Possible <PathExistence> possibleExistence; using (Counters.StartStopwatch(FileSystemViewCounters.RealFileSystemEnumerationsDuration)) { possibleExistence = LocalDiskFileSystem.TryEnumerateDirectoryAndTrackMembership(path, handleDirectoryEntry); } if (possibleExistence.Succeeded) { existence = GetOrAddExistence(path, mode, possibleExistence.Result); PathExistenceCache.AddOrUpdate(path, false, (key, data) => { throw Contract.AssertFailure("Entry should already be added for path"); }, (key, data, oldValue) => oldValue.SetFlag(FileSystemEntryFlags.IsRealFileSystemEnumerated)); return(existence); } return(possibleExistence); } using (Counters.StartStopwatch(FileSystemViewCounters.RealFileSystemEnumerationsDuration)) { var possibleFingerprintResult = DirectoryMembershipTrackingFingerprinter.ComputeFingerprint( path.Expand(PathTable).ExpandedPath, handleEntry: handleDirectoryEntry); return(possibleFingerprintResult.Succeeded ? new Possible <PathExistence>(possibleFingerprintResult.Result.PathExistence) : new Possible <PathExistence>(possibleFingerprintResult.Failure)); } } else if (ExistsInGraphFileSystem(PipGraph.TryGetLatestFileArtifactForPath(path), mode)) { return(PathExistence.ExistsAsFile); } return(PathExistence.Nonexistent); }