Update MSBuildProject.NuGetPackages APIs to work with packages.config (#619)

This updates INuGetReferences implementation to handle project files using packages.config package references. Also, updated some comments to more clearly explain what the different APIs on that interface do.

Fixes #554
This commit is contained in:
Mike Rousos 2021-06-14 17:22:43 -04:00 коммит произвёл GitHub
Родитель 57152ce9c7
Коммит 1264a65226
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 24 добавлений и 11 удалений

Просмотреть файл

@ -20,7 +20,7 @@ namespace Microsoft.DotNet.UpgradeAssistant
IEnumerable<NuGetReference> PackageReferences { get; }
/// <summary>
/// Gets the packages that are transitively referenced via other packages or projects for the given <paramref name="tfm"/>.
/// Gets all the packages that are referenced for the given <paramref name="tfm"/> either directly or transitively.
/// </summary>
/// <param name="tfm">The target framework to get the dependencies for.</param>
/// <param name="token">A cancellation token.</param>
@ -28,7 +28,7 @@ namespace Microsoft.DotNet.UpgradeAssistant
IAsyncEnumerable<NuGetReference> GetTransitivePackageReferencesAsync(TargetFrameworkMoniker tfm, CancellationToken token);
/// <summary>
/// Checks if the package name is transitively referenced via other packages or projects.
/// Checks if the package name is referenced either directly or transitively via other packages or projects.
/// </summary>
/// <param name="packageName">The name of a package.</param>
/// <param name="token">A cancellation token.</param>
@ -36,7 +36,9 @@ namespace Microsoft.DotNet.UpgradeAssistant
ValueTask<bool> IsTransitivelyAvailableAsync(string packageName, CancellationToken token);
/// <summary>
/// Checks if the package is transitively referenced via other packages or projects.
/// Checks if a particular version of a package is transitively referenced via other packages or projects.
/// This does not check whether the package is directly referenced or not and will always return false
/// for projects not using PackageReference package references.
/// </summary>
/// <param name="nugetReference">The package identity.</param>
/// <param name="token">A cancellation token.</param>

Просмотреть файл

@ -61,13 +61,19 @@ namespace Microsoft.DotNet.UpgradeAssistant.MSBuild
}
public IAsyncEnumerable<NuGetReference> GetTransitivePackageReferencesAsync(TargetFrameworkMoniker tfm, CancellationToken token)
=> GetAllDependenciesAsync(tfm, token).Select(l => new NuGetReference(l.Name, l.Version.ToNormalizedString()));
=> PackageReferenceFormat switch
{
NugetPackageFormat.PackageConfig => PackageReferences.ToAsyncEnumerable(),
NugetPackageFormat.PackageReference => GetAllPackageReferenceDependenciesAsync(tfm, token).Select(l => new NuGetReference(l.Name, l.Version.ToNormalizedString())),
_ => AsyncEnumerable.Empty<NuGetReference>()
};
public ValueTask<bool> IsTransitivelyAvailableAsync(string packageName, CancellationToken token)
=> TargetFrameworks.ToAsyncEnumerable().AnyAwaitAsync(tfm => ContainsDependencyAsync(tfm, d => string.Equals(packageName, d.Id, StringComparison.OrdinalIgnoreCase), token), cancellationToken: token);
public async ValueTask<bool> IsTransitivelyAvailableAsync(string packageName, CancellationToken token)
=> PackageReferences.Any(p => p.Name.Equals(packageName, StringComparison.OrdinalIgnoreCase))
|| (PackageReferenceFormat == NugetPackageFormat.PackageReference && await TargetFrameworks.ToAsyncEnumerable().AnyAwaitAsync(tfm => ContainsPackageDependencyAsync(tfm, d => string.Equals(packageName, d.Id, StringComparison.OrdinalIgnoreCase), token), cancellationToken: token).ConfigureAwait(false));
public ValueTask<bool> IsTransitiveDependencyAsync(NuGetReference nugetReference, CancellationToken token)
=> TargetFrameworks.ToAsyncEnumerable().AnyAwaitAsync(tfm => ContainsDependencyAsync(tfm, d => ReferenceSatisfiesDependency(d, nugetReference, true), token), token);
public async ValueTask<bool> IsTransitiveDependencyAsync(NuGetReference nugetReference, CancellationToken token)
=> PackageReferenceFormat == NugetPackageFormat.PackageReference && await TargetFrameworks.ToAsyncEnumerable().AnyAwaitAsync(tfm => ContainsPackageDependencyAsync(tfm, d => ReferenceSatisfiesDependency(d, nugetReference, true), token), token).ConfigureAwait(false);
private static bool ReferenceSatisfiesDependency(PackageDependency dependency, NuGetReference packageReference, bool minVersionMatchOnly)
{
@ -104,16 +110,21 @@ namespace Microsoft.DotNet.UpgradeAssistant.MSBuild
return true;
}
private ValueTask<bool> ContainsDependencyAsync(TargetFrameworkMoniker tfm, Func<PackageDependency, bool> filter, CancellationToken token)
=> GetAllDependenciesAsync(tfm, token).AnyAsync(l => l.Dependencies.Any(d => filter(d)), token);
private ValueTask<bool> ContainsPackageDependencyAsync(TargetFrameworkMoniker tfm, Func<PackageDependency, bool> filter, CancellationToken token)
=> GetAllPackageReferenceDependenciesAsync(tfm, token).AnyAsync(l => l.Dependencies.Any(d => filter(d)), token);
private async IAsyncEnumerable<LockFileTargetLibrary> GetAllDependenciesAsync(TargetFrameworkMoniker tfm, [EnumeratorCancellation] CancellationToken token)
private async IAsyncEnumerable<LockFileTargetLibrary> GetAllPackageReferenceDependenciesAsync(TargetFrameworkMoniker tfm, [EnumeratorCancellation] CancellationToken token)
{
if (!IsRestored)
{
throw new InvalidOperationException("Project should have already been restored. Please file an issue at https://github.com/dotnet/upgrade-assistant");
}
if (PackageReferenceFormat != NugetPackageFormat.PackageReference)
{
throw new InvalidOperationException("PackageReference restore for transitive dependencies should only happen for PackageReference package reference format");
}
var parsedTfm = NuGetFramework.Parse(tfm.Name);
var target = GetLockFileTarget(parsedTfm);