Пример #1
0
        public async Task <PackageAnalysisState> AnalyzeAsync(IProject project, PackageAnalysisState state, CancellationToken token)
        {
            if (project is null)
            {
                throw new ArgumentNullException(nameof(project));
            }

            if (state is null)
            {
                throw new ArgumentNullException(nameof(state));
            }

            var references = await project.GetNuGetReferencesAsync(token).ConfigureAwait(false);

            foreach (var packageReference in references.PackageReferences.Where(r => !state.PackagesToRemove.Contains(r)))
            {
                // If the package doesn't target the right framework but a newer version does, mark it for removal and the newer version for addition
                if (await _packageLoader.DoesPackageSupportTargetFrameworksAsync(packageReference, project.TargetFrameworks, token).ConfigureAwait(false))
                {
                    _logger.LogDebug("Package {NuGetPackage} will work on {TargetFramework}", packageReference, project.TargetFrameworks);
                    continue;
                }
                else
                {
                    // If the package won't work on the target Framework, check newer versions of the package
                    var updatedReference = await GetUpdatedPackageVersionAsync(packageReference, project.TargetFrameworks, token).ConfigureAwait(false);

                    if (updatedReference == null)
                    {
                        _logger.LogWarning("No version of {PackageName} found that supports {TargetFramework}; leaving unchanged", packageReference.Name, project.TargetFrameworks);
                    }
                    else
                    {
                        _logger.LogInformation("Marking package {NuGetPackage} for removal because it doesn't support the target framework but a newer version ({Version}) does", packageReference, updatedReference.Version);
                        var isMajorChange = _comparer.IsMajorChange(updatedReference.Version, packageReference.Version);

                        if (isMajorChange)
                        {
                            _logger.LogWarning("Package {NuGetPackage} has been upgraded across major versions ({OldVersion} -> {NewVersion}) which may introduce breaking changes", packageReference.Name, packageReference.Version, updatedReference.Version);
                            state.PossibleBreakingChangeRecommended = true;
                        }

                        if (updatedReference.IsPrerelease)
                        {
                            _logger.LogWarning("Package {NuGetPackage} has been upgraded to a prerelease version ({NewVersion}) because no released version supports target(s) {TFM}", packageReference.Name, updatedReference.Version, string.Join(", ", project.TargetFrameworks));
                        }

                        state.PackagesToRemove.Add(packageReference);
                        state.PackagesToAdd.Add(updatedReference);
                    }
                }
            }

            return(state);
        }
        public async Task AnalyzeAsync(IProject project, IDependencyAnalysisState state, CancellationToken token)
        {
            if (!(await project.IsWinUIProjectAsync(token).ConfigureAwait(false)))
            {
                return;
            }

            if (project.AllProjectReferences().Any(id => id.Contains(".vcxproj")))
            {
                var newPackage = new NuGetReference(CsWinRTPackageName, CsWinRTVersion);
                state.Packages.Add(newPackage,
                                   new OperationDetails()
                {
                    Risk = BuildBreakRisk.Medium, Details = ImmutableList.Create <string>(newPackage.Name)
                });
            }

            foreach (var package in state.Packages)
            {
                if (package.Name.StartsWith("Microsoft.Toolkit", StringComparison.Ordinal))
                {
                    var newPackageName = package.Name == "Microsoft.Toolkit" ? "CommunityToolkit.Common"
                        : package.Name.Replace("Microsoft.Toolkit.Uwp", "CommunityToolkit.WinUI")
                                         .Replace("Microsoft.Toolkit", "CommunityToolkit");

                    var newPackage = new NuGetReference(newPackageName, package.Version);
                    if (!await _packageLoader.DoesPackageSupportTargetFrameworksAsync(newPackage, project.TargetFrameworks, token).ConfigureAwait(true))
                    {
                        newPackage = await _packageLoader.GetLatestVersionAsync(newPackage.Name, project.TargetFrameworks,
                                                                                new PackageSearchOptions { LatestMinorAndBuildOnly = false, Prerelease = false, Unlisted = false }, token).ConfigureAwait(true);

                        if (newPackage == null)
                        {
                            _logger.LogWarning($"Unable to find a supported WinUI nuget package for {package.Name}. Skipping this package.");
                            continue;
                        }
                    }

                    _logger.LogInformation($"UWP Package not supported. Replacing {package.Name} v{package.Version} with {newPackage.Name} v{newPackage.Version}");
                    state.Packages.Add(newPackage, new OperationDetails()
                    {
                        Risk = BuildBreakRisk.Medium, Details = ImmutableList.Create <string>(newPackage.Name)
                    });
                    state.Packages.Remove(package, new OperationDetails()
                    {
                        Risk = BuildBreakRisk.Medium, Details = ImmutableList.Create <string>(package.Name)
                    });
                }
            }
        }
