예제 #1
0
        /// <summary>
        /// Chooses the most likely target TFM a project should be retargeted to based on its style, output type, dependencies, and
        /// the user's preference of current or LTS.
        /// </summary>
        public TargetFrameworkMoniker SelectTFM(IProject project)
        {
            if (project is null)
            {
                throw new ArgumentNullException(nameof(project));
            }

            var tfmName = GetNetStandardTFM(project);

            // Projects with web components or an Exe output type should use app TFMs
            if (project.Components.HasFlag(ProjectComponents.AspNet) || project.Components.HasFlag(ProjectComponents.AspNetCore) || project.OutputType == ProjectOutputType.Exe)
            {
                tfmName = AppTFMBase;
            }

            // Projects with Windows Desktop components or a WinExe output type should use a -windows suffix
            if (project.Components.HasFlag(ProjectComponents.WindowsDesktop) || project.OutputType == ProjectOutputType.WinExe)
            {
                tfmName = $"{AppTFMBase}{WindowsSuffix}";

                if (project.Components.HasFlag(ProjectComponents.WinRT))
                {
                    // TODO: Default to this version to ensure everything is supported.
                    tfmName += "10.0.19041.0";
                }
            }

            _logger.LogDebug("Considering TFM {TFM} for project {Project} based on its style and output type ({ProjectStyle}, {ProjectOutputType})", tfmName, project.FilePath, project.Components, project.OutputType);

            // If the project depends on another project with a higher version NetCore or NetStandard TFM,
            // use that TFM instead.
            var tfm = new TargetFrameworkMoniker(tfmName);

            foreach (var dep in project.ProjectReferences)
            {
                try
                {
                    if (_tfmComparer.IsCompatible(tfm, dep.TFM))
                    {
                        continue;
                    }

                    if (dep.TFM.IsNetCore || dep.TFM.IsNetStandard)
                    {
                        tfm = dep.TFM;
                        _logger.LogDebug("Considering TFM {TFM} for project {Project} based on its dependency on {DepProject}", tfm, project.FilePath, dep.FilePath);
                    }
                }
                catch (UpgradeException)
                {
                    _logger.LogWarning($"Unable to determine TFM for dependency {dep.FilePath}; TFM for {project.FilePath} may not be correct.");
                }
            }

            _logger.LogDebug("Recommending TFM {TFM} for project {Project}", tfm, project.FilePath);

            // Ensure we don't downgrade a project
            return(_tfmComparer.Compare(project.TFM, tfm) > 0 ? project.TFM : tfm);
        }
예제 #2
0
        // Consider a project completely upgraded if it is SDK-style and has a TFM equal to (or greater then) the expected one
        private async ValueTask <bool> IsCompletedAsync(IUpgradeContext context, IProject project, CancellationToken token)
        {
            if (!project.GetFile().IsSdk)
            {
                return(false);
            }

            var expectedTfm = await _tfmSelector.SelectTargetFrameworkAsync(project, token).ConfigureAwait(false);

            return(project.TargetFrameworks.Any(tfm => _tfmComparer.IsCompatible(tfm, expectedTfm)));
        }
 // Consider a project completely upgraded if it is SDK-style and has a TFM equal to (or greater then) the expected one
 private bool IsCompleted(IUpgradeContext context, IProject project) =>
 project.GetFile().IsSdk&& _tfmComparer.IsCompatible(project.TFM, _tfmSelector.SelectTFM(project));