private static void ProcessDirectory(IProject project, DirectorySnapshot directory, List<KeyValuePair<IProject, DirectorySnapshot>> result) { result.Add(KeyValuePair.Create(project, directory)); foreach (var child in directory.DirectoryEntries) { ProcessDirectory(project, child, result); } }
private static List<FileSystemEntry> BuildEntries(DirectorySnapshot directoryEntry) { return directoryEntry.DirectoryEntries .Select(x => BuildDirectoryEntry(x)) .Concat(directoryEntry.Files.Select(x => BuildFileEntry(x))) .ToList(); }
private static DirectoryEntry BuildDirectoryEntry(DirectorySnapshot directoryEntry) { return new DirectoryEntry { Name = (directoryEntry.DirectoryName.IsAbsoluteName ? directoryEntry.DirectoryName.FullPath.Value : directoryEntry.DirectoryName.RelativePath.FileName), Data = null, Entries = BuildEntries(directoryEntry) }; }
private static List <FileSystemEntry> BuildEntries(DirectorySnapshot directoryEntry) { return(directoryEntry.ChildDirectories .Select(x => BuildDirectoryEntry(x)) .Concat(directoryEntry.ChildFiles.Select(x => BuildFileEntry(x))) .ToList()); }
private static void ProcessDirectory(IProject project, DirectorySnapshot directory, List <KeyValuePair <IProject, DirectorySnapshot> > result) { result.Add(KeyValuePair.Create(project, directory)); foreach (var child in directory.DirectoryEntries) { ProcessDirectory(project, child, result); } }
private static DirectoryEntry BuildDirectoryEntry(DirectorySnapshot directoryEntry) { return(new DirectoryEntry { Name = (directoryEntry.DirectoryName.IsAbsoluteName ? directoryEntry.DirectoryName.FullPath.Value : directoryEntry.DirectoryName.RelativePath.FileName), Data = null, Entries = BuildEntries(directoryEntry) }); }
private static void VisitDirectory( IProject project, DirectorySnapshot directory, Action<IProject, DirectorySnapshot> callback) { callback(project, directory); foreach (var child in directory.ChildDirectories) { VisitDirectory(project, child, callback); } }
private static void VisitDirectory( IProject project, DirectorySnapshot directory, Action <IProject, DirectorySnapshot> callback) { callback(project, directory); foreach (var child in directory.ChildDirectories) { VisitDirectory(project, child, callback); } }
public ProjectRootSnapshot(IProject project, DirectorySnapshot directory) { _project = project; _directory = directory; }
private int CountFileEntries(DirectorySnapshot entry) { return entry.Files.Count + entry.DirectoryEntries.Aggregate(0, (acc, x) => acc + CountFileEntries(x)); }
private DirectorySnapshot CreateDirectorySnapshot( ProjectProcessingData data, DirectoryName directory, bool isSymLink) { // Create list of pairs (DirectoryName, List[FileNames]) var directoriesWithFiles = TraverseFileSystem(data, directory, isSymLink) .AsParallel() .WithExecutionMode(ParallelExecutionMode.ForceParallelism) .Select(traversedDirectoryEntry => { var directoryName = traversedDirectoryEntry.DirectoryData.DirectoryName; if (data.Progress.Step()) { data.Progress.DisplayProgress((i, n) => string.Format("Traversing directory: {0}\\{1}", data.Project.RootPath.Value, directoryName.RelativePath.Value)); } var fileNames = traversedDirectoryEntry.ChildFileNames .Where(childFilename => data.Project.FileFilter.Include(childFilename.RelativePath)) .OrderBy(x => x.RelativePath) .ToReadOnlyCollection(); return(KeyValuePair.Create(traversedDirectoryEntry.DirectoryData, fileNames)); }) .ToList(); // We sort entries by directory name *descending* to make sure we process // directories bottom up, so that we know // 1) it is safe to skip DirectoryEntry instances where "Entries.Count" == 0, // 2) we create instances of child directories before their parent. directoriesWithFiles.Sort((x, y) => - x.Key.DirectoryName.RelativePath.CompareTo(y.Key.DirectoryName.RelativePath)); // Build map from parent directory -> list of child directories var directoriesToChildDirectories = new Dictionary <DirectoryName, List <DirectoryName> >(); directoriesWithFiles.ForAll(x => { var directoryName = x.Key; // Ignore root project directory name if (directoryName.DirectoryName.IsAbsoluteName) { return; } GetOrCreateList(directoriesToChildDirectories, directoryName.DirectoryName.Parent).Add(directoryName.DirectoryName); }); // Build directory snapshots for each directory entry, using an // intermediate map to enable connecting snapshots to their parent. var directoriesToSnapshot = new Dictionary <DirectoryName, DirectorySnapshot>(); var directorySnapshots = directoriesWithFiles.Select(entry => { var directoryElement = entry.Key; var childFilenames = entry.Value; var childDirectories = GetOrEmptyList(directoriesToChildDirectories, directoryElement.DirectoryName) .Select(x => directoriesToSnapshot[x]) .OrderBy(x => x.DirectoryName.RelativePath) .ToReadOnlyCollection(); // TODO(rpaquay): Not clear the lines below are a perf win, even though // they do not hurt correctness. // Remove children since we processed them //GetOrEmptyList(directoriesToChildDirectories, directoryName) // .ForAll(x => directoriesToSnapshot.Remove(x)); var result = new DirectorySnapshot(directoryElement, childDirectories, childFilenames); directoriesToSnapshot.Add(directoryElement.DirectoryName, result); return(result); }) .ToList(); // Since we sort directories by name descending, the last entry is always the // entry correcsponding to the project root. Debug.Assert(directorySnapshots.Count >= 1); Debug.Assert(directorySnapshots.Last().DirectoryName.Equals(directory)); return(directorySnapshots.Last()); }
private DirectorySnapshot ApplyDirectorySnapshotDelta( ProjectProcessingData data, DirectorySnapshot oldDirectory) { var oldDirectoryPath = oldDirectory.DirectoryName.RelativePath; // Create lists of created dirs and files. We havet to access the file system to know // if each path is a file or a directory. List <IFileInfoSnapshot> createDirs = null; List <IFileInfoSnapshot> createdFiles = null; foreach (var path in data.PathChanges.GetCreatedEntries(oldDirectoryPath).ToForeachEnum()) { var info = _fileSystem.GetFileInfoSnapshot(data.Project.RootPath.Combine(path)); if (info.IsDirectory) { if (createDirs == null) { createDirs = new List <IFileInfoSnapshot>(); } createDirs.Add(info); } else if (info.IsFile) { if (createdFiles == null) { createdFiles = new List <IFileInfoSnapshot>(); } createdFiles.Add(info); } } // Recursively create new directory entires for previous (non deleted) // entries. var childDirectories = oldDirectory.ChildDirectories .Where(dir => !data.PathChanges.IsDeleted(dir.DirectoryName.RelativePath)) .Select(dir => ApplyDirectorySnapshotDelta(data, dir)) .ToList(); // Add created directories if (createDirs != null) { foreach (var info in createDirs.ToForeachEnum()) { var name = data.FileSystemNameFactory.CreateDirectoryName(oldDirectory.DirectoryName, info.Path.FileName); var childSnapshot = CreateDirectorySnapshot(data, name, info.IsSymLink); // Note: File system change notifications are not always 100% // reliable. We may get a "create" event for directory we already know // about. var index = childDirectories.FindIndex(x => SystemPathComparer.Instance.StringComparer.Equals(x.DirectoryName.RelativePath.FileName, name.RelativePath.FileName)); if (index >= 0) { childDirectories.RemoveAt(index); } childDirectories.Add(childSnapshot); } // We need to re-sort the array since we added new entries childDirectories.Sort((x, y) => SystemPathComparer.Instance.StringComparer.Compare(x.DirectoryName.RelativePath.FileName, y.DirectoryName.RelativePath.FileName)); } // Match non deleted files // Sepcial case: if no file deleted or created, just re-use the list. IList <FileName> newFileList; if (data.PathChanges.GetDeletedEntries(oldDirectoryPath).Count == 0 && createdFiles == null) { newFileList = oldDirectory.ChildFiles; } else { // Copy the list of previous children, minus deleted files. var newFileListTemp = oldDirectory.ChildFiles .Where(x => !data.PathChanges.IsDeleted(x.RelativePath)) .ToList(); // Add created files if (createdFiles != null) { foreach (var info in createdFiles.ToForeachEnum()) { var name = data.FileSystemNameFactory.CreateFileName(oldDirectory.DirectoryName, info.Path.FileName); newFileListTemp.Add(name); } // We need to re-sort the array since we added new entries newFileListTemp.Sort((x, y) => SystemPathComparer.Instance.StringComparer.Compare(x.RelativePath.FileName, y.RelativePath.FileName)); // Note: File system change notifications are not always 100% // reliable. We may get a "create" event for files we already know // about. ArrayUtilities.RemoveDuplicates(newFileListTemp, (x, y) => SystemPathComparer.Instance.StringComparer.Equals(x.RelativePath.FileName, y.RelativePath.FileName)); } newFileList = newFileListTemp; } var newData = new DirectoryData(oldDirectory.DirectoryName, oldDirectory.IsSymLink); return(new DirectorySnapshot( newData, childDirectories.ToReadOnlyCollection(), newFileList.ToReadOnlyCollection())); }
private int CountDirectoryEntries(DirectorySnapshot entry) { return 1 + entry.ChildDirectories.Aggregate(0, (acc, x) => acc + CountDirectoryEntries(x)); }