forked from libgit2/libgit2sharp
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDirectoryHelper.cs
More file actions
103 lines (90 loc) · 4.53 KB
/
DirectoryHelper.cs
File metadata and controls
103 lines (90 loc) · 4.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
namespace LibGit2Sharp.Tests.TestHelpers
{
public static class DirectoryHelper
{
private static readonly Dictionary<string, string> toRename = new Dictionary<string, string>
{
{ "dot_git", ".git" },
{ "gitmodules", ".gitmodules" },
};
private static readonly Type[] whitelist = { typeof(IOException), typeof(UnauthorizedAccessException) };
public static void CopyFilesRecursively(DirectoryInfo source, DirectoryInfo target)
{
// From http://stackoverflow.com/questions/58744/best-way-to-copy-the-entire-contents-of-a-directory-in-c/58779#58779
foreach (DirectoryInfo dir in source.GetDirectories())
{
CopyFilesRecursively(dir, target.CreateSubdirectory(Rename(dir.Name)));
}
foreach (FileInfo file in source.GetFiles())
{
file.CopyTo(Path.Combine(target.FullName, Rename(file.Name)));
}
}
private static string Rename(string name)
{
return toRename.ContainsKey(name) ? toRename[name] : name;
}
public static void DeleteDirectory(string directoryPath)
{
// From http://stackoverflow.com/questions/329355/cannot-delete-directory-with-directory-deletepath-true/329502#329502
if (!Directory.Exists(directoryPath))
{
Trace.WriteLine(string.Format("Directory '{0}' is missing and can't be removed.", directoryPath));
return;
}
NormalizeAttributes(directoryPath);
DeleteDirectory(directoryPath, maxAttempts: 5, initialTimeout: 16, timeoutFactor: 2);
}
private static void NormalizeAttributes(string directoryPath)
{
string[] filePaths = Directory.GetFiles(directoryPath);
string[] subdirectoryPaths = Directory.GetDirectories(directoryPath);
foreach (string filePath in filePaths)
{
File.SetAttributes(filePath, FileAttributes.Normal);
}
foreach (string subdirectoryPath in subdirectoryPaths)
{
NormalizeAttributes(subdirectoryPath);
}
File.SetAttributes(directoryPath, FileAttributes.Normal);
}
private static void DeleteDirectory(string directoryPath, int maxAttempts, int initialTimeout, int timeoutFactor)
{
for (int attempt = 1; attempt <= maxAttempts; attempt++)
{
try
{
Directory.Delete(directoryPath, true);
return;
}
catch (Exception ex)
{
var caughtExceptionType = ex.GetType();
if (!whitelist.Any(knownExceptionType => knownExceptionType.IsAssignableFrom(caughtExceptionType)))
{
throw;
}
if (attempt < maxAttempts)
{
Thread.Sleep(initialTimeout * (int)Math.Pow(timeoutFactor, attempt - 1));
continue;
}
Trace.WriteLine(string.Format("{0}The directory '{1}' could not be deleted ({2} attempts were made) due to a {3}: {4}" +
"{0}Most of the time, this is due to an external process accessing the files in the temporary repositories created during the test runs, and keeping a handle on the directory, thus preventing the deletion of those files." +
"{0}Known and common causes include:" +
"{0}- Windows Search Indexer (go to the Indexing Options, in the Windows Control Panel, and exclude the bin folder of LibGit2Sharp.Tests)" +
"{0}- Antivirus (exclude the bin folder of LibGit2Sharp.Tests from the paths scanned by your real-time antivirus)" +
"{0}- TortoiseGit (change the 'Icon Overlays' settings, e.g., adding the bin folder of LibGit2Sharp.Tests to 'Exclude paths' and appending an '*' to exclude all subfolders as well)",
Environment.NewLine, Path.GetFullPath(directoryPath), maxAttempts, caughtExceptionType, ex.Message));
}
}
}
}
}