public void LoadProjects(Options options) { string projectFilePath = Path.GetFullPath(options.ProjectFilePath); if (!File.Exists(projectFilePath)) { Console.Error.WriteLine($"The project file '{projectFilePath}' does not exist or is inaccessible."); return; } ImmutableDictionary <string, string> globalProperties = InitializeGlobalProperties(options); var collection = new ProjectCollection(globalProperties); ProjectRootElement = new MSBuildProjectRootElement(Microsoft.Build.Construction.ProjectRootElement.Open(projectFilePath, collection, preserveFormatting: true)); var configurations = DetermineConfigurations(ProjectRootElement); Project = new UnconfiguredProject(configurations); Project.LoadProjects(collection, globalProperties, projectFilePath); Console.WriteLine($"Successfully loaded project file '{projectFilePath}'."); var targetProjectProperties = options.TargetProjectProperties.ToImmutableDictionary(p => p.Split('=')[0], p => p.Split('=')[1]); SdkBaselineProject = CreateSdkBaselineProject(projectFilePath, Project.FirstConfiguredProject, globalProperties, configurations, targetProjectProperties); ProjectRootElement.Reload(throwIfUnsavedChanges: false, preserveFormatting: true); Console.WriteLine($"Successfully loaded sdk baseline of project."); }
/// <summary> /// Clear out the project's construction model and add a simple SDK-based project to get a baseline. /// We need to use the same name as the original csproj and same path so that all the default that derive /// from name\path get the right values (there are a lot of them). /// </summary> private BaselineProject CreateSdkBaselineProject(string projectFilePath, IProject project, ImmutableDictionary <string, string> globalProperties, ImmutableDictionary <string, ImmutableDictionary <string, string> > configurations, ImmutableDictionary <string, string> targetProjectProperties) { var projectStyle = GetProjectStyle(ProjectRootElement); var rootElement = Microsoft.Build.Construction.ProjectRootElement.Open(projectFilePath); rootElement.RemoveAllChildren(); switch (projectStyle) { case ProjectStyle.Default: rootElement.Sdk = "Microsoft.NET.Sdk"; break; case ProjectStyle.DefaultWithCustomTargets: var imports = ProjectRootElement.Imports; void CopyImport(ProjectImportElement import) { var newImport = rootElement.AddImport(import.Project); newImport.Condition = import.Condition; } CopyImport(imports.First()); CopyImport(imports.Last()); break; default: throw new NotSupportedException("This project has custom imports in a manner that's not supported."); } var propGroup = rootElement.AddPropertyGroup(); propGroup.AddProperty("TargetFramework", project.GetTargetFramework()); propGroup.AddProperty("OutputType", project.GetPropertyValue("OutputType") ?? throw new InvalidOperationException("OutputType is not set!")); var newGlobalProperties = globalProperties.AddRange(targetProjectProperties); // Create a new collection because a project with this name has already been loaded into the global collection. var pc = new ProjectCollection(newGlobalProperties); var newProject = new UnconfiguredProject(configurations); newProject.LoadProjects(pc, newGlobalProperties, rootElement); // If the original project had the TargetFramework property don't touch it during conversion. var propertiesInTheBaseline = ImmutableArray.Create("OutputType"); if (project.GetProperty("TargetFramework") != null) { propertiesInTheBaseline = propertiesInTheBaseline.Add("TargetFramework"); } return(new BaselineProject(newProject, propertiesInTheBaseline, targetProjectProperties, projectStyle)); }
/// <summary> /// Clear out the project's construction model and add a simple SDK-based project to get a baseline. /// We need to use the same name as the original csproj and same path so that all the default that derive /// from name\path get the right values (there are a lot of them). /// </summary> private BaselineProject CreateSdkBaselineProject(string projectFilePath, IProject project, ImmutableDictionary <string, string> globalProperties, ImmutableDictionary <string, ImmutableDictionary <string, string> > configurations) { var rootElement = ProjectRootElement.Open(projectFilePath); rootElement.RemoveAllChildren(); rootElement.Sdk = "Microsoft.NET.Sdk"; var propGroup = rootElement.AddPropertyGroup(); propGroup.AddProperty("TargetFramework", project.GetTargetFramework()); propGroup.AddProperty("OutputType", project.GetPropertyValue("OutputType") ?? throw new InvalidOperationException("OutputType is not set!")); // Create a new collection because a project with this name has already been loaded into the global collection. var pc = new ProjectCollection(globalProperties); var newProject = new UnconfiguredProject(configurations); newProject.LoadProjects(pc, globalProperties, rootElement); return(new BaselineProject(newProject, ImmutableArray.Create("OutputType"), GetProjectStyle(ProjectRootElement))); }
public void LoadProjects(Options options) { string projectFilePath = Path.GetFullPath(options.ProjectFilePath); if (!File.Exists(projectFilePath)) { Console.Error.WriteLine($"The project file '{projectFilePath}' does not exist or is inaccessible."); return; } ImmutableDictionary <string, string> globalProperties = InitializeGlobalProperties(options); var collection = new ProjectCollection(globalProperties, loggers: null, toolsetDefinitionLocations: ToolsetDefinitionLocations.Local); ProjectRootElement = ProjectRootElement.Open(projectFilePath).DeepClone(); var configurations = DetermineConfigurations(ProjectRootElement); Project = new UnconfiguredProject(configurations); Project.LoadProjects(collection, globalProperties, projectFilePath); Console.WriteLine($"Successfully loaded project file '{projectFilePath}'."); SdkBaselineProject = CreateSdkBaselineProject(projectFilePath, Project.FirstConfiguredProject, globalProperties, configurations); Console.WriteLine($"Successfully loaded sdk baseline of project."); }