Bläddra i källkod

Fixes #4116. NativeAot and SelfContained projects aren't working well in release mode (#4117)

* Fixes #4116. NativeAot and SelfContained projects aren't working well in release mode

* Revert delete nuget package because it fail in the git actions

* Trying automatize the nuget package installation

* Fixing UserProfile

* Trying fix push package for Unix OS

* Still triying to push nuget to the Unix

* Trying delete nuget package in the Pack target

* Trying fix git actions for release build

* Fix projects path

* Still fixing restore

* Add restore force parameter

* Build NativeAot and SelfContained projects before solution

* Build solution without restore

* Restore solutions packages before build

* Call dotnet restore before build the AOT and self-contained projects

* Remove unneeded run

* Revert "Remove unneeded run"

This reverts commit e04498d1ce814cd0d4f42d7d9369d6c684f20c3c.

* Trying fix racing fail unit tests

---------

Co-authored-by: Tig <[email protected]>
BDisp 3 månader sedan
förälder
incheckning
8fef16d35f

+ 15 - 2
.github/workflows/build-release.yml

@@ -30,5 +30,18 @@ jobs:
     - name: Pack Release Terminal.Gui
       run: dotnet pack Terminal.Gui/Terminal.Gui.csproj --configuration Release --output ./local_packages
 
-    - name: Build Release Solution
-      run: dotnet build --configuration Release
+    - name: Restore AOT and Self-Contained projects
+      run: |
+        dotnet restore ./Examples/NativeAot/NativeAot.csproj -f
+        dotnet restore ./Examples/SelfContained/SelfContained.csproj -f
+
+    - name: Restore Solution Packages
+      run: dotnet restore
+
+    - name: Build Release AOT and Self-Contained
+      run: |
+        dotnet build ./Examples/NativeAot/NativeAot.csproj --configuration Release
+        dotnet build ./Examples/SelfContained/SelfContained.csproj --configuration Release
+
+    - name: Build Release Solution without restore
+      run: dotnet build --configuration Release --no-restore

+ 16 - 16
Terminal.Gui/Configuration/DeepCloner.cs

@@ -46,22 +46,22 @@ public static class DeepCloner
         {
             return default (T?);
         }
-        // For AOT environments, use source generation exclusively
-        if (IsAotEnvironment ())
-        {
-            if (TryUseSourceGeneratedCloner<T> (source, out T? result))
-            {
-                return result;
-            }
-
-            // If in AOT but source generation failed, throw an exception
-            // instead of silently falling back to reflection
-            //throw new InvalidOperationException (
-            //                                     $"Type {typeof (T).FullName} is not properly registered in SourceGenerationContext " +
-            //                                     $"for AOT-compatible cloning.");
-            Logging.Error ($"Type {typeof (T).FullName} is not properly registered in SourceGenerationContext " +
-                          $"for AOT-compatible cloning.");
-        }
+        //// For AOT environments, use source generation exclusively
+        //if (IsAotEnvironment ())
+        //{
+        //    if (TryUseSourceGeneratedCloner<T> (source, out T? result))
+        //    {
+        //        return result;
+        //    }
+
+        //    // If in AOT but source generation failed, throw an exception
+        //    // instead of silently falling back to reflection
+        //    //throw new InvalidOperationException (
+        //    //                                     $"Type {typeof (T).FullName} is not properly registered in SourceGenerationContext " +
+        //    //                                     $"for AOT-compatible cloning.");
+        //    Logging.Error ($"Type {typeof (T).FullName} is not properly registered in SourceGenerationContext " +
+        //                  $"for AOT-compatible cloning.");
+        //}
 
         // Use reflection-based approach, which should have better performance in non-AOT environments
         ConcurrentDictionary<object, object> visited = new (ReferenceEqualityComparer.Instance);

+ 4 - 0
Terminal.Gui/Configuration/SourceGenerationContext.cs

@@ -36,6 +36,10 @@ namespace Terminal.Gui.Configuration;
 [JsonSerializable (typeof (Scope<string>))]
 [JsonSerializable (typeof (AppSettingsScope))]
 [JsonSerializable (typeof (SettingsScope))]
+[JsonSerializable (typeof (ThemeScope))]
+[JsonSerializable (typeof (Scope<ThemeScope>))]
+[JsonSerializable (typeof (Scope<AppSettingsScope>))]
+[JsonSerializable (typeof (Scope<SettingsScope>))]
 [JsonSerializable (typeof (ConcurrentDictionary<string, ThemeScope>))]
 [JsonSerializable (typeof (Dictionary<string, Scheme>))]
 

+ 13 - 0
Terminal.Gui/Terminal.Gui.csproj

@@ -156,7 +156,16 @@
         </VisualStudio>
     </ProjectExtensions>
 
