Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/migration/from-nuke.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ If your build had previously worked against NUKE, it should now work against Fal
| Base interface name | `: INukeBuild` | `: IFalloutBuild` |
| MSBuild properties in `_build.csproj` | `<NukeRootDirectory>`, `<NukeTelemetryVersion>` | `<FalloutRootDirectory>`, `<FalloutTelemetryVersion>` |
| Bootstrap scripts | `dotnet nuke`, `NUKE_TELEMETRY_OPTOUT`, `.nuke/temp` | `dotnet fallout`, `FALLOUT_TELEMETRY_OPTOUT`, `.fallout/temp` |
| Removes stale Nuke Enterprise NuGet source | The whole env var check for `NUKE_ENTERPRISE_TOKEN` and its handling | The bootstrapper files (`build.sh` and `build.ps1`) without these `if`'s |
| Config directory | `.nuke/` | `.fallout/` (contents preserved) |

The 1:1 namespace prefix swap is the only structural change. Type names (other than `NukeBuild` / `INukeBuild`) keep their identifiers — `[Parameter]`, `[Solution]`, `[GitHubActions]`, `Solution`, `GitRepository`, etc. all stay the same.
Expand Down
1 change: 1 addition & 0 deletions src/Fallout.Migrate/Migration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ internal sealed class Migration(AbsolutePath rootDirectory, bool dryRun, TextWri
new BumpDotNetVersionStep(),
new RewriteCsFilesStep(),
new RewriteBootstrapScriptsStep(),
new CleanupBootstrapScriptsStep(),
new RenameNukeDirectoryStep()
];

Expand Down
62 changes: 62 additions & 0 deletions src/Fallout.Migrate/Steps/CleanupBootstrapScriptsStep.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Fallout.Common.IO;
using Fallout.Migrate.Common;

namespace Fallout.Migrate.Steps;

internal partial class CleanupBootstrapScriptsStep : IMigrationStep
{
private static readonly Regex nukeEnterprisePattern = new(@"\bNUKE_ENTERPRISE_TOKEN\b", RegexOptions.Compiled);

public Task ExecuteAsync(MigrationContext context, Summary summary)
{
foreach (var file in new[]
{
"build.sh",
"build.ps1"
})
{
var path = context.RootDirectory / file;
if (path.FileExists())
{
MigrationFileOperations.ApplyRewrite(context, path, Cleanup, summary);
}
}

return Task.CompletedTask;
}

internal static RewriteResult Cleanup(string content)
{
if (!nukeEnterprisePattern.IsMatch(content))
{
return new(content, 0);
}

string newline =
GetLineFeedRegex().Match(content).Value is { Length: > 0 } value
? value
: Environment.NewLine;

var lines = GetLineFeedRegex().Split(content).ToList();

var indexOfEnterpriseEnvVarCheck = lines.FindIndex(line => line.Contains("NUKE_ENTERPRISE_TOKEN"));
var endOfIfBlock = lines.FindIndex(indexOfEnterpriseEnvVarCheck,
line => line.Trim() == "}" || line.Trim() == "fi");

if (lines[endOfIfBlock + 1].Trim() == "")
{
endOfIfBlock++;
}

lines.RemoveRange(indexOfEnterpriseEnvVarCheck, endOfIfBlock - indexOfEnterpriseEnvVarCheck + 1);

return new(string.Join(newline, lines), 1);
}

[GeneratedRegex(@"\r\n|\n|\r")]
private static partial Regex GetLineFeedRegex();
}
8 changes: 8 additions & 0 deletions tests/Fallout.Migrate.Specs/MigrationIntegrationSpecs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public async Task MigratesVanillaConsumerRepo()
buildSh.Should().Contain("dotnet fallout");
buildSh.Should().Contain("FALLOUT_TELEMETRY_OPTOUT");
buildSh.Should().Contain(".fallout/temp");
buildSh.Should().NotContain("if [[ ! -z ${NUKE_ENTERPRISE_TOKEN+x} && \"$NUKE_ENTERPRISE_TOKEN\" != \"\" ]]; then");

// .nuke/ moved to .fallout/.
Directory.Exists(Path.Combine(temp, ".nuke")).Should().BeFalse();
Expand Down Expand Up @@ -182,6 +183,13 @@ class Build : NukeBuild
#!/usr/bin/env bash
export NUKE_TELEMETRY_OPTOUT=1
TEMP_DIRECTORY="$SCRIPT_DIR/.nuke/temp"
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 nuke "$@"
""", new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));

Expand Down
76 changes: 76 additions & 0 deletions tests/Fallout.Migrate.Specs/ScriptRewriterSpecs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,80 @@ public void LeavesPlainWordNukeAlone()
var result = ScriptRewriter.Rewrite(input);
result.EditCount.Should().Be(0);
}

[Fact]
public void Removes_Nuke_enterprise_unix_bootstrapper_leftovers()
{
const string input =
"""
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 -- "$@"
""";

var result = CleanupBootstrapScriptsStep.Cleanup(input);
result.EditCount.Should().Be(1);
result.Content.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 void Removes_Nuke_enterprise_windows_bootstrapper_leftovers()
{
const string input =
"""
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 }
""";

var result = CleanupBootstrapScriptsStep.Cleanup(input);
result.EditCount.Should().Be(1);
result.Content.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 void Leaves_bootstrapper_scripts_without_leftovers_alone()
{
const string input =
"""
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 -- "$@"
""";

var result = CleanupBootstrapScriptsStep.Cleanup(input);
result.EditCount.Should().Be(0);
result.Content.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 -- "$@"
""");
}
}
Loading