Add source-generated Program entry point when no Main() is defined#183
Conversation
…sing Agent-Logs-Url: https://github.com/Tyrrrz/CliFx/sessions/d4116155-0df6-4e2a-af8a-ab8aa293e01f Co-authored-by: Tyrrrz <1935960+Tyrrrz@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Tyrrrz/CliFx/sessions/d4116155-0df6-4e2a-af8a-ab8aa293e01f Co-authored-by: Tyrrrz <1935960+Tyrrrz@users.noreply.github.com>
|
@copilot we probably don't need to check whether there's at least one command. Also, this new generator can be separate from the existing one. Maybe move the emitters out of partials into separate classes to make things cleaner. |
…view feedback Agent-Logs-Url: https://github.com/Tyrrrz/CliFx/sessions/c8ac7a8c-f53a-42be-a580-605b97c8d33e Co-authored-by: Tyrrrz <1935960+Tyrrrz@users.noreply.github.com>
Done in 14cbdc6:
|
Agent-Logs-Url: https://github.com/Tyrrrz/CliFx/sessions/b649e59d-21ac-4d76-a6fa-e2ac386b7b9a Co-authored-by: Tyrrrz <1935960+Tyrrrz@users.noreply.github.com>
…t API Agent-Logs-Url: https://github.com/Tyrrrz/CliFx/sessions/7a87bfaf-1c6d-423f-8ac2-a7034f3bbc6f Co-authored-by: Tyrrrz <1935960+Tyrrrz@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Tyrrrz/CliFx/sessions/d1c423e0-f923-4f7d-a6b4-58e9a56e4f9a Co-authored-by: Tyrrrz <1935960+Tyrrrz@users.noreply.github.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## prime #183 +/- ##
==========================================
+ Coverage 88.26% 88.48% +0.21%
==========================================
Files 77 79 +2
Lines 2326 2370 +44
Branches 293 295 +2
==========================================
+ Hits 2053 2097 +44
Misses 203 203
Partials 70 70 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Agent-Logs-Url: https://github.com/Tyrrrz/CliFx/sessions/41569876-500a-47ae-9a17-ade07de3232a Co-authored-by: Tyrrrz <1935960+Tyrrrz@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds a new source generator that emits an executable entry point for CliFx-based console apps when the project doesn’t already define one, and refactors existing generator emission logic into standalone emitter classes.
Changes:
- Introduces
ProgramEntryPointGeneratorto detect missing entry points viacompilation.GetEntryPoint()and emitProgram.g.csfor executable output kinds. - Adds
ProgramEntryPointEmitterto generate theAutoGeneratedCommandLineProgramsource (with XML docs) that runsCommandLineApplicationBuilder. - Refactors the existing generator by extracting command descriptor/registration emission into
CommandDescriptorandCommandRegistration.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| CliFx.Generators/ProgramEntryPointGenerator.cs | New incremental generator that conditionally emits a program entry point for executable projects lacking one. |
| CliFx.Generators/Generator.ProgramEntryPointEmitter.cs | Source emission for the auto-generated Main() entry point. |
| CliFx.Generators/Generator.cs | Updates generator to delegate emission to extracted helper classes (no longer partial). |
| CliFx.Generators/CommandRegistration.cs | Extracts command registration emission into a standalone emitter. |
| CliFx.Generators/Binding/CommandDescriptor.cs | Moves descriptor emission into CliFx.Generators.Binding and updates validator type references used in generated code. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Agent-Logs-Url: https://github.com/Tyrrrz/CliFx/sessions/6c360b75-ebd5-4d95-8bf1-7765512b19d6 Co-authored-by: Tyrrrz <1935960+Tyrrrz@users.noreply.github.com>
…tryPoint for assertions Agent-Logs-Url: https://github.com/Tyrrrz/CliFx/sessions/b1a767e6-ce8d-444c-8f1d-bf0ae095123f Co-authored-by: Tyrrrz <1935960+Tyrrrz@users.noreply.github.com>
Removed comments explaining entry point checks and generation.
…piler Agent-Logs-Url: https://github.com/Tyrrrz/CliFx/sessions/b531f80c-14fd-42c8-a556-32caa0adc8aa Co-authored-by: Tyrrrz <1935960+Tyrrrz@users.noreply.github.com>
…licationSpecs Agent-Logs-Url: https://github.com/Tyrrrz/CliFx/sessions/08c38d84-e57d-46cf-9e02-b5e6ad3914be Co-authored-by: Tyrrrz <1935960+Tyrrrz@users.noreply.github.com>
Removed redundant 'Arrange' comment in test method.
When a user creates a console app with CliFx commands but no entry point, the generator now produces one automatically.
What's generated
For executable projects (
OutputKind.ConsoleApplication/WindowsApplication) with no existing entry point, the generator emitsAutoGeneratedCommandLineProgram.g.cs:Generator conditions (all must hold)
ConsoleApplicationorWindowsApplication— suppresses generation for library projectscompilation.GetEntryPoint(cancellationToken)returnsnull— uses the Roslyn semantic API to detect existing entry points, covering explicitMainmethods, top-level statement programs, and entry points emitted by other source generatorsImplementation
ProgramEntryPointGenerator.cs— standalone[Generator]class (ProgramEntryPointGenerator) responsible solely for detecting and emitting the Program entry point; usescompilation.GetEntryPoint()instead of syntax-based heuristics; checksOutputKindinternally so no external conditional registration is requiredProgramEntryPoint.cs— standaloneinternal static class ProgramEntryPointwith the source emission logic (ProgramEntryPoint.Emit(...)); generatesAutoGeneratedCommandLineProgramwith XML docsCommandDescriptorGenerator.cs— standalone[Generator]class (CommandDescriptorGenerator) responsible for emitting command descriptors and theAddCommandsFromThisAssembly()extension methodCliFx.Generators/Binding/CommandDescriptor.cs— descriptor emitter logic inCliFx.Generators.Bindingnamespace asinternal static class CommandDescriptor(call site:CommandDescriptor.Emit(...))CliFx.Generators/CommandRegistration.cs— registration emitter logic in rootCliFx.Generatorsnamespace asinternal static class CommandRegistration(call site:CommandRegistration.Emit(...))CommandCompiler— extended with anoutputKindparameter (second position, defaultDynamicallyLinkedLibrary); bothCommandDescriptorGeneratorandProgramEntryPointGeneratorare always registered — the entry-point generator handles the output-kind guard itselfApplicationSpecs— new testI_can_create_an_application_without_a_configurationverifies that the generated entry point is present (commands[0].Type.Assembly.EntryPoint != null) when compiling as a console application