Пример #3
0
 public Task <bool> DoesPackageSupportTargetFrameworksAsync(NuGetReference packageReference, IEnumerable <TargetFrameworkMoniker> targetFrameworks, CancellationToken token)
 {
     return(_other.DoesPackageSupportTargetFrameworksAsync(packageReference, targetFrameworks, token));
 }
        public async Task AnalyzeAsync(IProject project, IDependencyAnalysisState state, CancellationToken token)
        {
            if (project is null)
            {
                throw new ArgumentNullException(nameof(project));
            }

            if (state is null)
            {
                throw new ArgumentNullException(nameof(state));
            }

            // Making a copy of state.Packages collection to avoid modifying a collection that is being enumerated.
            var packages = state.Packages.ToList();

            foreach (var packageReference in packages)
            {
                // If the package doesn't target the right framework but a newer version does, mark it for removal and the newer version for addition
                if (await _packageLoader.DoesPackageSupportTargetFrameworksAsync(packageReference, state.TargetFrameworks, token).ConfigureAwait(false))
                {
                    _logger.LogDebug("Package {NuGetPackage} will work on {TargetFramework}", packageReference, state.TargetFrameworks);
                    continue;
                }
                else
                {
                    // If the package won't work on the target Framework, check newer versions of the package
                    var newerVersions = await _packageLoader.GetNewerVersionsAsync(packageReference, state.TargetFrameworks, new() { LatestMinorAndBuildOnly = true }, token).ConfigureAwait(false);

                    var updatedReference = newerVersions.FirstOrDefault();
                    var details          = new List <string>();

                    if (updatedReference == null)
                    {
                        _logger.LogWarning("No version of {PackageName} found that supports {TargetFramework}; leaving unchanged", packageReference.Name, state.TargetFrameworks);
                    }
                    else
                    {
                        var logMessage = SR.Format("Package {0} does not support the target(s) {1} but a newer version ({2}) does.", packageReference, string.Join(", ", state.TargetFrameworks), updatedReference.Version);
                        _logger.LogInformation(logMessage);
                        var isMajorChange = _comparer.IsMajorChange(updatedReference.Version, packageReference.Version);

                        if (isMajorChange)
                        {
                            var logString = SR.Format("Package {0} needs to be upgraded across major versions ({1} -> {2}) which may introduce breaking changes.", packageReference.Name, packageReference.Version, updatedReference.Version);
                            details.Add($"{logMessage}  {logString}");
                            _logger.LogWarning(logString);
                        }

                        if (updatedReference.IsPrerelease)
                        {
                            var logString = SR.Format("Package {0} needs to be upgraded to a prerelease version ({1}) because no released version supports target(s) {2}", packageReference.Name, updatedReference.Version, string.Join(", ", state.TargetFrameworks));
                            details.Add($"{logMessage}  {logString}");
                            _logger.LogWarning(logString);
                        }

                        if (!isMajorChange && !updatedReference.IsPrerelease)
                        {
                            details.Add($"{logMessage}  {SR.Format("Package {0} needs to be upgraded from {1} to {2}.", packageReference.Name, packageReference.Version, updatedReference.Version)}");
                        }

                        state.Packages.Remove(packageReference, new OperationDetails()
                        {
                            Risk = BuildBreakRisk.None, Details = details
                        });
                        state.Packages.Add(updatedReference, new OperationDetails()
                        {
                            Risk = isMajorChange ? BuildBreakRisk.Medium : BuildBreakRisk.Low, Details = details
                        });
                    }
                }
            }
        }