Beispiel #1
0
        /// <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);
        }