+    <!--<Target Name="PreBuildCleanup" BeforeTargets="BeforeBuild" Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
+        <Exec Command="rmdir /s /q &quot;$(UserProfile)\.nuget\packages\terminal.gui\2.0.0&quot;" Condition=" '$(OS)' == 'Windows_NT' " />
+        <Exec Command="rm -rf ~/.nuget/packages/terminal.gui/2.0.0" Condition=" '$(OS)' != 'Windows_NT' " />
+    </Target>-->
+        
     <Target Name="CopyNuGetPackagesToLocalPackagesFolder" AfterTargets="Pack" Condition="'$(Configuration)' == 'Release'">
+	    <!-- Remove older NuGet Package from Global Cache -->
+	    <Exec Command="rmdir /s /q &quot;$(UserProfile)\.nuget\packages\terminal.gui\2.0.0&quot;" Condition=" '$(OS)' == 'Windows_NT' " />
+	    <Exec Command="rm -rf ~/.nuget/packages/terminal.gui/2.0.0" Condition=" '$(OS)' != 'Windows_NT' " />
+
         <PropertyGroup>
             <!-- Define the path for local_packages relative to the project directory -->
             <LocalPackagesPath>$(MSBuildThisFileDirectory)..\local_packages\</LocalPackagesPath>
@@ -181,5 +190,9 @@
 
         <!-- Log success -->
         <Message Text="Copy completed successfully." Importance="high" />
+
+        <!-- Install NuGet Package to Global Cache -->
+        <Exec Command="dotnet nuget push &quot;$(MSBuildThisFileDirectory)bin\$(Configuration)\Terminal.Gui.$(Version).nupkg&quot; --source &quot;$(UserProfile)\.nuget\packages&quot; --skip-duplicate" Condition=" '$(OS)' == 'Windows_NT' "/>
+        <Exec Command="dotnet nuget push &quot;$(MSBuildThisFileDirectory)bin\$(Configuration)/Terminal.Gui.$(Version).nupkg&quot; --source ~/.nuget/packages" Condition=" '$(OS)' != 'Windows_NT' "/>
     </Target>
 </Project>

+ 6 - 0
Terminal.sln

@@ -50,8 +50,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{C7A51224-5
 	EndProjectSection
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SelfContained", "Examples\SelfContained\SelfContained.csproj", "{524DEA78-7E7C-474D-B42D-52ED4C04FF14}"
+	ProjectSection(ProjectDependencies) = postProject
+		{00F366F8-DEE4-482C-B9FD-6DB0200B79E5} = {00F366F8-DEE4-482C-B9FD-6DB0200B79E5}
+	EndProjectSection
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NativeAot", "Examples\NativeAot\NativeAot.csproj", "{E6D716C6-AC94-4150-B10A-44AE13F79344}"
+	ProjectSection(ProjectDependencies) = postProject
+		{00F366F8-DEE4-482C-B9FD-6DB0200B79E5} = {00F366F8-DEE4-482C-B9FD-6DB0200B79E5}
+	EndProjectSection
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Benchmarks", "Tests\Benchmarks\Benchmarks.csproj", "{242FBD3E-2EC6-4274-BD40-8E62AF9327B2}"
 EndProject

+ 37 - 3
Tests/UnitTests/ConsoleDrivers/V2/ApplicationV2Tests.cs

@@ -25,7 +25,10 @@ public class ApplicationV2Tests
     [Fact]
     public void Init_CreatesKeybindings ()
     {
+        var orig = ApplicationImpl.Instance;
+
         var v2 = NewApplicationV2 ();
+        ApplicationImpl.ChangeInstance (v2);
 
         Application.KeyBindings.Clear ();
 
@@ -36,12 +39,17 @@ public class ApplicationV2Tests
         Assert.NotEmpty (Application.KeyBindings.GetBindings ());
 
         v2.Shutdown ();
+
+        ApplicationImpl.ChangeInstance (orig);
     }
 
     [Fact]
     public void Init_DriverIsFacade ()
     {
+        var orig = ApplicationImpl.Instance;
+
         var v2 = NewApplicationV2 ();
+        ApplicationImpl.ChangeInstance (v2);
 
         Assert.Null (Application.Driver);
         v2.Init ();
@@ -53,11 +61,15 @@ public class ApplicationV2Tests
         v2.Shutdown ();
 
         Assert.Null (Application.Driver);
+
+        ApplicationImpl.ChangeInstance (orig);
     }
 
     [Fact]
     public void Init_ExplicitlyRequestWin ()
     {
+        var orig = ApplicationImpl.Instance;
+
         Assert.Null (Application.Driver);
         var netInput = new Mock<INetInput> (MockBehavior.Strict);
         var netOutput = new Mock<IConsoleOutput> (MockBehavior.Strict);
@@ -77,6 +89,7 @@ public class ApplicationV2Tests
                                     () => netOutput.Object,
                                     () => winInput.Object,
                                     () => winOutput.Object);
+        ApplicationImpl.ChangeInstance (v2);
 
         Assert.Null (Application.Driver);
         v2.Init (null, "v2win");
@@ -90,11 +103,15 @@ public class ApplicationV2Tests
         Assert.Null (Application.Driver);
 
         winInput.VerifyAll ();
+
+        ApplicationImpl.ChangeInstance (orig);
     }
 
     [Fact]
     public void Init_ExplicitlyRequestNet ()
     {
+        var orig = ApplicationImpl.Instance;
+
         var netInput = new Mock<INetInput> (MockBehavior.Strict);
         var netOutput = new Mock<IConsoleOutput> (MockBehavior.Strict);
         var winInput = new Mock<IWindowsInput> (MockBehavior.Strict);
@@ -112,6 +129,7 @@ public class ApplicationV2Tests
                                     () => netOutput.Object,
                                     () => winInput.Object,
                                     () => winOutput.Object);
