mirror of
https://github.com/ckaczor/ChrisKaczor.ApplicationUpdate.git
synced 2026-01-13 17:22:16 -05:00
Add basic support for prerelease versions
This commit is contained in:
2
ApplicationUpdate.sln.DotSettings
Normal file
2
ApplicationUpdate.sln.DotSettings
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Kaczor/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||||
@@ -1,30 +1,84 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Converters;
|
using Newtonsoft.Json.Converters;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace ChrisKaczor.ApplicationUpdate
|
namespace ChrisKaczor.ApplicationUpdate
|
||||||
{
|
{
|
||||||
public partial class GitHubRelease
|
public partial class GitHubRelease
|
||||||
{
|
{
|
||||||
[JsonProperty("tag_name")]
|
private const string LatestSegment = "/latest";
|
||||||
public string? TagName { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("assets")]
|
private static readonly HttpClient HttpClient = new()
|
||||||
public List<Asset>? Assets { get; set; }
|
{
|
||||||
|
DefaultRequestHeaders =
|
||||||
|
{ UserAgent = { ProductInfoHeaderValue.Parse(UpdateCheck.ApplicationName.Replace(" ", "")) } }
|
||||||
|
};
|
||||||
|
|
||||||
|
private static GitHubRelease? FromJson(string json) =>
|
||||||
|
JsonConvert.DeserializeObject<GitHubRelease>(json, Converter.Settings);
|
||||||
|
|
||||||
|
private static List<GitHubRelease>? FromJsonArray(string json) =>
|
||||||
|
JsonConvert.DeserializeObject<List<GitHubRelease>>(json, Converter.Settings);
|
||||||
|
|
||||||
|
[JsonProperty("tag_name")] public string? TagName { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("assets")] public List<Asset>? Assets { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("prerelease")] public bool Prerelease { get; set; }
|
||||||
|
|
||||||
|
public static async Task<VersionInfo?> GetLatestAsync(string baseUrl)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var url = baseUrl.EndsWith(LatestSegment) ? baseUrl : baseUrl + LatestSegment;
|
||||||
|
|
||||||
|
var json = await HttpClient.GetStringAsync(url);
|
||||||
|
|
||||||
|
var release = FromJson(json);
|
||||||
|
|
||||||
|
var versionInfo = VersionInfo.CreateFromGitHubRelease(release);
|
||||||
|
|
||||||
|
return versionInfo;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<VersionInfo?> GetLatestPrereleaseAsync(string baseUrl)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var url = baseUrl.EndsWith(LatestSegment) ? baseUrl[..^LatestSegment.Length] : baseUrl;
|
||||||
|
|
||||||
|
var json = await HttpClient.GetStringAsync(url);
|
||||||
|
|
||||||
|
var releases = FromJsonArray(json);
|
||||||
|
|
||||||
|
var release = releases?.FirstOrDefault();
|
||||||
|
|
||||||
|
if (release == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var versionInfo = VersionInfo.CreateFromGitHubRelease(release);
|
||||||
|
|
||||||
|
return versionInfo;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Asset
|
public class Asset
|
||||||
{
|
{
|
||||||
[JsonProperty("created_at")]
|
[JsonProperty("created_at")] public DateTimeOffset? CreatedAt { get; set; }
|
||||||
public DateTimeOffset? CreatedAt { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("browser_download_url")]
|
[JsonProperty("browser_download_url")] public string? BrowserDownloadUrl { get; set; }
|
||||||
public string? BrowserDownloadUrl { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public partial class GitHubRelease
|
|
||||||
{
|
|
||||||
public static GitHubRelease? FromJson(string json) => JsonConvert.DeserializeObject<GitHubRelease>(json, Converter.Settings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class Converter
|
internal class Converter
|
||||||
|
|||||||
@@ -45,9 +45,9 @@ public static class UpdateCheck
|
|||||||
ApplicationUpdateMessage = applicationUpdateMessageDelegate;
|
ApplicationUpdateMessage = applicationUpdateMessageDelegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<bool> CheckForUpdate()
|
public static async Task<bool> CheckForUpdate(bool includePrerelease)
|
||||||
{
|
{
|
||||||
RemoteVersion = await VersionInfo.Load(UpdateServerType, UpdateServer, UpdateFile);
|
RemoteVersion = await VersionInfo.Load(UpdateServerType, UpdateServer, UpdateFile, includePrerelease);
|
||||||
|
|
||||||
if (RemoteVersion == null)
|
if (RemoteVersion == null)
|
||||||
return false;
|
return false;
|
||||||
@@ -98,9 +98,9 @@ public static class UpdateCheck
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async void DisplayUpdateInformation(bool showIfCurrent)
|
public static async Task DisplayUpdateInformation(bool showIfCurrent, bool includePrerelease)
|
||||||
{
|
{
|
||||||
await CheckForUpdate();
|
await CheckForUpdate(includePrerelease);
|
||||||
|
|
||||||
// Check for an update
|
// Check for an update
|
||||||
if (UpdateAvailable)
|
if (UpdateAvailable)
|
||||||
|
|||||||
@@ -1,28 +1,35 @@
|
|||||||
using System.Xml.Linq;
|
using System.Net.Http.Headers;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
namespace ChrisKaczor.ApplicationUpdate;
|
namespace ChrisKaczor.ApplicationUpdate;
|
||||||
|
|
||||||
public class VersionInfo
|
public class VersionInfo
|
||||||
{
|
{
|
||||||
|
private static readonly HttpClient HttpClient = new() { DefaultRequestHeaders = { UserAgent = { ProductInfoHeaderValue.Parse(UpdateCheck.ApplicationName) } } };
|
||||||
|
|
||||||
public Version? Version { get; set; }
|
public Version? Version { get; set; }
|
||||||
public string? InstallFile { get; set; }
|
public string? InstallFile { get; set; }
|
||||||
public DateTimeOffset? InstallCreated { get; set; }
|
public DateTimeOffset? InstallCreated { get; set; }
|
||||||
|
public bool? Prerelease { get; set; }
|
||||||
|
|
||||||
public static async Task<VersionInfo?> Load(ServerType updateServerType, string server, string file)
|
public static async Task<VersionInfo?> Load(ServerType updateServerType, string url, string file, bool includePrerelease)
|
||||||
{
|
{
|
||||||
return updateServerType switch
|
return updateServerType switch
|
||||||
{
|
{
|
||||||
ServerType.Generic => LoadFile(server, file),
|
ServerType.Generic => LoadFile(url, file, includePrerelease),
|
||||||
ServerType.GitHub => await LoadGitHub(server),
|
ServerType.GitHub => await LoadGitHub(url, includePrerelease),
|
||||||
_ => null
|
_ => null
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static VersionInfo? LoadFile(string server, string file)
|
private static VersionInfo? LoadFile(string url, string file, bool includePrerelease)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var document = XDocument.Load(server + file);
|
if (includePrerelease)
|
||||||
|
throw new NotSupportedException("Prerelease not currently supported for generic server type");
|
||||||
|
|
||||||
|
var document = XDocument.Load(url + file);
|
||||||
|
|
||||||
var versionInformationElement = document.Element("versionInformation");
|
var versionInformationElement = document.Element("versionInformation");
|
||||||
|
|
||||||
@@ -51,18 +58,15 @@ public class VersionInfo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<VersionInfo?> LoadGitHub(string server)
|
private static async Task<VersionInfo?> LoadGitHub(string baseUrl, bool includePrerelease)
|
||||||
{
|
{
|
||||||
try
|
var versionInfo = includePrerelease ? await GitHubRelease.GetLatestPrereleaseAsync(baseUrl) : await GitHubRelease.GetLatestAsync(baseUrl);
|
||||||
|
|
||||||
|
return versionInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static VersionInfo? CreateFromGitHubRelease(GitHubRelease? release)
|
||||||
{
|
{
|
||||||
var httpClient = new HttpClient();
|
|
||||||
|
|
||||||
httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(UpdateCheck.ApplicationName);
|
|
||||||
|
|
||||||
var json = await httpClient.GetStringAsync(server);
|
|
||||||
|
|
||||||
var release = GitHubRelease.FromJson(json);
|
|
||||||
|
|
||||||
if (release?.TagName == null || release.Assets == null || release.Assets.Count == 0)
|
if (release?.TagName == null || release.Assets == null || release.Assets.Count == 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@@ -70,14 +74,10 @@ public class VersionInfo
|
|||||||
{
|
{
|
||||||
Version = Version.Parse(release.TagName),
|
Version = Version.Parse(release.TagName),
|
||||||
InstallFile = release.Assets[0].BrowserDownloadUrl,
|
InstallFile = release.Assets[0].BrowserDownloadUrl,
|
||||||
InstallCreated = release.Assets[0].CreatedAt?.UtcDateTime
|
InstallCreated = release.Assets[0].CreatedAt?.UtcDateTime,
|
||||||
|
Prerelease = release.Prerelease
|
||||||
};
|
};
|
||||||
|
|
||||||
return versionInfo;
|
return versionInfo;
|
||||||
}
|
}
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user