Make Package Analyzers TFM aware (#608)
* Make Package Analyzers TFM aware * Fix tests * Add TFM to IDependencyAnalysisState * Remove unnecessary imports * Remove unnecessary imports * PR Feedback * Fix tests
This commit is contained in:
Родитель
c2b38597b9
Коммит
a9a1b91303
|
@ -1,6 +1,8 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.DotNet.UpgradeAssistant.Dependencies
|
||||
{
|
||||
public interface IDependencyAnalysisState
|
||||
|
@ -16,5 +18,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.Dependencies
|
|||
bool AreChangesRecommended { get; }
|
||||
|
||||
BuildBreakRisk Risk { get; }
|
||||
|
||||
IReadOnlyCollection<TargetFrameworkMoniker> TargetFrameworks { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.Extensions.Web
|
|||
// This reference only needs added to ASP.NET Core exes
|
||||
if (!(components.HasFlag(ProjectComponents.AspNetCore)
|
||||
&& project.OutputType == ProjectOutputType.Exe
|
||||
&& !project.TargetFrameworks.Any(tfm => _tfmComparer.Compare(tfm, TargetFrameworkMoniker.NetCoreApp30) < 0)))
|
||||
&& !state.TargetFrameworks.Any(tfm => _tfmComparer.Compare(tfm, TargetFrameworkMoniker.NetCoreApp30) < 0)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.Extensions.Web
|
|||
|
||||
if (!state.Packages.Any(r => NewtonsoftPackageName.Equals(r.Name, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
var newtonsoftPackage = await _packageLoader.GetLatestVersionAsync(NewtonsoftPackageName, project.TargetFrameworks, false, token).ConfigureAwait(false);
|
||||
var newtonsoftPackage = await _packageLoader.GetLatestVersionAsync(NewtonsoftPackageName, state.TargetFrameworks, false, token).ConfigureAwait(false);
|
||||
|
||||
if (newtonsoftPackage is not null)
|
||||
{
|
||||
|
|
|
@ -11,14 +11,17 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Packages
|
|||
public class AnalyzePackageStatus : IAnalyzeResultProvider
|
||||
{
|
||||
private readonly IDependencyAnalyzerRunner _packageAnalyzer;
|
||||
private readonly ITargetFrameworkSelector _tfmSelector;
|
||||
private IDependencyAnalysisState? _analysisState;
|
||||
|
||||
private ILogger Logger { get; }
|
||||
|
||||
public AnalyzePackageStatus(IDependencyAnalyzerRunner packageAnalyzer,
|
||||
ITargetFrameworkSelector tfmSelector,
|
||||
ILogger<AnalyzePackageStatus> logger)
|
||||
{
|
||||
Logger = logger;
|
||||
_tfmSelector = tfmSelector;
|
||||
_packageAnalyzer = packageAnalyzer ?? throw new ArgumentNullException(nameof(packageAnalyzer));
|
||||
_analysisState = null;
|
||||
}
|
||||
|
@ -35,9 +38,15 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Packages
|
|||
|
||||
foreach (var project in projects)
|
||||
{
|
||||
var targetTfm = await _tfmSelector.SelectTargetFrameworkAsync(project, token).ConfigureAwait(false);
|
||||
var targetframeworks = new TargetFrameworkMoniker[]
|
||||
{
|
||||
targetTfm
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
_analysisState = await _packageAnalyzer.AnalyzeAsync(context, project, token).ConfigureAwait(false);
|
||||
_analysisState = await _packageAnalyzer.AnalyzeAsync(context, project, targetframeworks, token).ConfigureAwait(false);
|
||||
if (!_analysisState.IsValid)
|
||||
{
|
||||
Logger.LogError($"Package analysis failed");
|
||||
|
@ -50,7 +59,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Packages
|
|||
Logger.LogCritical(exc, "Unexpected exception analyzing package references for: {ProjectPath}", context.CurrentProject.Required().FileInfo);
|
||||
}
|
||||
|
||||
Logger.LogInformation("Package Analysis for {ProjectPath}", project.FileInfo.Name);
|
||||
Logger.LogInformation("Package Analysis for {ProjectPath} for the target TFM of {TargetTFM}", project.FileInfo.Name, targetTfm);
|
||||
|
||||
if (_analysisState is null || !_analysisState.AreChangesRecommended)
|
||||
{
|
||||
|
|
|
@ -50,10 +50,8 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Packages.Analyzers
|
|||
throw new ArgumentNullException(nameof(state));
|
||||
}
|
||||
|
||||
var currentTFM = project.TargetFrameworks;
|
||||
|
||||
// Get package maps as an array here so that they're only loaded once (as opposed to each iteration through the loop)
|
||||
var packageMaps = currentTFM.Any(c => c.IsFramework) ? _packageMaps.Where(x => x.NetCorePackagesWorkOnNetFx).ToArray() : _packageMaps;
|
||||
var packageMaps = state.TargetFrameworks.Any(c => c.IsFramework) ? _packageMaps.Where(x => x.NetCorePackagesWorkOnNetFx).ToArray() : _packageMaps;
|
||||
|
||||
foreach (var packageReference in state.Packages)
|
||||
{
|
||||
|
@ -108,7 +106,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Packages.Analyzers
|
|||
var packageToAdd = newPackage;
|
||||
if (packageToAdd.HasWildcardVersion)
|
||||
{
|
||||
var reference = await _packageLoader.GetLatestVersionAsync(packageToAdd.Name, project.TargetFrameworks, false, token).ConfigureAwait(false);
|
||||
var reference = await _packageLoader.GetLatestVersionAsync(packageToAdd.Name, state.TargetFrameworks, false, token).ConfigureAwait(false);
|
||||
|
||||
if (reference is not null)
|
||||
{
|
||||
|
|
|
@ -43,20 +43,20 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Packages.Analyzers
|
|||
foreach (var packageReference in state.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, project.TargetFrameworks, token).ConfigureAwait(false))
|
||||
if (await _packageLoader.DoesPackageSupportTargetFrameworksAsync(packageReference, state.TargetFrameworks, token).ConfigureAwait(false))
|
||||
{
|
||||
_logger.LogDebug("Package {NuGetPackage} will work on {TargetFramework}", packageReference, project.TargetFrameworks);
|
||||
_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, project.TargetFrameworks, true, token).ConfigureAwait(false);
|
||||
var newerVersions = await _packageLoader.GetNewerVersionsAsync(packageReference, state.TargetFrameworks, true, token).ConfigureAwait(false);
|
||||
var updatedReference = newerVersions.FirstOrDefault();
|
||||
|
||||
if (updatedReference == null)
|
||||
{
|
||||
_logger.LogWarning("No version of {PackageName} found that supports {TargetFramework}; leaving unchanged", packageReference.Name, project.TargetFrameworks);
|
||||
_logger.LogWarning("No version of {PackageName} found that supports {TargetFramework}; leaving unchanged", packageReference.Name, state.TargetFrameworks);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -70,7 +70,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Packages.Analyzers
|
|||
|
||||
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));
|
||||
_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(", ", state.TargetFrameworks));
|
||||
}
|
||||
|
||||
state.Packages.Remove(packageReference);
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Packages.Analyzers
|
|||
// If the project doesn't include a reference to the analyzer package, mark it for addition
|
||||
if (!state.Packages.Any(r => AnalyzerPackageName.Equals(r.Name, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
var analyzerPackage = await _packageLoader.GetLatestVersionAsync(AnalyzerPackageName, project.TargetFrameworks, true, token).ConfigureAwait(false);
|
||||
var analyzerPackage = await _packageLoader.GetLatestVersionAsync(AnalyzerPackageName, state.TargetFrameworks, true, token).ConfigureAwait(false);
|
||||
|
||||
if (analyzerPackage is not null)
|
||||
{
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Packages.Analyzers
|
|||
throw new ArgumentNullException(nameof(state));
|
||||
}
|
||||
|
||||
if (!project.TargetFrameworks.Any(tfm => tfm.IsWindows))
|
||||
if (!state.TargetFrameworks.Any(tfm => tfm.IsWindows))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Packages.Analyzers
|
|||
return;
|
||||
}
|
||||
|
||||
var latestVersion = await _loader.GetLatestVersionAsync(PackageName, project.TargetFrameworks, false, token).ConfigureAwait(false);
|
||||
var latestVersion = await _loader.GetLatestVersionAsync(PackageName, state.TargetFrameworks, false, token).ConfigureAwait(false);
|
||||
|
||||
if (latestVersion is null)
|
||||
{
|
||||
|
|
|
@ -2,13 +2,14 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.DotNet.UpgradeAssistant.Dependencies;
|
||||
|
||||
namespace Microsoft.DotNet.UpgradeAssistant.Steps.Packages
|
||||
{
|
||||
public sealed class DependencyAnalysisState : IDependencyAnalysisState
|
||||
{
|
||||
public DependencyAnalysisState(IProject project, INuGetReferences nugetReferences)
|
||||
public DependencyAnalysisState(IProject project, INuGetReferences nugetReferences, IReadOnlyCollection<TargetFrameworkMoniker> targetFrameworks)
|
||||
{
|
||||
if (project is null)
|
||||
{
|
||||
|
@ -24,6 +25,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Packages
|
|||
Packages = new DependencyCollection<NuGetReference>(initial: nugetReferences.PackageReferences, setRisk: SetRisk);
|
||||
References = new DependencyCollection<Reference>(project.References, SetRisk);
|
||||
IsValid = true;
|
||||
TargetFrameworks = targetFrameworks;
|
||||
void SetRisk(BuildBreakRisk risk)
|
||||
{
|
||||
Risk = (BuildBreakRisk)Math.Max((int)Risk, (int)risk);
|
||||
|
@ -47,5 +49,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Packages
|
|||
public bool AreChangesRecommended => FrameworkReferences.HasChanges || Packages.HasChanges || References.HasChanges;
|
||||
|
||||
public bool IsValid { get; set; }
|
||||
|
||||
public IReadOnlyCollection<TargetFrameworkMoniker> TargetFrameworks { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Packages
|
|||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<IDependencyAnalysisState> AnalyzeAsync(IUpgradeContext context, IProject? projectRoot, CancellationToken token)
|
||||
public async Task<IDependencyAnalysisState> AnalyzeAsync(IUpgradeContext context, IProject? projectRoot, IReadOnlyCollection<TargetFrameworkMoniker> targetframeworks, CancellationToken token)
|
||||
{
|
||||
if (projectRoot is null)
|
||||
{
|
||||
|
@ -35,7 +35,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Packages
|
|||
}
|
||||
|
||||
await _packageRestorer.RestorePackagesAsync(context, projectRoot, token).ConfigureAwait(false);
|
||||
var analysisState = new DependencyAnalysisState(projectRoot, projectRoot.NuGetReferences);
|
||||
var analysisState = new DependencyAnalysisState(projectRoot, projectRoot.NuGetReferences, targetframeworks);
|
||||
|
||||
// Iterate through all package references in the project file
|
||||
foreach (var analyzer in _packageAnalyzers)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.DotNet.UpgradeAssistant.Dependencies;
|
||||
|
@ -9,6 +10,6 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Packages
|
|||
{
|
||||
public interface IDependencyAnalyzerRunner
|
||||
{
|
||||
Task<IDependencyAnalysisState> AnalyzeAsync(IUpgradeContext context, IProject? projectRoot, CancellationToken token);
|
||||
Task<IDependencyAnalysisState> AnalyzeAsync(IUpgradeContext context, IProject? projectRoot, IReadOnlyCollection<TargetFrameworkMoniker> targetframeworks, CancellationToken token);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,7 +77,8 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Packages
|
|||
|
||||
try
|
||||
{
|
||||
_analysisState = await _packageAnalyzer.AnalyzeAsync(context, context.CurrentProject, token).ConfigureAwait(false);
|
||||
var currentProject = context.CurrentProject.Required();
|
||||
_analysisState = await _packageAnalyzer.AnalyzeAsync(context, currentProject, currentProject.TargetFrameworks, token).ConfigureAwait(false);
|
||||
if (!_analysisState.IsValid)
|
||||
{
|
||||
return new UpgradeStepInitializeResult(UpgradeStepStatus.Failed, $"Package analysis failed", BuildBreakRisk.Unknown);
|
||||
|
@ -155,7 +156,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Packages
|
|||
count++;
|
||||
|
||||
Logger.LogDebug("Re-running analysis to check whether additional changes are needed");
|
||||
_analysisState = await _packageAnalyzer.AnalyzeAsync(context, context.CurrentProject, token).ConfigureAwait(false);
|
||||
_analysisState = await _packageAnalyzer.AnalyzeAsync(context, project, project.TargetFrameworks, token).ConfigureAwait(false);
|
||||
if (!_analysisState.IsValid)
|
||||
{
|
||||
return new UpgradeStepApplyResult(UpgradeStepStatus.Failed, "Package analysis failed");
|
||||
|
|
|
@ -37,6 +37,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.Extensions.Web.Tests
|
|||
|
||||
var packageState = new Mock<IDependencyAnalysisState>();
|
||||
packageState.Setup(p => p.Packages).Returns(packages.Object);
|
||||
packageState.Setup(p => p.TargetFrameworks).Returns(project.Object.TargetFrameworks);
|
||||
|
||||
var packageLoader = CreatePackageLoader(mock);
|
||||
|
||||
|
@ -70,6 +71,8 @@ namespace Microsoft.DotNet.UpgradeAssistant.Extensions.Web.Tests
|
|||
comparer.Setup(comparer => comparer.Compare(It.IsAny<TargetFrameworkMoniker>(), It.IsAny<TargetFrameworkMoniker>()))
|
||||
.Returns(-1);
|
||||
|
||||
packageState.Setup(p => p.TargetFrameworks).Returns(project.Object.TargetFrameworks);
|
||||
|
||||
// Act
|
||||
await analyzer.AnalyzeAsync(project.Object, packageState.Object, default).ConfigureAwait(false);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче