static void GetFilesInDir(int basePathLength, DirectoryInfo dir, ExclusionRules exclusionRules, Dictionary<string, FileInfo> filesDictionary, string location) { foreach (var file in dir.GetFiles().Where(f => !exclusionRules.IsMatch(f.FullName, ExclusionRuleTypes.File, location))) filesDictionary.Add(file.FullName.Substring(basePathLength + 1).ToLower(), file); foreach (var subDir in dir.GetDirectories().Where(subDir => !exclusionRules.IsMatch(subDir.FullName, ExclusionRuleTypes.Folder, location))) GetFilesInDir(basePathLength, subDir, exclusionRules, filesDictionary, location); }
static bool SyncUsingPubsync(string publishingPath, string xmlNamespace, XElement folder, XElement profile) { try { var stopwatch = new Stopwatch(); stopwatch.Start(); var folderPath = folder.Attribute("Path").Value; Console.WriteLine("{0}", folderPath); Console.WriteLine("------------------------------------------------------------------------------"); //var filesToExclude = folder.Elements(xmlNamespace + "Exclude").Where(e => e.Attribute("Type").Value == "File") // .Select( // d => // new Regex(d.Attribute("Expression").Value, RegexOptions.Compiled & RegexOptions.IgnoreCase)) // .ToList(); var exclusionRules = new ExclusionRules(GetExclusionRules(xmlNamespace, folder)); exclusionRules.Rules.AddRange(GetExclusionRules(xmlNamespace, profile)); //var foldersToExclude = //folder.Elements(xmlNamespace + "Exclude").Where(e => e.Attribute("Type").Value == "Folder") // .Select( // d => // new Regex(d.Attribute("Expression").Value, RegexOptions.Compiled & RegexOptions.IgnoreCase)) // .ToList(); var replacementRules = GetReplacementRules(xmlNamespace, folder); replacementRules.AddRange(GetReplacementRules(xmlNamespace, profile)); var sourceDir = new DirectoryInfo(folderPath); var sourceFilesDictionary = new Dictionary<string, FileInfo>(); if (!sourceDir.Exists) { Console.WriteLine("Folder '{0}' does not exist on the source.", folderPath); PrintSeparator(); return true; } GetFilesInDir(sourceDir.FullName.Length, sourceDir, exclusionRules, sourceFilesDictionary, "Source"); var destDir = new DirectoryInfo(Path.Combine(publishingPath, folderPath)); var destFilesDictionary = new Dictionary<string, FileInfo>(); if (!destDir.Exists) destDir.Create(); GetFilesInDir(destDir.FullName.Length, destDir, exclusionRules, destFilesDictionary, "Destination"); int changedFilesCount = 0; int deletedFilesCount = 0; int newFilesCount = 0; int skippedFilesCount = 0; int errorCount = 0; var keyMap = sourceFilesDictionary.Keys .ToDictionary(x => x, x => ApplyReplacementsToFileName(x, replacementRules)); // Check source files for new / changed foreach (var sourceFileEntry in sourceFilesDictionary) { try { FileInfo destFile; var destKey = keyMap[sourceFileEntry.Key]; if (destFilesDictionary.TryGetValue(destKey, out destFile)) { if (sourceFileEntry.Value.Length != destFile.Length || sourceFileEntry.Value.LastWriteTime != destFile.LastWriteTime) { // Console.WriteLine("C: {0}", sourceFileEntry.Value.Name); if (_syncFiles) sourceFileEntry.Value.CopyTo(Path.Combine(destDir.FullName, destKey), true); changedFilesCount++; } else skippedFilesCount++; } else { // Console.WriteLine("N: {0}", sourceFileEntry.Value.Name); if (_syncFiles) { destFile = new FileInfo(Path.Combine(destDir.FullName, destKey)); if (!destFile.Directory.Exists) destFile.Directory.Create(); sourceFileEntry.Value.CopyTo(destFile.FullName, true); } newFilesCount++; } } catch (Exception ex) { Console.WriteLine(ex); errorCount++; } } // Check for orphaned files to delete if (_syncFiles && !_noDelete) foreach (var fileKey in destFilesDictionary.Keys.Except(keyMap.Values)) { try { destFilesDictionary[fileKey].Delete(); deletedFilesCount++; } catch (Exception ex) { Console.WriteLine(ex); errorCount++; } } stopwatch.Stop(); Console.WriteLine("Skipped: {0}\r\nNew: {1}\r\nChanged: {2}\r\nDeleted: {3}\r\nErrors: {4}", skippedFilesCount, newFilesCount, changedFilesCount, deletedFilesCount, errorCount); Console.WriteLine("Time: {0}", stopwatch.Elapsed); PrintSeparator(); return errorCount==0; } catch (Exception ex) { Console.WriteLine(ex); return false; } }