From c09887d70002357e654c8a03fa3cf34446d86757 Mon Sep 17 00:00:00 2001 From: Chrison Simtian Date: Wed, 17 Jun 2026 21:54:33 +1200 Subject: [PATCH 1/2] Convert :trigger to TriggerCommand Lift the trigger handler off Program into a standalone IFalloutCommand type and register it directly, replacing its transitional DelegateCommand adapter. Part of the #392 incremental conversion; deletes Program.Trigger.cs. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../TriggerCommand.cs} | 13 ++++++++----- src/Fallout.Cli/Program.cs | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) rename src/Fallout.Cli/{Program.Trigger.cs => Commands/TriggerCommand.cs} (67%) diff --git a/src/Fallout.Cli/Program.Trigger.cs b/src/Fallout.Cli/Commands/TriggerCommand.cs similarity index 67% rename from src/Fallout.Cli/Program.Trigger.cs rename to src/Fallout.Cli/Commands/TriggerCommand.cs index 1497e5626..e0d5deb47 100644 --- a/src/Fallout.Cli/Program.Trigger.cs +++ b/src/Fallout.Cli/Commands/TriggerCommand.cs @@ -1,16 +1,19 @@ -using System; -using System.Linq; using Fallout.Common; using Fallout.Common.Git; using Fallout.Common.IO; using Fallout.Common.Tools.Git; using Fallout.Common.Utilities; -namespace Fallout.Cli; +namespace Fallout.Cli.Commands; -partial class Program +/// +/// fallout :trigger: pushes an empty commit with the given message to trigger a remote build. +/// +public sealed class TriggerCommand : IFalloutCommand { - public static int Trigger(string[] args, AbsolutePath rootDirectory, AbsolutePath buildScript) + public string Name => "trigger"; + + public int Execute(string[] args, AbsolutePath rootDirectory, AbsolutePath buildScript) { var repository = GitRepository.FromLocalDirectory(rootDirectory.NotNull()).NotNull("No Git repository"); Assert.NotNull(repository.Branch, "Git repository must not be detached"); diff --git a/src/Fallout.Cli/Program.cs b/src/Fallout.Cli/Program.cs index 0ce3d7e55..25c5839e1 100644 --- a/src/Fallout.Cli/Program.cs +++ b/src/Fallout.Cli/Program.cs @@ -53,6 +53,7 @@ private static void RegisterCommands(IServiceCollection services) { // Real command types — issue #392 converts one legacy handler per PR. services.AddSingleton(); + services.AddSingleton(); // Legacy handlers still living on Program, adapted until they are extracted into command // types. Each conversion deletes one line here plus its Program.X.cs partial. @@ -64,7 +65,6 @@ private static void RegisterCommands(IServiceCollection services) services.AddSingleton(new DelegateCommand("complete", Complete)); services.AddSingleton(new DelegateCommand("get-configuration", GetConfiguration)); services.AddSingleton(new DelegateCommand("secrets", Secrets)); - services.AddSingleton(new DelegateCommand("trigger", Trigger)); services.AddSingleton(new DelegateCommand("GetNextDirectory", GetNextDirectory)); services.AddSingleton(new DelegateCommand("PopDirectory", PopDirectory)); services.AddSingleton(new DelegateCommand("PushWithCurrentRootDirectory", PushWithCurrentRootDirectory)); From 1161bf2e37e09b610b134607412509f67fae2540 Mon Sep 17 00:00:00 2001 From: Chrison Simtian Date: Wed, 17 Jun 2026 22:29:35 +1200 Subject: [PATCH 2/2] Add tests for TriggerCommand Name resolution and the "outside a Git repository" guard. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../Commands/TriggerCommandTests.cs | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 tests/Fallout.Cli.Tests/Commands/TriggerCommandTests.cs diff --git a/tests/Fallout.Cli.Tests/Commands/TriggerCommandTests.cs b/tests/Fallout.Cli.Tests/Commands/TriggerCommandTests.cs new file mode 100644 index 000000000..2426f6e8b --- /dev/null +++ b/tests/Fallout.Cli.Tests/Commands/TriggerCommandTests.cs @@ -0,0 +1,34 @@ +using System; +using System.IO; +using Fallout.Cli.Commands; +using Fallout.Common.IO; +using FluentAssertions; +using Xunit; + +namespace Fallout.Cli.Tests.Commands; + +public class TriggerCommandTests +{ + [Fact] + public void Name_IsTrigger() + => new TriggerCommand().Name.Should().Be("trigger"); + + [Fact] + public void Execute_OutsideGitRepository_Throws() + { + var dir = (AbsolutePath)Path.Combine(Path.GetTempPath(), "fallout-trigger-" + Guid.NewGuid().ToString("N")); + dir.CreateDirectory(); + try + { + var action = () => new TriggerCommand().Execute(["a message"], dir, buildScript: null); + + // No resolvable Git repository at a throwaway temp dir → the command fails rather than + // pushing anything. + action.Should().Throw(); + } + finally + { + Directory.Delete(dir, recursive: true); + } + } +}