Exemplo n.º 1
0
 public SlnMergeMergeContext(SolutionFile solutionFile, SolutionFile overlaySolutionFile, SolutionFile mergedSolutionFile, SlnMergeSettings settings, ISlnMergeLogger logger)
 {
     SolutionFile        = solutionFile;
     OverlaySolutionFile = overlaySolutionFile;
     MergedSolutionFile  = mergedSolutionFile;
     Settings            = settings;
     Logger = logger;
 }
Exemplo n.º 2
0
        public static bool TryMerge(string solutionFilePath, string solutionFileContent, ISlnMergeLogger logger, out string resultSolutionContent)
        {
            try
            {
                // Load SlnMerge settings from .mergesttings
                var slnFileDirectory     = Path.GetDirectoryName(solutionFilePath);
                var slnMergeSettings     = new SlnMergeSettings();
                var slnMergeSettingsPath = Path.Combine(slnFileDirectory, Path.GetFileName(solutionFilePath) + ".mergesettings");
                if (File.Exists(slnMergeSettingsPath))
                {
                    logger.Debug($"Using SlnMerge Settings: {slnMergeSettingsPath}");
                    slnMergeSettings = SlnMergeSettings.FromFile(slnMergeSettingsPath);
                }
                else
                {
                    logger.Debug($"SlnMerge Settings (Not found): {slnMergeSettingsPath}");
                }

                if (slnMergeSettings.Disabled)
                {
                    logger.Debug("SlnMerge is currently disabled.");
                    resultSolutionContent = solutionFileContent;
                    return(true);
                }

                // Determine a overlay solution path.
                var overlaySolutionFilePath = Path.Combine(slnFileDirectory, Path.GetFileNameWithoutExtension(solutionFilePath) + ".Merge.sln");
                if (!string.IsNullOrEmpty(slnMergeSettings.MergeTargetSolution))
                {
                    overlaySolutionFilePath = NormalizePath(Path.Combine(slnFileDirectory, slnMergeSettings.MergeTargetSolution));
                }
                if (!File.Exists(overlaySolutionFilePath))
                {
                    logger.Warn($"Cannot load the solution file to merge. skipped: {overlaySolutionFilePath}");
                    resultSolutionContent = null;
                    return(false);
                }

                // Merge the solutions.
                var solutionFile        = SolutionFile.Parse(solutionFilePath, solutionFileContent);
                var overlaySolutionFile = SolutionFile.ParseFromFile(overlaySolutionFilePath);
                var mergedSolutionFile  = Merge(solutionFile, overlaySolutionFile, slnMergeSettings, logger);

                // Get file content of the merged solution.
                resultSolutionContent = mergedSolutionFile.ToFileContent();
            }
            catch (Exception e)
            {
                logger.Error("Failed to merge the solutions", e);
                resultSolutionContent = null;
                return(false);
            }

            return(true);
        }
Exemplo n.º 3
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);
        }
Exemplo n.º 4
0
        private static void ModifySolutionFolders(SolutionFile solutionFile, SlnMergeSettings settings, ISlnMergeLogger logger)
        {
            if (settings.NestedProjects == null || settings.NestedProjects.Length == 0)
            {
                return;
            }

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

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

            // Prepare to add nested projects.
            var nestedProjects = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

            foreach (var nestedProject in settings.NestedProjects)
            {
                var nestedProjectGuid       = default(string);
                var nestedProjectFolderGuid = default(string);

                // Find a target project
                if (string.IsNullOrEmpty(nestedProject.ProjectName))
                {
                    // by GUID
                    nestedProjectGuid = nestedProject.ProjectGuid;
                }
                else
                {
                    // by Name
                    var proj = solutionFile.Projects.Values.FirstOrDefault(x => x.Name == nestedProject.ProjectName);
                    if (proj != null)
                    {
                        nestedProjectGuid = proj.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.
                                var newFolder = new SolutionProject(solutionFile,
                                                                    typeGuid: GuidProjectTypeFolder,
                                                                    guid: Guid.NewGuid().ToString("B").ToUpper(),
                                                                    name: pathParts[i],
                                                                    path: pathParts[i]
                                                                    );
                                solutionFile.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(solutionFile);

                                nestedProjectFolderGuid = newFolder.Guid;
                            }
                        }
                    }
                }

                // Verify GUIDs / Paths
                if (nestedProjectGuid == null)
                {
                    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 (!solutionFile.Projects.ContainsKey(nestedProjectGuid))
                {
                    throw new Exception($"Project '{nestedProject.FolderGuid}' (GUID) does not exists in the solution.");
                }
                if (!solutionFile.Projects.ContainsKey(nestedProjectFolderGuid))
                {
                    throw new Exception($"Solution Folder '{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;
            }
        }
Exemplo n.º 5
0
 private static void MergeGlobalSections(SolutionFile solutionFile, SolutionFile overlaySolutionFile, SlnMergeSettings settings, ISlnMergeLogger logger)
 {
     foreach (var sectionKeyValue in overlaySolutionFile.Global.Sections)
     {
         if (solutionFile.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
         {
             solutionFile.Global.Sections.Add(sectionKeyValue.Key, sectionKeyValue.Value);
         }
     }
 }
Exemplo n.º 6
0
 private static void MergeProjects(SolutionFile solutionFile, SolutionFile overlaySolutionFile, SlnMergeSettings settings, ISlnMergeLogger logger)
 {
     foreach (var project in overlaySolutionFile.Projects)
     {
         if (!solutionFile.Projects.ContainsKey(project.Key))
         {
             if (!project.Value.IsFolder)
             {
                 var overlayProjectPathAbsolute = NormalizePath(Path.Combine(Path.GetDirectoryName(overlaySolutionFile.Path), project.Value.Path));
                 project.Value.Path = MakeRelative(solutionFile.Path, overlayProjectPathAbsolute);
             }
             solutionFile.Projects.Add(project.Key, project.Value);
         }
         else
         {
             // A project already exists.
         }
     }
 }