-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Enable support for app self upgrade
- Loading branch information
Showing
12 changed files
with
554 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
48 changes: 48 additions & 0 deletions
48
src/Ellosoft.AwsCredentialsManager/Infrastructure/FileDownloadService.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Copyright (c) 2023 Ellosoft Limited. All rights reserved. | ||
|
||
namespace Ellosoft.AwsCredentialsManager.Infrastructure; | ||
|
||
public interface IFileDownloadService | ||
{ | ||
Task DownloadFileAsync(HttpClient httpClient, string downloadUrl, Stream destinationStream); | ||
} | ||
|
||
public class FileDownloadService : IFileDownloadService | ||
{ | ||
public Task DownloadFileAsync(HttpClient httpClient, string downloadUrl, Stream destinationStream) | ||
{ | ||
return AnsiConsole.Progress() | ||
.HideCompleted(true) | ||
.AutoClear(true) | ||
.StartAsync(async ctx => | ||
{ | ||
var startingTask = ctx.AddTask("Starting download").IsIndeterminate(); | ||
|
||
using var httpResponse = await httpClient.GetAsync(downloadUrl, HttpCompletionOption.ResponseHeadersRead); | ||
|
||
httpResponse.EnsureSuccessStatusCode(); | ||
|
||
startingTask.StopTask(); | ||
|
||
var totalBytes = httpResponse.Content.Headers.ContentLength ?? throw new InvalidOperationException("Invalid download size"); | ||
|
||
var downloadTask = ctx.AddTask("Downloading", new ProgressTaskSettings { MaxValue = Convert.ToDouble(totalBytes) }); | ||
|
||
await using var downloadStream = await httpResponse.Content.ReadAsStreamAsync(); | ||
|
||
var buffer = new byte[16384]; | ||
int bytesRead; | ||
|
||
while ((bytesRead = await downloadStream.ReadAsync(buffer)) > 0) | ||
{ | ||
await destinationStream.WriteAsync(buffer, 0, bytesRead); | ||
downloadTask.Increment(bytesRead); | ||
} | ||
|
||
await destinationStream.FlushAsync(); | ||
destinationStream.Position = 0; | ||
|
||
downloadTask.StopTask(); | ||
}); | ||
} | ||
} |
142 changes: 142 additions & 0 deletions
142
src/Ellosoft.AwsCredentialsManager/Infrastructure/SemanticVersion.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
// Copyright (c) 2023 Ellosoft Limited. All rights reserved. | ||
|
||
using System.Diagnostics.CodeAnalysis; | ||
|
||
namespace Ellosoft.AwsCredentialsManager.Infrastructure; | ||
|
||
public record SemanticVersion : IComparable<SemanticVersion> | ||
{ | ||
private Version MainVersion { get; } | ||
|
||
private string? PreReleaseLabel { get; } | ||
|
||
private int PreReleaseNumber { get; } | ||
|
||
private string? BuildData { get; } | ||
|
||
public bool IsPreRelease => PreReleaseLabel is not null; | ||
|
||
public SemanticVersion(string versionValue) | ||
{ | ||
if (!TryParse(versionValue, out var mainVersion, out var preReleaseLabel, out var preReleaseNumber, out var buildData)) | ||
throw new ArgumentException($"'{versionValue}' is not a valid SemanticVersion"); | ||
|
||
MainVersion = mainVersion; | ||
PreReleaseLabel = preReleaseLabel; | ||
PreReleaseNumber = preReleaseNumber; | ||
BuildData = buildData; | ||
} | ||
|
||
private SemanticVersion(Version mainVersion, string? preReleaseLabel, int preReleaseNumber, string? buildData) | ||
{ | ||
MainVersion = mainVersion; | ||
PreReleaseLabel = preReleaseLabel; | ||
PreReleaseNumber = preReleaseNumber; | ||
BuildData = buildData; | ||
} | ||
|
||
public int CompareTo(SemanticVersion? other) | ||
{ | ||
if (other is null) | ||
return 1; | ||
|
||
var mainVersionComparison = MainVersion.CompareTo(other.MainVersion); | ||
|
||
if (mainVersionComparison != 0) | ||
return mainVersionComparison; | ||
|
||
var isPreRelease = !string.IsNullOrEmpty(PreReleaseLabel); | ||
var otherIsPreRelease = !string.IsNullOrEmpty(other.PreReleaseLabel); | ||
|
||
if (isPreRelease && !otherIsPreRelease) | ||
return -1; | ||
|
||
if (!isPreRelease && otherIsPreRelease) | ||
return 1; | ||
|
||
var preReleaseLabelComparison = StringComparer.OrdinalIgnoreCase.Compare(PreReleaseLabel, other.PreReleaseLabel); | ||
|
||
if (preReleaseLabelComparison != 0) | ||
return preReleaseLabelComparison; | ||
|
||
return PreReleaseNumber.CompareTo(other.PreReleaseNumber); | ||
} | ||
|
||
public override string ToString() | ||
{ | ||
var result = MainVersion.ToString(); | ||
|
||
if (PreReleaseLabel is not null) | ||
{ | ||
result += $"-{PreReleaseLabel}"; | ||
|
||
if (PreReleaseNumber != 0) | ||
result += $".{PreReleaseNumber}"; | ||
} | ||
|
||
if (BuildData is not null) | ||
result += $"+{BuildData}"; | ||
|
||
return result; | ||
} | ||
|
||
public static bool operator <(SemanticVersion left, SemanticVersion right) => left.CompareTo(right) < 0; | ||
|
||
public static bool operator >(SemanticVersion left, SemanticVersion right) => left.CompareTo(right) > 0; | ||
|
||
public static bool operator <=(SemanticVersion left, SemanticVersion right) => left.CompareTo(right) <= 0; | ||
|
||
public static bool operator >=(SemanticVersion left, SemanticVersion right) => left.CompareTo(right) >= 0; | ||
|
||
public static bool TryParse(string? versionValue, [NotNullWhen(true)] out SemanticVersion? version) | ||
{ | ||
version = null; | ||
|
||
if (!TryParse(versionValue, out var mainVersion, out var preReleaseLabel, out var preReleaseNumber, out var buildData)) | ||
return false; | ||
|
||
version = new SemanticVersion(mainVersion, preReleaseLabel, preReleaseNumber, buildData); | ||
|
||
return true; | ||
} | ||
|
||
private static bool TryParse(string? versionValue, | ||
[NotNullWhen(true)] out Version? mainVersion, out string? preReleaseLabel, out int preReleaseNumber, out string? buildData) | ||
{ | ||
mainVersion = null; | ||
preReleaseLabel = null; | ||
preReleaseNumber = 0; | ||
buildData = null; | ||
|
||
if (versionValue is null) | ||
return false; | ||
|
||
var buildDataIndex = versionValue.IndexOf('+'); | ||
|
||
if (buildDataIndex > 0) | ||
{ | ||
buildData = versionValue[(buildDataIndex + 1)..]; | ||
versionValue = versionValue[..buildDataIndex]; | ||
} | ||
|
||
var preReleaseIndex = versionValue.IndexOf('-'); | ||
|
||
if (preReleaseIndex > 0) | ||
{ | ||
preReleaseLabel = versionValue[(preReleaseIndex + 1)..]; | ||
versionValue = versionValue[..preReleaseIndex]; | ||
|
||
var preReleaseNumberIndex = preReleaseLabel.IndexOf('.'); | ||
|
||
if (preReleaseNumberIndex > 0) | ||
{ | ||
if (!int.TryParse(preReleaseLabel[(preReleaseNumberIndex + 1)..], out preReleaseNumber)) | ||
return false; | ||
|
||
preReleaseLabel = preReleaseLabel[..preReleaseNumberIndex]; | ||
} | ||
} | ||
|
||
return Version.TryParse(versionValue, out mainVersion); | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
src/Ellosoft.AwsCredentialsManager/Infrastructure/Upgrade/Models/GitHubRelease.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// Copyright (c) 2023 Ellosoft Limited. All rights reserved. | ||
|
||
using System.Text.Json.Serialization; | ||
|
||
namespace Ellosoft.AwsCredentialsManager.Infrastructure.Upgrade.Models; | ||
|
||
public class GitHubRelease | ||
{ | ||
[JsonPropertyName("name")] | ||
public required string Name { get; set; } | ||
|
||
[JsonPropertyName("html_url")] | ||
public required string Url { get; set; } | ||
|
||
[JsonPropertyName("prerelease")] | ||
public bool PreRelease { get; set; } | ||
|
||
[JsonPropertyName("assets")] | ||
public ICollection<ReleaseAsset> Assets { get; set; } = Array.Empty<ReleaseAsset>(); | ||
|
||
public class ReleaseAsset | ||
{ | ||
[JsonPropertyName("browser_download_url")] | ||
public required string DownloadUrl { get; set; } | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
...soft.AwsCredentialsManager/Infrastructure/Upgrade/Models/GithubSourceGenerationContext.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
// Copyright (c) 2023 Ellosoft Limited. All rights reserved. | ||
|
||
using System.Text.Json.Serialization; | ||
|
||
namespace Ellosoft.AwsCredentialsManager.Infrastructure.Upgrade.Models; | ||
|
||
[JsonSourceGenerationOptions] | ||
[JsonSerializable(typeof(GitHubRelease))] | ||
[JsonSerializable(typeof(List<GitHubRelease>))] | ||
internal partial class GithubSourceGenerationContext : JsonSerializerContext | ||
{ | ||
} |
Oops, something went wrong.