Esempio n. 1
0
        private static void MergeProjects(SlnMergeMergeContext ctx)
        {
            foreach (var project in ctx.OverlaySolutionFile.Projects)
            {
                if (!ctx.MergedSolutionFile.Projects.ContainsKey(project.Key))
                {
                    // If a solution contains a project that has same name, resolve conflict by resolution strategy.
                    if (ctx.MergedSolutionFile.Projects.Any(x => x.Value.Name == project.Value.Name))
                    {
                        if (ctx.Settings.ProjectConflictResolution == ProjectConflictResolution.PreserveUnity)
                        {
                            // Ignore Overlay's project
                            continue;
                        }
                        else if (ctx.Settings.ProjectConflictResolution == ProjectConflictResolution.PreserveOverlay)
                        {
                            // Remove Unity generated project
                            var duplicatedProject = ctx.MergedSolutionFile.Projects.First(x => x.Value.Name == project.Value.Name);
                            ctx.MergedSolutionFile.Projects.Remove(duplicatedProject.Key);
                        }
                        else
                        {
                            // Preserve all projects
                        }
                    }

                    if (project.Value.IsFolder)
                    {
                        // If the project is a folder and it contains solution items, we adjust the path of solution items.
                        if (project.Value.Sections.TryGetValue(("SolutionItems", "preProject"), out var solutionItems))
                        {
                            foreach (var solutionItem in solutionItems.Values.ToArray())
                            {
                                solutionItems.Values.Remove(solutionItem.Key);
                                var solutionItemPathAbsolute = NormalizePath(Path.Combine(Path.GetDirectoryName(ctx.OverlaySolutionFile.Path), solutionItem.Key));
                                var solutionItemPathRelative = MakeRelative(ctx.MergedSolutionFile.Path, solutionItemPathAbsolute);
                                solutionItems.Values[solutionItemPathRelative] = solutionItemPathRelative;
                            }
                        }
                    }
                    else
                    {
                        var overlayProjectPathAbsolute = NormalizePath(Path.Combine(Path.GetDirectoryName(ctx.OverlaySolutionFile.Path), project.Value.Path));
                        project.Value.Path = MakeRelative(ctx.MergedSolutionFile.Path, overlayProjectPathAbsolute);
                    }
                    ctx.MergedSolutionFile.Projects.Add(project.Key, project.Value);
                }
                else
                {
                    // A project already exists.
                }
            }
        }
Esempio n. 2
0
        public static SolutionFile Merge(SolutionFile solutionFile, SolutionFile overlaySolutionFile, SlnMergeSettings settings, ISlnMergeLogger logger)
        {
            logger.Debug($"Merge solution: Base={solutionFile.Path}; Overlay={overlaySolutionFile.Path}");

            var ctx = new SlnMergeMergeContext(solutionFile, overlaySolutionFile, solutionFile.Clone(), settings, logger);

            MergeProjects(ctx);

            MergeGlobalSections(ctx);

            ModifySolutionFolders(ctx);

            return(ctx.MergedSolutionFile);
        }
Esempio n. 3
0
 private static void MergeGlobalSections(SlnMergeMergeContext ctx)
 {
     foreach (var sectionKeyValue in ctx.OverlaySolutionFile.Global.Sections)
     {
         if (ctx.MergedSolutionFile.Global.Sections.TryGetValue(sectionKeyValue.Key, out var targetSection))
         {
             foreach (var keyValue in sectionKeyValue.Value.Values)
             {
                 targetSection.Values[keyValue.Key] = keyValue.Value;
             }
             targetSection.Children.AddRange(sectionKeyValue.Value.Children);
         }
         else
         {
             ctx.MergedSolutionFile.Global.Sections.Add(sectionKeyValue.Key, sectionKeyValue.Value);
         }
     }
 }
Esempio n. 4
0
        private static void MergeProjects(SlnMergeMergeContext ctx)
        {
            foreach (var project in ctx.OverlaySolutionFile.Projects)
            {
                if (!ctx.MergedSolutionFile.Projects.ContainsKey(project.Key))
                {
                    // If a solution contains a project that has same name, resolve conflict by resolution strategy.
                    if (ctx.MergedSolutionFile.Projects.Any(x => x.Value.Name == project.Value.Name))
                    {
                        if (ctx.Settings.ProjectConflictResolution == ProjectConflictResolution.PreserveUnity)
                        {
                            // Ignore Overlay's project
                            continue;
                        }
                        else if (ctx.Settings.ProjectConflictResolution == ProjectConflictResolution.PreserveOverlay)
                        {
                            // Remove Unity generated project
                            var duplicatedProject = ctx.MergedSolutionFile.Projects.First(x => x.Value.Name == project.Value.Name);
                            ctx.MergedSolutionFile.Projects.Remove(duplicatedProject.Key);
                        }
                        else
                        {
                            // Preserve all projects
                        }
                    }

                    if (!project.Value.IsFolder)
                    {
                        var overlayProjectPathAbsolute = NormalizePath(Path.Combine(Path.GetDirectoryName(ctx.OverlaySolutionFile.Path), project.Value.Path));
                        project.Value.Path = MakeRelative(ctx.MergedSolutionFile.Path, overlayProjectPathAbsolute);
                    }
                    ctx.MergedSolutionFile.Projects.Add(project.Key, project.Value);
                }
                else
                {
                    // A project already exists.
                }
            }
        }
