| File: GetLastStablePackage.cs | Web Access |
| Project: src\arcade\src\Microsoft.DotNet.Build.Tasks.Packaging\src\Microsoft.DotNet.Build.Tasks.Packaging.csproj (Microsoft.DotNet.Build.Tasks.Packaging) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.Build.Framework; using Microsoft.Build.Utilities; using NuGet.Versioning; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; namespace Microsoft.DotNet.Build.Tasks.Packaging { public class GetLastStablePackage : BuildTask { /// <summary> /// List of packages to look up. /// The closest StablePackage version that is less than the version of each of these packages will be returned in LastStablePackages. /// Identity: Package ID /// Version: Package version. /// </summary> [Required] public ITaskItem[] LatestPackages { get; set; } /// <summary> /// List of previously shipped packages. /// Identity: Package ID /// Version: Package version. /// </summary> public ITaskItem[] StablePackages { get; set; } /// <summary> /// Package index files used to define stable packages. /// </summary> public ITaskItem[] PackageIndexes { get; set; } /// <summary> /// <see langword="true"/> if the result version can be a version from the same release. /// <see langword="false"/> otherwise. Defaults to false. /// </summary> public bool DoNotAllowVersionsFromSameRelease { get; set; } /// <summary> /// Latest version from StablePackages for all packages in LatestPackages. /// If a version isn't found for an item in LatestPackage that will not be included in this set. /// </summary> [Output] public ITaskItem[] LastStablePackages { get; set; } public override bool Execute() { if (LatestPackages == null || LatestPackages.Length == 0) { return true; } if (PackageIndexes != null && PackageIndexes.Length > 0) { GetLastStablePackagesFromIndex(); } else { GetLastStablePackagesFromStablePackages(); } return !Log.HasLoggedErrors; } public void GetLastStablePackagesFromStablePackages() { Dictionary<string, ITaskItem> originalItems = new Dictionary<string, ITaskItem>(); Dictionary<string, Version> latestPackages = new Dictionary<string, Version>(); Dictionary<string, Version> lastStablePackages = new Dictionary<string, Version>(); foreach (var latestPackage in LatestPackages) { var packageId = latestPackage.ItemSpec; var versionString = latestPackage.GetMetadata("Version"); NuGetVersion nuGetVersion = null; if (versionString == null || !NuGetVersion.TryParse(versionString, out nuGetVersion)) { Log.LogMessage($"Could not parse version {versionString} for LatestPackage {packageId}, will use latest stable."); } latestPackages[packageId] = nuGetVersion?.Version; originalItems[packageId] = latestPackage; } foreach (var stablePackage in StablePackages.NullAsEmpty()) { var packageId = stablePackage.ItemSpec; Version latestVersion; if (!latestPackages.TryGetValue(packageId, out latestVersion)) { continue; } var versionString = stablePackage.GetMetadata("Version"); Version stableVersion; if (versionString == null || !Version.TryParse(versionString, out stableVersion)) { Log.LogError($"Could not parse version {versionString} for StablePackage {packageId}"); continue; } stableVersion = VersionUtility.As4PartVersion(stableVersion); // only consider a stable version less or equal to than current version if (latestVersion != null && stableVersion >= latestVersion) { continue; } Version lastStableVersion; if (!lastStablePackages.TryGetValue(packageId, out lastStableVersion) || lastStableVersion < stableVersion) { lastStablePackages[packageId] = stableVersion; } } LastStablePackages = lastStablePackages.Select(p => CreateItem(originalItems[p.Key], p.Value)).ToArray(); } public void GetLastStablePackagesFromIndex() { var index = PackageIndex.Load(PackageIndexes.Select(pi => pi.GetMetadata("FullPath"))); List<ITaskItem> lastStablePackages = new List<ITaskItem>(); foreach (var latestPackage in LatestPackages) { var packageId = latestPackage.ItemSpec; var versionString = latestPackage.GetMetadata("Version"); NuGetVersion nuGetVersion = null; if (versionString == null || !NuGetVersion.TryParse(versionString, out nuGetVersion)) { Log.LogMessage($"Could not parse version {versionString} for LatestPackage {packageId}, will use latest stable."); } var latestVersion = (DoNotAllowVersionsFromSameRelease) ? VersionUtility.As2PartVersion(nuGetVersion?.Version) : nuGetVersion?.Version; PackageInfo info; if (index.Packages.TryGetValue(packageId, out info)) { IEnumerable<Version> candidateVersions = (latestVersion == null) ? info.StableVersions : info.StableVersions.Where(sv => VersionUtility.As4PartVersion(sv) < latestVersion); if (candidateVersions.Any()) { lastStablePackages.Add(CreateItem(latestPackage, candidateVersions.Max())); } } } LastStablePackages = lastStablePackages.ToArray(); } private ITaskItem CreateItem(ITaskItem originalItem, Version version) { var item = new TaskItem(originalItem); item.SetMetadata("Version", version.ToString(3)); return item; } } }