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); } }
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); MemoryStream memoryStream = new MemoryStream(); StreamWriter writer = new StreamWriter(memoryStream); // xml begin header Write(Template.Project.ProjectBegin, writer, resolver); string defaultInterpreterRegisterKeyName = $@"HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\{ devEnvRange.MinDevEnv.GetVisualVersionString() }\PythonTools\Options\Interpreters"; var defaultInterpreter = (string)Registry.GetValue(defaultInterpreterRegisterKeyName, "DefaultInterpreter", "{}") ?? "{00000000-0000-0000-0000-000000000000}"; var defaultInterpreterVersion = (string)Registry.GetValue(defaultInterpreterRegisterKeyName, "DefaultInterpreterVersion", "2.7") ?? "2.7"; string currentInterpreterId = defaultInterpreter; string currentInterpreterVersion = defaultInterpreterVersion; foreach (PythonEnvironment pyEnvironment in _project.Environments) { if (pyEnvironment.IsActivated) { string interpreterRegisterKeyName = $@"HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\{ devEnvRange.MinDevEnv.GetVisualVersionString() }\PythonTools\Interpreters\{{{pyEnvironment.Guid}}}"; string interpreterDescription = (string)Registry.GetValue(interpreterRegisterKeyName, "Description", ""); if (interpreterDescription != string.Empty) { currentInterpreterId = $"{{{pyEnvironment.Guid}}}"; currentInterpreterVersion = (string)Registry.GetValue(interpreterRegisterKeyName, "Version", currentInterpreterVersion); } } } foreach (PythonVirtualEnvironment virtualEnvironment in _project.VirtualEnvironments) { if (virtualEnvironment.IsDefault) { string baseInterpreterRegisterKeyName = $@"HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\{ devEnvRange.MinDevEnv.GetVisualVersionString() }\PythonTools\Interpreters\{{{virtualEnvironment.BaseInterpreterGuid}}}"; string baseInterpreterDescription = (string)Registry.GetValue(baseInterpreterRegisterKeyName, "Description", ""); if (baseInterpreterDescription != string.Empty) { currentInterpreterId = $"{{{virtualEnvironment.Guid}}}"; currentInterpreterVersion = (string)Registry.GetValue(baseInterpreterRegisterKeyName, "Version", currentInterpreterVersion); } } } using (resolver.NewScopedParameter("interpreterId", currentInterpreterId)) using (resolver.NewScopedParameter("interpreterVersion", currentInterpreterVersion)) { Write(Template.Project.ProjectDescription, writer, resolver); } GenerateItems(writer, resolver); foreach (PythonVirtualEnvironment virtualEnvironment in _project.VirtualEnvironments) { Write(Template.Project.ProjectItemGroupBegin, writer, resolver); using (resolver.NewScopedParameter("name", virtualEnvironment.Name)) using (resolver.NewScopedParameter("version", currentInterpreterVersion)) using (resolver.NewScopedParameter("basePath", virtualEnvironment.Path)) using (resolver.NewScopedParameter("baseGuid", virtualEnvironment.BaseInterpreterGuid)) 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 = $@"HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\{ devEnvRange.MinDevEnv.GetVisualVersionString() }\PythonTools\Interpreters\{{{pyEnvironment.Guid}}}"; string interpreterDescription = (string)Registry.GetValue(interpreterRegisterKeyName, "Description", ""); if (interpreterDescription != string.Empty) { string interpreterVersion = (string)Registry.GetValue(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); writer.Write(itemGroups.Resolve(resolver)); Write(Template.Project.ProjectEnd, writer, resolver); // Write the project file writer.Flush(); // remove all line that contain 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); } }