public static IReadOnlyCollection <FileInfo> GetFilesRecursive( this DirectoryInfo directoryInfo, IEnumerable <string> fileExtensions = null, PathLookupSpecification pathLookupSpecification = null, string rootDir = null) { if (directoryInfo == null) { throw new ArgumentNullException(nameof(directoryInfo)); } if (!directoryInfo.Exists) { throw new DirectoryNotFoundException($"The directory '{directoryInfo.FullName}' does not exist"); } PathLookupSpecification usedPathLookupSpecification = pathLookupSpecification ?? DefaultPaths.DefaultPathLookupSpecification; IEnumerable <string> usedFileExtensions = fileExtensions ?? new List <string>(); if (usedPathLookupSpecification.IsBlackListed(directoryInfo.FullName, rootDir).Item1) { return(new List <FileInfo>()); } IReadOnlyCollection <string> invalidFileExtensions = usedFileExtensions .Where(fileExtension => !fileExtension.StartsWith(".", StringComparison.OrdinalIgnoreCase)) .ToReadOnlyCollection(); if (invalidFileExtensions.Any()) { throw new ArgumentException("File extensions must start with '.', eg .txt"); } var files = new List <FileInfo>(); List <FileInfo> directoryFiles = directoryInfo .GetFiles() .Where(file => !usedPathLookupSpecification.IsFileBlackListed(file.FullName, rootDir).Item1) .ToList(); List <FileInfo> filtered = (usedFileExtensions.Any() ? directoryFiles.Where(file => usedFileExtensions.Any(extension => file.Extension.Equals( extension, StringComparison.InvariantCultureIgnoreCase))) : directoryFiles) .ToList(); files.AddRange(filtered); DirectoryInfo[] subDirectories = directoryInfo.GetDirectories(); files.AddRange(subDirectories .SelectMany(dir => dir.GetFilesRecursive(fileExtensions, usedPathLookupSpecification, rootDir)) .ToList()); return(files); }
public static PathLookupSpecification WithIgnoredFileNameParts( this PathLookupSpecification pathLookupSpecification, IEnumerable <string> ignoredFileNameParts) { return(new PathLookupSpecification( pathLookupSpecification.IgnoredDirectorySegments, pathLookupSpecification.IgnoredFileStartsWithPatterns, pathLookupSpecification.IgnoredDirectorySegmentParts, pathLookupSpecification.IgnoredDirectoryStartsWithPatterns, ignoredFileNameParts.SafeToReadOnlyCollection())); }
public static PathLookupSpecification AddExcludedDirectorySegments( this PathLookupSpecification pathLookupSpecification, IEnumerable <string> ignoredExcludedDirectorySegments) { return(new PathLookupSpecification( pathLookupSpecification.IgnoredDirectorySegments.Concat(ignoredExcludedDirectorySegments), pathLookupSpecification.IgnoredFileStartsWithPatterns, pathLookupSpecification.IgnoredDirectorySegmentParts, pathLookupSpecification.IgnoredDirectoryStartsWithPatterns, pathLookupSpecification.IgnoredFileNameParts)); }
public static async Task <ExitCode> CopyAsync( string sourceDir, string targetDir, ILogger optionalLogger = null, PathLookupSpecification pathLookupSpecificationOption = null, string rootDir = null) { PathLookupSpecification pathLookupSpecification = pathLookupSpecificationOption ?? DefaultPaths.DefaultPathLookupSpecification; ILogger logger = optionalLogger ?? new NullLogger(); if (string.IsNullOrWhiteSpace(sourceDir)) { throw new ArgumentNullException(nameof(sourceDir)); } if (string.IsNullOrWhiteSpace(targetDir)) { throw new ArgumentNullException(nameof(targetDir)); } var sourceDirectory = new DirectoryInfo(sourceDir); if (!sourceDirectory.Exists) { throw new ArgumentException($"Source directory '{sourceDir}' does not exist"); } (bool, string)isBlackListed = pathLookupSpecification.IsBlackListed(sourceDir, rootDir); if (isBlackListed.Item1) { logger.WriteDebug( $"Directory '{sourceDir}' is blacklisted from specification {pathLookupSpecification}, {isBlackListed.Item2}"); return(ExitCode.Success); } new DirectoryInfo(targetDir).EnsureExists(); foreach (FileInfo file in sourceDirectory.GetFiles()) { string destFileName = Path.Combine(targetDir, file.Name); (bool, string)isFileBlackListed = pathLookupSpecification.IsFileBlackListed(file.FullName, rootDir, logger: optionalLogger); if (isFileBlackListed.Item1) { logger.WriteVerbose($"File '{file.FullName}' is blacklisted, skipping copying file, {isFileBlackListed.Item2}"); continue; } logger.WriteVerbose($"Copying file '{file.FullName}' to destination '{destFileName}'"); try { file.CopyTo(destFileName, true); } catch (PathTooLongException ex) { logger.WriteError( $"Could not copy file to '{destFileName}', path length is too long ({destFileName.Length})" + " " + ex); return(ExitCode.Failure); } catch (Exception ex) { logger.WriteError( $"Could not copy file '{file.FullName}' to destination '{destFileName}'" + " " + ex); return(ExitCode.Failure); } } foreach (DirectoryInfo directory in sourceDirectory.GetDirectories()) { ExitCode exitCode = await CopyAsync( directory.FullName, Path.Combine(targetDir, directory.Name), pathLookupSpecificationOption : pathLookupSpecification); if (!exitCode.IsSuccess) { return(exitCode); } } return(ExitCode.Success); }
public static (bool, string) IsBlackListed( this PathLookupSpecification pathLookupSpecification, string sourceDir, string rootDir = null, ILogger logger = null) { if (pathLookupSpecification == null) { throw new ArgumentNullException(nameof(pathLookupSpecification)); } if (string.IsNullOrWhiteSpace(sourceDir)) { throw new ArgumentNullException(nameof(sourceDir)); } if (!Directory.Exists(sourceDir)) { return(true, $"Source directory '{sourceDir}' does not exist"); } string[] sourceDirSegments = GetSourceDirSegments(sourceDir, rootDir); bool hasAnyPathSegment = HasAnyPathSegment( sourceDirSegments, pathLookupSpecification.IgnoredDirectorySegments, logger); if (hasAnyPathSegment) { string reasonMessage = $"The directory '{sourceDir}' has a path segment that is blacklisted"; logger?.WriteDebug(reasonMessage); return(true, reasonMessage); } bool hasAnyPathSegmentPart = HasAnyPathSegmentPart( sourceDirSegments, pathLookupSpecification.IgnoredDirectorySegmentParts); if (hasAnyPathSegmentPart) { string reasonMessage = $"The directory '{sourceDir}' has a path segment part that is blacklisted"; logger?.WriteDebug(reasonMessage); return(true, reasonMessage); } bool hasAnyPartStartsWith = HasAnyPathSegmentStartsWith( sourceDirSegments, pathLookupSpecification.IgnoredDirectoryStartsWithPatterns); if (hasAnyPartStartsWith) { string reasonMessage = $"The directory '{sourceDir}' has a path that starts with a pattern that is blacklisted"; logger?.WriteDebug( reasonMessage); return(true, reasonMessage); } logger?.WriteDebug($"The directory '{sourceDir}' is not blacklisted"); return(false, string.Empty); }
public static (bool, string) IsFileBlackListed( this PathLookupSpecification pathLookupSpecification, string sourceFile, string rootDir = null, bool allowNonExistingFiles = false, ILogger logger = null) { if (pathLookupSpecification == null) { throw new ArgumentNullException(nameof(pathLookupSpecification)); } if (string.IsNullOrWhiteSpace(sourceFile)) { throw new ArgumentNullException(nameof(sourceFile)); } if (!allowNonExistingFiles && !File.Exists(sourceFile)) { string messageMessage = $"File '{sourceFile}' does not exist"; logger?.WriteDebug(messageMessage); return(true, messageMessage); } var sourceFileInfo = new FileInfo(sourceFile); (bool, string)directoryBlackListed = pathLookupSpecification.IsBlackListed(sourceFileInfo.Directory.FullName, rootDir); if (directoryBlackListed.Item1) { string reasonMessage = $"Directory of '{sourceFile}' is blacklisted, {directoryBlackListed.Item2}"; logger?.WriteDebug(reasonMessage); return(true, reasonMessage); } bool isBlackListed = HasAnyPathSegmentStartsWith( sourceFileInfo.Name, pathLookupSpecification.IgnoredFileStartsWithPatterns); if (isBlackListed) { string reasonMessage = $"Path segments of '{sourceFile}' makes it blacklisted"; logger?.WriteDebug(reasonMessage); return(true, reasonMessage); } IReadOnlyCollection <string> ignoredFileNameParts = pathLookupSpecification.IgnoredFileNameParts .Where(part => !string.IsNullOrEmpty(part)) .Where( part => sourceFileInfo.Name.IndexOf(part, StringComparison.InvariantCultureIgnoreCase) >= 0) .SafeToReadOnlyCollection(); if (ignoredFileNameParts.Any()) { string reasonMessage = $"Ignored file name parts of '{sourceFile}' makes it blacklisted: {string.Join(", ", ignoredFileNameParts.Select(item => $"'{item}'"))}"; logger?.WriteDebug(reasonMessage); return(true, reasonMessage); } return(false, string.Empty); }