private async Task <bool> DownloadPackageToStreamAsync(NuGetReference packageReference, Stream stream, IEnumerable <PackageSource>?sources, CancellationToken token) { // Attempt to download the package from the sources var packageVersion = packageReference.GetNuGetVersion(); var packageSources = sources ?? _packageSource; foreach (var source in packageSources) { var repo = GetSourceRepository(source); try { var packageFinder = await repo.GetResourceAsync <FindPackageByIdResource>(token).ConfigureAwait(false); if (await packageFinder.DoesPackageExistAsync(packageReference.Name, packageVersion, _context, (NuGetLogger?)_nugetLogger, token).ConfigureAwait(false)) { if (await packageFinder.CopyNupkgToStreamAsync(packageReference.Name, packageVersion, stream, _context, (NuGetLogger?)_nugetLogger, token).ConfigureAwait(false)) { _logger.LogDebug("Package {NuGetPackage} downloaded from feed {NuGetFeed}", packageReference, source.Source); return(true); } else { _logger.LogDebug("Failed to download package {NuGetPackage} from source {NuGetFeed}", packageReference, source.Source); } } } catch (NuGetProtocolException) { _logger.LogWarning("Failed to get package finder from source {PackageSource} due to a NuGet protocol error, skipping this source", source.Source); _logger.LogInformation("If NuGet packages are coming from an authenticated source, Upgrade Assistant requires a .NET Core-compatible v2 credential provider be installed. To authenticate with an Azure DevOps NuGet source, for example, see https://github.com/microsoft/artifacts-credprovider#setup"); } } return(false); }
private static void AssertArgumentsProcessed(ProcessedArgs actualArgs, TestLogger logger, string expectedId, string expectedVersion, string expectedSqale) { Assert.IsNotNull(actualArgs, "Expecting the arguments to have been processed successfully"); Assert.IsNotNull(actualArgs.AnalyzerRef, "Not expecting the analyzer reference to be null"); Assert.AreEqual(actualArgs.AnalyzerRef.PackageId, expectedId, "Unexpected package id returned"); NuGetReference actualRef = actualArgs.AnalyzerRef; if (expectedVersion == null) { Assert.IsNull(actualRef.Version, "Expecting the version to be null"); } else { Assert.IsNotNull(actualRef.Version, "Not expecting the version to be null"); Assert.AreEqual(expectedVersion, actualRef.Version.ToString()); } Assert.AreEqual(expectedSqale, actualArgs.SqaleFilePath, "Unexpected sqale file path"); if (expectedSqale != null) { Assert.IsTrue(File.Exists(expectedSqale), "Specified sqale file should exist: {0}", expectedSqale); } logger.AssertErrorsLogged(0); }
private async Task <NuGetReference?> GetUpdatedPackageVersionAsync(NuGetReference packageReference, IEnumerable <TargetFrameworkMoniker> targetFramework, CancellationToken token) { var latestMinorVersions = await _packageLoader.GetNewerVersionsAsync(packageReference, true, token).ConfigureAwait(false); NuGetReference?prereleaseCandidate = null; foreach (var newerPackage in latestMinorVersions) { if (await _packageLoader.DoesPackageSupportTargetFrameworksAsync(newerPackage, targetFramework, token).ConfigureAwait(false)) { _logger.LogDebug("Package {NuGetPackage} will work on {TargetFramework}", newerPackage, targetFramework); // Only return a pre-release version if it's the only newer major version that supports the necessary TFM if (newerPackage.IsPrerelease) { if (prereleaseCandidate is null) { prereleaseCandidate = newerPackage; } } else { return(newerPackage); } } } return(prereleaseCandidate); }
public async Task <string?> RestoreAsync(ExtensionSource source, CancellationToken token) { if (source is null) { throw new ArgumentNullException(nameof(source)); } if (string.IsNullOrEmpty(source.Version)) { _logger.LogWarning("Cannot restore a source {Name} with no version", source.Name); return(null); } var path = _extensionLocator.GetInstallPath(source); if (Directory.Exists(path)) { _logger.LogDebug("{Name} is already restored at {Path}", source.Name, path); return(path); } _logger.LogDebug("Creating directory {Path} for extension {Name}", path, source.Name); Directory.CreateDirectory(path); var package = new NuGetReference(source.Name, source.Version); if (await _packageDownloader.Value.DownloadPackageToDirectoryAsync(path, package, source.Source ?? _options.Value.DefaultSource, token).ConfigureAwait(false)) { return(path); } Directory.Delete(path, true); return(null); }
public static NuGetVersion?GetNuGetVersion(this NuGetReference nugetRef) { if (nugetRef.HasWildcardVersion) { return(null); } return(NuGetVersion.Parse(nugetRef.Version)); }
public static NuGetVersion?GetNuGetVersion(this NuGetReference nugetRef) { if (nugetRef is null) { throw new System.ArgumentNullException(nameof(nugetRef)); } return(nugetRef.TryGetNuGetVersion(out var result) ? result : null); }
private static IPackageSearchMetadata MockSearchMetadata(NuGetReference reference, params TargetFrameworkMoniker[] tfms) { var metadata = new Mock <IPackageSearchMetadata>(); var identity = new PackageIdentity(reference.Name, reference.GetNuGetVersion()); var groups = tfms.Select(tfm => new PackageDependencyGroup(NuGetFramework.Parse(tfm.Name), Enumerable.Empty <PackageDependency>())); metadata.Setup(m => m.Identity).Returns(identity); metadata.Setup(m => m.DependencySets).Returns(groups); return(metadata.Object); }
private async Task <Stream> GetPackageStream(NuGetReference packageReference, string source, CancellationToken token) { var ms = new MemoryStream(); var packageSource = new[] { new PackageSource(source) }; await DownloadPackageToStreamAsync(packageReference, ms, packageSource, token).ConfigureAwait(false); ms.Position = 0; return(ms); }
public async Task <bool> DoesPackageSupportTargetFrameworksAsync(NuGetReference packageReference, IEnumerable <TargetFrameworkMoniker> targetFrameworks, CancellationToken token) { using var packageArchive = await GetPackageArchiveAsync(packageReference, token).ConfigureAwait(false); if (packageArchive is null) { return(false); } var packageFrameworks = await GetTargetFrameworksAsync(packageArchive, token).ConfigureAwait(false); return(targetFrameworks.All(tfm => packageFrameworks.Any(f => DefaultCompatibilityProvider.Instance.IsCompatible(NuGetFramework.Parse(tfm.Name), f)))); }
public Task <IEnumerable <NuGetReference> > GetNewerVersionsAsync(NuGetReference reference, IEnumerable <TargetFrameworkMoniker> tfms, PackageSearchOptions options, CancellationToken token) { if (reference is null) { throw new ArgumentNullException(nameof(reference)); } if (options is null) { throw new ArgumentNullException(nameof(options)); } return(SearchByNameAsync(reference.Name, tfms, options, currentVersion: reference.GetNuGetVersion(), _packageSource, token: token)); }
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) }); } } }
public async Task <IEnumerable <NuGetReference> > GetNewerVersionsAsync(NuGetReference reference, IEnumerable <TargetFrameworkMoniker> tfms, PackageSearchOptions options, CancellationToken token) { if (_packages.TryGetValue(reference.Name, out var known)) { return(new NuGetReference[] { known }); } var latest = await _other.GetNewerVersionsAsync(reference, tfms, options, token).ConfigureAwait(false); if (latest is not null && latest.LastOrDefault() is NuGetReference latestReference) { _unknownPackages[latestReference.Name] = latestReference.Version; _logger.LogError("Unexpected check for newer version: {Name}, {Version}", reference.Name, reference.Version); } return(latest ?? Enumerable.Empty <NuGetReference>()); }
/// <summary> /// Gets the NuGetReference data for a package that has been overriden, or returns false. /// </summary> /// <param name="name">name of the NuGet package.</param> /// <param name="nuget">a <see cref="NuGetReference"/>.</param> /// <returns>true if NuGetReference is populated, otherwise false.</returns> public bool TryGetValue(string name, [MaybeNullWhen(false)] out NuGetReference nuget) { if (_knownValues is null) { nuget = null; return(false); } if (_knownValues.TryGetValue(name, out var specificVersion)) { nuget = new NuGetReference(name, specificVersion.ToString()); return(true); } nuget = null; return(false); }
public async Task <IEnumerable <NuGetReference> > GetNewerVersionsAsync(NuGetReference reference, bool latestMinorAndBuildOnly, CancellationToken token) { if (_packages.TryGetValue(reference.Name, out var known)) { return(new NuGetReference[] { known }); } var latest = await _other.GetNewerVersionsAsync(reference, latestMinorAndBuildOnly, token).ConfigureAwait(false); if (latest is not null) { var latestReference = latest.Last(); _unknownPackages[latestReference.Name] = latestReference.Version; _logger.LogError("Unexpected check for newer version: {Name}, {Version}", reference.Name, reference.Version); } return(latest ?? Array.Empty <NuGetReference>()); }
public void GetNuGetVersionCanHandleFloatingVersions(string versionToTest, string expectedVersion) { if (versionToTest == null) { throw new ArgumentNullException(nameof(versionToTest)); } if (expectedVersion == null) { throw new ArgumentNullException(nameof(expectedVersion)); } var reference = new NuGetReference("Example", versionToTest); var actualVersion = reference.GetNuGetVersion(); Assert.Equal(expectedVersion, actualVersion?.ToString()); }
public async Task <IEnumerable <NuGetReference> > GetNewerVersionsAsync(NuGetReference reference, bool latestMinorAndBuildOnly, CancellationToken token) { if (reference is null) { throw new ArgumentNullException(nameof(reference)); } var versions = new List <NuGetVersion>(); // Query each package source for listed versions of the given package name foreach (var source in _packageSources) { try { var metadata = await GetSourceRepository(source).GetResourceAsync <PackageMetadataResource>(token).ConfigureAwait(false); var searchResults = await CallWithRetryAsync(() => metadata.GetMetadataAsync(reference.Name, includePrerelease: true, includeUnlisted: false, _cache, _nugetLogger, token)).ConfigureAwait(false); versions.AddRange(searchResults.Select(r => r.Identity.Version)); } catch (NuGetProtocolException) { _logger.LogWarning("Failed to get package versions from source {PackageSource} due to a NuGet protocol error", source.Source); } catch (HttpRequestException exc) { _logger.LogWarning("Failed to get package versions from source {PackageSource} due to an HTTP error ({StatusCode})", source.Source, exc.StatusCode); } } // Filter to only include versions higher than the user's current version and, // optionally, only the highest minor/build for each major version var currentVersion = reference.GetNuGetVersion(); var filteredVersions = versions.Distinct().Where(v => v > currentVersion); var versionsToReturn = latestMinorAndBuildOnly ? filteredVersions.GroupBy(v => v.Major).Select(v => v.Where(v => !v.IsPrerelease).Max() ?? v.Max() !) : filteredVersions; _logger.LogDebug("Found versions for package {PackageName}: {PackageVersions}", reference.Name, versionsToReturn); return(versionsToReturn.OrderBy(v => v).Select(v => reference with { Version = v.ToNormalizedString() }));
private Stream?GetCachedPackage(NuGetReference packageReference) { // First look in the local NuGet cache for the archive if (_options.Value.CachePath is string cachePath) { var archivePath = Path.Combine(cachePath, packageReference.Name, packageReference.Version, $"{packageReference.Name}.{packageReference.Version}.nupkg"); if (File.Exists(archivePath)) { _logger.LogDebug("NuGet package {NuGetPackage} loaded from {PackagePath}", packageReference, archivePath); return(File.Open(archivePath, FileMode.Open)); } else { _logger.LogDebug("NuGet package {NuGetPackage} not found in package cache", packageReference); } } return(null); }
private async Task <PackageArchiveReader?> GetPackageArchiveAsync(NuGetReference packageReference, CancellationToken token) { if (packageReference is null) { throw new ArgumentNullException(nameof(packageReference)); } if (packageReference.GetNuGetVersion() == null) { throw new ArgumentException("Package references must have specific versions to get package archives", nameof(packageReference)); } if (GetCachedPackage(packageReference) is Stream cached) { return(new PackageArchiveReader(cached, false)); } var ms = new MemoryStream(); if (await DownloadPackageToStreamAsync(packageReference, ms, sources: default, token).ConfigureAwait(false))
private static string BuildAddPackageCommand(NuGetReference reference) { var commandBuilder = new StringBuilder(); commandBuilder.Append("add package "); commandBuilder.Append(reference.PackageName); if (!string.IsNullOrWhiteSpace(reference.PackageVersion)) { commandBuilder.Append(" -v "); commandBuilder.Append(reference.PackageVersion); } if (reference.PackageSource != null) { commandBuilder.Append(" -s "); commandBuilder.Append(reference.PackageSource); } if (reference.Prerelease) { commandBuilder.Append(" --prerelease"); } return(commandBuilder.ToString()); }
public bool Generate(NuGetReference analyzeRef, string language, string sqaleFilePath) { // sqale file path is optional if (analyzeRef == null) { throw new ArgumentNullException("analyzeRef"); } if (string.IsNullOrWhiteSpace(language)) { throw new ArgumentNullException("language"); } SupportedLanguages.ThrowIfNotSupported(language); string nuGetDirectory = Utilities.CreateTempDirectory(".nuget"); IPackage package = this.packageHandler.FetchPackage(analyzeRef.PackageId, analyzeRef.Version, nuGetDirectory); if (package != null) { // Create a uniquely-named temp directory for this generation run string baseDirectory = Utilities.CreateTempDirectory(".gen"); baseDirectory = CreateSubDirectory(baseDirectory, Guid.NewGuid().ToString()); this.logger.LogDebug(UIResources.APG_CreatedTempWorkingDir, baseDirectory); PluginManifest pluginDefn = CreatePluginDefinition(package); string rulesFilePath = Path.Combine(baseDirectory, "rules.xml"); bool success = TryGenerateRulesFile(package, nuGetDirectory, baseDirectory, rulesFilePath, language); if (success) { BuildPlugin(package, language, rulesFilePath, sqaleFilePath, pluginDefn, baseDirectory); } } return(package != null); }
public Task <bool> DoesPackageSupportTargetFrameworksAsync(NuGetReference packageReference, IEnumerable <TargetFrameworkMoniker> targetFrameworks, CancellationToken token) { return(_other.DoesPackageSupportTargetFrameworksAsync(packageReference, targetFrameworks, token)); }
public static bool TryGetPackageByName(this IProject project, string packageName, [MaybeNullWhen(false)] out NuGetReference nugetReference) { var matches = project.Required().PackageReferences.Where(p => p.Name.Equals(packageName, StringComparison.OrdinalIgnoreCase)).OrderByDescending(p => Version.Parse(p.Version)); nugetReference = matches.FirstOrDefault(); return(nugetReference is not null); }
public static Task <bool> IsTransitiveDependencyAsync(this ITransitiveDependencyIdentifier identifier, NuGetReference package, IProject project, CancellationToken token) { if (identifier is null) { throw new ArgumentNullException(nameof(identifier)); } if (package is null) { throw new ArgumentNullException(nameof(package)); } if (project is null) { throw new ArgumentNullException(nameof(project)); } return(identifier.IsTransitiveDependencyAsync(package, project.GetProjectTranstiveDependencies(), project.TargetFrameworks, token)); }
private static bool ReferenceSatisfiesDependency(this PackageDependency dependency, NuGetReference packageReference, bool minVersionMatchOnly) { // If the dependency's name doesn't match the reference's name, return false if (!dependency.Id.Equals(packageReference.Name, StringComparison.OrdinalIgnoreCase)) { return(false); } var packageVersion = packageReference.GetNuGetVersion(); if (packageVersion == null) { throw new InvalidOperationException("Package references from a lock file should always have a specific version"); } // Return false if the reference's version falls outside of the dependency range var versionRange = dependency.VersionRange; if (versionRange.HasLowerBound && packageVersion < versionRange.MinVersion) { return(false); } if (versionRange.HasUpperBound && packageVersion > versionRange.MaxVersion) { return(false); } // In some cases (looking for transitive dependencies), it's interesting to only match packages that are the minimum version if (minVersionMatchOnly && versionRange.HasLowerBound && packageVersion != versionRange.MinVersion) { return(false); } // Otherwise, return true return(true); }
public static bool IsTransitiveDependency(this IProject project, NuGetReference nugetReference) => project.ContainsDependency(d => d.ReferenceSatisfiesDependency(nugetReference, true));
public Task <NuGetPackageMetadata?> GetPackageMetadata(NuGetReference reference, CancellationToken token) => _other.GetPackageMetadata(reference, token);
public static bool TryGetPackageByName(this INuGetReferences references, string packageName, [MaybeNullWhen(false)] out NuGetReference nugetReference) { if (references is null) { throw new ArgumentNullException(nameof(references)); } var matches = references.PackageReferences.Where(p => p.Name.Equals(packageName, StringComparison.OrdinalIgnoreCase)).OrderByDescending(p => Version.Parse(p.Version)); nugetReference = matches.FirstOrDefault(); return(nugetReference is not null); }
public bool IsTransitiveDependency(NuGetReference nugetReference) => TargetFrameworks.Any(tfm => ContainsDependency(tfm, d => ReferenceSatisfiesDependency(d, nugetReference, true)));
public static async Task <bool> IsTransitiveDependencyAsync(this ITransitiveDependencyIdentifier identifier, NuGetReference package, IEnumerable <NuGetReference> packages, IEnumerable <TargetFrameworkMoniker> tfms, CancellationToken token) { if (identifier is null) { throw new ArgumentNullException(nameof(identifier)); } if (package is null) { throw new ArgumentNullException(nameof(package)); } if (packages is null) { throw new ArgumentNullException(nameof(packages)); } if (tfms is null) { throw new ArgumentNullException(nameof(tfms)); } var result = await identifier.GetTransitiveDependenciesAsync(packages, tfms, token).ConfigureAwait(false); foreach (var item in result.References) { if (item.Equals(package)) { return(true); } } return(false); }