diff --git a/GitVersion.yml b/GitVersion.yml index 047d81fa..82de0c31 100644 --- a/GitVersion.yml +++ b/GitVersion.yml @@ -1,4 +1,4 @@ -next-version: 5.2.0 +next-version: 5.2.2 mode: ContinuousDeployment continuous-delivery-fallback-tag: '' branches: diff --git a/snapx-dev.cmd b/snapx-dev.cmd deleted file mode 100644 index 90e216be..00000000 --- a/snapx-dev.cmd +++ /dev/null @@ -1,2 +0,0 @@ -dotnet build -c Debug src/Snapx/Snapx.csproj -dotnet src/Snapx/bin/Debug/net6.0/Snapx.dll %* diff --git a/snapx-dev.sh b/snapx-dev.sh deleted file mode 100644 index c27c5aa8..00000000 --- a/snapx-dev.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -dotnet build -c Debug src/Snapx/Snapx.csproj -dotnet src/Snapx/bin/Debug/net6.0/snapx.dll $* diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 9241c24a..5eece8df 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -1,7 +1,7 @@ true - 11.0.0-preview6 + 11.0.0-preview7 @@ -16,7 +16,7 @@ - + diff --git a/src/Snap.Installer/ViewModels/AvaloniaMainWindowViewModel.cs b/src/Snap.Installer/ViewModels/AvaloniaMainWindowViewModel.cs index 42f90875..4287991d 100644 --- a/src/Snap.Installer/ViewModels/AvaloniaMainWindowViewModel.cs +++ b/src/Snap.Installer/ViewModels/AvaloniaMainWindowViewModel.cs @@ -75,7 +75,7 @@ public AvaloniaMainWindowViewModel([NotNull] ISnapInstallerEmbeddedResources sna public Task SetStatusTextAsync(string text) { - return Dispatcher.UIThread.InvokeAsync(() => StatusText = text); + return Dispatcher.UIThread.InvokeAsync(() => StatusText = text).GetTask(); } public Task SetErrorAsync() @@ -83,7 +83,7 @@ public Task SetErrorAsync() return Dispatcher.UIThread.InvokeAsync(() => { StatusTextBrush = (IImmutableBrush)Brush.Parse("#B80F0A"); - }); + }).GetTask(); } public void OnInitialized() diff --git a/src/Snap.Installer/Windows/CustomChromeWindow.cs b/src/Snap.Installer/Windows/CustomChromeWindow.cs index 9551d291..106fd489 100644 --- a/src/Snap.Installer/Windows/CustomChromeWindow.cs +++ b/src/Snap.Installer/Windows/CustomChromeWindow.cs @@ -1,6 +1,4 @@ -using System; -using System.Runtime.InteropServices; -using Avalonia.Controls; +using Avalonia.Controls; using Avalonia.Controls.Primitives; using Avalonia.Input; @@ -10,39 +8,15 @@ internal class CustomChromeWindow : Window { protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { - var thisHandle = PlatformImpl.Handle.Handle; - - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - NativeMethodsWindows.FocusThisWindow(thisHandle); - } - + Focus(); base.OnApplyTemplate(e); } protected override void OnPointerPressed(PointerPressedEventArgs e) { BeginMoveDrag(e); - base.OnPointerPressed(e); } - protected override void HandleWindowStateChanged(WindowState state) - { - WindowState = WindowState.Normal; - } - - protected static class NativeMethodsWindows - { - [DllImport("user32", SetLastError = true, EntryPoint = "SetActiveWindow")] - static extern IntPtr SetActiveWindow(IntPtr hWnd); - [DllImport("user32", SetLastError = true, EntryPoint = "SetForegroundWindow")] - static extern bool SetForegroundWindow(IntPtr hWnd); - - public static void FocusThisWindow(IntPtr hWnd) - { - SetActiveWindow(hWnd); - SetForegroundWindow(hWnd); - } - } -} \ No newline at end of file + protected override void HandleWindowStateChanged(WindowState state) => WindowState = WindowState.Normal; +} diff --git a/src/Snap.Tests/Core/SnapUpdateManagerTests.cs b/src/Snap.Tests/Core/SnapUpdateManagerTests.cs index 36a3dcd9..f394f050 100644 --- a/src/Snap.Tests/Core/SnapUpdateManagerTests.cs +++ b/src/Snap.Tests/Core/SnapUpdateManagerTests.cs @@ -2,12 +2,14 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Net; +using System.Net.Http; using System.Text; +using System.Text.Json; using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; using Moq; -using Newtonsoft.Json; using NuGet.Configuration; using NuGet.Versioning; using Snap.AnyOS; @@ -24,7 +26,7 @@ namespace Snap.Tests.Core; -public class SnapUpdateManagerTests : IClassFixture, IClassFixture, IClassFixture +public sealed class SnapUpdateManagerTests : IClassFixture, IClassFixture, IClassFixture { readonly BaseFixture _baseFixture; readonly BaseFixturePackaging _baseFixturePackaging; @@ -80,26 +82,29 @@ public async Task TestGetSnapReleasesAsync_SnapHttpFeed(bool versionIsNull) const string applicationId = "my-application-id"; - _snapHttpClientMock.Setup(x => x.GetStreamAsync(It.IsAny(), It.IsAny>())).ReturnsAsync(() => + _snapHttpClientMock.Setup(x => x.SendAsync(It.IsAny(), It.IsAny())).ReturnsAsync(() => { - var jsonStr = JsonConvert.SerializeObject(snapPackageManagerHttpFeed); + var jsonStr = JsonSerializer.Serialize(snapPackageManagerHttpFeed); var jsonBytes = Encoding.UTF8.GetBytes(jsonStr); - return new MemoryStream(jsonBytes); - }).Callback((Uri uri, IDictionary headers) => + return new HttpResponseMessage(HttpStatusCode.OK) + { + Content = new StreamContent(new MemoryStream(jsonBytes)) + }; + }).Callback((HttpRequestMessage httpRequestMessage, CancellationToken _) => { - Assert.Equal(uri, snapPackageManagerHttpFeed.Source); - Assert.NotNull(headers); - Assert.Equal(4, headers.Count); - Assert.Collection(headers, pair => Assert.Equal("X-Snapx-App-Id", snapApp.Id)); - Assert.Collection(headers, pair => Assert.Equal("X-Snapx-Channel", snapChannel.Name)); - Assert.Collection(headers, pair => Assert.Equal("X-Snapx-Application-Id", applicationId)); + Assert.Equal(snapPackageManagerHttpFeed.Source, httpRequestMessage.RequestUri); + Assert.NotNull(httpRequestMessage.Headers); + Assert.Equal(4, httpRequestMessage.Headers.Count()); + Assert.Collection(httpRequestMessage.Headers, _ => Assert.Equal("X-Snapx-App-Id", snapApp.Id)); + Assert.Collection(httpRequestMessage.Headers, _ => Assert.Equal("X-Snapx-Channel", snapChannel.Name)); + Assert.Collection(httpRequestMessage.Headers, _ => Assert.Equal("X-Snapx-Application-Id", applicationId)); if (versionIsNull) { - Assert.Collection(headers, pair => Assert.Null("X-Snapx-Application-Version")); + Assert.Collection(httpRequestMessage.Headers, _ => Assert.Null("X-Snapx-Application-Version")); } else { - Assert.Collection(headers, pair => Assert.Equal("X-Snapx-Application-Version", snapApp.Version.ToNormalizedString())); + Assert.Collection(httpRequestMessage.Headers, _ => Assert.Equal("X-Snapx-Application-Version", snapApp.Version.ToNormalizedString())); } }); @@ -110,9 +115,9 @@ public async Task TestGetSnapReleasesAsync_SnapHttpFeed(bool versionIsNull) Assert.Null(snapReleases); _snapHttpClientMock.Verify(x => - x.GetStreamAsync( - It.Is(v => v == snapChannel.UpdateFeed.Source), - It.Is>(v => v.Count == 4)), Times.Once); + x.SendAsync( + It.Is(v => v.RequestUri == snapChannel.UpdateFeed.Source && v.Headers.Count() == 4), + It.IsAny()), Times.Once); } [InlineData("1.0.0")] @@ -279,4 +284,4 @@ static void SetupUpdateManagerProgressSource(Mock(), It.IsAny(), It.IsAny())); progressSourceMock.Setup(x => x.RaiseTotalProgress(It.IsAny())); } -} \ No newline at end of file +} diff --git a/src/Snap/Core/SnapHttpClient.cs b/src/Snap/Core/SnapHttpClient.cs index fd8f92e7..68dd588f 100644 --- a/src/Snap/Core/SnapHttpClient.cs +++ b/src/Snap/Core/SnapHttpClient.cs @@ -1,15 +1,13 @@ using System; -using System.Collections.Generic; -using System.IO; using System.Net.Http; using System.Threading; using System.Threading.Tasks; +using JetBrains.Annotations; namespace Snap.Core; public interface ISnapHttpClient { - Task GetStreamAsync(Uri requestUri, IDictionary headers = null); Task SendAsync(HttpRequestMessage httpRequestMessage, CancellationToken cancellationToken); } @@ -17,24 +15,9 @@ public sealed class SnapHttpClient : ISnapHttpClient { readonly HttpClient _httpClient; - public SnapHttpClient(HttpClient httpClient) - { - _httpClient = httpClient; - } - - public async Task GetStreamAsync(Uri requestUri, IDictionary headers = null) - { - var httpResponseMessage = await _httpClient.GetAsync(requestUri); - if (headers != null) - { - foreach (var pair in headers) - { - httpResponseMessage.Headers.Add(pair.Key, pair.Value); - } - } - return await httpResponseMessage.Content.ReadAsStreamAsync(); - } - + public SnapHttpClient([NotNull] HttpClient httpClient) => + _httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient)); + public Task SendAsync(HttpRequestMessage httpRequestMessage, CancellationToken cancellationToken) => _httpClient.SendAsync(httpRequestMessage, cancellationToken); } diff --git a/src/Snap/Core/SnapPackageManager.cs b/src/Snap/Core/SnapPackageManager.cs index 83edb64d..3c9f9e69 100644 --- a/src/Snap/Core/SnapPackageManager.cs +++ b/src/Snap/Core/SnapPackageManager.cs @@ -3,7 +3,6 @@ using System.Diagnostics; using System.IO; using System.Linq; -using System.Net; using System.Net.Http; using System.Text; using System.Text.Json; @@ -73,7 +72,8 @@ public enum SnapPackageManagerRestoreType internal interface ISnapPackageManager { - Task GetPackageSourceAsync(SnapApp snapApp, ILog logger = null, string applicationId = null); + Task GetPackageSourceAsync(SnapApp snapApp, ILog logger = null, string applicationId = null, + CancellationToken cancellationToken = default); Task<(SnapAppsReleases snapAppsReleases, PackageSource packageSource, MemoryStream releasesMemoryStream, bool nupkgNotFound)> GetSnapsReleasesAsync( [NotNull] SnapApp snapApp, ILog logger = null, CancellationToken cancellationToken = default, string applicationId = null); @@ -86,12 +86,6 @@ Task RestoreAsync([NotNull] string packagesDir int checksumConcurrency = 1, int downloadConcurrency = 2, int restoreConcurrency = 1); } -[JsonSerializable(typeof(SnapPackageManagerNugetHttpFeed))] -internal partial class SnapPackageManagerNugetHttpFeedContext : JsonSerializerContext -{ - -} - internal sealed class SnapPackageManagerNugetHttpFeed { [JsonInclude] @@ -175,12 +169,11 @@ public SnapPackageManager([NotNull] ISnapFilesystem filesystem, _snapFilesystem = snapFilesystem ?? throw new ArgumentNullException(nameof(snapFilesystem)); } - public async Task GetPackageSourceAsync( - [NotNull] SnapApp snapApp, - ILog logger = null, - string applicationId = null) + public async Task GetPackageSourceAsync([NotNull] SnapApp snapApp, + ILog logger = null, + string applicationId = null, CancellationToken cancellationToken = default) { - if (snapApp == null) throw new ArgumentNullException(nameof(snapApp)); + ArgumentNullException.ThrowIfNull(snapApp); try { @@ -190,27 +183,29 @@ public async Task GetPackageSourceAsync( { case SnapHttpFeed feed: { - var headers = new Dictionary + using var httpResponseMessage = await _snapHttpClient.SendAsync(new HttpRequestMessage(HttpMethod.Get, feed.Source) { - { "X-Snapx-App-Id", snapApp.Id}, - { "X-Snapx-Channel", channel.Name }, - { "X-Snapx-Application-Id", applicationId }, - { "X-Snapx-Application-Version", snapApp.Version?.ToNormalizedString() } - }; - - await using var stream = await _snapHttpClient.GetStreamAsync(feed.Source, headers); - stream.Seek(0, SeekOrigin.Begin); + Headers = + { + { "X-Snapx-App-Id", snapApp.Id}, + { "X-Snapx-Channel", channel.Name }, + { "X-Snapx-Application-Id", applicationId }, + { "X-Snapx-Application-Version", snapApp.Version?.ToNormalizedString() } + } + }, cancellationToken); - await using var jsonStream = await stream.ReadToEndAsync(); + httpResponseMessage.EnsureSuccessStatusCode(); + + await using var stream = await httpResponseMessage.Content.ReadAsStreamAsync(cancellationToken); - var packageManagerNugetHttp = await JsonSerializer.DeserializeAsync(jsonStream, new SnapPackageManagerNugetHttpFeedContext(new JsonSerializerOptions + var packageManagerNugetHttp = await JsonSerializer.DeserializeAsync(stream, new JsonSerializerOptions { PropertyNameCaseInsensitive = true - }).SnapPackageManagerNugetHttpFeed); + }, cancellationToken: cancellationToken); if (packageManagerNugetHttp == null) { - throw new Exception($"Unable to deserialize nuget http feed. Url: {feed.Source}. Response length: {stream.Position}"); + throw new Exception($"Unable to deserialize nuget http feed. Url: {feed.Source}."); } if (packageManagerNugetHttp.Source == null) @@ -247,13 +242,13 @@ public async Task GetPackageSourceAsync( public async Task<(SnapAppsReleases snapAppsReleases, PackageSource packageSource, MemoryStream releasesMemoryStream, bool nupkgNotFound)> GetSnapsReleasesAsync( SnapApp snapApp, ILog logger = null, CancellationToken cancellationToken = default, string applicationId = null) { - if (snapApp == null) throw new ArgumentNullException(nameof(snapApp)); + ArgumentNullException.ThrowIfNull(snapApp); var packageId = snapApp.BuildNugetReleasesUpstreamId(); try { - var packageSource = await GetPackageSourceAsync(snapApp, logger, applicationId); + var packageSource = await GetPackageSourceAsync(snapApp, logger, applicationId, cancellationToken); var snapReleasesDownloadResult = await _nugetService.DownloadLatestAsync(packageId, packageSource, false, true, cancellationToken); diff --git a/src/Snap/Core/SnapUpdateManager.cs b/src/Snap/Core/SnapUpdateManager.cs index 75a3744f..66663fdb 100644 --- a/src/Snap/Core/SnapUpdateManager.cs +++ b/src/Snap/Core/SnapUpdateManager.cs @@ -221,7 +221,7 @@ async Task UpdateToLatestReleaseAsyncImpl(ISnapUpdateManagerProgressSou var sw = new Stopwatch(); sw.Restart(); - var packageSource = await _snapPackageManager.GetPackageSourceAsync(_snapApp, _logger, ApplicationId); + var packageSource = await _snapPackageManager.GetPackageSourceAsync(_snapApp, _logger, ApplicationId, cancellationToken); if (packageSource == null) { _logger.Error("Unknown error resolving update feed."); diff --git a/src/Snapx/Program.CommandList.cs b/src/Snapx/Program.CommandList.cs index ca78968e..bdf04e61 100644 --- a/src/Snapx/Program.CommandList.cs +++ b/src/Snapx/Program.CommandList.cs @@ -69,7 +69,7 @@ static async Task CommandListAsync([NotNull] ListOptions options, [NotNull] continue; } - var packageSource = await packageManager.GetPackageSourceAsync(snapApp, logger); + var packageSource = await packageManager.GetPackageSourceAsync(snapApp, logger, cancellationToken: cancellationToken); snapAppsesPackageSources.Add((snapApp, snapApp.BuildNugetUpstreamId(), packageSource)); var table = tables.SingleOrDefault(x => x.snapApp.Id == snapApp.Id); diff --git a/src/Snapx/Program.CommandPack.cs b/src/Snapx/Program.CommandPack.cs index 3ca8ce45..93e65ed9 100644 --- a/src/Snapx/Program.CommandPack.cs +++ b/src/Snapx/Program.CommandPack.cs @@ -118,7 +118,7 @@ static async Task CommandPackAsync([NotNull] PackOptions packOptions, [NotN logger.Info('-'.Repeat(TerminalBufferWidth)); - var updateFeedPackageSource = await snapPackageManager.GetPackageSourceAsync(snapApp); + var updateFeedPackageSource = await snapPackageManager.GetPackageSourceAsync(snapApp, cancellationToken: cancellationToken); logger.Info("Downloading releases nupkg.");