From 1cbab39e6745c276aab135771a54d1cf0c4020e0 Mon Sep 17 00:00:00 2001
From: Gregorius Soedharmo <arkatufus@yahoo.com>
Date: Tue, 25 Jun 2024 04:02:14 +0700
Subject: [PATCH] Modernize solution (#80)

* Modernize solution

* Fix build script

* Add nuget.config

* Fix directory.build.props

* Make code compatible with .NET Standard 2.0
---
 Akka.Serialization.Compressed.sln             |  4 +++
 NuGet.Config                                  | 13 ++++++++
 build/Build.cs                                |  4 +--
 build/_build.csproj.DotSettings               |  5 ++-
 ...n.Compressed.Json.Tests.Performance.csproj |  4 +--
 ...Serialization.Compressed.Json.Tests.csproj |  8 ++---
 .../Akka.Serialization.Compressed.Json.csproj |  4 +--
 .../AkkaHostingExtensions.cs                  |  5 +--
 .../CompressedJsonSerializer.cs               | 18 ++++++-----
 .../Akka.Serialization.TestKit.csproj         | 12 ++-----
 src/Directory.Build.props                     | 20 ++++--------
 src/Directory.Generated.props                 |  6 ++++
 src/Directory.Packages.props                  | 31 +++++++++++++++++++
 13 files changed, 91 insertions(+), 43 deletions(-)
 create mode 100644 NuGet.Config
 create mode 100644 src/Directory.Generated.props
 create mode 100644 src/Directory.Packages.props

diff --git a/Akka.Serialization.Compressed.sln b/Akka.Serialization.Compressed.sln
index 165f471..0131ddb 100644
--- a/Akka.Serialization.Compressed.sln
+++ b/Akka.Serialization.Compressed.sln
@@ -15,6 +15,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
 	ProjectSection(SolutionItems) = preProject
 		README.md = README.md
 		RELEASE_NOTES.md = RELEASE_NOTES.md
+		src\Directory.Build.props = src\Directory.Build.props
+		src\Directory.Generated.props = src\Directory.Generated.props
+		src\Directory.Packages.props = src\Directory.Packages.props
+		NuGet.Config = NuGet.Config
 	EndProjectSection
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Json", "Json", "{25F8AE7C-D98B-41B1-A534-49E9603D8533}"
diff --git a/NuGet.Config b/NuGet.Config
new file mode 100644
index 0000000..8bb7f8f
--- /dev/null
+++ b/NuGet.Config
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <packageSources>
+    <clear />
+    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
+  </packageSources>
+
+  <packageSourceMapping>
+    <packageSource key="nuget.org">
+      <package pattern="*" />
+    </packageSource>
+  </packageSourceMapping>
+</configuration>
diff --git a/build/Build.cs b/build/Build.cs
index 0769b33..081e44a 100644
--- a/build/Build.cs
+++ b/build/Build.cs
@@ -330,8 +330,8 @@ IEnumerable<Project> GetProjects()
         .After(Restore)
         .Executes(() =>
         {
-            XmlTasks.XmlPoke(SourceDirectory / "Directory.Build.props", "//Project/PropertyGroup/PackageReleaseNotes", GetNuGetReleaseNotes(ChangelogFile));
-            XmlTasks.XmlPoke(SourceDirectory / "Directory.Build.props", "//Project/PropertyGroup/VersionPrefix", ReleaseVersion);
+            XmlTasks.XmlPoke(SourceDirectory / "Directory.Generated.props", "//Project/PropertyGroup/PackageReleaseNotes", GetNuGetReleaseNotes(ChangelogFile));
+            XmlTasks.XmlPoke(SourceDirectory / "Directory.Generated.props", "//Project/PropertyGroup/VersionPrefix", ReleaseVersion);
 
         });
 
diff --git a/build/_build.csproj.DotSettings b/build/_build.csproj.DotSettings
index 7bc2848..337271d 100644
--- a/build/_build.csproj.DotSettings
+++ b/build/_build.csproj.DotSettings
@@ -16,6 +16,8 @@
 	<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_ANONYMOUSMETHOD_ON_SINGLE_LINE/@EntryValue">False</s:Boolean>
 	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
 	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
+	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=4a98fdf6_002D7d98_002D4f5a_002Dafeb_002Dea44ad98c70c/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
+	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=f9fce829_002De6f4_002D4cb2_002D80f1_002D5497c44f51df/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
 	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
@@ -24,4 +26,5 @@
 	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
-	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
+	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean>
+	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EPredefinedNamingRulesToUserRulesUpgrade/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
diff --git a/src/Akka.Serialization.Compressed.Json.Tests.Performance/Akka.Serialization.Compressed.Json.Tests.Performance.csproj b/src/Akka.Serialization.Compressed.Json.Tests.Performance/Akka.Serialization.Compressed.Json.Tests.Performance.csproj
index 99fbd96..28a12c4 100644
--- a/src/Akka.Serialization.Compressed.Json.Tests.Performance/Akka.Serialization.Compressed.Json.Tests.Performance.csproj
+++ b/src/Akka.Serialization.Compressed.Json.Tests.Performance/Akka.Serialization.Compressed.Json.Tests.Performance.csproj
@@ -2,12 +2,12 @@
 
   <PropertyGroup>
     <OutputType>Exe</OutputType>
-    <TargetFrameworks>$(TestsNetCore);$(TestsNet)</TargetFrameworks>
+    <TargetFrameworks>$(TestsNetFx);$(TestsNet)</TargetFrameworks>
     <IsPackable>false</IsPackable>
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="BenchmarkDotNet" Version="$(BenchmarkDotNetVersion)" />
+    <PackageReference Include="BenchmarkDotNet" />
   </ItemGroup>
 
   <ItemGroup>
diff --git a/src/Akka.Serialization.Compressed.Json.Tests/Akka.Serialization.Compressed.Json.Tests.csproj b/src/Akka.Serialization.Compressed.Json.Tests/Akka.Serialization.Compressed.Json.Tests.csproj
index f640eba..86abce4 100644
--- a/src/Akka.Serialization.Compressed.Json.Tests/Akka.Serialization.Compressed.Json.Tests.csproj
+++ b/src/Akka.Serialization.Compressed.Json.Tests/Akka.Serialization.Compressed.Json.Tests.csproj
@@ -1,13 +1,13 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>    
-    <TargetFrameworks>$(TestsNetCore);$(TestsNet)</TargetFrameworks>
+    <TargetFrameworks>$(TestsNetFx);$(TestsNet)</TargetFrameworks>
     <IsPackable>false</IsPackable>
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(TestSdkVersion)" />
-    <PackageReference Include="xunit" Version="$(XunitVersion)" />
-    <PackageReference Include="xunit.runner.visualstudio" Version="$(XunitRunnerVisualstudio)">
+    <PackageReference Include="Microsoft.NET.Test.Sdk" />
+    <PackageReference Include="xunit" />
+    <PackageReference Include="xunit.runner.visualstudio" >
       <PrivateAssets>all</PrivateAssets>
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
     </PackageReference>
diff --git a/src/Akka.Serialization.Compressed.Json/Akka.Serialization.Compressed.Json.csproj b/src/Akka.Serialization.Compressed.Json/Akka.Serialization.Compressed.Json.csproj
index 1425f79..9832584 100644
--- a/src/Akka.Serialization.Compressed.Json/Akka.Serialization.Compressed.Json.csproj
+++ b/src/Akka.Serialization.Compressed.Json/Akka.Serialization.Compressed.Json.csproj
@@ -8,8 +8,8 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Akka" Version="$(AkkaVersion)" />
-    <PackageReference Include="Akka.Hosting" Version="$(AkkaHostingVersion)" />
+    <PackageReference Include="Akka" />
+    <PackageReference Include="Akka.Hosting" />
   </ItemGroup>
 
   <ItemGroup>
diff --git a/src/Akka.Serialization.Compressed.Json/AkkaHostingExtensions.cs b/src/Akka.Serialization.Compressed.Json/AkkaHostingExtensions.cs
index 920d18c..ae190f6 100644
--- a/src/Akka.Serialization.Compressed.Json/AkkaHostingExtensions.cs
+++ b/src/Akka.Serialization.Compressed.Json/AkkaHostingExtensions.cs
@@ -6,6 +6,7 @@
 // -----------------------------------------------------------------------
 
 using System;
+using System.Collections.Immutable;
 using System.Linq;
 using Akka.Hosting;
 
@@ -23,8 +24,8 @@ public static AkkaConfigurationBuilder WithCompressedJsonSerializer(this AkkaCon
     
     public static AkkaConfigurationBuilder WithCompressedJsonSerializer(this AkkaConfigurationBuilder builder, params Type[] boundTypes)
     {
-        var typeHash = boundTypes.ToHashSet();
-        typeHash.Add(typeof(IShouldCompress));
+        var typeHash = boundTypes.ToImmutableHashSet();
+        typeHash = typeHash.Add(typeof(IShouldCompress));
         
         return builder.WithCustomSerializer(
             serializerIdentifier: "json-gzip",
diff --git a/src/Akka.Serialization.Compressed.Json/CompressedJsonSerializer.cs b/src/Akka.Serialization.Compressed.Json/CompressedJsonSerializer.cs
index 02c50b9..bd6d496 100644
--- a/src/Akka.Serialization.Compressed.Json/CompressedJsonSerializer.cs
+++ b/src/Akka.Serialization.Compressed.Json/CompressedJsonSerializer.cs
@@ -371,8 +371,8 @@ private static object GetValue(string? value)
             if(value is null)
                 throw new NotSupportedException("Null is not supported");
             
-            var t = value[..1];
-            var v = value[1..];
+            var t = value.Substring(0, 1);
+            var v = value.Substring(1);
             return t switch
             {
                 "I" => int.Parse(v, NumberFormatInfo.InvariantInfo),
@@ -386,9 +386,11 @@ private static object GetValue(string? value)
         private static byte[] Compress(byte[] data)
         {
             using var compressedStream = new MemoryStream();
-            using var compressor = new GZipStream(compressedStream, CompressionMode.Compress);
-            compressor.Write(data, 0, data.Length);
-            compressor.Flush(); // It is critical to flush here
+            using (var compressor = new GZipStream(compressedStream, CompressionMode.Compress, false))
+            {
+                compressor.Write(data, 0, data.Length);
+                compressor.Flush(); // It is critical to flush here
+            }
             return compressedStream.ToArray();
         }
 
@@ -396,9 +398,11 @@ private static byte[] Compress(byte[] data)
         private static byte[] Decompress(byte[] raw)
         {
             using var compressedStream = new MemoryStream(raw);
-            using var compressor = new GZipStream(compressedStream, CompressionMode.Decompress);
             using var uncompressedStream = new MemoryStream();
-            compressor.CopyTo(uncompressedStream);
+            using (var compressor = new GZipStream(compressedStream, CompressionMode.Decompress, false))
+            {
+                compressor.CopyTo(uncompressedStream);
+            }
             return uncompressedStream.ToArray();
         }
 
diff --git a/src/Akka.Serialization.TestKit/Akka.Serialization.TestKit.csproj b/src/Akka.Serialization.TestKit/Akka.Serialization.TestKit.csproj
index 9779553..3819db9 100644
--- a/src/Akka.Serialization.TestKit/Akka.Serialization.TestKit.csproj
+++ b/src/Akka.Serialization.TestKit/Akka.Serialization.TestKit.csproj
@@ -1,22 +1,16 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <TargetFrameworks>$(TestsNetCore);$(TestsNet)</TargetFrameworks>
+    <TargetFrameworks>$(TestsNetFx);$(TestsNet)</TargetFrameworks>
     <IsPackable>false</IsPackable>
   </PropertyGroup>
   
-<!--
-  <ItemGroup>
-    <ProjectReference Include="..\..\..\core\Akka.Tests.Shared.Internals\Akka.Tests.Shared.Internals.csproj" />
-  </ItemGroup>
--->
-
   <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
     <DefineConstants>$(DefineConstants);RELEASE</DefineConstants>
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Akka.TestKit.Xunit2" Version="$(AkkaVersion)" />
-    <PackageReference Include="FluentAssertions" Version="$(FluentAssertionsVersion)" />
+    <PackageReference Include="Akka.TestKit.Xunit2" />
+    <PackageReference Include="FluentAssertions" />
   </ItemGroup>
 
 </Project>
\ No newline at end of file
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index 834d2a6..e7f1207 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -1,34 +1,26 @@
 <Project>
+  <Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Generated.props', '$(MSBuildThisFileDirectory)'))" />
+  
   <PropertyGroup>
     <Copyright>Copyright © 2013-2023 Akka.NET Team</Copyright>
     <Authors>Akka.NET Team</Authors>
-    <VersionPrefix>0.3.0</VersionPrefix>
-    <PackageReleaseNotes>• Fixed bugs</PackageReleaseNotes>
     <PackageIconUrl>akkalogo.png</PackageIconUrl>
     <PackageProjectUrl>https://github.com/akkadotnet/Akka.Serialization.Compressed</PackageProjectUrl>
     <PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
     <NoWarn>$(NoWarn);CS1591</NoWarn>
     <Nullable>enable</Nullable>
-    <LangVersion>10.0</LangVersion>
+    <LangVersion>latest</LangVersion>
   </PropertyGroup>
   
   <PropertyGroup>
-    <LibraryFramework>netstandard2.1</LibraryFramework>
+    <LibraryFramework>netstandard2.0</LibraryFramework>
     <TestsNet>net6.0</TestsNet>
-    <TestsNetCore>netcoreapp3.1</TestsNetCore>
-    <XunitVersion>2.5.1</XunitVersion>
-    <XunitRunnerVisualstudio>2.5.1</XunitRunnerVisualstudio>
-    <TestSdkVersion>17.8.0</TestSdkVersion>
-    
-    <AkkaVersion>1.5.13</AkkaVersion>
-    <AkkaHostingVersion>1.5.13</AkkaHostingVersion>
-    <FluentAssertionsVersion>6.12.0</FluentAssertionsVersion>
-    <BenchmarkDotNetVersion>0.13.8</BenchmarkDotNetVersion>
+    <TestsNetFx>net472</TestsNetFx>
   </PropertyGroup>
   
   <!-- SourceLink support for all Akka.NET projects -->
   <ItemGroup>
-    <PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
+    <PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" />
   </ItemGroup>
 
   <ItemGroup>
diff --git a/src/Directory.Generated.props b/src/Directory.Generated.props
new file mode 100644
index 0000000..bcef6d9
--- /dev/null
+++ b/src/Directory.Generated.props
@@ -0,0 +1,6 @@
+<Project>
+  <PropertyGroup>
+    <VersionPrefix/>
+    <PackageReleaseNotes/>
+  </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props
new file mode 100644
index 0000000..e89f62b
--- /dev/null
+++ b/src/Directory.Packages.props
@@ -0,0 +1,31 @@
+<Project>
+  <PropertyGroup>
+    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
+    <AkkaVersion>1.5.25</AkkaVersion>
+    <AkkaHostingVersion>1.5.25</AkkaHostingVersion>
+  </PropertyGroup>
+  <!-- Akka dependencies -->
+  <ItemGroup>
+    <PackageVersion Include="Akka" Version="$(AkkaVersion)" />
+    <PackageVersion Include="Akka.Hosting" Version="$(AkkaHostingVersion)" />
+  </ItemGroup>
+  <!-- App dependencies -->
+  <ItemGroup>
+  </ItemGroup>
+  <!-- Test dependencies -->
+  <ItemGroup>
+    <PackageVersion Include="Akka.TestKit.Xunit2" Version="$(AkkaVersion)" />
+    <PackageVersion Include="Akka.Hosting.TestKit" Version="$(AkkaHostingVersion)" />
+    <PackageVersion Include="BenchmarkDotNet" Version="0.13.12" />
+    <PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
+    <PackageVersion Include="Docker.DotNet" Version="3.125.15" />
+    <PackageVersion Include="FluentAssertions" Version="6.12.0" />
+    <PackageVersion Include="xunit" Version="2.8.1" />
+    <PackageVersion Include="xunit.runner.visualstudio" Version="2.8.1" />
+    <PackageVersion Include="coverlet.collector" Version="6.0.2" />
+  </ItemGroup>
+  <!-- SourceLink support for all Akka.NET projects -->
+  <ItemGroup>
+    <PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
+  </ItemGroup>
+</Project>
\ No newline at end of file