Esempio n. 5
0
        private static void ModifySolutionFolders(SlnMergeMergeContext ctx)
        {
            if (ctx.Settings.NestedProjects == null || ctx.Settings.NestedProjects.Length == 0)
            {
                return;
            }

            // Build a solution folder tree.
            var solutionTree = BuildSolutionFlatTree(ctx.MergedSolutionFile);

            // Create a NestedProject section in the solution if it does not exist.
            if (!ctx.MergedSolutionFile.Global.Sections.TryGetValue(("NestedProjects", "preSolution"), out var section))
            {
                section = new SolutionGlobalSection(ctx.MergedSolutionFile.Global, "NestedProjects", "preSolution");
                ctx.MergedSolutionFile.Global.Sections.Add((section.Category, section.Value), section);
            }

            // Prepare to add nested projects.
            var definedSolutionFolders = (ctx.Settings.SolutionFolders ?? Array.Empty <SlnMergeSettings.SolutionFolder>())
                                         .ToDictionary(k => k.FolderPath.Replace('\\', '/'), v => v.Guid);
            var nestedProjects = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

            foreach (var nestedProject in ctx.Settings.NestedProjects)
            {
                IEnumerable <string> nestedProjectGuids;
                var nestedProjectFolderGuid = default(string);

                // Find a target project
                if (string.IsNullOrEmpty(nestedProject.ProjectName))
                {
                    // by GUID
                    nestedProjectGuids = new[] { nestedProject.ProjectGuid };
                }
                else
                {
                    // by Name
                    var nestedProjectNamePattern = new Regex(
                        "^" + Regex.Escape(nestedProject.ProjectName)
                        .Replace(@"\*", ".*").Replace(@"\?", ".") + "$");
                    nestedProjectGuids = ctx.MergedSolutionFile.Projects.Values
                                         .Where(x => nestedProjectNamePattern.IsMatch(x.Name))
                                         .Select(x => x.Guid);
                }

                // Find a solution folder
                if (string.IsNullOrEmpty(nestedProject.FolderPath))
                {
                    // by GUID
                    nestedProjectFolderGuid = nestedProject.FolderGuid;
                }
                else
                {
                    // by Path
                    if (solutionTree.TryGetValue(nestedProject.FolderPath, out var folderNode))
                    {
                        if (!folderNode.IsFolder)
                        {
                            throw new Exception($"Path '{nestedProject.FolderPath}' is not a Solution Folder.");
                        }
                        nestedProjectFolderGuid = folderNode.Project.Guid;
                    }
                    else
                    {
                        // The target Solution Folder does not exist. make the Solution Folders.
                        var pathParts = nestedProject.FolderPath.Split('/', '\\');
                        for (var i = 0; i < pathParts.Length; i++)
                        {
                            var path       = string.Join("/", pathParts.Take(i + 1));
                            var parentPath = string.Join("/", pathParts.Take(i));

                            if (solutionTree.TryGetValue(path, out var folderNode2))
                            {
                                // A solution tree node already exists.
                                if (!folderNode2.IsFolder)
                                {
                                    throw new Exception($"Path '{path}' is not a Solution Folder.");
                                }
                            }
                            else
                            {
                                // Create a new solution folder.
                                if (!definedSolutionFolders.TryGetValue(path, out var guid))
                                {
                                    throw new Exception($"Path '{path}' doesn't exist in the Solution or Solution Folder definitions. To create a new folder, you need to define SolutionFolder in .mergesettings.");
                                }

                                var newFolder = new SolutionProject(ctx.MergedSolutionFile,
                                                                    typeGuid: GuidProjectTypeFolder,
                                                                    guid: guid.ToUpper(),
                                                                    name: pathParts[i],
                                                                    path: pathParts[i]
                                                                    );
                                ctx.MergedSolutionFile.Projects.Add(newFolder.Guid, newFolder);

                                // If the solution folder has a parent folder, add the created folder as a child immediately.
                                if (!string.IsNullOrEmpty(parentPath))
                                {
                                    section.Values[newFolder.Guid] = solutionTree[parentPath].Project.Guid;
                                }

                                // Rebuild the solution tree.
                                solutionTree = BuildSolutionFlatTree(ctx.MergedSolutionFile);

                                nestedProjectFolderGuid = newFolder.Guid;
                            }
                        }
                    }
                }

                // Verify GUIDs / Paths
                if (!nestedProjectGuids.Any())
                {
                    throw new Exception($"Project '{nestedProject.ProjectName}' does not exists in the solution.");
                }
                if (nestedProjectFolderGuid == null)
                {
                    throw new Exception($"Solution Folder '{nestedProject.FolderGuid}' (GUID) does not exists in the solution.");
                }
                if (!ctx.MergedSolutionFile.Projects.ContainsKey(nestedProjectFolderGuid))
                {
                    throw new Exception($"Solution Folder '{nestedProject.FolderGuid}' (GUID) does not exists in the solution.");
                }
                foreach (var nestedProjectGuid in nestedProjectGuids)
                {
                    if (!ctx.MergedSolutionFile.Projects.ContainsKey(nestedProjectGuid))
                    {
                        throw new Exception($"Project '{nestedProject.FolderGuid}' (GUID) does not exists in the solution.");
                    }
                    nestedProjects.Add(nestedProjectGuid, nestedProjectFolderGuid);
                }
            }

            // Add nested projects.
            foreach (var keyValue in nestedProjects)
            {
                section.Values[keyValue.Key] = keyValue.Value;
            }
        }