+        ApplicationImpl.ChangeInstance (v2);
 
         Assert.Null (Application.Driver);
         v2.Init (null, "v2net");
@@ -125,6 +143,8 @@ public class ApplicationV2Tests
         Assert.Null (Application.Driver);
 
         netInput.VerifyAll ();
+
+        ApplicationImpl.ChangeInstance (orig);
     }
 
     private void SetupRunInputMockMethodToBlock (Mock<IWindowsInput> winInput)
@@ -159,12 +179,17 @@ public class ApplicationV2Tests
     [Fact]
     public void NoInitThrowOnRun ()
     {
+        var orig = ApplicationImpl.Instance;
+
         Assert.Null (Application.Driver);
         var app = NewApplicationV2 ();
+        ApplicationImpl.ChangeInstance (app);
 
         var ex = Assert.Throws<NotInitializedException> (() => app.Run (new Window ()));
         Assert.Equal ("Run cannot be accessed before Initialization", ex.Message);
         app.Shutdown();
+
+        ApplicationImpl.ChangeInstance (orig);
     }
 
     [Fact]
@@ -449,6 +474,8 @@ public class ApplicationV2Tests
     [Fact]
     public void Shutdown_Called_Repeatedly_DoNotDuplicateDisposeOutput ()
     {
+        var orig = ApplicationImpl.Instance;
+
         var netInput = new Mock<INetInput> ();
         SetupRunInputMockMethodToBlock (netInput);
         Mock<IConsoleOutput>? outputMock = null;
@@ -459,6 +486,7 @@ public class ApplicationV2Tests
                                    () => (outputMock = new Mock<IConsoleOutput> ()).Object,
                                    Mock.Of<IWindowsInput>,
                                    Mock.Of<IConsoleOutput>);
+        ApplicationImpl.ChangeInstance (v2);
 
         v2.Init (null, "v2net");
 
@@ -466,11 +494,17 @@ public class ApplicationV2Tests
         v2.Shutdown ();
         v2.Shutdown ();
         outputMock!.Verify (o => o.Dispose (), Times.Once);
+
+        ApplicationImpl.ChangeInstance (orig);
     }
+
     [Fact]
     public void Init_Called_Repeatedly_WarnsAndIgnores ()
     {
+        var orig = ApplicationImpl.Instance;
+
         var v2 = NewApplicationV2 ();
+        ApplicationImpl.ChangeInstance (v2);
 
         Assert.Null (Application.Driver);
         v2.Init ();
@@ -496,12 +530,12 @@ public class ApplicationV2Tests
 
         // Restore the original null logger to be polite to other tests
         Logging.Logger = beforeLogger;
-    }
 
+        ApplicationImpl.ChangeInstance (orig);
+    }
 
-    // QUESTION: What does this test really test? It's poorly named.
     [Fact]
-    public void Open_CallsContinueWithOnUIThread ()
+    public void Open_Calls_ContinueWith_On_UIThread ()
     {
         var orig = ApplicationImpl.Instance;
 

BIN
local_packages/Terminal.Gui.2.0.0.nupkg


BIN
local_packages/Terminal.Gui.2.0.0.snupkg


+ 3 - 3
nuget.config

@@ -15,8 +15,8 @@
     <packageSource key="nuget">
       <package pattern="*" />
     </packageSource>
-	<packageSource key="LocalPackages">
-       <package pattern="Terminal.Gui*" />
-	</packageSource>
+    <packageSource key="LocalPackages">
+      <package pattern="Terminal.Gui*" />
+    </packageSource>
   </packageSourceMapping>
 </configuration>