From 042d8e6c707eb0965fa3f5dca0e39e121ef019bc Mon Sep 17 00:00:00 2001 From: Florian Rappl Date: Fri, 4 Sep 2026 13:26:27 +0200 Subject: [PATCH] Infra enhancements --- src/ElectronNET.Host/ElectronNET.Host.esproj | 2 +- .../Tests/ElectronCleanTargetsTests.cs | 108 ++++++++++++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 src/ElectronNET.IntegrationTests/Tests/ElectronCleanTargetsTests.cs diff --git a/src/ElectronNET.Host/ElectronNET.Host.esproj b/src/ElectronNET.Host/ElectronNET.Host.esproj index 0f56fbf..4469c3b 100644 --- a/src/ElectronNET.Host/ElectronNET.Host.esproj +++ b/src/ElectronNET.Host/ElectronNET.Host.esproj @@ -1,4 +1,4 @@ - + diff --git a/src/ElectronNET.IntegrationTests/Tests/ElectronCleanTargetsTests.cs b/src/ElectronNET.IntegrationTests/Tests/ElectronCleanTargetsTests.cs new file mode 100644 index 0000000..9923e6d --- /dev/null +++ b/src/ElectronNET.IntegrationTests/Tests/ElectronCleanTargetsTests.cs @@ -0,0 +1,108 @@ +using System.Diagnostics; + +namespace ElectronNET.IntegrationTests.Tests; + +/// +/// Tests for the Electron clean targets. +/// Covers GitHub issue #1096: cleaning must not require a restore, so the clean targets +/// must not depend on targets that need the assets file (NETSDK1004). +/// +public class ElectronCleanTargetsTests +{ + private static readonly string CorePropsPath = FindBuildFile("src/ElectronNET/build/ElectronNET.Core.props", "ElectronNET/build/ElectronNET.Core.props"); + private static readonly string CoreTargetsPath = FindBuildFile("src/ElectronNET/build/ElectronNET.Core.targets", "ElectronNET/build/ElectronNET.Core.targets"); + + [Fact] + public async Task ElectronCleanTargets_WithoutRestore_ShouldSucceed() + { + var tempDir = CreateTempProjectDirectory(); + + try + { + await WriteMinimalCsprojAsync(tempDir); + + var (exitCode, output) = await RunDotnetMsBuildAsync(tempDir, "Clean"); + + output.Should().NotContain("NETSDK1004", + $"cleaning must not require the assets file of a previous restore. Full output:\n{output}"); + + exitCode.Should().Be(0, + $"cleaning an unrestored project must succeed. Full output:\n{output}"); + } + finally + { + Directory.Delete(tempDir, recursive: true); + } + } + + private static string FindBuildFile(string relativeFromRepoRoot, string relativeFromSrc) + { + var dir = new DirectoryInfo(AppContext.BaseDirectory); + while (dir != null) + { + var fromRepoRoot = Path.Combine(dir.FullName, relativeFromRepoRoot); + if (File.Exists(fromRepoRoot)) + { + return Path.GetFullPath(fromRepoRoot); + } + + var fromSrc = Path.Combine(dir.FullName, relativeFromSrc); + if (File.Exists(fromSrc)) + { + return Path.GetFullPath(fromSrc); + } + + dir = dir.Parent; + } + + throw new FileNotFoundException( + $"Could not locate '{relativeFromRepoRoot}' by walking up from '{AppContext.BaseDirectory}'."); + } + + private static string CreateTempProjectDirectory() + { + var tempDir = Path.Combine(Path.GetTempPath(), $"electron-net-clean-test-{Guid.NewGuid():N}"); + Directory.CreateDirectory(tempDir); + Directory.CreateDirectory(Path.Combine(tempDir, "Properties")); + return tempDir; + } + + private static Task WriteMinimalCsprojAsync(string tempDir) + { + var propsPathEscaped = CorePropsPath.Replace("'", "'"); + var targetsPathEscaped = CoreTargetsPath.Replace("'", "'"); + + return File.WriteAllTextAsync( + Path.Combine(tempDir, "TestApp.csproj"), + $$""" + + + net10.0 + + + + + + + """); + } + + private static async Task<(int ExitCode, string Output)> RunDotnetMsBuildAsync(string workingDirectory, string target) + { + // Deliberately without /restore - that is what issue #1096 is about. + var psi = new ProcessStartInfo("dotnet", $"msbuild TestApp.csproj --nologo -v:minimal /t:{target}") + { + WorkingDirectory = workingDirectory, + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + }; + + using var process = Process.Start(psi)!; + var stdOut = await process.StandardOutput.ReadToEndAsync(); + var stdErr = await process.StandardError.ReadToEndAsync(); + await process.WaitForExitAsync(); + + return (process.ExitCode, stdOut + stdErr); + } +}