From aa8369eabffb82b64dbc53977218a6a70cb13e78 Mon Sep 17 00:00:00 2001 From: TheCakeIsNaOH Date: Fri, 16 Dec 2022 15:52:50 -0600 Subject: [PATCH] (#9) Add Download Progress This adds download progress to the console when ChocolateyProgressInfo.ShouldDisplayDownloadProgress is set to true. It works for both v2 and v3 feeds, but does not display for local feeds. --- .../NuGet.Protocol/ChocolateyProgressInfo.cs | 28 +++++++++ .../ChocolateyProgressStream.cs | 55 +++++++++++++++++ .../NuGet.Protocol/HttpSource/HttpSource.cs | 37 +++++++++++ .../NuGet.Protocol/HttpSource/IHttpSource.cs | 8 +++ .../PublicAPI/net472/PublicAPI.Unshipped.txt | 61 ++++++++++++++----- .../netcoreapp5.0/PublicAPI.Unshipped.txt | 61 ++++++++++++++----- .../netstandard2.0/PublicAPI.Unshipped.txt | 61 ++++++++++++++----- .../Utility/GetDownloadResultUtility.cs | 46 ++++++++++++-- .../Utility/GlobalPackagesFolderUtility.cs | 58 +++++++++++++++--- 9 files changed, 357 insertions(+), 58 deletions(-) create mode 100644 src/NuGet.Core/NuGet.Protocol/ChocolateyProgressInfo.cs create mode 100644 src/NuGet.Core/NuGet.Protocol/ChocolateyProgressStream.cs diff --git a/src/NuGet.Core/NuGet.Protocol/ChocolateyProgressInfo.cs b/src/NuGet.Core/NuGet.Protocol/ChocolateyProgressInfo.cs new file mode 100644 index 00000000000..fe8b9c7e550 --- /dev/null +++ b/src/NuGet.Core/NuGet.Protocol/ChocolateyProgressInfo.cs @@ -0,0 +1,28 @@ +// Copyright (c) 2022-Present Chocolatey Software, Inc. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using NuGet.Packaging.Core; + +namespace NuGet.Protocol +{ + public class ChocolateyProgressInfo + { + public ChocolateyProgressInfo(PackageIdentity identity, long? length = null, string operation = "") + { + Operation = operation; + Length = length; + Identity = identity; + } + + public string Operation { get; set; } + public PackageIdentity Identity { get; set; } + public long? Length { get; set; } + public static bool ShouldDisplayDownloadProgress { get; set; } + public bool Completed { get; set; } + } +} diff --git a/src/NuGet.Core/NuGet.Protocol/ChocolateyProgressStream.cs b/src/NuGet.Core/NuGet.Protocol/ChocolateyProgressStream.cs new file mode 100644 index 00000000000..42ec6410308 --- /dev/null +++ b/src/NuGet.Core/NuGet.Protocol/ChocolateyProgressStream.cs @@ -0,0 +1,55 @@ +// Copyright (c) 2022-Present Chocolatey Software, Inc. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.IO; + +namespace NuGet.Protocol +{ + public delegate void StreamUpdate(Stream sender, long progress, long totalProgress); + + // Based on https://www.thomasbogholm.net/2021/07/15/extend-streams-with-progress-reporting-progressreportingstream/ + public class ChocolateyProgressStream : Stream + { + public event StreamUpdate WriteProgress; + public event StreamUpdate ReadProgress; + long _totalBytesRead; + long _totalBytesWritten; + private void UpdateRead(long read) + { + _totalBytesRead += read; + ReadProgress?.Invoke(this, read, _totalBytesRead); + } + private void UpdateWritten(long written) + { + _totalBytesWritten += written; + WriteProgress?.Invoke(this, written, _totalBytesWritten); + } + + Stream InnerStream { get; } + + public override int Read(byte[] buffer, int offset, int count) + { + var result = InnerStream.Read(buffer, offset, count); + UpdateRead(result); + return result; + } + public override void Write(byte[] buffer, int offset, int count) + { + InnerStream.Write(buffer, offset, count); + UpdateWritten(count); + } + public override bool CanRead => InnerStream.CanRead; + public override bool CanSeek => InnerStream.CanSeek; + public override bool CanWrite => InnerStream.CanWrite; + public override long Length => InnerStream.Length; + public override long Position { get => InnerStream.Position; set => InnerStream.Position = value; } + public ChocolateyProgressStream(Stream s) + { + InnerStream = s; + } + public override void Flush() => InnerStream.Flush(); + public override long Seek(long offset, SeekOrigin origin) => InnerStream.Seek(offset, origin); + public override void SetLength(long value) => InnerStream.SetLength(value); + } +} diff --git a/src/NuGet.Core/NuGet.Protocol/HttpSource/HttpSource.cs b/src/NuGet.Core/NuGet.Protocol/HttpSource/HttpSource.cs index 4d0edce9403..d5a3e738278 100644 --- a/src/NuGet.Core/NuGet.Protocol/HttpSource/HttpSource.cs +++ b/src/NuGet.Core/NuGet.Protocol/HttpSource/HttpSource.cs @@ -264,6 +264,43 @@ public async Task ProcessStreamAsync( token); } + ////////////////////////////////////////////////////////// + // Start - Chocolatey Specific Modification + ////////////////////////////////////////////////////////// + public async Task ProcessStreamAsync( + HttpSourceRequest request, + Func> processAsync, + SourceCacheContext cacheContext, + ILogger log, + ChocolateyProgressInfo progressInfo, + CancellationToken token) + { + return await ProcessResponseAsync( + request, + async response => + { + if ((request.IgnoreNotFounds && response.StatusCode == HttpStatusCode.NotFound) || + response.StatusCode == HttpStatusCode.NoContent) + { + return await processAsync(null, null); + } + + response.EnsureSuccessStatusCode(); + + progressInfo.Length = response.Content.Headers.ContentLength; + progressInfo.Operation = "Downloading"; + + var networkStream = await response.Content.ReadAsStreamAsync(); + return await processAsync(networkStream, progressInfo); + }, + cacheContext, + log, + token); + } + ////////////////////////////////////////////////////////// + // End - Chocolatey Specific Modification + ////////////////////////////////////////////////////////// + public Task ProcessResponseAsync( HttpSourceRequest request, Func> processAsync, diff --git a/src/NuGet.Core/NuGet.Protocol/HttpSource/IHttpSource.cs b/src/NuGet.Core/NuGet.Protocol/HttpSource/IHttpSource.cs index be5e4b74846..a9f010639e7 100644 --- a/src/NuGet.Core/NuGet.Protocol/HttpSource/IHttpSource.cs +++ b/src/NuGet.Core/NuGet.Protocol/HttpSource/IHttpSource.cs @@ -47,6 +47,14 @@ Task ProcessStreamAsync( ILogger log, CancellationToken token); + Task ProcessStreamAsync( + HttpSourceRequest request, + Func> processAsync, + SourceCacheContext cacheContext, + ILogger log, + ChocolateyProgressInfo progressInfo, + CancellationToken token); + Task ProcessResponseAsync( HttpSourceRequest request, Func> processAsync, diff --git a/src/NuGet.Core/NuGet.Protocol/PublicAPI/net472/PublicAPI.Unshipped.txt b/src/NuGet.Core/NuGet.Protocol/PublicAPI/net472/PublicAPI.Unshipped.txt index 48fde9e16c0..b4ce04d5599 100644 --- a/src/NuGet.Core/NuGet.Protocol/PublicAPI/net472/PublicAPI.Unshipped.txt +++ b/src/NuGet.Core/NuGet.Protocol/PublicAPI/net472/PublicAPI.Unshipped.txt @@ -16,6 +16,37 @@ NuGet.Protocol.Core.Types.DownloadCache.FileName.get -> string NuGet.Protocol.Core.Types.DownloadCache.FileName.set -> void NuGet.Protocol.Core.Types.DownloadCache.OriginalUrl.get -> string NuGet.Protocol.Core.Types.DownloadCache.OriginalUrl.set -> void +NuGet.Protocol.ChocolateyProgressInfo +NuGet.Protocol.ChocolateyProgressInfo.ChocolateyProgressInfo(NuGet.Packaging.Core.PackageIdentity identity, long? length = null, string operation = "") -> void +NuGet.Protocol.ChocolateyProgressInfo.Completed.get -> bool +NuGet.Protocol.ChocolateyProgressInfo.Completed.set -> void +NuGet.Protocol.ChocolateyProgressInfo.Identity.get -> NuGet.Packaging.Core.PackageIdentity +NuGet.Protocol.ChocolateyProgressInfo.Identity.set -> void +NuGet.Protocol.ChocolateyProgressInfo.Length.get -> long? +NuGet.Protocol.ChocolateyProgressInfo.Length.set -> void +NuGet.Protocol.ChocolateyProgressInfo.Operation.get -> string +NuGet.Protocol.ChocolateyProgressInfo.Operation.set -> void +NuGet.Protocol.ChocolateyProgressStream +NuGet.Protocol.ChocolateyProgressStream.ChocolateyProgressStream(System.IO.Stream s) -> void +NuGet.Protocol.ChocolateyProgressStream.ReadProgress -> NuGet.Protocol.StreamUpdate +NuGet.Protocol.ChocolateyProgressStream.WriteProgress -> NuGet.Protocol.StreamUpdate +NuGet.Protocol.HttpSource.ProcessHttpStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.HttpSource.ProcessStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Protocol.Core.Types.SourceCacheContext cacheContext, NuGet.Common.ILogger log, NuGet.Protocol.ChocolateyProgressInfo progressInfo, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.HttpSourceResource.OverrideHttpSource(NuGet.Protocol.IHttpSource source) -> void +NuGet.Protocol.IHttpSource +NuGet.Protocol.IHttpSource.GetAsync(NuGet.Protocol.HttpSourceCachedRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.IHttpSource.GetJObjectAsync(NuGet.Protocol.HttpSourceRequest request, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.IHttpSource.HttpCacheDirectory.get -> string +NuGet.Protocol.IHttpSource.HttpCacheDirectory.set -> void +NuGet.Protocol.IHttpSource.PackageSource.get -> string +NuGet.Protocol.IHttpSource.ProcessHttpStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.IHttpSource.ProcessResponseAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.IHttpSource.ProcessResponseAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Protocol.Core.Types.SourceCacheContext cacheContext, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.IHttpSource.ProcessStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Protocol.Core.Types.SourceCacheContext cacheContext, NuGet.Common.ILogger log, NuGet.Protocol.ChocolateyProgressInfo progressInfo, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.IHttpSource.ProcessStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.IHttpSource.ProcessStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Protocol.Core.Types.SourceCacheContext cacheContext, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.IHttpSource.RetryHandler.get -> NuGet.Protocol.IHttpRetryHandler +NuGet.Protocol.IHttpSource.RetryHandler.set -> void NuGet.Protocol.Core.Types.IPackageSearchMetadata.DownloadCache.get -> System.Collections.Generic.IEnumerable NuGet.Protocol.Core.Types.IPackageSearchMetadata.DownloadCacheDate.get -> System.DateTime? NuGet.Protocol.Core.Types.IPackageSearchMetadata.IsApproved.get -> bool @@ -71,21 +102,6 @@ NuGet.Protocol.Core.Types.PackageSearchMetadataBuilder.ClonedPackageSearchMetada NuGet.Protocol.Core.Types.PackageSearchMetadataBuilder.ClonedPackageSearchMetadata.PackageValidationResultStatus.set -> void NuGet.Protocol.Core.Types.PackageSearchMetadataBuilder.ClonedPackageSearchMetadata.VersionDownloadCount.get -> int? NuGet.Protocol.Core.Types.PackageSearchMetadataBuilder.ClonedPackageSearchMetadata.VersionDownloadCount.set -> void -NuGet.Protocol.HttpSource.ProcessHttpStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task -NuGet.Protocol.HttpSourceResource.OverrideHttpSource(NuGet.Protocol.IHttpSource source) -> void -NuGet.Protocol.IHttpSource -NuGet.Protocol.IHttpSource.GetAsync(NuGet.Protocol.HttpSourceCachedRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task -NuGet.Protocol.IHttpSource.GetJObjectAsync(NuGet.Protocol.HttpSourceRequest request, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task -NuGet.Protocol.IHttpSource.HttpCacheDirectory.get -> string -NuGet.Protocol.IHttpSource.HttpCacheDirectory.set -> void -NuGet.Protocol.IHttpSource.PackageSource.get -> string -NuGet.Protocol.IHttpSource.ProcessHttpStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task -NuGet.Protocol.IHttpSource.ProcessResponseAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task -NuGet.Protocol.IHttpSource.ProcessResponseAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Protocol.Core.Types.SourceCacheContext cacheContext, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task -NuGet.Protocol.IHttpSource.ProcessStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task -NuGet.Protocol.IHttpSource.ProcessStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Protocol.Core.Types.SourceCacheContext cacheContext, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task -NuGet.Protocol.IHttpSource.RetryHandler.get -> NuGet.Protocol.IHttpRetryHandler -NuGet.Protocol.IHttpSource.RetryHandler.set -> void NuGet.Protocol.LocalPackageSearchMetadata.DownloadCache.get -> System.Collections.Generic.IEnumerable NuGet.Protocol.LocalPackageSearchMetadata.DownloadCacheDate.get -> System.DateTime? NuGet.Protocol.LocalPackageSearchMetadata.GetNuspecReader.get -> NuGet.Packaging.NuspecReader @@ -161,6 +177,7 @@ NuGet.Protocol.PackageSearchMetadataV2Feed.PackageTestResultStatusDate.get -> Sy NuGet.Protocol.PackageSearchMetadataV2Feed.PackageValidationResultDate.get -> System.DateTime? NuGet.Protocol.PackageSearchMetadataV2Feed.PackageValidationResultStatus.get -> string NuGet.Protocol.PackageSearchMetadataV2Feed.VersionDownloadCount.get -> int? +NuGet.Protocol.StreamUpdate NuGet.Protocol.V2FeedPackageInfo.DownloadCacheDate.get -> System.DateTime? NuGet.Protocol.V2FeedPackageInfo.DownloadCacheString.get -> string NuGet.Protocol.V2FeedPackageInfo.IsApproved.get -> bool @@ -188,3 +205,17 @@ override NuGet.Protocol.LocalDependencyInfoResource.ResolvePackage(NuGet.Packagi override NuGet.Protocol.LocalDependencyInfoResource.ResolvePackages(string packageId, Chocolatey.NuGet.Frameworks.NuGetFramework projectFramework, NuGet.Protocol.Core.Types.SourceCacheContext sourceCacheContext, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task> override NuGet.Protocol.Plugins.PluginPackageReader.GetSupportedFrameworks() -> System.Collections.Generic.IEnumerable override NuGet.Protocol.Plugins.PluginPackageReader.GetSupportedFrameworksAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task> +override NuGet.Protocol.ChocolateyProgressStream.CanRead.get -> bool +override NuGet.Protocol.ChocolateyProgressStream.CanSeek.get -> bool +override NuGet.Protocol.ChocolateyProgressStream.CanWrite.get -> bool +override NuGet.Protocol.ChocolateyProgressStream.Flush() -> void +override NuGet.Protocol.ChocolateyProgressStream.Length.get -> long +override NuGet.Protocol.ChocolateyProgressStream.Position.get -> long +override NuGet.Protocol.ChocolateyProgressStream.Position.set -> void +override NuGet.Protocol.ChocolateyProgressStream.Read(byte[] buffer, int offset, int count) -> int +override NuGet.Protocol.ChocolateyProgressStream.Seek(long offset, System.IO.SeekOrigin origin) -> long +override NuGet.Protocol.ChocolateyProgressStream.SetLength(long value) -> void +override NuGet.Protocol.ChocolateyProgressStream.Write(byte[] buffer, int offset, int count) -> void +static NuGet.Protocol.ChocolateyProgressInfo.ShouldDisplayDownloadProgress.get -> bool +static NuGet.Protocol.ChocolateyProgressInfo.ShouldDisplayDownloadProgress.set -> void +static NuGet.Protocol.GlobalPackagesFolderUtility.AddPackageAsync(string source, NuGet.Packaging.Core.PackageIdentity packageIdentity, System.IO.Stream packageStream, string globalPackagesFolder, System.Guid parentId, NuGet.Packaging.Signing.ClientPolicyContext clientPolicyContext, NuGet.Common.ILogger logger, System.Threading.CancellationToken token, NuGet.Protocol.ChocolateyProgressInfo progressInfo) -> System.Threading.Tasks.Task \ No newline at end of file diff --git a/src/NuGet.Core/NuGet.Protocol/PublicAPI/netcoreapp5.0/PublicAPI.Unshipped.txt b/src/NuGet.Core/NuGet.Protocol/PublicAPI/netcoreapp5.0/PublicAPI.Unshipped.txt index 48fde9e16c0..b4ce04d5599 100644 --- a/src/NuGet.Core/NuGet.Protocol/PublicAPI/netcoreapp5.0/PublicAPI.Unshipped.txt +++ b/src/NuGet.Core/NuGet.Protocol/PublicAPI/netcoreapp5.0/PublicAPI.Unshipped.txt @@ -16,6 +16,37 @@ NuGet.Protocol.Core.Types.DownloadCache.FileName.get -> string NuGet.Protocol.Core.Types.DownloadCache.FileName.set -> void NuGet.Protocol.Core.Types.DownloadCache.OriginalUrl.get -> string NuGet.Protocol.Core.Types.DownloadCache.OriginalUrl.set -> void +NuGet.Protocol.ChocolateyProgressInfo +NuGet.Protocol.ChocolateyProgressInfo.ChocolateyProgressInfo(NuGet.Packaging.Core.PackageIdentity identity, long? length = null, string operation = "") -> void +NuGet.Protocol.ChocolateyProgressInfo.Completed.get -> bool +NuGet.Protocol.ChocolateyProgressInfo.Completed.set -> void +NuGet.Protocol.ChocolateyProgressInfo.Identity.get -> NuGet.Packaging.Core.PackageIdentity +NuGet.Protocol.ChocolateyProgressInfo.Identity.set -> void +NuGet.Protocol.ChocolateyProgressInfo.Length.get -> long? +NuGet.Protocol.ChocolateyProgressInfo.Length.set -> void +NuGet.Protocol.ChocolateyProgressInfo.Operation.get -> string +NuGet.Protocol.ChocolateyProgressInfo.Operation.set -> void +NuGet.Protocol.ChocolateyProgressStream +NuGet.Protocol.ChocolateyProgressStream.ChocolateyProgressStream(System.IO.Stream s) -> void +NuGet.Protocol.ChocolateyProgressStream.ReadProgress -> NuGet.Protocol.StreamUpdate +NuGet.Protocol.ChocolateyProgressStream.WriteProgress -> NuGet.Protocol.StreamUpdate +NuGet.Protocol.HttpSource.ProcessHttpStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.HttpSource.ProcessStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Protocol.Core.Types.SourceCacheContext cacheContext, NuGet.Common.ILogger log, NuGet.Protocol.ChocolateyProgressInfo progressInfo, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.HttpSourceResource.OverrideHttpSource(NuGet.Protocol.IHttpSource source) -> void +NuGet.Protocol.IHttpSource +NuGet.Protocol.IHttpSource.GetAsync(NuGet.Protocol.HttpSourceCachedRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.IHttpSource.GetJObjectAsync(NuGet.Protocol.HttpSourceRequest request, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.IHttpSource.HttpCacheDirectory.get -> string +NuGet.Protocol.IHttpSource.HttpCacheDirectory.set -> void +NuGet.Protocol.IHttpSource.PackageSource.get -> string +NuGet.Protocol.IHttpSource.ProcessHttpStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.IHttpSource.ProcessResponseAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.IHttpSource.ProcessResponseAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Protocol.Core.Types.SourceCacheContext cacheContext, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.IHttpSource.ProcessStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Protocol.Core.Types.SourceCacheContext cacheContext, NuGet.Common.ILogger log, NuGet.Protocol.ChocolateyProgressInfo progressInfo, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.IHttpSource.ProcessStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.IHttpSource.ProcessStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Protocol.Core.Types.SourceCacheContext cacheContext, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.IHttpSource.RetryHandler.get -> NuGet.Protocol.IHttpRetryHandler +NuGet.Protocol.IHttpSource.RetryHandler.set -> void NuGet.Protocol.Core.Types.IPackageSearchMetadata.DownloadCache.get -> System.Collections.Generic.IEnumerable NuGet.Protocol.Core.Types.IPackageSearchMetadata.DownloadCacheDate.get -> System.DateTime? NuGet.Protocol.Core.Types.IPackageSearchMetadata.IsApproved.get -> bool @@ -71,21 +102,6 @@ NuGet.Protocol.Core.Types.PackageSearchMetadataBuilder.ClonedPackageSearchMetada NuGet.Protocol.Core.Types.PackageSearchMetadataBuilder.ClonedPackageSearchMetadata.PackageValidationResultStatus.set -> void NuGet.Protocol.Core.Types.PackageSearchMetadataBuilder.ClonedPackageSearchMetadata.VersionDownloadCount.get -> int? NuGet.Protocol.Core.Types.PackageSearchMetadataBuilder.ClonedPackageSearchMetadata.VersionDownloadCount.set -> void -NuGet.Protocol.HttpSource.ProcessHttpStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task -NuGet.Protocol.HttpSourceResource.OverrideHttpSource(NuGet.Protocol.IHttpSource source) -> void -NuGet.Protocol.IHttpSource -NuGet.Protocol.IHttpSource.GetAsync(NuGet.Protocol.HttpSourceCachedRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task -NuGet.Protocol.IHttpSource.GetJObjectAsync(NuGet.Protocol.HttpSourceRequest request, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task -NuGet.Protocol.IHttpSource.HttpCacheDirectory.get -> string -NuGet.Protocol.IHttpSource.HttpCacheDirectory.set -> void -NuGet.Protocol.IHttpSource.PackageSource.get -> string -NuGet.Protocol.IHttpSource.ProcessHttpStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task -NuGet.Protocol.IHttpSource.ProcessResponseAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task -NuGet.Protocol.IHttpSource.ProcessResponseAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Protocol.Core.Types.SourceCacheContext cacheContext, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task -NuGet.Protocol.IHttpSource.ProcessStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task -NuGet.Protocol.IHttpSource.ProcessStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Protocol.Core.Types.SourceCacheContext cacheContext, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task -NuGet.Protocol.IHttpSource.RetryHandler.get -> NuGet.Protocol.IHttpRetryHandler -NuGet.Protocol.IHttpSource.RetryHandler.set -> void NuGet.Protocol.LocalPackageSearchMetadata.DownloadCache.get -> System.Collections.Generic.IEnumerable NuGet.Protocol.LocalPackageSearchMetadata.DownloadCacheDate.get -> System.DateTime? NuGet.Protocol.LocalPackageSearchMetadata.GetNuspecReader.get -> NuGet.Packaging.NuspecReader @@ -161,6 +177,7 @@ NuGet.Protocol.PackageSearchMetadataV2Feed.PackageTestResultStatusDate.get -> Sy NuGet.Protocol.PackageSearchMetadataV2Feed.PackageValidationResultDate.get -> System.DateTime? NuGet.Protocol.PackageSearchMetadataV2Feed.PackageValidationResultStatus.get -> string NuGet.Protocol.PackageSearchMetadataV2Feed.VersionDownloadCount.get -> int? +NuGet.Protocol.StreamUpdate NuGet.Protocol.V2FeedPackageInfo.DownloadCacheDate.get -> System.DateTime? NuGet.Protocol.V2FeedPackageInfo.DownloadCacheString.get -> string NuGet.Protocol.V2FeedPackageInfo.IsApproved.get -> bool @@ -188,3 +205,17 @@ override NuGet.Protocol.LocalDependencyInfoResource.ResolvePackage(NuGet.Packagi override NuGet.Protocol.LocalDependencyInfoResource.ResolvePackages(string packageId, Chocolatey.NuGet.Frameworks.NuGetFramework projectFramework, NuGet.Protocol.Core.Types.SourceCacheContext sourceCacheContext, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task> override NuGet.Protocol.Plugins.PluginPackageReader.GetSupportedFrameworks() -> System.Collections.Generic.IEnumerable override NuGet.Protocol.Plugins.PluginPackageReader.GetSupportedFrameworksAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task> +override NuGet.Protocol.ChocolateyProgressStream.CanRead.get -> bool +override NuGet.Protocol.ChocolateyProgressStream.CanSeek.get -> bool +override NuGet.Protocol.ChocolateyProgressStream.CanWrite.get -> bool +override NuGet.Protocol.ChocolateyProgressStream.Flush() -> void +override NuGet.Protocol.ChocolateyProgressStream.Length.get -> long +override NuGet.Protocol.ChocolateyProgressStream.Position.get -> long +override NuGet.Protocol.ChocolateyProgressStream.Position.set -> void +override NuGet.Protocol.ChocolateyProgressStream.Read(byte[] buffer, int offset, int count) -> int +override NuGet.Protocol.ChocolateyProgressStream.Seek(long offset, System.IO.SeekOrigin origin) -> long +override NuGet.Protocol.ChocolateyProgressStream.SetLength(long value) -> void +override NuGet.Protocol.ChocolateyProgressStream.Write(byte[] buffer, int offset, int count) -> void +static NuGet.Protocol.ChocolateyProgressInfo.ShouldDisplayDownloadProgress.get -> bool +static NuGet.Protocol.ChocolateyProgressInfo.ShouldDisplayDownloadProgress.set -> void +static NuGet.Protocol.GlobalPackagesFolderUtility.AddPackageAsync(string source, NuGet.Packaging.Core.PackageIdentity packageIdentity, System.IO.Stream packageStream, string globalPackagesFolder, System.Guid parentId, NuGet.Packaging.Signing.ClientPolicyContext clientPolicyContext, NuGet.Common.ILogger logger, System.Threading.CancellationToken token, NuGet.Protocol.ChocolateyProgressInfo progressInfo) -> System.Threading.Tasks.Task \ No newline at end of file diff --git a/src/NuGet.Core/NuGet.Protocol/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt b/src/NuGet.Core/NuGet.Protocol/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt index 48fde9e16c0..b4ce04d5599 100644 --- a/src/NuGet.Core/NuGet.Protocol/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/NuGet.Core/NuGet.Protocol/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt @@ -16,6 +16,37 @@ NuGet.Protocol.Core.Types.DownloadCache.FileName.get -> string NuGet.Protocol.Core.Types.DownloadCache.FileName.set -> void NuGet.Protocol.Core.Types.DownloadCache.OriginalUrl.get -> string NuGet.Protocol.Core.Types.DownloadCache.OriginalUrl.set -> void +NuGet.Protocol.ChocolateyProgressInfo +NuGet.Protocol.ChocolateyProgressInfo.ChocolateyProgressInfo(NuGet.Packaging.Core.PackageIdentity identity, long? length = null, string operation = "") -> void +NuGet.Protocol.ChocolateyProgressInfo.Completed.get -> bool +NuGet.Protocol.ChocolateyProgressInfo.Completed.set -> void +NuGet.Protocol.ChocolateyProgressInfo.Identity.get -> NuGet.Packaging.Core.PackageIdentity +NuGet.Protocol.ChocolateyProgressInfo.Identity.set -> void +NuGet.Protocol.ChocolateyProgressInfo.Length.get -> long? +NuGet.Protocol.ChocolateyProgressInfo.Length.set -> void +NuGet.Protocol.ChocolateyProgressInfo.Operation.get -> string +NuGet.Protocol.ChocolateyProgressInfo.Operation.set -> void +NuGet.Protocol.ChocolateyProgressStream +NuGet.Protocol.ChocolateyProgressStream.ChocolateyProgressStream(System.IO.Stream s) -> void +NuGet.Protocol.ChocolateyProgressStream.ReadProgress -> NuGet.Protocol.StreamUpdate +NuGet.Protocol.ChocolateyProgressStream.WriteProgress -> NuGet.Protocol.StreamUpdate +NuGet.Protocol.HttpSource.ProcessHttpStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.HttpSource.ProcessStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Protocol.Core.Types.SourceCacheContext cacheContext, NuGet.Common.ILogger log, NuGet.Protocol.ChocolateyProgressInfo progressInfo, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.HttpSourceResource.OverrideHttpSource(NuGet.Protocol.IHttpSource source) -> void +NuGet.Protocol.IHttpSource +NuGet.Protocol.IHttpSource.GetAsync(NuGet.Protocol.HttpSourceCachedRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.IHttpSource.GetJObjectAsync(NuGet.Protocol.HttpSourceRequest request, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.IHttpSource.HttpCacheDirectory.get -> string +NuGet.Protocol.IHttpSource.HttpCacheDirectory.set -> void +NuGet.Protocol.IHttpSource.PackageSource.get -> string +NuGet.Protocol.IHttpSource.ProcessHttpStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.IHttpSource.ProcessResponseAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.IHttpSource.ProcessResponseAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Protocol.Core.Types.SourceCacheContext cacheContext, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.IHttpSource.ProcessStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Protocol.Core.Types.SourceCacheContext cacheContext, NuGet.Common.ILogger log, NuGet.Protocol.ChocolateyProgressInfo progressInfo, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.IHttpSource.ProcessStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.IHttpSource.ProcessStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Protocol.Core.Types.SourceCacheContext cacheContext, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task +NuGet.Protocol.IHttpSource.RetryHandler.get -> NuGet.Protocol.IHttpRetryHandler +NuGet.Protocol.IHttpSource.RetryHandler.set -> void NuGet.Protocol.Core.Types.IPackageSearchMetadata.DownloadCache.get -> System.Collections.Generic.IEnumerable NuGet.Protocol.Core.Types.IPackageSearchMetadata.DownloadCacheDate.get -> System.DateTime? NuGet.Protocol.Core.Types.IPackageSearchMetadata.IsApproved.get -> bool @@ -71,21 +102,6 @@ NuGet.Protocol.Core.Types.PackageSearchMetadataBuilder.ClonedPackageSearchMetada NuGet.Protocol.Core.Types.PackageSearchMetadataBuilder.ClonedPackageSearchMetadata.PackageValidationResultStatus.set -> void NuGet.Protocol.Core.Types.PackageSearchMetadataBuilder.ClonedPackageSearchMetadata.VersionDownloadCount.get -> int? NuGet.Protocol.Core.Types.PackageSearchMetadataBuilder.ClonedPackageSearchMetadata.VersionDownloadCount.set -> void -NuGet.Protocol.HttpSource.ProcessHttpStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task -NuGet.Protocol.HttpSourceResource.OverrideHttpSource(NuGet.Protocol.IHttpSource source) -> void -NuGet.Protocol.IHttpSource -NuGet.Protocol.IHttpSource.GetAsync(NuGet.Protocol.HttpSourceCachedRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task -NuGet.Protocol.IHttpSource.GetJObjectAsync(NuGet.Protocol.HttpSourceRequest request, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task -NuGet.Protocol.IHttpSource.HttpCacheDirectory.get -> string -NuGet.Protocol.IHttpSource.HttpCacheDirectory.set -> void -NuGet.Protocol.IHttpSource.PackageSource.get -> string -NuGet.Protocol.IHttpSource.ProcessHttpStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task -NuGet.Protocol.IHttpSource.ProcessResponseAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task -NuGet.Protocol.IHttpSource.ProcessResponseAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Protocol.Core.Types.SourceCacheContext cacheContext, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task -NuGet.Protocol.IHttpSource.ProcessStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task -NuGet.Protocol.IHttpSource.ProcessStreamAsync(NuGet.Protocol.HttpSourceRequest request, System.Func> processAsync, NuGet.Protocol.Core.Types.SourceCacheContext cacheContext, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task -NuGet.Protocol.IHttpSource.RetryHandler.get -> NuGet.Protocol.IHttpRetryHandler -NuGet.Protocol.IHttpSource.RetryHandler.set -> void NuGet.Protocol.LocalPackageSearchMetadata.DownloadCache.get -> System.Collections.Generic.IEnumerable NuGet.Protocol.LocalPackageSearchMetadata.DownloadCacheDate.get -> System.DateTime? NuGet.Protocol.LocalPackageSearchMetadata.GetNuspecReader.get -> NuGet.Packaging.NuspecReader @@ -161,6 +177,7 @@ NuGet.Protocol.PackageSearchMetadataV2Feed.PackageTestResultStatusDate.get -> Sy NuGet.Protocol.PackageSearchMetadataV2Feed.PackageValidationResultDate.get -> System.DateTime? NuGet.Protocol.PackageSearchMetadataV2Feed.PackageValidationResultStatus.get -> string NuGet.Protocol.PackageSearchMetadataV2Feed.VersionDownloadCount.get -> int? +NuGet.Protocol.StreamUpdate NuGet.Protocol.V2FeedPackageInfo.DownloadCacheDate.get -> System.DateTime? NuGet.Protocol.V2FeedPackageInfo.DownloadCacheString.get -> string NuGet.Protocol.V2FeedPackageInfo.IsApproved.get -> bool @@ -188,3 +205,17 @@ override NuGet.Protocol.LocalDependencyInfoResource.ResolvePackage(NuGet.Packagi override NuGet.Protocol.LocalDependencyInfoResource.ResolvePackages(string packageId, Chocolatey.NuGet.Frameworks.NuGetFramework projectFramework, NuGet.Protocol.Core.Types.SourceCacheContext sourceCacheContext, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task> override NuGet.Protocol.Plugins.PluginPackageReader.GetSupportedFrameworks() -> System.Collections.Generic.IEnumerable override NuGet.Protocol.Plugins.PluginPackageReader.GetSupportedFrameworksAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task> +override NuGet.Protocol.ChocolateyProgressStream.CanRead.get -> bool +override NuGet.Protocol.ChocolateyProgressStream.CanSeek.get -> bool +override NuGet.Protocol.ChocolateyProgressStream.CanWrite.get -> bool +override NuGet.Protocol.ChocolateyProgressStream.Flush() -> void +override NuGet.Protocol.ChocolateyProgressStream.Length.get -> long +override NuGet.Protocol.ChocolateyProgressStream.Position.get -> long +override NuGet.Protocol.ChocolateyProgressStream.Position.set -> void +override NuGet.Protocol.ChocolateyProgressStream.Read(byte[] buffer, int offset, int count) -> int +override NuGet.Protocol.ChocolateyProgressStream.Seek(long offset, System.IO.SeekOrigin origin) -> long +override NuGet.Protocol.ChocolateyProgressStream.SetLength(long value) -> void +override NuGet.Protocol.ChocolateyProgressStream.Write(byte[] buffer, int offset, int count) -> void +static NuGet.Protocol.ChocolateyProgressInfo.ShouldDisplayDownloadProgress.get -> bool +static NuGet.Protocol.ChocolateyProgressInfo.ShouldDisplayDownloadProgress.set -> void +static NuGet.Protocol.GlobalPackagesFolderUtility.AddPackageAsync(string source, NuGet.Packaging.Core.PackageIdentity packageIdentity, System.IO.Stream packageStream, string globalPackagesFolder, System.Guid parentId, NuGet.Packaging.Signing.ClientPolicyContext clientPolicyContext, NuGet.Common.ILogger logger, System.Threading.CancellationToken token, NuGet.Protocol.ChocolateyProgressInfo progressInfo) -> System.Threading.Tasks.Task \ No newline at end of file diff --git a/src/NuGet.Core/NuGet.Protocol/Utility/GetDownloadResultUtility.cs b/src/NuGet.Core/NuGet.Protocol/Utility/GetDownloadResultUtility.cs index 616f76d7c01..19c8d2e1d2c 100644 --- a/src/NuGet.Core/NuGet.Protocol/Utility/GetDownloadResultUtility.cs +++ b/src/NuGet.Core/NuGet.Protocol/Utility/GetDownloadResultUtility.cs @@ -76,7 +76,10 @@ public static async Task GetDownloadResultAsync( IgnoreNotFounds = true, MaxTries = 1 }, - async packageStream => + ////////////////////////////////////////////////////////// + // Start - Chocolatey Specific Modification + ////////////////////////////////////////////////////////// + async (packageStream, progressInfo) => { if (packageStream == null) { @@ -90,7 +93,8 @@ public static async Task GetDownloadResultAsync( identity, packageStream, downloadContext, - token); + token, + progressInfo); } else { @@ -102,11 +106,16 @@ public static async Task GetDownloadResultAsync( downloadContext.ParentId, downloadContext.ClientPolicyContext, logger, - token); + token, + progressInfo); } }, + ////////////////////////////////////////////////////////// + // End - Chocolatey Specific Modification + ////////////////////////////////////////////////////////// downloadContext.SourceCacheContext, logger, + new ChocolateyProgressInfo(identity), token); } catch (OperationCanceledException) @@ -161,12 +170,16 @@ public static void CleanUpDirectDownloads(PackageDownloadContext downloadContext } } + ////////////////////////////////////////////////////////// + // Start - Chocolatey Specific Modification + ////////////////////////////////////////////////////////// private static async Task DirectDownloadAsync( string source, PackageIdentity packageIdentity, Stream packageStream, PackageDownloadContext downloadContext, - CancellationToken token) + CancellationToken token, + ChocolateyProgressInfo progressInfo) { if (packageIdentity == null) { @@ -211,7 +224,27 @@ private static async Task DirectDownloadAsync( BufferSize, FileOptions.DeleteOnClose); - await packageStream.CopyToAsync(fileStream, BufferSize, token); + using (var progressPackageStream = new ChocolateyProgressStream(packageStream)) + { + progressPackageStream.ReadProgress += (sender, progress, totalProgress) => + { + if (progressInfo.Length != null && ChocolateyProgressInfo.ShouldDisplayDownloadProgress && !progressInfo.Completed) + { + var percentComplete = ((double)totalProgress / (double)progressInfo.Length * 100); + var progressString = + $"Progress: {progressInfo.Operation} {progressInfo.Identity.Id} {progressInfo.Identity.Version}... {(percentComplete.ToString("##"))}"; + // http://stackoverflow.com/a/888569/18475 + Console.Write("\r{0}%", progressString); + if (totalProgress == progressInfo.Length) + { + Console.WriteLine(""); + progressInfo.Completed = true; + } + } + }; + + await progressPackageStream.CopyToAsync(fileStream, BufferSize, token); + } fileStream.Seek(0, SeekOrigin.Begin); @@ -224,5 +257,8 @@ private static async Task DirectDownloadAsync( throw; } } + ////////////////////////////////////////////////////////// + // End - Chocolatey Specific Modification + ////////////////////////////////////////////////////////// } } diff --git a/src/NuGet.Core/NuGet.Protocol/Utility/GlobalPackagesFolderUtility.cs b/src/NuGet.Core/NuGet.Protocol/Utility/GlobalPackagesFolderUtility.cs index ce5a59b9901..cd9d346c4d9 100644 --- a/src/NuGet.Core/NuGet.Protocol/Utility/GlobalPackagesFolderUtility.cs +++ b/src/NuGet.Core/NuGet.Protocol/Utility/GlobalPackagesFolderUtility.cs @@ -1,3 +1,4 @@ +// Copyright (c) 2022-Present Chocolatey Software, Inc. // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. @@ -81,6 +82,9 @@ private static DownloadResourceResult CreateDownloadResourceResult(string nupkgP } } + ////////////////////////////////////////////////////////// + // Start - Chocolatey Specific Modification + ////////////////////////////////////////////////////////// public static async Task AddPackageAsync( string source, PackageIdentity packageIdentity, @@ -90,6 +94,21 @@ public static async Task AddPackageAsync( ClientPolicyContext clientPolicyContext, ILogger logger, CancellationToken token) + { + return await AddPackageAsync(source, packageIdentity, packageStream, globalPackagesFolder, parentId, + clientPolicyContext, logger, token, null); + } + + public static async Task AddPackageAsync( + string source, + PackageIdentity packageIdentity, + Stream packageStream, + string globalPackagesFolder, + Guid parentId, + ClientPolicyContext clientPolicyContext, + ILogger logger, + CancellationToken token, + ChocolateyProgressInfo progressInfo) { if (packageIdentity == null) { @@ -118,14 +137,34 @@ public static async Task AddPackageAsync( var versionFolderPathResolver = new VersionFolderPathResolver(globalPackagesFolder); - await PackageExtractor.InstallFromSourceAsync( - source, - packageIdentity, - stream => packageStream.CopyToAsync(stream, BufferSize, token), - versionFolderPathResolver, - extractionContext, - token, - parentId); + using (var progressPackageStream = new ChocolateyProgressStream(packageStream)) + { + progressPackageStream.ReadProgress += (sender, progress, totalProgress) => + { + if (progressInfo.Length != null && ChocolateyProgressInfo.ShouldDisplayDownloadProgress && !progressInfo.Completed) + { + var percentComplete = ((double)totalProgress / (double)progressInfo.Length * 100); + var progressString = + $"Progress: {progressInfo.Operation} {progressInfo.Identity.Id} {progressInfo.Identity.Version}... {(percentComplete.ToString("##"))}"; + // http://stackoverflow.com/a/888569/18475 + Console.Write("\r{0}%", progressString); + if (totalProgress == progressInfo.Length) + { + Console.WriteLine(""); + progressInfo.Completed = true; + } + } + }; + await PackageExtractor.InstallFromSourceAsync( + source, + packageIdentity, + stream => progressPackageStream.CopyToAsync(stream, BufferSize, token), + versionFolderPathResolver, + extractionContext, + token, + parentId); + + } var package = GetPackage(packageIdentity, globalPackagesFolder); @@ -134,5 +173,8 @@ await PackageExtractor.InstallFromSourceAsync( return package; } + ////////////////////////////////////////////////////////// + // End - Chocolatey Specific Modification + ////////////////////////////////////////////////////////// } }