From 4d80bcebe80044fe141818be034cd5e5946e71fe Mon Sep 17 00:00:00 2001 From: Marko Lahma Date: Mon, 24 Nov 2025 11:44:05 +0200 Subject: [PATCH 1/2] Add :setup support for slnx solution files * add ManagePackageVersionsCentrally false directive to generated build.csproj --- ...ContentTests.TestXml_number=1.verified.txt | 4 ++ .../UpdateSolutionFileContentTests.cs | 32 +++++++++++++++ source/Nuke.GlobalTool/Program.Setup.cs | 41 ++++++++++++++++--- .../Nuke.GlobalTool/templates/_build.csproj | 2 + 4 files changed, 73 insertions(+), 6 deletions(-) create mode 100644 source/Nuke.GlobalTool.Tests/UpdateSolutionFileContentTests.TestXml_number=1.verified.txt diff --git a/source/Nuke.GlobalTool.Tests/UpdateSolutionFileContentTests.TestXml_number=1.verified.txt b/source/Nuke.GlobalTool.Tests/UpdateSolutionFileContentTests.TestXml_number=1.verified.txt new file mode 100644 index 000000000..4f5ec7ca4 --- /dev/null +++ b/source/Nuke.GlobalTool.Tests/UpdateSolutionFileContentTests.TestXml_number=1.verified.txt @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/source/Nuke.GlobalTool.Tests/UpdateSolutionFileContentTests.cs b/source/Nuke.GlobalTool.Tests/UpdateSolutionFileContentTests.cs index fd0b985dd..f78c86679 100644 --- a/source/Nuke.GlobalTool.Tests/UpdateSolutionFileContentTests.cs +++ b/source/Nuke.GlobalTool.Tests/UpdateSolutionFileContentTests.cs @@ -3,8 +3,11 @@ // https://github.com/nuke-build/nuke/blob/master/LICENSE using System; +using System.IO; using System.Linq; using System.Threading.Tasks; +using System.Xml; +using System.Xml.Linq; using Nuke.Common.Utilities; using VerifyXunit; using Xunit; @@ -140,4 +143,33 @@ public Task Test(int number, string input, string expected) return Verifier.Verify(expected) .UseParameters(number); } + + [Theory] + [InlineData( + 1, + """ + + + + """, + """ + + + + + """)] + public Task TestXml(int number, string input, string expected) + { + var content = XDocument.Load(new StringReader(input)); + Program.UpdateSolutionXmlFileContent(content, "RELATIVE"); + + var settings = new XmlWriterSettings { OmitXmlDeclaration = true, Indent = true }; + var stringStream = new StringWriter(); + using var writer = XmlWriter.Create(stringStream, settings); + content.Save(writer); + writer.Flush(); + + return Verifier.Verify(stringStream.ToString()) + .UseParameters(number); + } } diff --git a/source/Nuke.GlobalTool/Program.Setup.cs b/source/Nuke.GlobalTool/Program.Setup.cs index 9700f1a37..1506b9af0 100644 --- a/source/Nuke.GlobalTool/Program.Setup.cs +++ b/source/Nuke.GlobalTool/Program.Setup.cs @@ -8,6 +8,8 @@ using System.Linq; using System.Reflection; using System.Text; +using System.Xml; +using System.Xml.Linq; using JetBrains.Annotations; using Nuke.Common; using Nuke.Common.Execution; @@ -27,7 +29,7 @@ partial class Program { // ReSharper disable InconsistentNaming - private const string TARGET_FRAMEWORK = "net8.0"; + private const string TARGET_FRAMEWORK = "net10.0"; private const string PROJECT_KIND = "9A19103F-16F7-4668-BE54-9A1E7A4F7556"; // ReSharper disable once CognitiveComplexity @@ -84,7 +86,7 @@ public static int Setup(string[] args, [CanBeNull] AbsolutePath rootDirectory, [ "Which solution should be the default?", choices: new DirectoryInfo(rootDirectory) .EnumerateFiles("*", SearchOption.AllDirectories) - .Where(x => x.FullName.EndsWithOrdinalIgnoreCase(".sln")) + .Where(x => x.FullName.EndsWithOrdinalIgnoreCase(".sln") || x.FullName.EndsWithOrdinalIgnoreCase(".slnx")) .OrderByDescending(x => x.FullName) .Select(x => (x, rootDirectory.GetRelativePathTo(x.FullName).ToString())) .Concat((null, "None")).ToArray())?.FullName; @@ -110,10 +112,22 @@ public static int Setup(string[] args, [CanBeNull] AbsolutePath rootDirectory, [ if (solutionFile != null) { - var solutionFileContent = solutionFile.ReadAllLines().ToList(); var buildProjectFileRelative = solutionFile.Parent.GetWinRelativePathTo(buildProjectFile); - UpdateSolutionFileContent(solutionFileContent, buildProjectFileRelative, buildProjectGuid, buildProjectName); - solutionFile.WriteAllLines(solutionFileContent, Encoding.UTF8); + if (solutionFile.Extension.EqualsOrdinalIgnoreCase(".slnx")) + { + var solutionDocument = XDocument.Load(solutionFile); + UpdateSolutionXmlFileContent(solutionDocument, buildProjectFileRelative); + + var settings = new XmlWriterSettings { OmitXmlDeclaration = true, Indent = true }; + using var writer = XmlWriter.Create(solutionFile, settings); + solutionDocument.Save(writer); + } + else + { + var solutionFileContent = solutionFile.ReadAllLines().ToList(); + UpdateSolutionFileContent(solutionFileContent, buildProjectFileRelative, buildProjectGuid, buildProjectName); + solutionFile.WriteAllLines(solutionFileContent, Encoding.UTF8); + } } buildProjectFile.WriteAllLines( @@ -186,12 +200,27 @@ internal static void UpdateSolutionFileContent( "EndProject"); } + internal static void UpdateSolutionXmlFileContent(XDocument content, string buildProjectFileRelative) + { + var solutionElement = content.Root; + Assert.True(solutionElement?.Name == "Solution", "Could not find a root 'Solution' element in solution file"); + + // file uses forward slashes for paths on every platform + var path = buildProjectFileRelative.Replace(oldChar: '\\', newChar: '/'); + + if (solutionElement.Elements("Project").Any(x => x.GetAttributeValue("Path").EqualsOrdinalIgnoreCase(path))) + { + return; + } + + solutionElement.Add(new XElement("Project", new XAttribute("Path", path))); + } + private static string[] GetTemplate(string templateName) { return ResourceUtility.GetResourceAllLines($"templates.{templateName}"); } - private static void WriteBuildScripts( AbsolutePath scriptDirectory, AbsolutePath rootDirectory, diff --git a/source/Nuke.GlobalTool/templates/_build.csproj b/source/Nuke.GlobalTool/templates/_build.csproj index 23c2cc858..7a5d63ef9 100644 --- a/source/Nuke.GlobalTool/templates/_build.csproj +++ b/source/Nuke.GlobalTool/templates/_build.csproj @@ -9,6 +9,8 @@ _SCRIPT_DIRECTORY_ _TELEMETRY_VERSION_ false + false + false From c5cd8791f14c7c049572c08384beedcfe5442c15 Mon Sep 17 00:00:00 2001 From: Marko Lahma Date: Mon, 24 Nov 2025 12:22:46 +0200 Subject: [PATCH 2/2] set no build for NUKE project --- ...dateSolutionFileContentTests.TestXml_number=1.verified.txt | 4 +++- .../Nuke.GlobalTool.Tests/UpdateSolutionFileContentTests.cs | 4 +++- source/Nuke.GlobalTool/Program.Setup.cs | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/source/Nuke.GlobalTool.Tests/UpdateSolutionFileContentTests.TestXml_number=1.verified.txt b/source/Nuke.GlobalTool.Tests/UpdateSolutionFileContentTests.TestXml_number=1.verified.txt index 4f5ec7ca4..74518468c 100644 --- a/source/Nuke.GlobalTool.Tests/UpdateSolutionFileContentTests.TestXml_number=1.verified.txt +++ b/source/Nuke.GlobalTool.Tests/UpdateSolutionFileContentTests.TestXml_number=1.verified.txt @@ -1,4 +1,6 @@  - + + + \ No newline at end of file diff --git a/source/Nuke.GlobalTool.Tests/UpdateSolutionFileContentTests.cs b/source/Nuke.GlobalTool.Tests/UpdateSolutionFileContentTests.cs index f78c86679..f20f83f59 100644 --- a/source/Nuke.GlobalTool.Tests/UpdateSolutionFileContentTests.cs +++ b/source/Nuke.GlobalTool.Tests/UpdateSolutionFileContentTests.cs @@ -155,7 +155,9 @@ public Task Test(int number, string input, string expected) """ - + + + """)] public Task TestXml(int number, string input, string expected) diff --git a/source/Nuke.GlobalTool/Program.Setup.cs b/source/Nuke.GlobalTool/Program.Setup.cs index 1506b9af0..f8fdb56ec 100644 --- a/source/Nuke.GlobalTool/Program.Setup.cs +++ b/source/Nuke.GlobalTool/Program.Setup.cs @@ -213,7 +213,9 @@ internal static void UpdateSolutionXmlFileContent(XDocument content, string buil return; } - solutionElement.Add(new XElement("Project", new XAttribute("Path", path))); + var projectElement = new XElement("Project", new XAttribute("Path", path)); + projectElement.Add(new XElement("Build", new XAttribute("Project", value: false))); + solutionElement.Add(projectElement); } private static string[] GetTemplate(string templateName)