private string Generate()

in Sharpmake.Generators/VisualStudio/Pyproj.cs [86:276]


        private string Generate(PythonProject project, List<Project.Configuration> unsortedConfigurations, string projectPath, string projectFile, out bool updated)
        {
            var itemGroups = new ItemGroups();

            // Need to sort by name and platform
            List<Project.Configuration> configurations = new List<Project.Configuration>();
            configurations.AddRange(unsortedConfigurations.OrderBy(conf => conf.Name + conf.Platform));
            string sourceRootPath = project.IsSourceFilesCaseSensitive ? Util.GetCapitalizedPath(project.SourceRootPath) : project.SourceRootPath;

            Resolver resolver = new Resolver();

            using (resolver.NewScopedParameter("guid", configurations.First().ProjectGuid))
            using (resolver.NewScopedParameter("projectHome", Util.PathGetRelative(projectPath, sourceRootPath)))
            using (resolver.NewScopedParameter("startupFile", project.StartupFile))
            using (resolver.NewScopedParameter("searchPath", project.SearchPaths.JoinStrings(";")))
            {
                _project = project;
                _projectConfigurationList = configurations;

                DevEnvRange devEnvRange = new DevEnvRange(unsortedConfigurations);
                bool needsPypatching = devEnvRange.MinDevEnv >= DevEnv.vs2017;

                if (!needsPypatching && (devEnvRange.MinDevEnv != devEnvRange.MaxDevEnv))
                {
                    Builder.Instance.LogWarningLine("There are mixed devEnvs for one project. VS2017 or higher Visual Studio solutions will require manual updates.");
                }

                MemoryStream memoryStream = new MemoryStream();
                StreamWriter writer = new StreamWriter(memoryStream);

                // xml begin header
                Write(Template.Project.ProjectBegin, writer, resolver);

                string defaultInterpreterRegisterKeyName = $@"Software\Microsoft\VisualStudio\{devEnvRange.MinDevEnv.GetVisualVersionString()}\PythonTools\Options\Interpreters";

                var defaultInterpreter = GetRegistryCurrentUserSubKeyValue(defaultInterpreterRegisterKeyName, "DefaultInterpreter", "{00000000-0000-0000-0000-000000000000}");
                var defaultInterpreterVersion = GetRegistryCurrentUserSubKeyValue(defaultInterpreterRegisterKeyName, "DefaultInterpreterVersion", "2.7");

                string currentInterpreterId = defaultInterpreter;
                string currentInterpreterVersion = defaultInterpreterVersion;
                string ptvsTargetsFile = $@"$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Python Tools\Microsoft.PythonTools.targets";

                // environments
                foreach (PythonEnvironment pyEnvironment in _project.Environments)
                {
                    if (pyEnvironment.IsActivated)
                    {
                        string interpreterRegisterKeyName =
                            $@"Software\Microsoft\VisualStudio\{devEnvRange.MinDevEnv.GetVisualVersionString()}\PythonTools\Interpreters\{{{pyEnvironment.Guid}}}";
                        string interpreterDescription = GetRegistryCurrentUserSubKeyValue(interpreterRegisterKeyName, "Description", "");
                        if (interpreterDescription != string.Empty)
                        {
                            currentInterpreterId = $"{{{pyEnvironment.Guid}}}";
                            currentInterpreterVersion = GetRegistryCurrentUserSubKeyValue(interpreterRegisterKeyName, "Version", currentInterpreterVersion);
                        }
                    }
                }

                // virtual environments
                foreach (PythonVirtualEnvironment virtualEnvironment in _project.VirtualEnvironments)
                {
                    if (virtualEnvironment.IsDefault)
                    {
                        string baseInterpreterRegisterKeyName =
                            $@"Software\Microsoft\VisualStudio\{devEnvRange.MinDevEnv.GetVisualVersionString()}\PythonTools\Interpreters\{{{virtualEnvironment.BaseInterpreterGuid}}}";
                        string baseInterpreterDescription = GetRegistryCurrentUserSubKeyValue(baseInterpreterRegisterKeyName, "Description", "");
                        if (baseInterpreterDescription != string.Empty)
                        {
                            currentInterpreterId = $"{{{virtualEnvironment.Guid}}}";
                            currentInterpreterVersion = GetRegistryCurrentUserSubKeyValue(baseInterpreterRegisterKeyName, "Version", currentInterpreterVersion);
                        }
                    }
                }

                // Project description
                if (needsPypatching)
                {
                    currentInterpreterId = $"MSBuild|debug|$(MSBuildProjectFullPath)";
                    ptvsTargetsFile = FileGeneratorUtilities.RemoveLineTag;
                }

                using (resolver.NewScopedParameter("interpreterId", currentInterpreterId))
                using (resolver.NewScopedParameter("interpreterVersion", currentInterpreterVersion))
                using (resolver.NewScopedParameter("ptvsTargetsFile", ptvsTargetsFile))
                {
                    Write(Template.Project.ProjectDescription, writer, resolver);
                }

                GenerateItems(writer, resolver);

                string baseGuid = FileGeneratorUtilities.RemoveLineTag;

                foreach (PythonVirtualEnvironment virtualEnvironment in _project.VirtualEnvironments)
                {
                    baseGuid = needsPypatching ? baseGuid : virtualEnvironment.BaseInterpreterGuid.ToString();
                    string pyVersion = string.IsNullOrEmpty(virtualEnvironment.Version) ? currentInterpreterVersion : virtualEnvironment.Version;

                    Write(Template.Project.ProjectItemGroupBegin, writer, resolver);
                    using (resolver.NewScopedParameter("name", virtualEnvironment.Name))
                    using (resolver.NewScopedParameter("version", pyVersion))
                    using (resolver.NewScopedParameter("basePath", virtualEnvironment.Path))
                    using (resolver.NewScopedParameter("baseGuid", baseGuid))
                    using (resolver.NewScopedParameter("guid", virtualEnvironment.Guid))
                    {
                        Write(Template.Project.VirtualEnvironmentInterpreter, writer, resolver);
                    }
                    Write(Template.Project.ProjectItemGroupEnd, writer, resolver);
                }

                Write(Template.Project.ProjectItemGroupBegin, writer, resolver);

                if (_project.Environments.Count > 0)
                {
                    foreach (PythonEnvironment pyEnvironment in _project.Environments)
                    {
                        // Verify if the interpreter exists in the register.
                        string interpreterRegisterKeyName =
                            $@"Software\Microsoft\VisualStudio\{devEnvRange.MinDevEnv.GetVisualVersionString()}\PythonTools\Interpreters\{{{pyEnvironment.Guid}}}";
                        string interpreterDescription = GetRegistryCurrentUserSubKeyValue(interpreterRegisterKeyName, "Description", "");
                        if (interpreterDescription != string.Empty)
                        {
                            string interpreterVersion = GetRegistryCurrentUserSubKeyValue(interpreterRegisterKeyName, "Version", currentInterpreterVersion);
                            using (resolver.NewScopedParameter("guid", $"{{{pyEnvironment.Guid}}}"))
                            using (resolver.NewScopedParameter("version", interpreterVersion))
                            {
                                Write(Template.Project.InterpreterReference, writer, resolver);
                            }
                        }
                    }
                }
                else if (_project.VirtualEnvironments.Count == 0) // Set the default interpreter
                {
                    using (resolver.NewScopedParameter("guid", currentInterpreterId))
                    using (resolver.NewScopedParameter("version", currentInterpreterVersion))
                    {
                        Write(Template.Project.InterpreterReference, writer, resolver);
                    }
                }
                Write(Template.Project.ProjectItemGroupEnd, writer, resolver);

                // configuration general
                foreach (Project.Configuration conf in _projectConfigurationList)
                {
                    foreach (var dependencies in new[] { conf.ResolvedPublicDependencies, conf.DotNetPrivateDependencies.Select(x => x.Configuration) })
                    {
                        foreach (var dependency in dependencies)
                        {
                            string relativeToProjectFile = Util.PathGetRelative(sourceRootPath, dependency.ProjectFullFileNameWithExtension);
                            bool privateDependency = project.DependenciesCopyLocal.HasFlag(Project.DependenciesCopyLocalTypes.ProjectReferences);
                            conf.GetDependencySetting(dependency.Project.GetType());

                            itemGroups.ProjectReferences.Add(new ItemGroups.ProjectReference
                            {
                                Include = relativeToProjectFile,
                                Name = dependency.ProjectName,
                                Private = privateDependency ? "True" : "False",
                                Project = new Guid(dependency.ProjectGuid)
                            });
                        }
                    }
                }

                GenerateFolders(writer, resolver);

                // Import native Python Tools project
                if (needsPypatching)
                {
                    Write(Template.Project.ImportPythonTools, writer, resolver);
                }

                writer.Write(itemGroups.Resolve(resolver));

                Write(Template.Project.ProjectEnd, writer, resolver);

                // Write the project file
                writer.Flush();

                // remove all line that contain RemoveLineTag
                memoryStream = Util.RemoveLineTags(memoryStream, FileGeneratorUtilities.RemoveLineTag);
                memoryStream.Seek(0, SeekOrigin.Begin);

                FileInfo projectFileInfo = new FileInfo(projectPath + @"\" + projectFile + ProjectExtension);
                updated = _builder.Context.WriteGeneratedFile(project.GetType(), projectFileInfo, memoryStream);

                writer.Close();

                _project = null;

                return projectFileInfo.FullName;
            }
        }