private static void EditXmlDocument(string path, Action <XmlDocument> modify) { var doc = new XmlDocument(); Encoding enc; using (var reader = new StreamReader(path, new UTF8Encoding(false))) { doc.Load(reader); enc = reader.CurrentEncoding; if (enc is UTF8Encoding utf8) { Console.WriteLine("Preamble length: {0}", utf8.Preamble.Length); } } modify(doc); string newLine = LineEndingUtil.Detect(path); using (var writer = new StreamWriter(path, false, enc) { NewLine = newLine }) doc.Save(writer); }
public static void UpdateToVersion() { if (string.IsNullOrEmpty(RiderFolderPath)) { Error($"Parameter {nameof(RiderFolderPath)} is empty"); } if (string.IsNullOrEmpty(RdVersion)) { Error($"Parameter {nameof(RdVersion)} is empty"); } var productRoot = RiderFolderPath + "/Product.Root"; if (!File.Exists(productRoot)) { Error($"Invalid repository root: file `{productRoot}` doesn't exist"); } bool IsPackagesConfig(string file) => file.EndsWith("packages.config", StringComparison.OrdinalIgnoreCase); bool IsProj(string file) => file.EndsWith(".csproj", StringComparison.OrdinalIgnoreCase) || file.EndsWith(".vbproj", StringComparison.OrdinalIgnoreCase) || file.EndsWith(".vcxproj", StringComparison.OrdinalIgnoreCase); IEnumerable <string> FilesToProcess(string folder) { if (folder.EndsWith("data") && folder.Replace('\\', '/').EndsWith("test/data")) { yield break; //very big folder } var files = Directory.GetFiles(folder, "*", SearchOption.TopDirectoryOnly) .Where(it => IsProj(it) || IsPackagesConfig(it)) .ToList(); if (files.Count > 0) { foreach (var file in files) { yield return(file); } } if (!files.Any(IsProj)) //treat proj as terminating file { var dirs = Directory.GetDirectories(folder, "*", SearchOption.TopDirectoryOnly) .SelectMany(FilesToProcess); foreach (var file in dirs) { yield return(file); } } } void UpdatePackagesConfig(string file) { var doc = new XmlDocument(); Console.WriteLine($"Updating: {file}"); doc.Load(file); foreach (var pkg in Packages) { foreach (XmlNode node in doc.SelectNodes($"/packages/package[@id='{pkg}']")) { node.Attributes["version"].Value = RdVersion; } } string newLine = LineEndingUtil.Detect(file); using (var writer = new StreamWriter(file) { NewLine = newLine }) doc.Save(writer); } void UpdateCsproj(string file) { var doc = new XmlDocument(); Console.WriteLine($"Updating: {file}"); doc.Load(file); var namespaceManager = new XmlNamespaceManager(doc.NameTable); namespaceManager.AddNamespace("", doc.DocumentElement.NamespaceURI); namespaceManager.AddNamespace("x", doc.DocumentElement.NamespaceURI); foreach (var pkg in Packages) { foreach (XmlNode node in doc.SelectNodes($"//x:HintPath[contains(text(), \"{pkg}\")]", namespaceManager)) { var text = (XmlText)node.FirstChild; text.Value = Regex.Replace(text.Value, $"{pkg}.*.\\\\lib", $"{pkg}.{RdVersion}\\lib"); } foreach (XmlNode node in doc.SelectNodes($"//x:Import[contains(@Project, \"{pkg}\")]", namespaceManager)) { node.Attributes["Project"].Value = Regex.Replace(node.Attributes["Project"].Value, $"{pkg}.*.\\\\build", $"{pkg}.{RdVersion}\\build"); } } string newLine = LineEndingUtil.Detect(file); using (var writer = new StreamWriter(file) { NewLine = newLine }) doc.Save(writer); } var roots = Directory.GetDirectories(RiderFolderPath, "*", SearchOption.TopDirectoryOnly) .Where(it => File.Exists(it + "/SubplatformsCollection.Root ")); var sw = new Stopwatch(); foreach (var root in roots) { sw.Reset(); sw.Start(); foreach (var file in FilesToProcess(root).ToList()) { if (IsPackagesConfig(file)) { UpdatePackagesConfig(file); } if (IsProj(file)) { UpdateCsproj(file); } } Console.WriteLine($"{root}: {sw.Elapsed}"); } // var filesToProcess = roots.SelectMany(FilesToProcess); // Console.WriteLine(filesToProcess.Count(IsCsproj)); // Console.WriteLine(filesToProcess.Count(IsPackagesConfig)); }