PageRenderTime 35ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/tools/CleanProject/CleanProject/DirectoryHelper.cs

#
C# | 326 lines | 173 code | 39 blank | 114 comment | 24 complexity | 5b00a02f701b77421ebab9c1f3ef886c MD5 | raw file
  1. // --------------------------------------------------------------------------------------------------------------------
  2. // <copyright file="DirectoryHelper.cs" company="Microsoft">
  3. // Copyright (c) Microsoft Corporation. All rights reserved.
  4. // </copyright>
  5. // --------------------------------------------------------------------------------------------------------------------
  6. namespace CleanProject
  7. {
  8. using System;
  9. using System.Collections.Generic;
  10. using System.IO;
  11. using System.Linq;
  12. /// <summary>
  13. /// Helpers for dealing with directories
  14. /// </summary>
  15. internal class DirectoryHelper
  16. {
  17. #region Static Fields
  18. /// <summary>
  19. /// The list of excluded directories
  20. /// </summary>
  21. private static List<string> excludedDirs;
  22. /// <summary>
  23. /// List of directories to be removed
  24. /// </summary>
  25. private static List<string> removeDirs;
  26. #endregion
  27. #region Public Methods and Operators
  28. /// <summary>
  29. /// Finds the list of excluded directories
  30. /// </summary>
  31. public static void FindExcludedDirectories()
  32. {
  33. excludedDirs = new List<string>();
  34. if (Program.Options.ExcludeDirectories == null)
  35. {
  36. return;
  37. }
  38. foreach (var pattern in Program.Options.ExcludeDirectories)
  39. {
  40. foreach (var directory in Program.Options.Directories)
  41. {
  42. excludedDirs.AddRange(Directory.GetDirectories(directory, pattern, SearchOption.AllDirectories));
  43. }
  44. }
  45. }
  46. /// <summary>
  47. /// Finds the list of Remove directories
  48. /// </summary>
  49. public static void FindRemoveDirectories()
  50. {
  51. removeDirs = new List<string>();
  52. if (Program.Options.RemoveDirectories == null)
  53. {
  54. return;
  55. }
  56. foreach (var pattern in Program.Options.RemoveDirectories)
  57. {
  58. foreach (var directory in Program.Options.Directories)
  59. {
  60. removeDirs.AddRange(Directory.GetDirectories(directory, pattern, SearchOption.AllDirectories));
  61. }
  62. }
  63. }
  64. /// <summary>
  65. /// Removes SubDirectories not excluded
  66. /// </summary>
  67. /// <param name="directory">
  68. /// The directory.
  69. /// </param>
  70. /// <param name="searchPattern">
  71. /// The search pattern.
  72. /// </param>
  73. public static void RemoveSubDirectories(string directory, string searchPattern)
  74. {
  75. if (!Directory.Exists(directory))
  76. {
  77. return;
  78. }
  79. foreach (var d in
  80. Directory.GetDirectories(directory, searchPattern, SearchOption.AllDirectories).Except(excludedDirs))
  81. {
  82. Remove(d);
  83. }
  84. }
  85. /// <summary>
  86. /// Removes SubDirectories
  87. /// </summary>
  88. /// <param name="directory">
  89. /// The directory.
  90. /// </param>
  91. public static void RemoveSubDirectories(string directory)
  92. {
  93. foreach (var pattern in Program.Options.RemoveDirectories.Except(excludedDirs))
  94. {
  95. RemoveSubDirectories(directory, pattern);
  96. }
  97. }
  98. #endregion
  99. #region Methods
  100. /// <summary>
  101. /// Copies a directory
  102. /// </summary>
  103. /// <param name="source">
  104. /// The source.
  105. /// </param>
  106. /// <param name="dest">
  107. /// The dest.
  108. /// </param>
  109. /// <param name="subdirs">
  110. /// The subdirs.
  111. /// </param>
  112. /// <param name="removeIfExists">
  113. /// The remove if exists.
  114. /// </param>
  115. /// <exception cref="DirectoryNotFoundException">
  116. /// The source does not exist
  117. /// </exception>
  118. internal static void CopyDirectory(string source, string dest, bool subdirs, bool removeIfExists)
  119. {
  120. var dir = new DirectoryInfo(source);
  121. var dirs = dir.GetDirectories();
  122. // If the source directory does not exist, throw an exception.
  123. if (!dir.Exists)
  124. {
  125. throw new DirectoryNotFoundException("Source directory does not exist or could not be found: " + source);
  126. }
  127. // Don't copy excluded or directories that will be removed
  128. if (DirectoryExcludedOrInRemoveList(dir))
  129. {
  130. return;
  131. }
  132. // Removes the directory if it already exists
  133. if (removeIfExists)
  134. {
  135. Remove(dest);
  136. }
  137. // If the destination directory does not exist, create it.
  138. if (!Directory.Exists(dest))
  139. {
  140. Directory.CreateDirectory(dest);
  141. }
  142. // Get the file contents of the directory to copy.
  143. var files = dir.GetFiles();
  144. var excludedFiles = GetExcludedFiles(dir);
  145. foreach (var file in files.Except(excludedFiles))
  146. {
  147. // Create the path to the new copy of the file.
  148. var temppath = Path.Combine(dest, file.Name);
  149. // Copy the file.
  150. file.CopyTo(temppath, false);
  151. }
  152. // If subdirs is true, copy the subdirectories.
  153. if (subdirs)
  154. {
  155. foreach (var subdir in dirs.Where(s => !DirectoryExcludedOrInRemoveList(s)))
  156. {
  157. // Create the subdirectory.
  158. var temppath = Path.Combine(dest, subdir.Name);
  159. // Copy the subdirectories.
  160. CopyDirectory(subdir.FullName, temppath, true, removeIfExists);
  161. }
  162. }
  163. }
  164. /// <summary>
  165. /// Removes a directory
  166. /// </summary>
  167. /// <param name="directory">
  168. /// The directory.
  169. /// </param>
  170. /// <exception cref="ApplicationException">
  171. /// Error removing directory
  172. /// </exception>
  173. internal static void Remove(string directory)
  174. {
  175. try
  176. {
  177. if (!Directory.Exists(directory))
  178. {
  179. return;
  180. }
  181. Program.WriteVerboseMessage("Checking Directory {0}", directory);
  182. if (excludedDirs != null && excludedDirs.Contains(directory))
  183. {
  184. Program.WriteVerboseMessage("Not Removing Excluded Directory {0}", directory);
  185. }
  186. else
  187. {
  188. Program.WriteVerboseMessage("Removing {0}", directory);
  189. FileHelper.DeleteFiles(directory);
  190. // If the directory contains any excluded files, don't remove it.
  191. if (Program.Options.ExcludeFiles != null
  192. &&
  193. Program.Options.ExcludeFiles.Any(
  194. pattern => Directory.EnumerateFiles(directory, pattern, SearchOption.AllDirectories).Any()))
  195. {
  196. Program.WriteVerboseMessage("Directory contains excluded files, not removing {0}", directory);
  197. return;
  198. }
  199. Directory.Delete(directory, true);
  200. }
  201. }
  202. catch (UnauthorizedAccessException exception)
  203. {
  204. throw new ApplicationException(
  205. string.Format("Error removing directory {0}: {1}", directory, exception.Message));
  206. }
  207. catch (IOException exception)
  208. {
  209. throw new ApplicationException(
  210. string.Format("Error removing directory {0}: {1}", directory, exception.Message));
  211. }
  212. }
  213. /// <summary>
  214. /// Determines if a directory is excluded
  215. /// </summary>
  216. /// <param name="dir">
  217. /// The dir.
  218. /// </param>
  219. /// <returns>
  220. /// true if the directory is excluded
  221. /// </returns>
  222. private static bool DirectoryExcludedOrInRemoveList(DirectoryInfo dir)
  223. {
  224. // Don't copy directories that are excluded or to be removed
  225. return IsInList(excludedDirs, dir.FullName) || IsInList(removeDirs, dir.FullName);
  226. }
  227. /// <summary>
  228. /// Determines if a directory is excluded
  229. /// </summary>
  230. /// <param name="dir">
  231. /// The dir.
  232. /// </param>
  233. /// <returns>
  234. /// true if the directory is excluded
  235. /// </returns>
  236. private static bool DirectoryExcludedOrInRemoveList(string dir)
  237. {
  238. // Don't copy directories that are excluded or to be removed
  239. return excludedDirs.Contains(dir) || removeDirs.Contains(dir);
  240. }
  241. /// <summary>
  242. /// Gets a list of excluded files
  243. /// </summary>
  244. /// <param name="dir">
  245. /// The dir.
  246. /// </param>
  247. /// <returns>
  248. /// The list of files
  249. /// </returns>
  250. private static IEnumerable<FileInfo> GetExcludedFiles(DirectoryInfo dir)
  251. {
  252. var excludedFiles = new List<FileInfo>();
  253. if (Program.Options.ExcludeFiles != null)
  254. {
  255. foreach (var excludeFile in Program.Options.ExcludeFiles)
  256. {
  257. excludedFiles.AddRange(dir.GetFiles(excludeFile));
  258. }
  259. }
  260. if (Program.Options.RemoveFiles != null)
  261. {
  262. foreach (var removeFile in Program.Options.RemoveFiles)
  263. {
  264. excludedFiles.AddRange(dir.GetFiles(removeFile));
  265. }
  266. }
  267. return excludedFiles;
  268. }
  269. /// <summary>
  270. /// Determines if an item is in a list
  271. /// </summary>
  272. /// <param name="list">
  273. /// The list.
  274. /// </param>
  275. /// <param name="s">
  276. /// The s.
  277. /// </param>
  278. /// <returns>
  279. /// true if in the list
  280. /// </returns>
  281. private static bool IsInList(ICollection<string> list, string s)
  282. {
  283. return list != null && list.Contains(s);
  284. }
  285. #endregion
  286. }
  287. }