mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
Add AOT analyzer, implement fixes, add json source generation
This commit is contained in:
36
src/Velopack.Packaging/SimpleJson.cs
Normal file
36
src/Velopack.Packaging/SimpleJson.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
namespace Velopack.Json;
|
||||
|
||||
public class SimpleJson
|
||||
{
|
||||
#if NET6_0_OR_GREATER
|
||||
private static readonly System.Text.Json.JsonSerializerOptions Options = new System.Text.Json.JsonSerializerOptions {
|
||||
AllowTrailingCommas = true,
|
||||
ReadCommentHandling = System.Text.Json.JsonCommentHandling.Skip,
|
||||
PropertyNameCaseInsensitive = true,
|
||||
WriteIndented = true,
|
||||
DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull,
|
||||
Converters = {
|
||||
new System.Text.Json.Serialization.JsonStringEnumConverter(),
|
||||
new SemanticVersionConverter(),
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
||||
public static T DeserializeObject<T>(string json)
|
||||
{
|
||||
#if NET6_0_OR_GREATER
|
||||
return System.Text.Json.JsonSerializer.Deserialize<T>(json, Options);
|
||||
#else
|
||||
return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(json, CompiledJson.Options);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static string SerializeObject<T>(T obj)
|
||||
{
|
||||
#if NET6_0_OR_GREATER
|
||||
return System.Text.Json.JsonSerializer.Serialize(obj, Options);
|
||||
#else
|
||||
return Newtonsoft.Json.JsonConvert.SerializeObject(obj, CompiledJson.Options);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System;
|
||||
using NuGet.Versioning;
|
||||
using Velopack.Sources;
|
||||
using System.Collections.Generic;
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
#if NET6_0_OR_GREATER
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
#else
|
||||
@@ -11,7 +13,7 @@ using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
#endif
|
||||
|
||||
#if !NET5_0_OR_GREATER
|
||||
#if !NET6_0_OR_GREATER
|
||||
namespace System.Text.Json.Serialization
|
||||
{
|
||||
// this is just here so our code can "use" System.Text.Json.Serialization
|
||||
@@ -22,26 +24,54 @@ namespace System.Text.Json.Serialization
|
||||
|
||||
namespace Velopack.Json
|
||||
{
|
||||
#if NET5_0_OR_GREATER
|
||||
internal static class SimpleJson
|
||||
#if NET6_0_OR_GREATER
|
||||
|
||||
[JsonSerializable(typeof(List<GithubRelease>))]
|
||||
[JsonSerializable(typeof(List<GitlabRelease>))]
|
||||
[JsonSerializable(typeof(VelopackAssetFeed))]
|
||||
#if NET8_0_OR_GREATER
|
||||
[JsonSourceGenerationOptions(UseStringEnumConverter = true)]
|
||||
#endif
|
||||
internal partial class CompiledJsonSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
public static readonly JsonSerializerOptions Options = new JsonSerializerOptions {
|
||||
}
|
||||
|
||||
internal static class CompiledJson
|
||||
{
|
||||
private static readonly JsonSerializerOptions Options = new JsonSerializerOptions {
|
||||
AllowTrailingCommas = true,
|
||||
ReadCommentHandling = JsonCommentHandling.Skip,
|
||||
PropertyNameCaseInsensitive = true,
|
||||
WriteIndented = true,
|
||||
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
|
||||
Converters = { new JsonStringEnumConverter(), new SemanticVersionConverter() },
|
||||
Converters = {
|
||||
#if !NET8_0_OR_GREATER
|
||||
new JsonStringEnumConverter(),
|
||||
#endif
|
||||
new SemanticVersionConverter(),
|
||||
},
|
||||
};
|
||||
|
||||
public static T? DeserializeObject<T>(string json)
|
||||
private static readonly CompiledJsonSourceGenerationContext Context = new CompiledJsonSourceGenerationContext(Options);
|
||||
|
||||
public static List<GithubRelease>? DeserializeGithubReleaseList(string json)
|
||||
{
|
||||
return JsonSerializer.Deserialize<T>(json, Options);
|
||||
return JsonSerializer.Deserialize(json, Context.ListGithubRelease);
|
||||
}
|
||||
|
||||
public static string SerializeObject<T>(T obj)
|
||||
public static List<GitlabRelease>? DeserializeGitlabReleaseList(string json)
|
||||
{
|
||||
return JsonSerializer.Serialize(obj, Options);
|
||||
return JsonSerializer.Deserialize(json, Context.ListGitlabRelease);
|
||||
}
|
||||
|
||||
public static VelopackAsset[]? DeserializeVelopackAssetArray(string json)
|
||||
{
|
||||
return JsonSerializer.Deserialize(json, Context.VelopackAssetArray);
|
||||
}
|
||||
|
||||
public static VelopackAssetFeed? DeserializeVelopackAssetFeed(string json)
|
||||
{
|
||||
return JsonSerializer.Deserialize(json, Context.VelopackAssetFeed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,22 +100,32 @@ namespace Velopack.Json
|
||||
}
|
||||
}
|
||||
|
||||
internal static class SimpleJson
|
||||
internal static class CompiledJson
|
||||
{
|
||||
private static readonly JsonSerializerSettings Options = new JsonSerializerSettings {
|
||||
public static readonly JsonSerializerSettings Options = new JsonSerializerSettings {
|
||||
Converters = { new StringEnumConverter(), new SemanticVersionConverter() },
|
||||
ContractResolver = new JsonNameContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
};
|
||||
|
||||
public static T? DeserializeObject<T>(string json)
|
||||
public static List<GithubRelease>? DeserializeGithubReleaseList(string json)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<T>(json, Options);
|
||||
return JsonConvert.DeserializeObject<List<GithubRelease>>(json, Options);
|
||||
}
|
||||
|
||||
public static string SerializeObject<T>(T obj)
|
||||
public static List<GitlabRelease>? DeserializeGitlabReleaseList(string json)
|
||||
{
|
||||
return JsonConvert.SerializeObject(obj, Formatting.Indented, Options);
|
||||
return JsonConvert.DeserializeObject<List<GitlabRelease>>(json, Options);
|
||||
}
|
||||
|
||||
public static VelopackAsset[]? DeserializeVelopackAssetArray(string json)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<VelopackAsset[]>(json, Options);
|
||||
}
|
||||
|
||||
public static VelopackAssetFeed? DeserializeVelopackAssetFeed(string json)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<VelopackAssetFeed>(json, Options);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -642,6 +642,15 @@ namespace Velopack
|
||||
if (!File.Exists(source)) throw new FileNotFoundException("File not found", source);
|
||||
if (overwrite) File.Delete(dest);
|
||||
File.Move(source, dest);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static TEnum[] GetEnumValues<TEnum>() where TEnum : struct, Enum
|
||||
{
|
||||
#if NET6_0_OR_GREATER
|
||||
return Enum.GetValues<TEnum>();
|
||||
#else
|
||||
return Enum.GetValues(typeof(TEnum)).Cast<TEnum>().ToArray();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace Velopack.Sources
|
||||
var baseUri = GetApiBaseUrl(RepoUri);
|
||||
var getReleasesUri = new Uri(baseUri, releasesPath);
|
||||
var response = await Downloader.DownloadString(getReleasesUri.ToString(), Authorization, "application/vnd.github.v3+json").ConfigureAwait(false);
|
||||
var releases = SimpleJson.DeserializeObject<List<GithubRelease>>(response);
|
||||
var releases = CompiledJson.DeserializeGithubReleaseList(response);
|
||||
if (releases == null) return new GithubRelease[0];
|
||||
return releases.OrderByDescending(d => d.PublishedAt).Where(x => includePrereleases || !x.Prerelease).ToArray();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
@@ -153,7 +152,7 @@ namespace Velopack.Sources
|
||||
var baseUri = new Uri("https://gitlab.com");
|
||||
var getReleasesUri = new Uri(baseUri, releasesPath);
|
||||
var response = await Downloader.DownloadString(getReleasesUri.ToString(), Authorization).ConfigureAwait(false);
|
||||
var releases = SimpleJson.DeserializeObject<List<GitlabRelease>>(response);
|
||||
var releases = CompiledJson.DeserializeGitlabReleaseList(response);
|
||||
if (releases == null) return new GitlabRelease[0];
|
||||
return releases.OrderByDescending(d => d.ReleasedAt).Where(x => includePrereleases || !x.UpcomingRelease).ToArray();
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Velopack.Sources
|
||||
public IFileDownloader Downloader { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<VelopackAssetFeed> GetReleaseFeed(ILogger logger, string channel, Guid? stagingId = null,
|
||||
public async Task<VelopackAssetFeed> GetReleaseFeed(ILogger logger, string channel, Guid? stagingId = null,
|
||||
VelopackAsset? latestLocalRelease = null)
|
||||
{
|
||||
Uri baseUri = new(BaseUri, $"v1.0/manifest/");
|
||||
@@ -58,7 +58,7 @@ namespace Velopack.Sources
|
||||
|
||||
var json = await Downloader.DownloadString(uriAndQuery.ToString()).ConfigureAwait(false);
|
||||
|
||||
var releaseAssets = SimpleJson.DeserializeObject<VelopackReleaseAsset[]>(json);
|
||||
var releaseAssets = CompiledJson.DeserializeVelopackAssetArray(json);
|
||||
return new VelopackAssetFeed() {
|
||||
Assets = releaseAssets
|
||||
};
|
||||
|
||||
@@ -5,12 +5,16 @@
|
||||
<TargetFrameworks>net462;net48;net6.0;net8.0</TargetFrameworks>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
||||
<CheckEolTargetFramework>false</CheckEolTargetFramework>
|
||||
<LangVersion>9</LangVersion>
|
||||
<VelopackPackageId>Velopack</VelopackPackageId>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
||||
<CheckEolTargetFramework>false</CheckEolTargetFramework>
|
||||
<IsAotCompatible Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net7.0'))">true</IsAotCompatible>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NuGet.Versioning" Version="6.9.1" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -26,14 +26,14 @@ namespace Velopack
|
||||
/// <summary>
|
||||
/// A list of assets available in this feed.
|
||||
/// </summary>
|
||||
public VelopackAsset[] Assets { get; init; } = Array.Empty<VelopackAsset>();
|
||||
public VelopackAsset[] Assets { get; set; } = Array.Empty<VelopackAsset>();
|
||||
|
||||
/// <summary>
|
||||
/// Parse a json string into a <see cref="VelopackAssetFeed"/>.
|
||||
/// </summary>
|
||||
public static VelopackAssetFeed FromJson(string json)
|
||||
{
|
||||
return SimpleJson.DeserializeObject<VelopackAssetFeed>(json) ?? new VelopackAssetFeed();
|
||||
return CompiledJson.DeserializeVelopackAssetFeed(json) ?? new VelopackAssetFeed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,28 +43,28 @@ namespace Velopack
|
||||
public record VelopackAsset
|
||||
{
|
||||
/// <summary> The name or Id of the package containing this release. </summary>
|
||||
public string PackageId { get; init; }
|
||||
public string PackageId { get; set; }
|
||||
|
||||
/// <summary> The version of this release. </summary>
|
||||
public SemanticVersion Version { get; init; }
|
||||
public SemanticVersion Version { get; set; }
|
||||
|
||||
/// <summary> The type of asset (eg. full or delta). </summary>
|
||||
public VelopackAssetType Type { get; init; }
|
||||
public VelopackAssetType Type { get; set; }
|
||||
|
||||
/// <summary> The filename of the update package containing this release. </summary>
|
||||
public string FileName { get; init; }
|
||||
public string FileName { get; set; }
|
||||
|
||||
/// <summary> The SHA1 checksum of the update package containing this release. </summary>
|
||||
public string SHA1 { get; init; }
|
||||
public string SHA1 { get; set; }
|
||||
|
||||
/// <summary> The size in bytes of the update package containing this release. </summary>
|
||||
public long Size { get; init; }
|
||||
public long Size { get; set; }
|
||||
|
||||
/// <summary> The release notes in markdown format, as passed to Velopack when packaging the release. </summary>
|
||||
public string NotesMarkdown { get; init; }
|
||||
public string NotesMarkdown { get; set; }
|
||||
|
||||
/// <summary> The release notes in HTML format, transformed from Markdown when packaging the release. </summary>
|
||||
public string NotesHTML { get; init; }
|
||||
public string NotesHTML { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Convert a <see cref="ZipPackage"/> to a <see cref="VelopackAsset"/>.
|
||||
|
||||
@@ -317,8 +317,10 @@ namespace Velopack.Windows
|
||||
var typestr = match.Groups["type"].Value; // default is WindowsDesktop
|
||||
|
||||
var archValid = Enum.TryParse<RuntimeCpu>(String.IsNullOrWhiteSpace(archstr) ? "x64" : archstr, true, out var cpu);
|
||||
if (!archValid)
|
||||
throw new ArgumentException($"Invalid machine architecture '{archstr}'. Valid values: {String.Join(", ", Enum.GetValues(typeof(RuntimeCpu)))}");
|
||||
if (!archValid) {
|
||||
throw new ArgumentException($"Invalid machine architecture '{archstr}'. " +
|
||||
$"Valid values: {String.Join(", ", Utility.GetEnumValues<RuntimeCpu>())}");
|
||||
}
|
||||
|
||||
var type = DotnetRuntimeType.WindowsDesktop;
|
||||
if (!String.IsNullOrEmpty(typestr)) {
|
||||
|
||||
@@ -1066,7 +1066,7 @@ namespace Velopack.Windows
|
||||
displayName = "";
|
||||
|
||||
SHFILEINFO shfi = new SHFILEINFO();
|
||||
uint shfiSize = (uint) Marshal.SizeOf(shfi.GetType());
|
||||
uint shfiSize = (uint) Marshal.SizeOf<SHFILEINFO>();
|
||||
|
||||
IntPtr ret = SHGetFileInfo(
|
||||
fileName, 0, ref shfi, shfiSize, (uint) (flags));
|
||||
|
||||
@@ -280,7 +280,7 @@ namespace Velopack.Windows
|
||||
|
||||
private ShortcutLocation[] GetLocations(ShortcutLocation flag)
|
||||
{
|
||||
var locations = (ShortcutLocation[]) Enum.GetValues(typeof(ShortcutLocation));
|
||||
var locations = Utility.GetEnumValues<ShortcutLocation>();
|
||||
return locations
|
||||
.Where(x => x != ShortcutLocation.None)
|
||||
.Where(x => flag.HasFlag(x))
|
||||
|
||||
@@ -157,6 +157,12 @@
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.NET.ILLink.Tasks": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.1, )",
|
||||
"resolved": "8.0.1",
|
||||
"contentHash": "ADdJXuKNjwZDfBmybMnpvwd5CK3gp92WkWqqeQhW4W+q4MO3Qaa9QyW2DcFLAvCDMcCWxT5hRXqGdv13oon7nA=="
|
||||
},
|
||||
"Microsoft.SourceLink.GitHub": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.0, )",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
#pragma warning disable CS0612 // Type or member is obsolete
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using Velopack.Json;
|
||||
using Velopack.Sources;
|
||||
|
||||
namespace Velopack.Tests.TestHelpers;
|
||||
@@ -63,7 +63,7 @@ internal class FakeFixtureRepository : Sources.IFileDownloader
|
||||
}
|
||||
|
||||
if (url.Contains($"/{_releasesNameNew}?")) {
|
||||
var json = JsonSerializer.Serialize(_releasesNew, SimpleJsonTests.Options);
|
||||
var json = SimpleJson.SerializeObject(_releasesNew);
|
||||
return Task.FromResult(Encoding.UTF8.GetBytes(json));
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ internal class FakeFixtureRepository : Sources.IFileDownloader
|
||||
}
|
||||
|
||||
if (url.Contains($"/{_releasesNameNew}?")) {
|
||||
var json = JsonSerializer.Serialize(_releasesNew, SimpleJsonTests.Options);
|
||||
var json = SimpleJson.SerializeObject(_releasesNew);
|
||||
return Task.FromResult(json);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using NuGet.Versioning;
|
||||
using Velopack.Json;
|
||||
using Velopack.Locators;
|
||||
using Velopack.Sources;
|
||||
using Velopack.Tests.TestHelpers;
|
||||
@@ -38,7 +38,7 @@ public class UpdateManagerTests
|
||||
},
|
||||
}
|
||||
};
|
||||
var json = JsonSerializer.Serialize(feed, SimpleJsonTests.Options);
|
||||
var json = SimpleJson.SerializeObject(feed);
|
||||
return new FakeDownloader() { MockedResponseBytes = Encoding.UTF8.GetBytes(json) };
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ public class UpdateManagerTests
|
||||
},
|
||||
}
|
||||
};
|
||||
var json = JsonSerializer.Serialize(feed, SimpleJsonTests.Options);
|
||||
var json = SimpleJson.SerializeObject(feed);
|
||||
return new FakeDownloader() { MockedResponseBytes = Encoding.UTF8.GetBytes(json) };
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\..\src\Velopack.Packaging\SimpleJson.cs" Link="SimpleJson.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.IO.Packaging" Version="8.0.0" />
|
||||
<PackageReference Include="System.Text.Json" Version="8.0.3" />
|
||||
|
||||
Reference in New Issue
Block a user