Exemplo n.º 1
0
        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);
            }
        }
Exemplo n.º 2
0
        /// <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));
        }
Exemplo n.º 3
0
        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);
                }
            }
        }
Exemplo n.º 4
0
        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));
        }
Exemplo n.º 5
0
        /// <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);
        }
Exemplo n.º 6
0
        /// <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);
        }