public BaselineProject(UnconfiguredProject project, ImmutableArray <string> globalProperties, ProjectStyle projectStyle) : this() { GlobalProperties = globalProperties; Project = project ?? throw new ArgumentNullException(nameof(project)); ProjectStyle = 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 bool TryCreateSdkBaselineProject(string projectFilePath, IProject project, IProjectRootElement root, ImmutableDictionary <string, ImmutableDictionary <string, string> > configurations, string tfm, bool keepCurrentTFMs, [NotNullWhen(true)] out BaselineProject?baselineProject) { var projectStyle = GetProjectStyle(root); var outputType = GetProjectOutputType(root); var rootElement = ProjectRootElement.Open(projectFilePath); rootElement.RemoveAllChildren(); switch (projectStyle) { case ProjectStyle.Default: case ProjectStyle.DefaultSubset: case ProjectStyle.MSTest: rootElement.Sdk = MSBuildFacts.DefaultSDKAttribute; break; case ProjectStyle.WindowsDesktop: rootElement.Sdk = tfm.ContainsIgnoreCase(MSBuildFacts.Net5) ? MSBuildFacts.DefaultSDKAttribute : DesktopFacts.WinSDKAttribute; // pre-.NET 5 apps need a special SDK attribute. break; case ProjectStyle.Web: rootElement.Sdk = WebFacts.WebSDKAttribute; break; default: baselineProject = null; return(false); } var propGroup = rootElement.AddPropertyGroup(); propGroup.AddProperty(MSBuildFacts.TargetFrameworkNodeName, project.GetTargetFramework()); var outputTypeValue = outputType switch { ProjectOutputType.Exe => MSBuildFacts.ExeOutputType, ProjectOutputType.Library => MSBuildFacts.LibraryOutputType, ProjectOutputType.WinExe => MSBuildFacts.WinExeOutputType, _ => project.GetPropertyValue(MSBuildFacts.OutputTypeNodeName) }; propGroup.AddProperty(MSBuildFacts.OutputTypeNodeName, outputTypeValue ?? throw new InvalidOperationException($"OutputType is not set! '{projectFilePath}'")); if (projectStyle == ProjectStyle.WindowsDesktop) { if (MSBuildHelpers.IsWinForms(root)) { MSBuildHelpers.AddUseWinForms(propGroup); } if (MSBuildHelpers.IsWPF(root)) { MSBuildHelpers.AddUseWPF(propGroup); } // User is referencing WindowsBase only if (MSBuildHelpers.IsDesktop(root) && !MSBuildHelpers.HasWPFOrWinForms(propGroup)) { MSBuildHelpers.AddUseWinForms(propGroup); } } // Create a new collection because a project with this name has already been loaded into the global collection. using var pc = new ProjectCollection(); var newProject = new UnconfiguredProject(configurations); newProject.LoadProjects(pc, rootElement); // If the original project had the TargetFramework property don't touch it during conversion. var propertiesInTheBaseline = ImmutableArray.Create(MSBuildFacts.OutputTypeNodeName); if (project.GetProperty(MSBuildFacts.TargetFrameworkNodeName) is { })
private static string GetCurrentTFM(ImmutableArray <string> globalProperties, UnconfiguredProject project) { if (globalProperties.Contains(MSBuildFacts.TargetFrameworkNodeName, StringComparer.OrdinalIgnoreCase)) { // The original project had a TargetFramework property. No need to add it again. return(globalProperties.First(p => p.Equals(MSBuildFacts.TargetFrameworkNodeName, StringComparison.OrdinalIgnoreCase))); } var rawTFM = project.FirstConfiguredProject.GetProperty(MSBuildFacts.TargetFrameworkNodeName)?.EvaluatedValue; if (rawTFM == null) { throw new InvalidOperationException( $"{MSBuildFacts.TargetFrameworkNodeName} is not set in {nameof(project.FirstConfiguredProject)}"); } // This is pretty much never gonna happen, but it was cheap to write the code return(MSBuildHelpers.IsNotNetFramework(rawTFM) ? StripDecimals(rawTFM) : rawTFM);