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);
        }
Example #6
0
        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);
        }