diff --git a/src/Fallout.Migrate/Steps/RewriteBootstrapScriptsStep.cs b/src/Fallout.Migrate/Steps/RewriteBootstrapScriptsStep.cs
index 1e1fb5df..741b118b 100644
--- a/src/Fallout.Migrate/Steps/RewriteBootstrapScriptsStep.cs
+++ b/src/Fallout.Migrate/Steps/RewriteBootstrapScriptsStep.cs
@@ -1,3 +1,4 @@
+using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Fallout.Common.IO;
using Fallout.Migrate.Common;
@@ -5,11 +6,30 @@
namespace Fallout.Migrate.Steps;
///
-/// Rewrites build.cmd, build.ps1, and build.sh at the repository root, when
-/// present, via .
+/// Rewrites bootstrap scripts (build.cmd/build.ps1/build.sh): dotnet nuke
+/// invocations, .nuke path references, and legacy NUKE_* environment variables become
+/// their Fallout equivalents.
///
internal sealed class RewriteBootstrapScriptsStep : IMigrationStep
{
+ /// The ordered find/replace patterns applied by .
+ private static readonly (Regex Pattern, string Replacement)[] patterns =
+ [
+ // Strip any telemetry opt-out line entirely — telemetry was removed from Fallout
+ // (ADR-0010), so there is nothing to opt out of. Handles bash `export`, PowerShell
+ // `$env:`, and cmd `set` spellings by matching the whole line. Runs before the
+ // env-var renames below so the line is gone rather than renamed to a dead variable.
+ (new Regex(@"^.*\b(?:NUKE|FALLOUT)_TELEMETRY_OPTOUT\b.*\r?\n?", RegexOptions.Compiled | RegexOptions.Multiline), ""),
+ // `dotnet nuke` invocations
+ (new Regex(@"\bdotnet\s+nuke\b", RegexOptions.Compiled), "dotnet fallout"),
+ // .nuke directory references → .fallout
+ (new Regex(@"(?<=[\\/.""'\s])\.nuke(?=[\\/""'\s])", RegexOptions.Compiled), ".fallout"),
+ // Legacy env vars (consumer-facing ones from P3.5c)
+ (new Regex(@"\bNUKE_GLOBAL_TOOL_VERSION\b", RegexOptions.Compiled), "FALLOUT_GLOBAL_TOOL_VERSION"),
+ (new Regex(@"\bNUKE_GLOBAL_TOOL_START_TIME\b", RegexOptions.Compiled), "FALLOUT_GLOBAL_TOOL_START_TIME"),
+ (new Regex(@"\bNUKE_INTERNAL_INTERCEPTOR\b", RegexOptions.Compiled), "FALLOUT_INTERNAL_INTERCEPTOR")
+ ];
+
///
public Task ExecuteAsync(MigrationContext context, Summary summary)
{
@@ -23,10 +43,32 @@ public Task ExecuteAsync(MigrationContext context, Summary summary)
var path = context.RootDirectory / name;
if (path.FileExists())
{
- MigrationFileOperations.ApplyRewrite(context, path, ScriptRewriter.Rewrite, summary);
+ MigrationFileOperations.ApplyRewrite(context, path, Rewrite, summary);
}
}
return Task.CompletedTask;
}
+
+ ///
+ /// Rewrites script content, applying every pattern in
+ /// in order.
+ ///
+ /// The original script file content.
+ /// The rewritten content and the number of edits made.
+ private static RewriteResult Rewrite(string original)
+ {
+ var edits = 0;
+ var content = original;
+ foreach (var (pattern, replacement) in patterns)
+ {
+ content = pattern.Replace(content, _ =>
+ {
+ edits++;
+ return replacement;
+ });
+ }
+
+ return new RewriteResult(content, edits);
+ }
}
diff --git a/src/Fallout.Migrate/Steps/RewriteCsFilesStep.cs b/src/Fallout.Migrate/Steps/RewriteCsFilesStep.cs
index 7c0bfbd7..2b6064b1 100644
--- a/src/Fallout.Migrate/Steps/RewriteCsFilesStep.cs
+++ b/src/Fallout.Migrate/Steps/RewriteCsFilesStep.cs
@@ -49,7 +49,7 @@ public Task ExecuteAsync(MigrationContext context, Summary summary)
///
/// The original .cs file content.
/// The rewritten content and the number of edits made.
- public static RewriteResult Rewrite(string original)
+ private static RewriteResult Rewrite(string original)
{
var edits = 0;
diff --git a/src/Fallout.Migrate/Steps/RewriteCsprojsStep.cs b/src/Fallout.Migrate/Steps/RewriteCsprojsStep.cs
index 37e98152..1d211826 100644
--- a/src/Fallout.Migrate/Steps/RewriteCsprojsStep.cs
+++ b/src/Fallout.Migrate/Steps/RewriteCsprojsStep.cs
@@ -80,7 +80,7 @@ public Task ExecuteAsync(MigrationContext context, Summary summary)
/// The original .csproj file content.
/// The Fallout version to pin into rewritten inline-versioned references.
/// The rewritten content and the number of edits made.
- public static RewriteResult Rewrite(string original, string falloutVersion)
+ private static RewriteResult Rewrite(string original, string falloutVersion)
{
var edits = 0;
var content = original;
diff --git a/src/Fallout.Migrate/Steps/ScriptRewriter.cs b/src/Fallout.Migrate/Steps/ScriptRewriter.cs
deleted file mode 100644
index 2e681a3c..00000000
--- a/src/Fallout.Migrate/Steps/ScriptRewriter.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-using System.Text.RegularExpressions;
-using Fallout.Migrate.Common;
-
-namespace Fallout.Migrate.Steps;
-
-///
-/// Rewrites bootstrap scripts (build.cmd/build.ps1/build.sh): dotnet nuke
-/// invocations, .nuke path references, and legacy NUKE_* environment variables become
-/// their Fallout equivalents. Driven by .
-///
-internal static class ScriptRewriter
-{
- /// The ordered find/replace patterns applied by .
- private static readonly (Regex Pattern, string Replacement)[] patterns =
- {
- // Strip any telemetry opt-out line entirely — telemetry was removed from Fallout
- // (ADR-0010), so there is nothing to opt out of. Handles bash `export`, PowerShell
- // `$env:`, and cmd `set` spellings by matching the whole line. Runs before the
- // env-var renames below so the line is gone rather than renamed to a dead variable.
- (new Regex(@"^.*\b(?:NUKE|FALLOUT)_TELEMETRY_OPTOUT\b.*\r?\n?", RegexOptions.Compiled | RegexOptions.Multiline), ""),
- // `dotnet nuke` invocations
- (new Regex(@"\bdotnet\s+nuke\b", RegexOptions.Compiled), "dotnet fallout"),
- // .nuke directory references → .fallout
- (new Regex(@"(?<=[\\/.""'\s])\.nuke(?=[\\/""'\s])", RegexOptions.Compiled), ".fallout"),
- // Legacy env vars (consumer-facing ones from P3.5c)
- (new Regex(@"\bNUKE_GLOBAL_TOOL_VERSION\b", RegexOptions.Compiled), "FALLOUT_GLOBAL_TOOL_VERSION"),
- (new Regex(@"\bNUKE_GLOBAL_TOOL_START_TIME\b", RegexOptions.Compiled), "FALLOUT_GLOBAL_TOOL_START_TIME"),
- (new Regex(@"\bNUKE_INTERNAL_INTERCEPTOR\b", RegexOptions.Compiled), "FALLOUT_INTERNAL_INTERCEPTOR"),
- };
-
- ///
- /// Rewrites script content, applying every pattern in
- /// in order.
- ///
- /// The original script file content.
- /// The rewritten content and the number of edits made.
- public static RewriteResult Rewrite(string original)
- {
- var edits = 0;
- var content = original;
- foreach (var (pattern, replacement) in patterns)
- {
- content = pattern.Replace(content, _ =>
- {
- edits++;
- return replacement;
- });
- }
-
- return new RewriteResult(content, edits);
- }
-}
diff --git a/tests/Fallout.Migrate.Specs/MigrationIntegrationSpecs.cs b/tests/Fallout.Migrate.Specs/MigrationIntegrationSpecs.cs
index 39cb6108..995a23ad 100644
--- a/tests/Fallout.Migrate.Specs/MigrationIntegrationSpecs.cs
+++ b/tests/Fallout.Migrate.Specs/MigrationIntegrationSpecs.cs
@@ -51,6 +51,12 @@ class Build : NukeBuild
#!/usr/bin/env bash
export NUKE_TELEMETRY_OPTOUT=1
TEMP_DIRECTORY="$SCRIPT_DIR/.nuke/temp"
+
+ if [[ ! -z ${NUKE_ENTERPRISE_TOKEN+x} && "$NUKE_ENTERPRISE_TOKEN" != "" ]]; then
+ "$DOTNET_EXE" nuget remove source "nuke-enterprise" &>/dev/null || true
+ "$DOTNET_EXE" nuget add source "https://f.feedz.io/nuke/enterprise/nuget" --name "nuke-enterprise" --username "PAT" --password "$NUKE_ENTERPRISE_TOKEN" --store-password-in-clear-text &>/dev/null || true
+ fi
+
dotnet nuke "$@"
""");
diff --git a/tests/Fallout.Migrate.Specs/RewriteBootstrapScriptsStepSpecs.cs b/tests/Fallout.Migrate.Specs/RewriteBootstrapScriptsStepSpecs.cs
new file mode 100644
index 00000000..4c847fc8
--- /dev/null
+++ b/tests/Fallout.Migrate.Specs/RewriteBootstrapScriptsStepSpecs.cs
@@ -0,0 +1,198 @@
+using System;
+using System.IO;
+using System.Threading.Tasks;
+using Fallout.Common.IO;
+using Fallout.Migrate.Common;
+using Fallout.Migrate.Steps;
+using FluentAssertions;
+using Xunit;
+
+namespace Fallout.Migrate.Specs;
+
+public class RewriteBootstrapScriptsStepSpecs : IDisposable
+{
+ private readonly AbsolutePath tempDirectory;
+ private readonly MigrationContext context;
+ private readonly Summary summary = new();
+
+ public RewriteBootstrapScriptsStepSpecs()
+ {
+ tempDirectory = AbsolutePath.Temp("fallout-migrate-test");
+ context = new MigrationContext(tempDirectory, dryRun: false, TextWriter.Null);
+ }
+
+ public void Dispose()
+ {
+ tempDirectory.DeleteDirectory();
+ }
+
+ [Fact]
+ public async Task Dotnet_nuke_invocations_become_dotnet_fallout()
+ {
+ (tempDirectory / "build.sh").WriteAllText("dotnet nuke Compile", eofLineBreak: false);
+
+ await new RewriteBootstrapScriptsStep().ExecuteAsync(context, summary);
+
+ summary.EditCount.Should().Be(1);
+ var buildSh = (tempDirectory / "build.sh").ReadAllText();
+ buildSh.Should().Be("dotnet fallout Compile");
+ }
+
+ [Fact]
+ public async Task Dot_nuke_directory_references_become_dot_fallout()
+ {
+ (tempDirectory / "build.sh").WriteAllText("""TEMP_DIRECTORY="$SCRIPT_DIR/.nuke/temp" """, eofLineBreak: false);
+
+ await new RewriteBootstrapScriptsStep().ExecuteAsync(context, summary);
+
+ summary.EditCount.Should().Be(1);
+ var buildSh = (tempDirectory / "build.sh").ReadAllText();
+ buildSh.Should().Contain(".fallout/temp");
+ buildSh.Should().NotContain(".nuke/");
+ }
+
+ [Fact]
+ public async Task Legacy_nuke_env_vars_are_renamed_to_their_fallout_equivalents()
+ {
+ (tempDirectory / "build.ps1").WriteAllText("""
+ $env:NUKE_GLOBAL_TOOL_VERSION = "10.0"
+ """, eofLineBreak: false);
+
+ await new RewriteBootstrapScriptsStep().ExecuteAsync(context, summary);
+
+ summary.EditCount.Should().Be(1);
+ var buildPs1 = (tempDirectory / "build.ps1").ReadAllText();
+ buildPs1.Should().Contain("FALLOUT_GLOBAL_TOOL_VERSION");
+ }
+
+ [Theory]
+ [InlineData("build.sh", "export NUKE_TELEMETRY_OPTOUT=1")] // build.sh
+ [InlineData("build.ps1", """$env:NUKE_TELEMETRY_OPTOUT = "1" """)] // build.ps1
+ [InlineData("build.cmd", "set NUKE_TELEMETRY_OPTOUT=1")] // build.cmd
+ public async Task Telemetry_opt_out_line_is_stripped_entirely(string fileName, string optOutLine)
+ {
+ // Telemetry was removed from Fallout (ADR-0010) — the opt-out is dropped, not renamed
+ // to a dead FALLOUT_TELEMETRY_OPTOUT. Whichever bootstrap script spelled it, the whole
+ // line goes and the surrounding ones are untouched.
+ var input = $"""
+ export DOTNET_ROLL_FORWARD="Major"
+ {optOutLine}
+ dotnet nuke "$@"
+ """;
+ (tempDirectory / fileName).WriteAllText(input, eofLineBreak: false);
+
+ await new RewriteBootstrapScriptsStep().ExecuteAsync(context, summary);
+
+ var content = (tempDirectory / fileName).ReadAllText();
+ content.Should().NotContain("TELEMETRY_OPTOUT");
+ content.Should().Contain("DOTNET_ROLL_FORWARD");
+ content.Should().Contain("dotnet fallout");
+ }
+
+ [Fact]
+ public async Task Plain_word_nuke_in_prose_is_left_alone()
+ {
+ // The word "nuke" in a comment or string isn't a command invocation.
+ (tempDirectory / "build.sh").WriteAllText("# This was previously a NUKE-based build.", eofLineBreak: false);
+
+ await new RewriteBootstrapScriptsStep().ExecuteAsync(context, summary);
+
+ summary.EditCount.Should().Be(0);
+ }
+
+ [Fact]
+ public async Task Removes_Nuke_enterprise_unix_bootstrapper_leftovers()
+ {
+ (tempDirectory / "build.sh").WriteAllText("""
+ echo "Microsoft (R) .NET SDK version $("$DOTNET_EXE" --version)"
+
+ if [[ ! -z ${NUKE_ENTERPRISE_TOKEN+x} && "$NUKE_ENTERPRISE_TOKEN" != "" ]]; then
+ "$DOTNET_EXE" nuget remove source "nuke-enterprise" &>/dev/null || true
+ "$DOTNET_EXE" nuget add source "https://f.feedz.io/nuke/enterprise/nuget" --name "nuke-enterprise" --username "PAT" --password "$NUKE_ENTERPRISE_TOKEN" --store-password-in-clear-text &>/dev/null || true
+ fi
+
+ "$DOTNET_EXE" build "$BUILD_PROJECT_FILE" /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet
+ "$DOTNET_EXE" run --project "$BUILD_PROJECT_FILE" --no-build -- "$@"
+ """, eofLineBreak: false);
+
+ await new CleanupBootstrapScriptsStep().ExecuteAsync(context, summary);
+
+ var buildSh = (tempDirectory / "build.sh").ReadAllText();
+ summary.EditCount.Should().Be(1);
+ buildSh.Should().Be(
+ """
+ echo "Microsoft (R) .NET SDK version $("$DOTNET_EXE" --version)"
+
+ "$DOTNET_EXE" build "$BUILD_PROJECT_FILE" /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet
+ "$DOTNET_EXE" run --project "$BUILD_PROJECT_FILE" --no-build -- "$@"
+ """);
+ }
+
+ [Fact]
+ public async Task Does_not_throw_when_Nuke_enterprise_check_is_last_in_file()
+ {
+ (tempDirectory / "build.sh").WriteAllText("""
+ if [[ ! -z ${NUKE_ENTERPRISE_TOKEN+x} && "$NUKE_ENTERPRISE_TOKEN" != "" ]]; then
+ "$DOTNET_EXE" nuget remove source "nuke-enterprise" &>/dev/null || true
+ "$DOTNET_EXE" nuget add source "https://f.feedz.io/nuke/enterprise/nuget" --name "nuke-enterprise" --username "PAT" --password "$NUKE_ENTERPRISE_TOKEN" --store-password-in-clear-text &>/dev/null || true
+ fi
+ """);
+
+ await new CleanupBootstrapScriptsStep().ExecuteAsync(context, summary);
+
+ var buildSh = (tempDirectory / "build.sh").ReadAllText();
+ summary.EditCount.Should().Be(1);
+ buildSh.Should().Be("");
+ }
+
+ [Fact]
+ public async Task Removes_Nuke_enterprise_windows_bootstrapper_leftovers()
+ {
+ (tempDirectory / "build.ps1").WriteAllText("""
+ Write-Output "Microsoft (R) .NET SDK version $(& $env:DOTNET_EXE --version)"
+
+ if (Test-Path env:NUKE_ENTERPRISE_TOKEN) {
+ & $env:DOTNET_EXE nuget remove source "nuke-enterprise" > $null
+ & $env:DOTNET_EXE nuget add source "https://f.feedz.io/nuke/enterprise/nuget" --name "nuke-enterprise" --username "PAT" --password $env:NUKE_ENTERPRISE_TOKEN > $null
+ }
+
+ ExecSafe { & $env:DOTNET_EXE build $BuildProjectFile /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet }
+ ExecSafe { & $env:DOTNET_EXE run --project $BuildProjectFile --no-build -- $BuildArguments }
+ """, eofLineBreak: false);
+
+ await new CleanupBootstrapScriptsStep().ExecuteAsync(context, summary);
+
+ var buildPs1 = (tempDirectory / "build.ps1").ReadAllText();
+ summary.EditCount.Should().Be(1);
+ buildPs1.Should().Be(
+ """
+ Write-Output "Microsoft (R) .NET SDK version $(& $env:DOTNET_EXE --version)"
+
+ ExecSafe { & $env:DOTNET_EXE build $BuildProjectFile /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet }
+ ExecSafe { & $env:DOTNET_EXE run --project $BuildProjectFile --no-build -- $BuildArguments }
+ """);
+ }
+
+ [Fact]
+ public async Task Leaves_bootstrapper_scripts_without_leftovers_alone()
+ {
+ (tempDirectory / "build.sh").WriteAllText("""
+ echo "Microsoft (R) .NET SDK version $("$DOTNET_EXE" --version)"
+
+ "$DOTNET_EXE" build "$BUILD_PROJECT_FILE" /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet
+ "$DOTNET_EXE" run --project "$BUILD_PROJECT_FILE" --no-build -- "$@"
+ """, eofLineBreak: false);
+
+ await new CleanupBootstrapScriptsStep().ExecuteAsync(context, summary);
+
+ var buildSh = (tempDirectory / "build.sh").ReadAllText();
+ summary.EditCount.Should().Be(0);
+ buildSh.Should().Be(
+ """
+ echo "Microsoft (R) .NET SDK version $("$DOTNET_EXE" --version)"
+
+ "$DOTNET_EXE" build "$BUILD_PROJECT_FILE" /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet
+ "$DOTNET_EXE" run --project "$BUILD_PROJECT_FILE" --no-build -- "$@"
+ """);
+ }
+}
diff --git a/tests/Fallout.Migrate.Specs/RewriteCsFilesStepSpecs.cs b/tests/Fallout.Migrate.Specs/RewriteCsFilesStepSpecs.cs
index 988cb16c..c98925c6 100644
--- a/tests/Fallout.Migrate.Specs/RewriteCsFilesStepSpecs.cs
+++ b/tests/Fallout.Migrate.Specs/RewriteCsFilesStepSpecs.cs
@@ -1,111 +1,160 @@
+using System;
+using System.IO;
+using System.Threading.Tasks;
+using Fallout.Common.IO;
+using Fallout.Migrate.Common;
+using Fallout.Migrate.Steps;
using FluentAssertions;
using Xunit;
-using Fallout.Migrate.Steps;
namespace Fallout.Migrate.Specs;
-public class RewriteCsFilesStepSpecs
+public class RewriteCsFilesStepSpecs : IDisposable
{
+ private readonly AbsolutePath tempDirectory;
+ private readonly MigrationContext context;
+ private readonly Summary summary = new();
+
+ public RewriteCsFilesStepSpecs()
+ {
+ tempDirectory = AbsolutePath.Temp("fallout-migrate-test");
+ context = new MigrationContext(tempDirectory, dryRun: false, TextWriter.Null);
+ }
+
+ public void Dispose()
+ {
+ tempDirectory.DeleteDirectory();
+ }
+
[Fact]
- public void RewritesUsingDirective()
+ public async Task Nuke_using_directives_are_rewritten_to_fallout()
{
- const string input = """
- using Nuke.Common;
- using Nuke.Common.IO;
- using Fallout.Common;
- """;
+ (tempDirectory / "Build.cs").WriteAllText("""
+ using Nuke.Common;
+ using Nuke.Common.IO;
+ using Fallout.Common;
+ """);
- var result = RewriteCsFilesStep.Rewrite(input);
+ await new RewriteCsFilesStep().ExecuteAsync(context, summary);
- result.EditCount.Should().Be(2);
- result.Content.Should().Contain("using Fallout.Common;");
- result.Content.Should().Contain("using Fallout.Common.IO;");
+ summary.EditCount.Should().Be(2);
+ var buildCs = (tempDirectory / "Build.cs").ReadAllText();
+ buildCs.Should().Contain("using Fallout.Common;");
+ buildCs.Should().Contain("using Fallout.Common.IO;");
}
[Fact]
- public void RewritesQualifiedTypeReference()
+ public async Task Qualified_nuke_type_references_are_rewritten_to_fallout()
{
- const string input = "var x = new Nuke.Common.Tools.DotNet.DotNetTasks();";
- var result = RewriteCsFilesStep.Rewrite(input);
- result.EditCount.Should().Be(1);
- result.Content.Should().Be("var x = new Fallout.Common.Tools.DotNet.DotNetTasks();");
+ (tempDirectory / "Build.cs").WriteAllText("var x = new Nuke.Common.Tools.DotNet.DotNetTasks();");
+
+ await new RewriteCsFilesStep().ExecuteAsync(context, summary);
+
+ summary.EditCount.Should().Be(1);
+ var buildCs = (tempDirectory / "Build.cs").ReadAllText().Trim();
+ buildCs.Should().Be("var x = new Fallout.Common.Tools.DotNet.DotNetTasks();");
}
[Fact]
- public void RewritesNukeBuildBaseType()
+ public async Task NukeBuild_base_type_is_renamed_to_FalloutBuild()
{
- const string input = "class Build : NukeBuild { }";
- var result = RewriteCsFilesStep.Rewrite(input);
- result.EditCount.Should().Be(1);
- result.Content.Should().Be("class Build : FalloutBuild { }");
+ (tempDirectory / "Build.cs").WriteAllText("class Build : NukeBuild { }");
+
+ await new RewriteCsFilesStep().ExecuteAsync(context, summary);
+
+ summary.EditCount.Should().Be(1);
+ var buildCs = (tempDirectory / "Build.cs").ReadAllText().Trim();
+ buildCs.Should().Be("class Build : FalloutBuild { }");
}
[Fact]
- public void RewritesINukeBuildInterface()
+ public async Task INukeBuild_interface_is_renamed_to_IFalloutBuild()
{
- const string input = "public static int IsApplicable(INukeBuild build) => 0;";
- var result = RewriteCsFilesStep.Rewrite(input);
- result.EditCount.Should().Be(1);
- result.Content.Should().Be("public static int IsApplicable(IFalloutBuild build) => 0;");
+ (tempDirectory / "Build.cs").WriteAllText("public static int IsApplicable(INukeBuild build) => 0;");
+
+ await new RewriteCsFilesStep().ExecuteAsync(context, summary);
+
+ summary.EditCount.Should().Be(1);
+ var buildCs = (tempDirectory / "Build.cs").ReadAllText().Trim();
+ buildCs.Should().Be("public static int IsApplicable(IFalloutBuild build) => 0;");
}
[Fact]
- public void DoesNotMatchNukeAsPartOfAnotherIdentifier()
+ public async Task Nuke_as_part_of_another_identifier_is_not_matched()
{
// A type like `NukeAdjacentThing` must not match `\bNukeBuild\b`.
const string input = "var x = new NukeBuilderXYZ();";
- var result = RewriteCsFilesStep.Rewrite(input);
- result.EditCount.Should().Be(0);
- result.Content.Should().Be(input);
+ (tempDirectory / "Build.cs").WriteAllText(input);
+
+ await new RewriteCsFilesStep().ExecuteAsync(context, summary);
+
+ summary.EditCount.Should().Be(0);
+ var buildCs = (tempDirectory / "Build.cs").ReadAllText().Trim();
+ buildCs.Should().Be(input);
}
[Fact]
- public void DoesNotMatchLowercaseNukePrefix()
+ public async Task Lowercase_nuke_prefix_in_a_path_is_not_matched()
{
// ".nuke/foo" filenames stay as-is — handled by ScriptRewriter / DirectoryRenamer.
const string input = """var path = "/repo/.nuke/parameters.json";""";
- var result = RewriteCsFilesStep.Rewrite(input);
- result.EditCount.Should().Be(0);
+ (tempDirectory / "Build.cs").WriteAllText(input);
+
+ await new RewriteCsFilesStep().ExecuteAsync(context, summary);
+
+ summary.EditCount.Should().Be(0);
}
[Fact]
- public void RewritesNukeProjectModelUsingToSolutions()
+ public async Task Nuke_project_model_using_is_rewritten_to_solutions()
{
// The solution types moved to Fallout.Solutions in v11 — a NUKE-era
// `using` must land there, not on the dead Fallout.Common.ProjectModel.
- const string input = "using Nuke.Common.ProjectModel;";
- var result = RewriteCsFilesStep.Rewrite(input);
- result.EditCount.Should().Be(1);
- result.Content.Should().Be("using Fallout.Solutions;");
+ (tempDirectory / "Build.cs").WriteAllText("using Nuke.Common.ProjectModel;");
+
+ await new RewriteCsFilesStep().ExecuteAsync(context, summary);
+
+ summary.EditCount.Should().Be(1);
+ var buildCs = (tempDirectory / "Build.cs").ReadAllText().Trim();
+ buildCs.Should().Be("using Fallout.Solutions;");
}
[Fact]
- public void RewritesQualifiedNukeProjectModelTypeToSolutions()
+ public async Task Qualified_nuke_project_model_type_is_rewritten_to_solutions()
{
- const string input = "Nuke.Common.ProjectModel.Solution x;";
- var result = RewriteCsFilesStep.Rewrite(input);
- result.EditCount.Should().Be(1);
- result.Content.Should().Be("Fallout.Solutions.Solution x;");
+ (tempDirectory / "Build.cs").WriteAllText("Nuke.Common.ProjectModel.Solution x;");
+
+ await new RewriteCsFilesStep().ExecuteAsync(context, summary);
+
+ summary.EditCount.Should().Be(1);
+ var buildCs = (tempDirectory / "Build.cs").ReadAllText().Trim();
+ buildCs.Should().Be("Fallout.Solutions.Solution x;");
}
[Fact]
- public void RewritesAlreadyPartiallyMigratedProjectModelNamespace()
+ public async Task Already_partially_migrated_project_model_namespace_is_salvaged()
{
// Code previously run through a prefix-only migrator lands on the dead
// Fallout.Common.ProjectModel; the ProjectModel rule salvages it.
- const string input = "using Fallout.Common.ProjectModel;";
- var result = RewriteCsFilesStep.Rewrite(input);
- result.EditCount.Should().Be(1);
- result.Content.Should().Be("using Fallout.Solutions;");
+ (tempDirectory / "Build.cs").WriteAllText("using Fallout.Common.ProjectModel;");
+
+ await new RewriteCsFilesStep().ExecuteAsync(context, summary);
+
+ summary.EditCount.Should().Be(1);
+ var buildCs = (tempDirectory / "Build.cs").ReadAllText().Trim();
+ buildCs.Should().Be("using Fallout.Solutions;");
}
[Fact]
- public void DoesNotMatchProjectModelAsPartOfAnotherIdentifier()
+ public async Task ProjectModel_as_part_of_another_identifier_is_not_truncated()
{
// `ProjectModelFoo` must not be truncated by the ProjectModel rule.
- const string input = "using Nuke.Common.ProjectModelFoo;";
- var result = RewriteCsFilesStep.Rewrite(input);
- result.EditCount.Should().Be(1);
- result.Content.Should().Be("using Fallout.Common.ProjectModelFoo;");
+ (tempDirectory / "Build.cs").WriteAllText("using Nuke.Common.ProjectModelFoo;");
+
+ await new RewriteCsFilesStep().ExecuteAsync(context, summary);
+
+ summary.EditCount.Should().Be(1);
+ var buildCs = (tempDirectory / "Build.cs").ReadAllText().Trim();
+ buildCs.Should().Be("using Fallout.Common.ProjectModelFoo;");
}
}
diff --git a/tests/Fallout.Migrate.Specs/RewriteCsprojsStepSpecs.cs b/tests/Fallout.Migrate.Specs/RewriteCsprojsStepSpecs.cs
index d3628111..4686d5b4 100644
--- a/tests/Fallout.Migrate.Specs/RewriteCsprojsStepSpecs.cs
+++ b/tests/Fallout.Migrate.Specs/RewriteCsprojsStepSpecs.cs
@@ -1,74 +1,101 @@
+using System;
+using System.IO;
+using System.Threading.Tasks;
+using Fallout.Common.IO;
+using Fallout.Migrate.Common;
+using Fallout.Migrate.Steps;
using FluentAssertions;
using Xunit;
-using Fallout.Migrate.Steps;
namespace Fallout.Migrate.Specs;
-public class RewriteCsprojsStepSpecs
+public class RewriteCsprojsStepSpecs : IDisposable
{
private const string TestFalloutVersion = "11.0.0";
- [Fact]
- public void Nuke_package_references_are_renamed_to_their_fallout_equivalents()
- {
- const string input = """
-
-
-
-
-
-
- """;
+ private readonly AbsolutePath tempDirectory;
+ private readonly MigrationContext context;
+ private readonly Summary summary = new();
- var result = RewriteCsprojsStep.Rewrite(input, TestFalloutVersion);
+ public RewriteCsprojsStepSpecs()
+ {
+ tempDirectory = AbsolutePath.Temp("fallout-migrate-test");
+ (tempDirectory / "build").CreateDirectory();
+ context = new MigrationContext(tempDirectory, dryRun: false, TextWriter.Null)
+ {
+ FalloutVersion = TestFalloutVersion
+ };
+ }
- result.EditCount.Should().Be(2);
- result.Content.Should().Contain(@"Include=""Fallout.Common""");
- result.Content.Should().Contain(@"Include=""Fallout.Components""");
- result.Content.Should().NotContain(@"Include=""Nuke.");
+ public void Dispose()
+ {
+ tempDirectory.DeleteDirectory();
}
[Fact]
- public void Nuke_root_directory_property_is_renamed()
+ public async Task Nuke_package_references_are_renamed_to_their_fallout_equivalents()
{
- const string input = """
-
-
- .\..
-
-
- """;
-
- var result = RewriteCsprojsStep.Rewrite(input, TestFalloutVersion);
+ (tempDirectory / "build" / "_build.csproj").WriteAllText("""
+
+
+
+
+
+
+ """);
+
+ await new RewriteCsprojsStep().ExecuteAsync(context, summary);
+
+ summary.EditCount.Should().Be(2);
+ var buildCsproj = (tempDirectory / "build" / "_build.csproj").ReadAllText();
+ buildCsproj.Should().Contain(@"Include=""Fallout.Common""");
+ buildCsproj.Should().Contain(@"Include=""Fallout.Components""");
+ buildCsproj.Should().NotContain(@"Include=""Nuke.");
+ }
- result.EditCount.Should().Be(2); // 1 opening + 1 closing tag
- result.Content.Should().Contain("");
- result.Content.Should().Contain("");
- result.Content.Should().NotContain("");
+ [Fact]
+ public async Task Nuke_root_directory_property_is_renamed()
+ {
+ (tempDirectory / "build" / "_build.csproj").WriteAllText("""
+
+
+ .\..
+
+
+ """);
+
+ await new RewriteCsprojsStep().ExecuteAsync(context, summary);
+
+ summary.EditCount.Should().Be(2); // 1 opening + 1 closing tag
+ var buildCsproj = (tempDirectory / "build" / "_build.csproj").ReadAllText();
+ buildCsproj.Should().Contain("");
+ buildCsproj.Should().Contain("");
+ buildCsproj.Should().NotContain("");
}
[Fact]
- public void Telemetry_version_property_is_stripped_instead_of_renamed()
+ public async Task Telemetry_version_property_is_stripped_instead_of_renamed()
{
// Telemetry was removed from Fallout (ADR-0010): NukeTelemetryVersion is dropped, not
// renamed to a dead FalloutTelemetryVersion. Sibling properties are left intact.
- const string input = """
-
-
- .\..
- 1
-
-
- """;
-
- var result = RewriteCsprojsStep.Rewrite(input, TestFalloutVersion);
-
- result.Content.Should().NotContain("TelemetryVersion");
- result.Content.Should().Contain("");
+ (tempDirectory / "build" / "_build.csproj").WriteAllText("""
+
+
+ .\..
+ 1
+
+
+ """);
+
+ await new RewriteCsprojsStep().ExecuteAsync(context, summary);
+
+ var buildCsproj = (tempDirectory / "build" / "_build.csproj").ReadAllText();
+ buildCsproj.Should().NotContain("TelemetryVersion");
+ buildCsproj.Should().Contain("");
}
[Fact]
- public void Unrelated_nuke_prefixed_properties_are_left_alone()
+ public async Task Unrelated_nuke_prefixed_properties_are_left_alone()
{
const string input = """
@@ -77,15 +104,17 @@ public void Unrelated_nuke_prefixed_properties_are_left_alone()
""";
+ (tempDirectory / "build" / "_build.csproj").WriteAllText(input, eofLineBreak: false);
- var result = RewriteCsprojsStep.Rewrite(input, TestFalloutVersion);
+ await new RewriteCsprojsStep().ExecuteAsync(context, summary);
- result.EditCount.Should().Be(0);
- result.Content.Should().Be(input);
+ summary.EditCount.Should().Be(0);
+ var buildCsproj = (tempDirectory / "build" / "_build.csproj").ReadAllText();
+ buildCsproj.Should().Be(input);
}
[Fact]
- public void Content_without_nuke_references_is_returned_unchanged()
+ public async Task Content_without_nuke_references_is_returned_unchanged()
{
const string input = """
@@ -94,95 +123,103 @@ public void Content_without_nuke_references_is_returned_unchanged()
""";
+ (tempDirectory / "build" / "_build.csproj").WriteAllText(input, eofLineBreak: false);
- var result = RewriteCsprojsStep.Rewrite(input, TestFalloutVersion);
+ await new RewriteCsprojsStep().ExecuteAsync(context, summary);
- result.EditCount.Should().Be(0);
- result.Content.Should().Be(input);
+ summary.EditCount.Should().Be(0);
+ var buildCsproj = (tempDirectory / "build" / "_build.csproj").ReadAllText();
+ buildCsproj.Should().Be(input);
}
[Fact]
- public void Inline_nuke_package_versions_are_bumped_to_the_current_fallout_version()
+ public async Task Inline_nuke_package_versions_are_bumped_to_the_current_fallout_version()
{
// Regression guard for #217: NUKE-era pins like 10.1.0 never existed as Fallout.X
// and would trip NU1603 on the migrated project. Migrate must bump in the same pass.
- const string input = """
-
-
-
-
-
-
- """;
-
- var result = RewriteCsprojsStep.Rewrite(input, TestFalloutVersion);
-
- result.Content.Should().Contain(@"Include=""Fallout.Common"" Version=""11.0.0""");
- result.Content.Should().Contain(@"Include=""Fallout.Components"" Version=""11.0.0""");
- result.Content.Should().NotContain(@"Version=""10.1.0""");
+ (tempDirectory / "build" / "_build.csproj").WriteAllText("""
+
+
+
+
+
+
+ """);
+
+ await new RewriteCsprojsStep().ExecuteAsync(context, summary);
+
+ var buildCsproj = (tempDirectory / "build" / "_build.csproj").ReadAllText();
+ buildCsproj.Should().Contain(@"Include=""Fallout.Common""");
+ buildCsproj.Should().Contain(@"Include=""Fallout.Components""");
+ buildCsproj.Should().NotContain(@"Version=""10.1.0""");
+ buildCsproj.Should().Contain($@"Version=""{TestFalloutVersion}""");
}
[Fact]
- public void Version_is_bumped_across_extra_attributes_between_include_and_version()
+ public async Task Version_is_bumped_across_extra_attributes_between_include_and_version()
{
// PrivateAssets / IncludeAssets are common NUKE-era attributes that sit between
// Include and Version. The combined-rewrite pattern needs to tolerate them.
- const string input = """
-
-
-
-
-
- """;
-
- var result = RewriteCsprojsStep.Rewrite(input, TestFalloutVersion);
-
- result.Content.Should().Contain(@"Include=""Fallout.Common"" PrivateAssets=""all"" Version=""11.0.0""");
+ (tempDirectory / "build" / "_build.csproj").WriteAllText("""
+
+
+
+
+
+ """);
+
+ await new RewriteCsprojsStep().ExecuteAsync(context, summary);
+
+ var buildCsproj = (tempDirectory / "build" / "_build.csproj").ReadAllText();
+ buildCsproj.Should().Contain(@"Include=""Fallout.Common"" PrivateAssets=""all""");
+ buildCsproj.Should().NotContain(@"Version=""10.1.0""");
}
[Fact]
- public void Centrally_managed_references_do_not_gain_an_inline_version()
+ public async Task Centrally_managed_references_do_not_gain_an_inline_version()
{
// Central package management — no inline Version attribute, version lives in
// Directory.Packages.props. The namespace-only pass still renames Nuke. → Fallout.
// but we must NOT inject a Version where there wasn't one.
- const string input = """
-
-
-
-
-
- """;
-
- var result = RewriteCsprojsStep.Rewrite(input, TestFalloutVersion);
-
- result.Content.Should().Contain(@"");
- result.Content.Should().NotContain(@"Version=");
+ (tempDirectory / "build" / "_build.csproj").WriteAllText("""
+
+
+
+
+
+ """);
+
+ await new RewriteCsprojsStep().ExecuteAsync(context, summary);
+
+ var buildCsproj = (tempDirectory / "build" / "_build.csproj").ReadAllText();
+ buildCsproj.Should().Contain(@"");
+ buildCsproj.Should().NotContain("Version=");
}
[Fact]
- public void Conflicting_system_security_cryptography_xml_pin_is_stripped()
+ public async Task Conflicting_system_security_cryptography_xml_pin_is_stripped()
{
// #217: NUKE-era projects often carry an explicit System.Security.Cryptography.Xml pin
// that conflicts with Fallout.Common's transitive >= 10.0.6 requirement (NU1605 downgrade).
// Removing the explicit pin lets the transitive version win.
- const string input = """
-
-
-
-
-
-
- """;
-
- var result = RewriteCsprojsStep.Rewrite(input, TestFalloutVersion);
-
- result.Content.Should().NotContain("System.Security.Cryptography.Xml");
- result.Content.Should().Contain(@"Include=""Fallout.Common"" Version=""11.0.0""");
+ (tempDirectory / "build" / "_build.csproj").WriteAllText("""
+
+
+
+
+
+
+ """);
+
+ await new RewriteCsprojsStep().ExecuteAsync(context, summary);
+
+ var buildCsproj = (tempDirectory / "build" / "_build.csproj").ReadAllText();
+ buildCsproj.Should().NotContain("System.Security.Cryptography.Xml");
+ buildCsproj.Should().Contain(@"Include=""Fallout.Common""");
}
[Fact]
- public void Other_system_packages_are_left_alone()
+ public async Task Other_system_packages_are_left_alone()
{
// Only System.Security.Cryptography.Xml is the known culprit. Other System.* packages
// (System.Text.Json etc.) stay as the user pinned them — they're not in any known
@@ -195,10 +232,12 @@ public void Other_system_packages_are_left_alone()
""";
+ (tempDirectory / "build" / "_build.csproj").WriteAllText(input, eofLineBreak: false);
- var result = RewriteCsprojsStep.Rewrite(input, TestFalloutVersion);
+ await new RewriteCsprojsStep().ExecuteAsync(context, summary);
- result.EditCount.Should().Be(0);
- result.Content.Should().Be(input);
+ summary.EditCount.Should().Be(0);
+ var buildCsproj = (tempDirectory / "build" / "_build.csproj").ReadAllText();
+ buildCsproj.Should().Be(input);
}
}
diff --git a/tests/Fallout.Migrate.Specs/ScriptRewriterSpecs.cs b/tests/Fallout.Migrate.Specs/ScriptRewriterSpecs.cs
deleted file mode 100644
index 53a912ca..00000000
--- a/tests/Fallout.Migrate.Specs/ScriptRewriterSpecs.cs
+++ /dev/null
@@ -1,191 +0,0 @@
-using System;
-using System.IO;
-using System.Threading.Tasks;
-using Fallout.Migrate.Common;
-using FluentAssertions;
-using Xunit;
-using Fallout.Migrate.Steps;
-
-namespace Fallout.Migrate.Specs;
-
-public class ScriptRewriterSpecs
-{
- [Fact]
- public void Dotnet_nuke_invocations_become_dotnet_fallout()
- {
- var result = ScriptRewriter.Rewrite("dotnet nuke Compile");
- result.EditCount.Should().Be(1);
- result.Content.Should().Be("dotnet fallout Compile");
- }
-
- [Fact]
- public void Dot_nuke_directory_references_become_dot_fallout()
- {
- var result = ScriptRewriter.Rewrite("""TEMP_DIRECTORY="$SCRIPT_DIR/.nuke/temp" """);
- result.EditCount.Should().Be(1);
- result.Content.Should().Contain(".fallout/temp");
- result.Content.Should().NotContain(".nuke/");
- }
-
- [Fact]
- public void Legacy_nuke_env_vars_are_renamed_to_their_fallout_equivalents()
- {
- const string input = """
- $env:NUKE_GLOBAL_TOOL_VERSION = "10.0"
- """;
-
- var result = ScriptRewriter.Rewrite(input);
- result.EditCount.Should().Be(1);
- result.Content.Should().Contain("FALLOUT_GLOBAL_TOOL_VERSION");
- }
-
- [Theory]
- [InlineData("export NUKE_TELEMETRY_OPTOUT=1")] // build.sh
- [InlineData("""$env:NUKE_TELEMETRY_OPTOUT = "1" """)] // build.ps1
- [InlineData("set NUKE_TELEMETRY_OPTOUT=1")] // build.cmd
- public void Telemetry_opt_out_line_is_stripped_entirely(string optOutLine)
- {
- // Telemetry was removed from Fallout (ADR-0010) — the opt-out is dropped, not renamed
- // to a dead FALLOUT_TELEMETRY_OPTOUT. Whichever bootstrap script spelled it, the whole
- // line goes and the surrounding ones are untouched.
- var input = $"""
- export DOTNET_ROLL_FORWARD="Major"
- {optOutLine}
- dotnet nuke "$@"
- """;
-
- var result = ScriptRewriter.Rewrite(input);
-
- result.Content.Should().NotContain("TELEMETRY_OPTOUT");
- result.Content.Should().Contain("DOTNET_ROLL_FORWARD");
- result.Content.Should().Contain("dotnet fallout");
- }
-
- [Fact]
- public void Plain_word_nuke_in_prose_is_left_alone()
- {
- // The word "nuke" in a comment or string isn't a command invocation.
- const string input = "# This was previously a NUKE-based build.";
- var result = ScriptRewriter.Rewrite(input);
- result.EditCount.Should().Be(0);
- }
-
- [Fact]
- public async Task Removes_Nuke_enterprise_unix_bootstrapper_leftovers()
- {
- var filename = "build.sh";
- var dir = CreateBootstrapScript(filename, """
- echo "Microsoft (R) .NET SDK version $("$DOTNET_EXE" --version)"
-
- if [[ ! -z ${NUKE_ENTERPRISE_TOKEN+x} && "$NUKE_ENTERPRISE_TOKEN" != "" ]]; then
- "$DOTNET_EXE" nuget remove source "nuke-enterprise" &>/dev/null || true
- "$DOTNET_EXE" nuget add source "https://f.feedz.io/nuke/enterprise/nuget" --name "nuke-enterprise" --username "PAT" --password "$NUKE_ENTERPRISE_TOKEN" --store-password-in-clear-text &>/dev/null || true
- fi
-
- "$DOTNET_EXE" build "$BUILD_PROJECT_FILE" /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet
- "$DOTNET_EXE" run --project "$BUILD_PROJECT_FILE" --no-build -- "$@"
- """);
-
- Summary summary = await ExecuteMigrationStep(dir);
-
- var buildSh = await File.ReadAllTextAsync(Path.Combine(dir, filename));
- summary.EditCount.Should().Be(1);
- buildSh.Should().Be(
- """
- echo "Microsoft (R) .NET SDK version $("$DOTNET_EXE" --version)"
-
- "$DOTNET_EXE" build "$BUILD_PROJECT_FILE" /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet
- "$DOTNET_EXE" run --project "$BUILD_PROJECT_FILE" --no-build -- "$@"
- """);
- }
-
- [Fact]
- public async Task Does_not_throw_when_Nuke_enterprise_check_is_last_in_file()
- {
- var filename = "build.sh";
- var dir = CreateBootstrapScript(filename,"""
- if [[ ! -z ${NUKE_ENTERPRISE_TOKEN+x} && "$NUKE_ENTERPRISE_TOKEN" != "" ]]; then
- "$DOTNET_EXE" nuget remove source "nuke-enterprise" &>/dev/null || true
- "$DOTNET_EXE" nuget add source "https://f.feedz.io/nuke/enterprise/nuget" --name "nuke-enterprise" --username "PAT" --password "$NUKE_ENTERPRISE_TOKEN" --store-password-in-clear-text &>/dev/null || true
- fi
- """);
-
- Summary summary = await ExecuteMigrationStep(dir);
-
- var buildSh = await File.ReadAllTextAsync(Path.Combine(dir, filename));
- summary.EditCount.Should().Be(1);
- buildSh.Should().Be("");
- }
-
- [Fact]
- public async Task Removes_Nuke_enterprise_windows_bootstrapper_leftovers()
- {
- var filename = "build.ps1";
- var dir = CreateBootstrapScript(filename,"""
- Write-Output "Microsoft (R) .NET SDK version $(& $env:DOTNET_EXE --version)"
-
- if (Test-Path env:NUKE_ENTERPRISE_TOKEN) {
- & $env:DOTNET_EXE nuget remove source "nuke-enterprise" > $null
- & $env:DOTNET_EXE nuget add source "https://f.feedz.io/nuke/enterprise/nuget" --name "nuke-enterprise" --username "PAT" --password $env:NUKE_ENTERPRISE_TOKEN > $null
- }
-
- ExecSafe { & $env:DOTNET_EXE build $BuildProjectFile /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet }
- ExecSafe { & $env:DOTNET_EXE run --project $BuildProjectFile --no-build -- $BuildArguments }
- """);
-
- Summary summary = await ExecuteMigrationStep(dir);
-
- var buildPs1 = await File.ReadAllTextAsync(Path.Combine(dir, filename));
- summary.EditCount.Should().Be(1);
- buildPs1.Should().Be(
- """
- Write-Output "Microsoft (R) .NET SDK version $(& $env:DOTNET_EXE --version)"
-
- ExecSafe { & $env:DOTNET_EXE build $BuildProjectFile /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet }
- ExecSafe { & $env:DOTNET_EXE run --project $BuildProjectFile --no-build -- $BuildArguments }
- """);
- }
-
- [Fact]
- public async Task Leaves_bootstrapper_scripts_without_leftovers_alone()
- {
- var filename = "build.sh";
- var dir = CreateBootstrapScript(filename,"""
- echo "Microsoft (R) .NET SDK version $("$DOTNET_EXE" --version)"
-
- "$DOTNET_EXE" build "$BUILD_PROJECT_FILE" /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet
- "$DOTNET_EXE" run --project "$BUILD_PROJECT_FILE" --no-build -- "$@"
- """);
-
- Summary summary = await ExecuteMigrationStep(dir);
-
- var buildSh = await File.ReadAllTextAsync(Path.Combine(dir, filename));
- summary.EditCount.Should().Be(0);
- buildSh.Should().Be(
- """
- echo "Microsoft (R) .NET SDK version $("$DOTNET_EXE" --version)"
-
- "$DOTNET_EXE" build "$BUILD_PROJECT_FILE" /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet
- "$DOTNET_EXE" run --project "$BUILD_PROJECT_FILE" --no-build -- "$@"
- """);
- }
-
- private string CreateBootstrapScript(string bootstrapFile, string bootstrapFileConent)
- {
- var dir = Path.Combine(Path.GetTempPath(), "fallout-migrate-test-" + Guid.NewGuid().ToString("N")[..8]);
- Directory.CreateDirectory(dir);
-
- File.WriteAllText(Path.Combine(dir, bootstrapFile), bootstrapFileConent);
-
- return dir;
- }
-
- private static async Task ExecuteMigrationStep(string dir)
- {
- var step = new CleanupBootstrapScriptsStep();
- var summary = new Summary();
- await step.ExecuteAsync(new MigrationContext(dir, false, TextWriter.Null), summary);
- return summary;
- }
-
-}