/// <inheritdoc /> public void DeleteDirectoryContents( string path, bool deleteRootDirectory = false, Func <string, bool> shouldDelete = null, ITempDirectoryCleaner tempDirectoryCleaner = null) { if (!Directory.Exists(path)) { return; } shouldDelete = shouldDelete ?? (p => true); EnumerateDirectoryResult result = s_fileSystem.EnumerateDirectoryEntries( path, (name, attributes) => { var isDirectory = FileUtilities.IsDirectoryNoFollow(attributes); string childPath = Path.Combine(path, name); if (isDirectory) { DeleteDirectoryContents( childPath, deleteRootDirectory: true, shouldDelete: shouldDelete, tempDirectoryCleaner: tempDirectoryCleaner); } else { if (shouldDelete(childPath)) { // This method already has retry logic, so no need to do retry in DeleteFile DeleteFile(childPath, waitUntilDeletionFinished: true, tempDirectoryCleaner: tempDirectoryCleaner); } } }); if (deleteRootDirectory) { bool success = false; success = Helpers.RetryOnFailure( finalRound => { // An exception will be thrown on failure, which will trigger a retry, this deletes the path itself // and any file or dir still in recursively through the 'true' flag Directory.Delete(path, true); // Only reached if there are no exceptions return(true); }); if (!success) { throw new BuildXLException(path); } } }
private int DeleteDirectoryContentsInternal( string path, bool deleteRootDirectory, Func <string, bool> shouldDelete, ITempCleaner tempDirectoryCleaner, CancellationToken?cancellationToken) { int remainingChildCount = 0; if (!Directory.Exists(path)) { return(remainingChildCount); } shouldDelete = shouldDelete ?? (p => true); EnumerateDirectoryResult result = s_fileSystem.EnumerateDirectoryEntries( path, (name, attributes) => { cancellationToken?.ThrowIfCancellationRequested(); var isDirectory = FileUtilities.IsDirectoryNoFollow(attributes); string childPath = Path.Combine(path, name); if (isDirectory) { int subDirectoryCount = DeleteDirectoryContentsInternal( childPath, deleteRootDirectory: true, shouldDelete: shouldDelete, tempDirectoryCleaner: tempDirectoryCleaner, cancellationToken: cancellationToken); if (subDirectoryCount > 0) { ++remainingChildCount; } } else { if (shouldDelete(childPath)) { // This method already has retry logic, so no need to do retry in DeleteFile DeleteFile(childPath, waitUntilDeletionFinished: true, tempDirectoryCleaner: tempDirectoryCleaner); } else { ++remainingChildCount; } } }, isEnumerationForDirectoryDeletion: true); if (deleteRootDirectory && remainingChildCount == 0) { bool success = false; success = Helpers.RetryOnFailure( finalRound => { // An exception will be thrown on failure, which will trigger a retry, this deletes the path itself // and any file or dir still in recursively through the 'true' flag Directory.Delete(path, true); // Only reached if there are no exceptions return(true); }); if (!success) { throw new BuildXLException(path); } } return(remainingChildCount); }
private int DeleteDirectoryContentsInternal( string path, bool deleteRootDirectory, Func <string, bool> shouldDelete, ITempCleaner tempDirectoryCleaner, bool bestEffort, CancellationToken?cancellationToken) { int remainingChildCount = 0; if (!Directory.Exists(path)) { return(remainingChildCount); } shouldDelete = shouldDelete ?? (p => true); EnumerateDirectoryResult result = m_fileSystem.EnumerateDirectoryEntries( path, (name, attributes) => { cancellationToken?.ThrowIfCancellationRequested(); var isDirectory = FileUtilities.IsDirectoryNoFollow(attributes); string childPath = Path.Combine(path, name); if (isDirectory) { int subDirectoryCount = DeleteDirectoryContentsInternal( childPath, deleteRootDirectory: true, shouldDelete: shouldDelete, tempDirectoryCleaner: tempDirectoryCleaner, bestEffort: bestEffort, cancellationToken: cancellationToken); if (subDirectoryCount > 0) { ++remainingChildCount; } } else { if (shouldDelete(childPath)) { // This method already has retry logic, so no need to do retry in DeleteFile DeleteFile(childPath, retryOnFailure: !bestEffort, tempDirectoryCleaner: tempDirectoryCleaner); } else { ++remainingChildCount; } } }, isEnumerationForDirectoryDeletion: true); if (deleteRootDirectory && remainingChildCount == 0) { bool success = Helpers.RetryOnFailure( finalRound => { // An exception will be thrown on failure, which will trigger a retry, this deletes the path itself // and any file or dir still in recursively through the 'true' flag Directory.Delete(path, true); // Only reached if there are no exceptions return(true); }, numberOfAttempts: bestEffort ? 1 : Helpers.DefaultNumberOfAttempts); if (!success && Directory.Exists(path)) { var code = (int)Tracing.LogEventId.RetryOnFailureException; throw new BuildXLException($"Failed to delete directory: {path}. Search for DX{code:0000} log messages to see why."); } } return(remainingChildCount); }