From 24538b7b29c39a96f225f82acf23c32e5859cfea Mon Sep 17 00:00:00 2001 From: harry-xi Date: Sat, 8 Mar 2025 20:13:13 +0800 Subject: [PATCH 1/2] refactor: make lip core support aot --- Golang.Org.X.Mod/Golang.Org.X.Mod.csproj | 1 + Lip.Context/Lip.Context.csproj | 1 + Lip.Core/Lip.Core.csproj | 2 + Lip.Core/PackageLock.cs | 21 ++++++++-- Lip.Core/PackageManifest.cs | 35 +++++++++++----- Lip.Core/RuntimeConfig.cs | 51 ++++++++++++++++++++++-- Lip.Migration/Lip.Migration.csproj | 2 + Lip.Migration/Manifest.cs | 11 ++++- Lip.Migration/ManifestV1.cs | 5 +++ Lip.Migration/MigratorFromV1.cs | 4 +- Lip.Migration/MigratorFromV2.cs | 9 ++++- 11 files changed, 119 insertions(+), 23 deletions(-) diff --git a/Golang.Org.X.Mod/Golang.Org.X.Mod.csproj b/Golang.Org.X.Mod/Golang.Org.X.Mod.csproj index 125f4c93..8523c08f 100644 --- a/Golang.Org.X.Mod/Golang.Org.X.Mod.csproj +++ b/Golang.Org.X.Mod/Golang.Org.X.Mod.csproj @@ -4,6 +4,7 @@ net9.0 enable enable + true diff --git a/Lip.Context/Lip.Context.csproj b/Lip.Context/Lip.Context.csproj index 370d2b6c..65718728 100644 --- a/Lip.Context/Lip.Context.csproj +++ b/Lip.Context/Lip.Context.csproj @@ -4,6 +4,7 @@ net9.0 enable enable + true diff --git a/Lip.Core/Lip.Core.csproj b/Lip.Core/Lip.Core.csproj index 5cbc56d7..b6f2ea1f 100644 --- a/Lip.Core/Lip.Core.csproj +++ b/Lip.Core/Lip.Core.csproj @@ -4,6 +4,8 @@ net9.0 enable enable + true + false diff --git a/Lip.Core/PackageLock.cs b/Lip.Core/PackageLock.cs index 1c35bbf1..9cd44c97 100644 --- a/Lip.Core/PackageLock.cs +++ b/Lip.Core/PackageLock.cs @@ -129,7 +129,7 @@ public async Task ToStream(Stream stream) } [ExcludeFromCodeCoverage] -file record RawPackageLock +internal record RawPackageLock { public record Package { @@ -166,14 +166,27 @@ public record Package public static async Task FromStream(Stream stream) { - return await JsonSerializer.DeserializeAsync( + return await JsonSerializer.DeserializeAsync( stream, - _jsonSerializerOptions) + RawPackageLockJsonContext.Default.RawPackageLock) ?? throw new SchemaViolationException("", "JSON bytes deserialized to null."); } public async Task ToStream(Stream stream) { - await JsonSerializer.SerializeAsync(stream, this, _jsonSerializerOptions); + await JsonSerializer.SerializeAsync(stream, this, RawPackageLockJsonContext.Default.RawPackageLock); } } + +[JsonSourceGenerationOptions( + AllowTrailingCommas = true, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + IndentSize = 4, + ReadCommentHandling = JsonCommentHandling.Skip, + WriteIndented = true, + GenerationMode = JsonSourceGenerationMode.Metadata +)] +[JsonSerializable(typeof(RawPackageLock))] +internal partial class RawPackageLockJsonContext : JsonSerializerContext +{ +} diff --git a/Lip.Core/PackageManifest.cs b/Lip.Core/PackageManifest.cs index c4c7d3c5..7d6c8f66 100644 --- a/Lip.Core/PackageManifest.cs +++ b/Lip.Core/PackageManifest.cs @@ -294,7 +294,7 @@ public static PackageManifest FromJsonElement(JsonElement jsonElement) kvp => (kvp.Value.ValueKind == JsonValueKind.Array && kvp.Value.EnumerateArray() .All(elem => elem.ValueKind == JsonValueKind.String)) - ? kvp.Value.Deserialize>()! + ? kvp.Value.Deserialize(RawPackageManifestJsonContext.Default.ListString)! : throw new SchemaViolationException( $"variants[].assets[].scripts.'{kvp.Key}'", $"Invalid script list" @@ -418,7 +418,7 @@ public JsonElement ToJsonElement() PostUninstall = variant.Scripts.PostUninstall, AdditionalProperties = variant.Scripts.AdditionalScripts.ToDictionary( kvp => kvp.Key, - kvp => JsonSerializer.SerializeToElement(kvp.Value, _jsonSerializerOptions) + kvp => JsonSerializer.SerializeToElement(kvp.Value, RawPackageManifestJsonContext.Default.ListString) ) } }) @@ -437,11 +437,11 @@ public async Task ToStream(Stream stream) } [ExcludeFromCodeCoverage] -file record RawPackageManifest +internal record RawPackageManifest { public record Asset { - [JsonConverter(typeof(JsonStringEnumConverter))] + [JsonConverter(typeof(JsonStringEnumConverter))] public enum TypeEnum { [JsonStringEnumMemberName("self")] @@ -483,7 +483,7 @@ public record InfoType public record Placement { - [JsonConverter(typeof(JsonStringEnumConverter))] + [JsonConverter(typeof(JsonStringEnumConverter))] public enum TypeEnum { [JsonStringEnumMemberName("file")] @@ -529,7 +529,7 @@ public record ScriptsType public List? PostUninstall { get; init; } [JsonExtensionData] - public Dictionary? AdditionalProperties { get; init; } + public Dictionary? AdditionalProperties { get; set; } } public record Variant @@ -585,20 +585,20 @@ public record Variant public static RawPackageManifest FromJsonElement(JsonElement jsonElement) { - return JsonSerializer.Deserialize( + return JsonSerializer.Deserialize( jsonElement, - _jsonSerializerOptions) + RawPackageManifestJsonContext.Default.RawPackageManifest) ?? throw new SchemaViolationException("", "JSON bytes deserialized to null."); } public JsonElement ToJsonElement() { - return JsonSerializer.SerializeToElement(this, _jsonSerializerOptions); + return JsonSerializer.SerializeToElement(this, RawPackageManifestJsonContext.Default.RawPackageManifest); } public RawPackageManifest WithTemplateRendered() { - string jsonText = JsonSerializer.Serialize(this); + string jsonText = JsonSerializer.Serialize(this, RawPackageManifestJsonContext.Default.RawPackageManifest); Template template = Template.Parse(jsonText); @@ -611,3 +611,18 @@ public RawPackageManifest WithTemplateRendered() return FromJsonElement(jsonElementRendered); } } + +[JsonSourceGenerationOptions( + AllowTrailingCommas = true, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + IndentSize = 4, + ReadCommentHandling = JsonCommentHandling.Skip, + WriteIndented = true, + GenerationMode = JsonSourceGenerationMode.Metadata +)] +[JsonSerializable(typeof(RawPackageManifest))] +[JsonSerializable(typeof(RawPackageManifest.Asset.TypeEnum), TypeInfoPropertyName = "RawPackageManifestAssetTypeEnumTypeInfo")] +[JsonSerializable(typeof(RawPackageManifest.Placement.TypeEnum), TypeInfoPropertyName = "RawPackageManifestPlacementTypeEnumTypeInfo")] +internal partial class RawPackageManifestJsonContext : JsonSerializerContext +{ +} diff --git a/Lip.Core/RuntimeConfig.cs b/Lip.Core/RuntimeConfig.cs index 084a9d6f..fdadf368 100644 --- a/Lip.Core/RuntimeConfig.cs +++ b/Lip.Core/RuntimeConfig.cs @@ -45,10 +45,17 @@ public static RuntimeConfig FromJsonBytes(byte[] bytes) { try { - return JsonSerializer.Deserialize( + var raw = JsonSerializer.Deserialize( bytes, - s_jsonSerializerOptions + RawRuntimeConfigJsonContext.Default.RawRuntimeConfig ) ?? throw new JsonException("JSON bytes deserialized to null."); + return new RuntimeConfig + { + Cache = raw.Cache ?? Path.Join( + Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "lip", "cache"), + GitHubProxiesText = raw.GitHubProxies ?? "", + GoModuleProxiesText = raw.GoModuleProxies ?? "https://proxy.golang.org" + }; } catch (Exception ex) when (ex is JsonException) { @@ -58,6 +65,44 @@ public static RuntimeConfig FromJsonBytes(byte[] bytes) public byte[] ToJsonBytes() { - return JsonSerializer.SerializeToUtf8Bytes(this, s_jsonSerializerOptions); + return JsonSerializer.SerializeToUtf8Bytes(this, RuntimeConfigJsonContext.Default.RuntimeConfig); } } + +internal record RawRuntimeConfig +{ + [JsonPropertyName("cache")] + public string? Cache { get; init; } + + [JsonPropertyName("github_proxies")] + public string? GitHubProxies { get; init; } + + [JsonPropertyName("go_module_proxies")] + public string? GoModuleProxies { get; init; } +} + +[JsonSourceGenerationOptions( + AllowTrailingCommas = true, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + IndentSize = 4, + ReadCommentHandling = JsonCommentHandling.Skip, + WriteIndented = true, + GenerationMode = JsonSourceGenerationMode.Metadata +)] +[JsonSerializable(typeof(RawRuntimeConfig))] +internal partial class RawRuntimeConfigJsonContext : JsonSerializerContext +{ +} + +[JsonSourceGenerationOptions( + AllowTrailingCommas = true, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + IndentSize = 4, + ReadCommentHandling = JsonCommentHandling.Skip, + WriteIndented = true, + GenerationMode = JsonSourceGenerationMode.Metadata +)] +[JsonSerializable(typeof(RuntimeConfig))] +internal partial class RuntimeConfigJsonContext : JsonSerializerContext +{ +} diff --git a/Lip.Migration/Lip.Migration.csproj b/Lip.Migration/Lip.Migration.csproj index 0b8630ee..1c69ee09 100644 --- a/Lip.Migration/Lip.Migration.csproj +++ b/Lip.Migration/Lip.Migration.csproj @@ -4,6 +4,8 @@ net9.0 enable enable + true + false diff --git a/Lip.Migration/Manifest.cs b/Lip.Migration/Manifest.cs index eeff0175..7a905480 100644 --- a/Lip.Migration/Manifest.cs +++ b/Lip.Migration/Manifest.cs @@ -36,7 +36,7 @@ public record Asset [JsonPropertyName("placements")] public List? Placements { get; set; } - [JsonConverter(typeof(JsonStringEnumConverter))] + [JsonConverter(typeof(JsonStringEnumConverter))] public enum TypeEnum { [JsonStringEnumMemberName("self")] @@ -78,7 +78,7 @@ public record Placement [JsonPropertyName("dest")] public required string Dest { get; set; } - [JsonConverter(typeof(JsonStringEnumConverter))] + [JsonConverter(typeof(JsonStringEnumConverter))] public enum TypeEnum { [JsonStringEnumMemberName("file")] @@ -142,3 +142,10 @@ public record Variant public ScriptsType? Scripts { get; set; } } } + +[JsonSerializable(typeof(Manifest))] +[JsonSerializable(typeof(Manifest.Asset.TypeEnum), TypeInfoPropertyName = "AssetTypeEnumTypeInfo")] +[JsonSerializable(typeof(Manifest.Placement.TypeEnum), TypeInfoPropertyName = "PlacementTypeEnumTypeInfo")] +public partial class ManifestJsonContext : JsonSerializerContext +{ +} diff --git a/Lip.Migration/ManifestV1.cs b/Lip.Migration/ManifestV1.cs index 457708b2..7471f5a5 100644 --- a/Lip.Migration/ManifestV1.cs +++ b/Lip.Migration/ManifestV1.cs @@ -67,3 +67,8 @@ public record Command public string? GOARCH { get; set; } } } + +[JsonSerializable(typeof(ManifestV1))] +public partial class ManifestV1JsonContext : JsonSerializerContext +{ +} diff --git a/Lip.Migration/MigratorFromV1.cs b/Lip.Migration/MigratorFromV1.cs index 17f30079..26a0b1a5 100644 --- a/Lip.Migration/MigratorFromV1.cs +++ b/Lip.Migration/MigratorFromV1.cs @@ -18,7 +18,7 @@ public static bool IsMigratable(JsonElement json) public static JsonElement Migrate(JsonElement json) { - var manifestV1 = json.Deserialize() + var manifestV1 = JsonSerializer.Deserialize(json, ManifestV1JsonContext.Default.ManifestV1) ?? throw new JsonException("Failed to deserialize the obsolete manifest."); var info = new ManifestV2.InfoType @@ -81,6 +81,6 @@ public static JsonElement Migrate(JsonElement json) Platforms = null // No conversion for platforms from ManifestV1 }; - return MigratorFromV2.Migrate(JsonSerializer.SerializeToElement(manifestV2)); + return MigratorFromV2.Migrate(JsonSerializer.SerializeToElement(manifestV2, ManifestV2JsonContext.Default.ManifestV2)); } } diff --git a/Lip.Migration/MigratorFromV2.cs b/Lip.Migration/MigratorFromV2.cs index 86a16d70..35059a7f 100644 --- a/Lip.Migration/MigratorFromV2.cs +++ b/Lip.Migration/MigratorFromV2.cs @@ -1,5 +1,6 @@ using System.Runtime.InteropServices; using System.Text.Json; +using System.Text.Json.Serialization; using System.Text.RegularExpressions; namespace Lip.Migration; @@ -24,7 +25,7 @@ public static JsonElement Migrate(JsonElement json) Regex regex = new(@"\$\(([^)]+?)\)"); string jsonString = regex.Replace(json.GetRawText(), "{{$1}}"); - ManifestV2 manifestV2 = JsonSerializer.Deserialize(jsonString)!; + ManifestV2 manifestV2 = JsonSerializer.Deserialize(jsonString, ManifestV2JsonContext.Default.ManifestV2)!; Manifest manifest = new() { @@ -155,7 +156,7 @@ .. manifestV2.Platforms? manifest.Variants.Insert(0, new Manifest.Variant { Platform = RuntimeInformation.RuntimeIdentifier }); } - return JsonSerializer.SerializeToElement(manifest); + return JsonSerializer.SerializeToElement(manifest, ManifestJsonContext.Default.Manifest); } private static Manifest.ScriptsType ConvertCommandsToScripts(ManifestV2.CommandsType commands) @@ -208,3 +209,7 @@ private static Manifest.Placement ConvertPlaceToPlacement(ManifestV2.PlaceType p }; } } +[JsonSerializable(typeof(ManifestV2))] +public partial class ManifestV2JsonContext : JsonSerializerContext +{ +} From 9a6b9d8801437f965ceed373f157a1a6c03afcd0 Mon Sep 17 00:00:00 2001 From: harry-xi Date: Sat, 8 Mar 2025 20:25:32 +0800 Subject: [PATCH 2/2] fix: use new defulat goproxy --- Lip.Core/RuntimeConfig.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lip.Core/RuntimeConfig.cs b/Lip.Core/RuntimeConfig.cs index fdadf368..44ef496e 100644 --- a/Lip.Core/RuntimeConfig.cs +++ b/Lip.Core/RuntimeConfig.cs @@ -54,7 +54,7 @@ public static RuntimeConfig FromJsonBytes(byte[] bytes) Cache = raw.Cache ?? Path.Join( Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "lip", "cache"), GitHubProxiesText = raw.GitHubProxies ?? "", - GoModuleProxiesText = raw.GoModuleProxies ?? "https://proxy.golang.org" + GoModuleProxiesText = raw.GoModuleProxies ?? "https://goproxy.io" }; } catch (Exception ex) when (ex is JsonException)