public GenerationContext(Builder builder, string projectPath, Project project, IEnumerable <Project.Configuration> projectConfigurations) { Builder = builder; FileInfo fileInfo = new FileInfo(projectPath); ProjectPath = fileInfo.FullName; ProjectDirectory = Path.GetDirectoryName(ProjectPath); ProjectFileName = Path.GetFileName(ProjectPath); Project = project; AndroidPackageProject = (AndroidPackageProject)Project; ProjectDirectoryCapitalized = Util.GetCapitalizedPath(ProjectDirectory); ProjectSourceCapitalized = Util.GetCapitalizedPath(Project.SourceRootPath); ProjectConfigurations = VsUtil.SortConfigurations(projectConfigurations, Path.Combine(ProjectDirectoryCapitalized, ProjectFileName + ProjectExtension)).ToArray(); DevelopmentEnvironmentsRange = new DevEnvRange(ProjectConfigurations); PresentPlatforms = ProjectConfigurations.Select(conf => conf.Platform).Distinct().ToDictionary(p => p, p => PlatformRegistry.Get <IPlatformVcxproj>(p)); }
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 void Generate( AndroidPackageProject project, List <Project.Configuration> unsortedConfigurations, string projectPath, string projectFile, List <string> generatedFiles, List <string> skipFiles) { // Need to sort by name and platform List <Project.Configuration> configurations = new List <Project.Configuration>(); configurations.AddRange(unsortedConfigurations.OrderBy(conf => conf.Name + conf.Platform)); // validate that 2 conf name in the same project don't have the same name Dictionary <string, Project.Configuration> configurationNameMapping = new Dictionary <string, Project.Configuration>(); string projectName = null; foreach (Project.Configuration conf in configurations) { if (projectName == null) { projectName = conf.ProjectName; } else if (projectName != conf.ProjectName) { throw new Error("Project configurations in the same project files must be the same: {0} != {1} in {2}", projectName, conf.ProjectName, projectFile); } Project.Configuration otherConf; string projectUniqueName = conf.Name + Util.GetPlatformString(conf.Platform, conf.Project); if (configurationNameMapping.TryGetValue(projectUniqueName, out otherConf)) { var differBy = Util.MakeDifferenceString(conf, otherConf); throw new Error( "Project {0} ({5} in {6}) have 2 configurations with the same name: \"{1}\" for {2} and {3}" + Environment.NewLine + "Nb: ps3 and win32 cannot have same conf name: {4}", project.Name, conf.Name, otherConf.Target, conf.Target, differBy, projectFile, projectPath); } configurationNameMapping[projectUniqueName] = conf; // set generator information switch (conf.Platform) { case Platform.android: conf.GeneratorSetGeneratedInformation("elf", "elf", "so", "pdb"); break; default: break; } } Resolver resolver = new Resolver(); _ProjectDirectoryCapitalized = Util.GetCapitalizedPath(projectPath); //_ProjectSourceCapitalized = Util.GetCapitalizedPath(project.SourceRootPath); _Project = project; _ProjectConfigurationList = configurations; MemoryStream memoryStream = new MemoryStream(); StreamWriter writer = new StreamWriter(memoryStream); // xml begin header DevEnvRange devEnvRange = new DevEnvRange(unsortedConfigurations); using (resolver.NewScopedParameter("toolsVersion", devEnvRange.MinDevEnv.GetVisualProjectToolsVersionString())) { Write(Template.Project.ProjectBegin, writer, resolver); } Write(Template.Project.ProjectBeginConfigurationDescription, writer, resolver); // xml header contain description of each target foreach (Project.Configuration conf in _ProjectConfigurationList) { using (resolver.NewScopedParameter("platformName", Util.GetPlatformString(conf.Platform, conf.Project))) using (resolver.NewScopedParameter("conf", conf)) { Write(Template.Project.ProjectConfigurationDescription, writer, resolver); } } Write(Template.Project.ProjectEndConfigurationDescription, writer, resolver); // xml end header var firstConf = _ProjectConfigurationList.First(); using (resolver.NewScopedParameter("projectName", projectName)) using (resolver.NewScopedParameter("guid", firstConf.ProjectGuid)) using (resolver.NewScopedParameter("toolsVersion", devEnvRange.MinDevEnv.GetVisualProjectToolsVersionString())) { Write(Template.Project.ProjectDescription, writer, resolver); } // generate all configuration options once... Dictionary <Project.Configuration, Options.ExplicitOptions> options = new Dictionary <Project.Configuration, Options.ExplicitOptions>(); foreach (Project.Configuration conf in _ProjectConfigurationList) { _ProjectConfiguration = conf; Options.ExplicitOptions option = GenerateOptions(project, projectPath, conf); _ProjectConfiguration = null; options.Add(conf, option); } // configuration general foreach (Project.Configuration conf in _ProjectConfigurationList) { using (resolver.NewScopedParameter("platformName", Util.GetPlatformString(conf.Platform, conf.Project))) using (resolver.NewScopedParameter("conf", conf)) using (resolver.NewScopedParameter("options", options[conf])) { Write(Template.Project.ProjectConfigurationsGeneral, writer, resolver); } } // .props files Write(Template.Project.ProjectAfterConfigurationsGeneral, writer, resolver); Write(Template.Project.ProjectAfterImportedProps, writer, resolver); string androidPackageDirectory = project.AntBuildRootDirectory; // configuration ItemDefinitionGroup foreach (Project.Configuration conf in _ProjectConfigurationList) { using (resolver.NewScopedParameter("platformName", Util.GetPlatformString(conf.Platform, conf.Project))) using (resolver.NewScopedParameter("conf", conf)) using (resolver.NewScopedParameter("options", options[conf])) using (resolver.NewScopedParameter("androidPackageDirectory", androidPackageDirectory)) { Write(Template.Project.ProjectConfigurationBeginItemDefinition, writer, resolver); { Write(Template.Project.AntPackage, writer, resolver); } Write(Template.Project.ProjectConfigurationEndItemDefinition, writer, resolver); } } GenerateFilesSection(project, writer, resolver, projectPath, projectFile, generatedFiles, skipFiles); GenerateProjectReferences(configurations, resolver, writer, options); // .targets Write(Template.Project.ProjectTargets, writer, resolver); Write(Template.Project.ProjectEnd, writer, resolver); // Write the project file writer.Flush(); // remove all line that contain RemoveLineTag MemoryStream cleanMemoryStream = Util.RemoveLineTags(memoryStream, FileGeneratorUtilities.RemoveLineTag); FileInfo projectFileInfo = new FileInfo(Path.Combine(projectPath, projectFile + ProjectExtension)); if (_Builder.Context.WriteGeneratedFile(project.GetType(), projectFileInfo, cleanMemoryStream)) { generatedFiles.Add(projectFileInfo.FullName); } else { skipFiles.Add(projectFileInfo.FullName); } writer.Close(); _Project = null; }
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); } }