public static List<BaseProject> Parse(SolutionInfo solutionInfo) { return ReProjects.Matches(solutionInfo.Text) .Cast<Match>() .Select(m => BaseProject.Create(m.Groups["Guid"].Value, m.Groups["Name"].Value, m.Groups["Project"].Value, new ProjectInfo(solutionInfo, m.Groups["Package"].Value, m.Groups["All"].Value))) .ToList(); }
public ProjectInfo(SolutionInfo solutionInfo, string package, string all) { SolutionInfo = solutionInfo; Package = package; this.all = all; pathResolver = new PathResolver(BaseDir); }
public static SolutionInfo Parse(string slnPath) { var slnText = File.ReadAllText(slnPath); var path = Path.GetFullPath(slnPath); var slnBaseDir = Path.GetDirectoryName(path); var props = SolutionPropertiesInfo.Parse(slnText); var sln = new SolutionInfo(Path.GetFileNameWithoutExtension(path), slnBaseDir, props, new NestedProjectsInfo()) { Text = slnText }; sln.Projects = ProjectInfo.Parse(sln); return sln; }
public static SolutionInfo MergeSolutions(string newName, string baseDir, out string warnings, params SolutionInfo[] solutions) { var allProjects = solutions.SelectMany(s => s.Projects).Distinct(BaseProject.ProjectGuidLocationComparer).ToList(); warnings = SolutionDiagnostics.DiagnoseDupeGuids(solutions); var mergedSln = new SolutionInfo(newName, baseDir, solutions[0].PropsSection, new NestedProjectsInfo()) { Projects = allProjects }; mergedSln.CreateNestedDirs() .Projects.ForEach(pr => pr.ProjectInfo.SolutionInfo = mergedSln); return mergedSln; }
public static void FixAllSolutions(SolutionInfo[] allSolutions, out string errors) { var dupes = SolutionDiagnostics.GetProjectGuidDuplicates(allSolutions); if (dupes.Length == 0) { errors = null; return; } errors = SolutionDiagnostics.DiagnoseDupeGuidsInTheSameSolution(dupes); if (!string.IsNullOrEmpty(errors)) return; var dupedProjects = dupes.SelectMany(g => g.Skip(1)).ToArray();//it's sufficient to rename all but one dupe - it'll be left with uniquer GUID //Find all solutions with dupes var slns = allSolutions.Where(s => s.Projects.Any(p => dupedProjects.Contains(p, BaseProject.ProjectGuidLocationComparer))).ToDictionary(s => s, s => s.Text); //Find all projects of these solutions - check for read/write access?? var prjs = slns.Keys.SelectMany(s => s.Projects).OfType<Project>().Distinct<Project>(BaseProject.ProjectGuidLocationComparer).Where(pp => File.Exists(pp.AbsolutePath)).ToDictionary(pp => pp, pp => File.ReadAllText(pp.AbsolutePath)); //checks for Read/Write access :) - overwrites potentially modified files without changes errors = OverwriteFiles(slns, prjs); if (!string.IsNullOrEmpty(errors)) return; foreach (var dupedProject in dupedProjects) { var dupe = dupedProject; var brokenGuid = dupe.Guid.Substring(1, dupe.Guid.Length - 2); var newGuid = Guid.NewGuid().ToString().ToUpper(); var affectedSolutions = slns.Keys.Where(s => s.Projects.Contains(dupe, BaseProject.ProjectGuidLocationComparer)).ToArray(); foreach (var s in affectedSolutions) { slns[s] = slns[s].Replace(brokenGuid, newGuid); } if (dupe is ProjectDirectory)// directories are mentioned only in solution files continue; var affectedProjects = prjs.Keys.Where(p => affectedSolutions.Contains(p.ProjectInfo.SolutionInfo)).ToArray(); foreach (var p in affectedProjects) { prjs[p] = prjs[p].Replace(brokenGuid, newGuid); } } errors = OverwriteFiles(slns, prjs); }
public static SolutionInfo MergeSolutions(string newName, string baseDir, out string warnings, params SolutionInfo[] solutions) { var duplicates = solutions .SelectMany(s => s.Projects) .GroupBy(p => p.Guid) .Where(g => g.Count() > 1) .Select(y => y.Key) .ToList(); var relocation = new Dictionary <string, Dictionary <string, string> >(); var allProjects = new List <BaseProject>(); foreach (var solution in solutions) { foreach (var project in solution.Projects) { var shouldRelocate = duplicates.Contains(project.Guid); if (shouldRelocate) { // Whenever we see this project GUID in the nested project section, // we are going to replace it with this new GUID. var newGuid = $"{{{Guid.NewGuid().ToString()}}}"; if (relocation.ContainsKey(solution.Name)) { relocation[solution.Name].Add(project.Guid, newGuid); } else { relocation.Add(solution.Name, new Dictionary <string, string> { { project.Guid, newGuid } }); } // We have a copy of this GUID - update it now. project.Guid = newGuid; } allProjects.Add(project); } } warnings = SolutionDiagnostics.DiagnoseDupeGuids(solutions); var mergedSln = new SolutionInfo(newName, baseDir, solutions[0].PropsSection, new NestedProjectsInfo()) { Projects = allProjects }; // Parse the following section in each .sln file: // // GlobalSection(NestedProjects) = preSolution // {GUID A} = {GUID B} // {GUID C} = {GUID D} // ... // EndGlobalSection // // and determine its original location associations (e.g. A belongs to B, C belongs to D). char[] charsToTrim = { ' ', '\t' }; var nested = new Regex(@"GlobalSection\(NestedProjects\)\s=\spreSolution(?<Section>[\s\S]*?)EndGlobalSection", RegexOptions.Multiline | RegexOptions.Compiled); var allNestedProjects = new Dictionary <string, Dictionary <string, string> >(); foreach (var solution in solutions) { var found = nested.Match(solution.Text).Groups["Section"].Value; if (string.IsNullOrEmpty(found)) { continue; } var value = found .Trim(charsToTrim) .Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries) .Select(part => part.Split('=')) .ToDictionary( split => // GUID of this project. { var newGuid = string.Empty; var key = split[0].Trim(charsToTrim); if (relocation.ContainsKey(solution.Name) && relocation[solution.Name].TryGetValue(key, out newGuid)) { key = newGuid; } return(key); }, split => // GUID of location where this project belongs. { var newGuid = string.Empty; var key = split[1].Trim(charsToTrim); if (relocation.ContainsKey(solution.Name) && relocation[solution.Name].TryGetValue(key, out newGuid)) { key = newGuid; } return(key); }); allNestedProjects.Add(solution.Name, value); } mergedSln.CreateNestedDirs(allNestedProjects) .Projects.ForEach(pr => { pr.ProjectInfo.SolutionInfo = mergedSln; }); return(mergedSln); }