예제 #1
0
 public BaselineProject(UnconfiguredProject project, ImmutableArray <string> globalProperties, ProjectStyle projectStyle) : this()
 {
     GlobalProperties = globalProperties;
     Project          = project ?? throw new ArgumentNullException(nameof(project));
     ProjectStyle     = projectStyle;
 }
예제 #2
0
        /// <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 { })
예제 #3
0
        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);