Convert remaining Fallout.Cli commands to IFalloutCommand dispatch (#392)#476
Merged
ChrisonSimtian merged 11 commits intoJul 18, 2026
Merged
Conversation
ITaluone
requested changes
Jul 14, 2026
ITaluone
approved these changes
Jul 15, 2026
ChrisonSimtian
marked this pull request as ready for review
July 15, 2026 09:21
ITaluone
requested changes
Jul 15, 2026
Collaborator
|
Found one little quirck :D |
ChrisonSimtian
force-pushed
the
cli-command-dispatch
branch
from
July 18, 2026 11:53
03e2abb to
1fb7d42
Compare
Extract Program.Trigger into a real IFalloutCommand (async ExecuteAsync per the merged foundation contract), register the type directly, and drop the DelegateCommand shim + the Program.Trigger.cs partial. Test re-homed to Fallout.Cli.Specs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract the shared logic the converted commands depend on into injectable services: ConfigurationReader (build-script config parsing), PackageManager (package add/replace), BuildScaffolder (build scripts/solution wiring, incl. the .slnx writer), CakeConverter (Cake script conversion), and CliConventions/ToolBanner (banner + script-name helpers). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fallout-build#392) Convert complete, get-configuration, add-package, update, secrets, cake-convert, cake-clean, setup, and the navigation cluster into real IFalloutCommand types (async ExecuteAsync, DI-injected services), register them directly, and delete the DelegateCommand shims + every Program.X.cs partial. Program is now a thin entry point (DI wiring + root resolution). Commands and new CLI interfaces are internal, matching the merged foundation. Derived from main's current handlers, so the .slnx setup support, net10.0 target, and nuke->fallout rebrand are preserved. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add async specs for the converted commands (Fallout.Cli.Specs/Commands, *Specs naming) plus a FakeConsolePrompts double and ConfigurationReader specs, and repoint the existing CakeConversion / UpdateSolutionFileContent specs at their new service homes (CakeConverter, PackageManager, BuildScaffolder). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
AddPackage, CakeConvert and Setup did real async work (NuGet version resolution, nested command invocation) but blocked on it via .GetAwaiter().GetResult() inside a synchronous Execute wrapped in Task.FromResult. Fold the private Execute into an async ExecuteAsync and await the work directly, removing the sync-over-async anti-pattern. Purely-sync commands keep Task.FromResult(Execute(...)) — they have no async work to await. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The new command specs used Method_State_Result names; the repo convention (docs/agents/conventions.md, AV1600) is short present-tense descriptions of observable behavior. Rename all command spec methods to match. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The last sync-over-async in the command layer sat in ProjectUpdater, reached from UpdateCommand via the synchronous ConfirmExecution(Action) prompt boundary. ConfirmExecution is a hand-rolled helper (not a Spectre primitive), so add a Func<Task> overload alongside the Action one and flow async through: - IConsolePrompts.ConfirmExecutionAsync + SpectreConsolePrompts impl - ProjectUpdater.Update -> async UpdateAsync (out param becomes a return) - UpdateCommand.UpdateBuildProject -> UpdateBuildProjectAsync, folded into a genuine async ExecuteAsync The genuinely-sync update steps (build scripts, config file, global.json) stay on the sync ConfirmExecution overload. No .GetAwaiter().GetResult() remains in the command layer. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The migrated commands are all `internal sealed`, but three types were still `public` with no consumer outside the assembly and no PublicAPI tracking: RunCommand (the lone public command), ProjectUpdater, and Program (the tool entry point). None are part of a public surface — there is no public command SDK yet (that's milestone #7). Make them internal to match the rest of the command set. Fallout.Cli.Specs already has InternalsVisibleTo, so the specs are unaffected; DI registration works unchanged with internal types. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The build-project update logic lived in a separate static ProjectUpdater helper, splitting the update command's behaviour across two files for no reason. Move it into UpdateCommand as private methods so the command owns its own logic, and delete ProjectUpdater. Also drops the stale "Nuke" name (UpdateNukeCommonPackage -> UpdateFalloutCommonPackage). No behaviour change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The :update command's build-project step reset TargetFramework to net8.0, which can't restore Fallout.Common or resolve its namespaces — the framework targets net10.0. SetupCommand already scaffolds new projects at net10.0 (TARGET_FRAMEWORK), so update now matches. Centralizing the target-framework literal (SetupCommand + UpdateCommand share "net10.0") is deferred to a dedicated cleanup PR. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The net8.0 bug slipped through because the build-project update path had no spec. Add one: parse a project pinned to an old TargetFramework, run the retarget, assert it lands on net10.0. Guards the literal from drifting again. UpdateTargetFramework is now internal (Fallout.Cli.Specs already has IVT) and Cli.Specs gets the ProjectModel MSBuild-resolver ModuleInit so a test can hold a Microsoft.Build.Evaluation.Project local. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ChrisonSimtian
force-pushed
the
cli-command-dispatch
branch
from
July 18, 2026 12:03
1fb7d42 to
75499c5
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Second step of the
Fallout.Clicommand-dispatch migration (#392). Builds on the merged foundation (#448); supersedes fork-only PRs #17–#26, which were collapsed into one and re-authored against the current (async/internal) contract.Converts the remaining legacy
Program.Xhandlers into realIFalloutCommandtypes and reducesProgramto a thin entry point.What
complete,get-configuration,add-package,update,secrets,cake-convert,cake-clean,setup, and thenavigationcluster → real command types (ExecuteAsync, DI-injected services)ConfigurationReader,PackageManager,BuildScaffolder,CakeConverter,CliConventionsDelegateCommandshims + everyProgram.X.cspartialFallout.Cli.Specs(async); existing specs repointed to the new service homesNot breaking / no regressions
Derived from
main's current handlers, so these are preserved:.slnxsetup support,net10.0target, the_FALLOUT_VERSION_template token, and the nuke→fallout rebrand.Fallout.Cli.Specs46/46 green; runtime dispatch verified (all 15 commands resolve via DI).Notes
Programregistration + config services couple the commands (CakeConvertdepends onSetupCommand), so it lands as 4 logical commits.Task.FromResult(...)(as the existingDelegateCommanddid); only genuinely async work is truly async.🤖 Generated with Claude Code