diff --git a/src/Fallout.Cli/Program.Navigation.cs b/src/Fallout.Cli/Program.Navigation.cs index ede03690..17a369a2 100644 --- a/src/Fallout.Cli/Program.Navigation.cs +++ b/src/Fallout.Cli/Program.Navigation.cs @@ -23,7 +23,7 @@ private static string SessionId _ => throw new NotSupportedException($"{EnvironmentInfo.Platform} has no session id selector.") }; - private static AbsolutePath SessionFile => GlobalTemporaryDirectory / $"nuke-{SessionId}.dat"; + private static AbsolutePath SessionFile => GlobalTemporaryDirectory / $"fallout-{SessionId}.dat"; private static int GetNextDirectory() { diff --git a/src/Fallout.Cli/Program.Setup.cs b/src/Fallout.Cli/Program.Setup.cs index ae74774c..b08005df 100644 --- a/src/Fallout.Cli/Program.Setup.cs +++ b/src/Fallout.Cli/Program.Setup.cs @@ -4,6 +4,8 @@ using System.Linq; using System.Reflection; using System.Text; +using System.Xml; +using System.Xml.Linq; using Fallout.Common; using Fallout.Common.Execution; using Fallout.Common.IO; @@ -22,7 +24,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 @@ -38,9 +40,9 @@ public static int Setup(string[] args, AbsolutePath rootDirectory, AbsolutePath #region Basic - var nukeLatestReleaseVersion = NuGetVersionResolver.GetLatestVersion(FalloutCommonPackageId, includePrereleases: false); - var nukeLatestPrereleaseVersion = NuGetVersionResolver.GetLatestVersion(FalloutCommonPackageId, includePrereleases: true); - var nukeLatestLocalVersion = NuGetPackageResolver.GetGlobalInstalledPackage(FalloutCommonPackageId, version: null, packagesConfigFile: null) + var falloutLatestReleaseVersion = NuGetVersionResolver.GetLatestVersion(FalloutCommonPackageId, includePrereleases: false); + var falloutLatestPrereleaseVersion = NuGetVersionResolver.GetLatestVersion(FalloutCommonPackageId, includePrereleases: true); + var falloutLatestLocalVersion = NuGetPackageResolver.GetGlobalInstalledPackage(FalloutCommonPackageId, version: null, packagesConfigFile: null) ?.Version.ToString(); if (rootDirectory == null) @@ -61,24 +63,24 @@ public static int Setup(string[] args, AbsolutePath rootDirectory, AbsolutePath ClearPreviousLine(); ShowInput("round_pushpin", "Build project location", buildProjectRelativeDirectory); - var nukeVersion = PromptForChoice("Which Fallout.Common version should be used?", + var falloutVersion = PromptForChoice("Which Fallout.Common version should be used?", new[] { - ("latest release", nukeLatestReleaseVersion.GetAwaiter().GetResult()), - ("latest prerelease", nukeLatestPrereleaseVersion.GetAwaiter().GetResult()), - ("latest local", nukeLatestLocalVersion), + ("latest release", falloutLatestReleaseVersion.GetAwaiter().GetResult()), + ("latest prerelease", falloutLatestPrereleaseVersion.GetAwaiter().GetResult()), + ("latest local", falloutLatestLocalVersion), ("same as global tool", typeof(Program).GetTypeInfo().Assembly.GetVersionText()) } .Where(x => x.Item2 != null) .Distinct(x => x.Item2) .Select(x => (x.Item2, $"{x.Item2} ({x.Item1})")).ToArray()); - ShowInput("gem_stone", "Fallout.Common version", nukeVersion); + ShowInput("gem_stone", "Fallout.Common version", falloutVersion); var solutionFile = (AbsolutePath) PromptForChoice( "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; @@ -102,10 +104,22 @@ public static int Setup(string[] args, AbsolutePath rootDirectory, AbsolutePath 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( @@ -118,7 +132,7 @@ public static int Setup(string[] args, AbsolutePath rootDirectory, AbsolutePath ScriptDirectory = buildDirectory.GetWinRelativePathTo(WorkingDirectory), TargetFramework = TARGET_FRAMEWORK, TelemetryVersion = Telemetry.CurrentVersion, - NukeVersion = nukeVersion, + FalloutVersion = falloutVersion, }))); (buildDirectory / "Directory.Build.props").WriteAllLines(GetTemplate("Directory.Build.props")); @@ -176,12 +190,29 @@ 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; + } + + var projectElement = new XElement("Project", new XAttribute("Path", path)); + projectElement.Add(new XElement("Build", new XAttribute("Project", value: false))); + solutionElement.Add(projectElement); + } + internal static string[] GetTemplate(string templateName) { return ResourceUtility.GetResourceAllLines($"templates.{templateName}"); } - internal static void WriteBuildScripts( AbsolutePath scriptDirectory, AbsolutePath rootDirectory) diff --git a/src/Fallout.Cli/templates/_build.csproj b/src/Fallout.Cli/templates/_build.csproj index 54b6ef9a..9418f37a 100644 --- a/src/Fallout.Cli/templates/_build.csproj +++ b/src/Fallout.Cli/templates/_build.csproj @@ -9,10 +9,12 @@ _SCRIPT_DIRECTORY_ _TELEMETRY_VERSION_ false + false + false - + // GITVERSION diff --git a/tests/Fallout.Cli.Specs/UpdateSolutionFileContentSpecs.TestXml_number=1.verified.txt b/tests/Fallout.Cli.Specs/UpdateSolutionFileContentSpecs.TestXml_number=1.verified.txt new file mode 100644 index 00000000..74518468 --- /dev/null +++ b/tests/Fallout.Cli.Specs/UpdateSolutionFileContentSpecs.TestXml_number=1.verified.txt @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/tests/Fallout.Cli.Specs/UpdateSolutionFileContentSpecs.cs b/tests/Fallout.Cli.Specs/UpdateSolutionFileContentSpecs.cs index da9c5ccc..3bc159dc 100644 --- a/tests/Fallout.Cli.Specs/UpdateSolutionFileContentSpecs.cs +++ b/tests/Fallout.Cli.Specs/UpdateSolutionFileContentSpecs.cs @@ -1,6 +1,9 @@ using System; +using System.IO; using System.Linq; using System.Threading.Tasks; +using System.Xml; +using System.Xml.Linq; using Fallout.Common.Utilities; using VerifyXunit; using Xunit; @@ -70,4 +73,27 @@ public Task Test(int number, string input) return Verifier.Verify(string.Join(Environment.NewLine, content)) .UseParameters(number); } + + [Theory] + [InlineData( + 1, + """ + + + + """)] + public Task TestXml(int number, string input) + { + 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); + } }