Cmdlets/src/XpandPwsh.Cmdlets/Nuget/Get-NugetPackageSearchMetadata.cs
using System;
using System.Collections.Generic; using System.Linq; using System.Management.Automation; using System.Reactive.Linq; using System.Threading.Tasks; using JetBrains.Annotations; using NuGet.Protocol.Core.Types; namespace XpandPwsh.Cmdlets.Nuget{ [Cmdlet(VerbsCommon.Get, "NugetPackageSearchMetadata")] [CmdletBinding()] [CmdLetTag(CmdLetTag.Nuget,CmdLetTag.Reactive,CmdLetTag.RX)][PublicAPI] public class GetNugetPackageSearchMetadata : NugetCmdlet{ [Parameter(Position = 0, ValueFromPipeline = true)] public string Name{ get; set; } [Parameter(Position = 1,Mandatory = true)] public string Source{ get; set; } [Parameter] public SwitchParameter IncludePrerelease{ get; set; } = new SwitchParameter(false); [Parameter] public SwitchParameter AllVersions{ get; set; } = new SwitchParameter(false); [Parameter] public string[] Versions{ get; set; } [Parameter] public SwitchParameter IncludeDelisted{ get; set; } protected override Task BeginProcessingAsync(){ Versions = Versions?.Select(s => { var version = Version.Parse(s); var vString = $"{version.Major}.{version.Minor}.{version.Build}"; if (version.Revision > 0){ vString += $".{version.Revision}"; } return vString; }).ToArray(); return base.BeginProcessingAsync(); } protected override async Task ProcessRecordAsync(){ if (Name == null && (Versions == null || !Versions.Any())){ await Providers.ListPackages(Source, IncludeDelisted, AllVersions, IncludePrerelease) .HandleErrors(this).WriteObject(this); return; } var listPackages = Name != null ? Observable.Return(Name) : Providers.ListPackages(Source, IncludeDelisted,false,IncludePrerelease).ToPackageObject().Select(_ => _.Id); var metaData = listPackages .SelectMany(package => SelectPackages(package, Providers)) .Where(metadata => metadata!=null) .HandleErrors(this) .Distinct(new MetadataComparer()).Replay().AutoConnect(); var searchMetadata = await metaData.DefaultIfEmpty(); if (searchMetadata==null) return; var packageSearchMetadatas = metaData.ToEnumerable().ToArray() .OrderByDescending(_ => _.Identity.Version.Version).ToArray(); if (!AllVersions && Versions == null){ WriteObject(packageSearchMetadatas.OrderByDescending(metadata => metadata.Identity.Version.Version).FirstOrDefault()); return; } foreach (var packageSearchMetadata in packageSearchMetadatas.Where(VersionMatch)){ WriteObject(packageSearchMetadata); } } private bool VersionMatch(IPackageSearchMetadata metadata){ if (Versions == null||Versions.All(string.IsNullOrWhiteSpace)) return true; return Versions.Contains(metadata.Identity.Version.ToString()); } public class MetadataComparer : IEqualityComparer<IPackageSearchMetadata>{ public bool Equals(IPackageSearchMetadata x, IPackageSearchMetadata y){ return x?.Identity.Id == y?.Identity.Id && x?.Identity.Version.Version==y?.Identity.Version.Version; } public int GetHashCode(IPackageSearchMetadata obj){ return $"{obj.Identity.Id}{obj.Identity.Version.Version}".GetHashCode(); } } private IObservable<IPackageSearchMetadata> SelectPackages(string s, List<Lazy<INuGetResourceProvider>> providers){ return Source.Split(';').ToObservable().SelectMany(source => providers.PackageMetadata(source, s,IncludeDelisted,IncludePrerelease)); } } } |