internal IReadOnlyList <string> FindProjFileAtOrAbovePath(IPhysicalFileSystem fileSystem, string startPath, HashSet <string> extensionLimiters) { string directory; if (fileSystem.DirectoryExists(startPath)) { directory = startPath; } else { directory = Path.GetDirectoryName(startPath); } do { List <string> filesInDir = fileSystem.EnumerateFileSystemEntries(directory, "*.*proj", SearchOption.TopDirectoryOnly).ToList(); List <string> matches = new List <string>(); if (extensionLimiters.Count == 0) { matches = filesInDir; } else { foreach (string filename in filesInDir) { string extension = Path.GetExtension(filename); if (extensionLimiters.Contains(extension)) { matches.Add(filename); } } } if (matches.Count > 0) { return(matches); } if (Path.GetPathRoot(directory) != directory) { directory = Directory.GetParent(directory).FullName; } else { directory = null; } } while (directory != null); return(new List <string>()); }
// Walks up the directory path looking for files that match the matchPattern and the secondary filter (if provided) // Returns all the matching files in the first directory that has any matched files. public static IReadOnlyList <string> FindFilesAtOrAbovePath(IPhysicalFileSystem fileSystem, string startPath, string matchPattern, Func <string, bool> secondaryFilter = null) { string directory; if (fileSystem.DirectoryExists(startPath)) { directory = startPath; } else { directory = Path.GetDirectoryName(startPath); } do { List <string> filesInDir = fileSystem.EnumerateFileSystemEntries(directory, matchPattern, SearchOption.TopDirectoryOnly).ToList(); List <string> matches = new List <string>(); if (secondaryFilter == null) { matches = filesInDir; } else { matches = filesInDir.Where(x => secondaryFilter(x)).ToList(); } if (matches.Count > 0) { return(matches); } if (Path.GetPathRoot(directory) != directory) { directory = Directory.GetParent(directory).FullName; } else { directory = null; } } while (directory != null); return(new List <string>()); }
public IEnumerable <string> EnumerateFileSystemEntries(string directoryName, string pattern, SearchOption searchOption) { if (!IsPathInCone(directoryName, out string processedPath)) { //TODO: Handle cases where part of the directory set is inside our cone and part is not foreach (string s in _basis.EnumerateFileSystemEntries(directoryName, pattern, searchOption)) { yield return(s); } yield break; } directoryName = processedPath; string rel = directoryName.Substring(_root.FullPath.Length).Trim('/', '\\'); FileSystemDirectory currentDir = _root; if (!string.IsNullOrEmpty(rel)) { string[] parts = rel.Split('/', '\\'); for (int i = 0; i < parts.Length; ++i) { FileSystemDirectory dir; if (!currentDir.Directories.TryGetValue(parts[i], out dir)) { yield break; } currentDir = dir; } } Regex rx = new Regex("^" + Regex.Escape(pattern).Replace("\\*", ".*").Replace("\\?", ".") + "$"); foreach (KeyValuePair <string, FileSystemFile> entry in currentDir.Files) { if (rx.IsMatch(entry.Key)) { yield return(entry.Value.FullPath); } } if (searchOption == SearchOption.TopDirectoryOnly) { foreach (KeyValuePair <string, FileSystemDirectory> entry in currentDir.Directories) { if (rx.IsMatch(entry.Key)) { yield return(entry.Value.FullPath); } } yield break; } Stack <IEnumerator <KeyValuePair <string, FileSystemDirectory> > > directories = new Stack <IEnumerator <KeyValuePair <string, FileSystemDirectory> > >(); IEnumerator <KeyValuePair <string, FileSystemDirectory> > current = currentDir.Directories.GetEnumerator(); bool moveNext; while ((moveNext = current.MoveNext()) || directories.Count > 0) { while (!moveNext) { current.Dispose(); if (directories.Count == 0) { break; } current = directories.Pop(); moveNext = current.MoveNext(); } if (!moveNext) { break; } if (rx.IsMatch(current.Current.Key)) { yield return(current.Current.Value.FullPath); } foreach (KeyValuePair <string, FileSystemFile> entry in current.Current.Value.Files) { if (rx.IsMatch(entry.Key)) { yield return(entry.Value.FullPath); } } directories.Push(current); current = current.Current.Value.Directories.GetEnumerator(); } }