public void AddProjectToSln(string outputRootPath, string solutionName,
                                    string masterSolutionPath, CProject project)
        {
            var tempFileName = Path.GetFileName(Path.GetTempFileName());

            var relativePathBuilder = new RelativePathBuilder();

            var tempFolder       = relativePathBuilder.GetRelativePath(masterSolutionPath, Path.GetDirectoryName(project.Path));
            var tempRelativeFile = Path.Combine(tempFolder, tempFileName).Replace(@"/", @"\");
            var tempAbsFile      = Path.Combine(Path.GetDirectoryName(project.Path), tempFileName);

            if (!Directory.Exists(Path.GetDirectoryName(tempAbsFile)))
            {
                return;
            }

            var projectRelPath = relativePathBuilder.GetRelativePath(masterSolutionPath, Path.GetDirectoryName(project.Path));

            projectRelPath = Path.Combine(projectRelPath, Path.GetFileName(project.Path)).Replace(@"/", @"\");


            var slnTextA = File.ReadAllText(masterSolutionPath);

            if (slnTextA.Contains(projectRelPath))
            {
                return;
            }

            File.WriteAllText(tempAbsFile, "<Project/>");
            //add the mock project
            CommandProcessor.ExecuteCommand($@"dotnet sln ""{solutionName}.sln"" add ""{tempRelativeFile}""", outputRootPath);
            File.Delete(tempAbsFile);

            //update the .sln to point to real project. This is super fast, and won't get errors
            var slnText = File.ReadAllText(masterSolutionPath);

            slnText = slnText.Replace(tempRelativeFile, projectRelPath);
            slnText = slnText.Replace(Path.GetFileNameWithoutExtension(tempFileName), project.ProjectShortName);
            File.WriteAllText(masterSolutionPath, slnText);

            if (project.ProjectIs.HasFlag(CProjectIs.DataBase))
            {
                //fixup the project. turn the SqlProj back into true SqlProj
                var solutionFileText = File.ReadAllText(masterSolutionPath);

                solutionFileText = solutionFileText.Replace(
                    $@"Project(""{{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}}"") = ""{project.ProjectName}""",
                    $@"Project(""{{00D1A9C2-B5F0-4AF3-8072-F6C62B433612}}"") = ""{project.ProjectName}""");
                File.WriteAllText(masterSolutionPath, solutionFileText);


                FixupSqlProjFiles(project, outputRootPath);
            }
        }
        public CDockerComposeFile Build(CMetaRepo metaRepo)
        {
            //todo: switch to Visitor pattern
            var relativePathBuilder = new RelativePathBuilder();
            var dockerComposeFile   = new CDockerComposeFile();

            foreach (var repo in metaRepo.Repos)
            {
                foreach (var solution in repo.RepoSolution)
                {
                    foreach (var project in solution.Project)
                    {
                        if (!project.HasDockerFile)
                        {
                            continue;
                        }

                        //todo: move this into domain model ?
                        var relativePath = relativePathBuilder
                                           .GetRelativePath(metaRepo.CompositeRepo.RepoSolution.First().SolutionPath,
                                                            Path.GetDirectoryName(project.Path)).Replace(@"\", @"/");

                        dockerComposeFile.Service.Add(new CDockerFileService
                        {
                            ServiceName = project.ProjectShortName.ToLower().Replace(".", "_"),
                            Context     = $"./{relativePath}"
                        });
                    }
                }
            }

            return(dockerComposeFile);
        }