Repository navigation
[make:webhook] Fix the crash under --no-interaction - #1817
Merged
GromNaN merged 1 commit intoSep 7, 2026
Merged
Conversation
wachterjohannes
force-pushed
the
fix/make-webhook-non-interactive
branch
from
August 31, 2026 17:37
15359ec to
f56af5c
Compare
The name argument was already declared, and already marked
non-interactive, but interact() copied it onto the maker and generate()
read it back from there. Command::run() skips interact() without a
terminal, so the copy never happened:
$ php bin/console make:webhook remote_service --no-interaction
Typed property MakeWebhook::$name must not be accessed before
initialization
generate() now reads the argument it was given. The name check that
interact() applied moved next to it, so a name with illegal characters
is rejected on both paths instead of only when someone is watching.
symfony/webhook was installed from interact(), which is the one place
that does not always run, and the generated parser extends a class from
that package. The install moved to generate(), the step that always
runs, rather than being called from both: a second composer require in
the same process rebuilds the container underneath the command and the
run dies afterwards on a stale cache file.
$io was being stashed on the maker as well. It is passed to the one
private method that asks anything, and the property is gone along with
the one holding the name.
wachterjohannes
force-pushed
the
fix/make-webhook-non-interactive
branch
from
September 3, 2026 20:37
f56af5c to
e93df0d
Compare
wachterjohannes
marked this pull request as ready for review
September 3, 2026 20:37
GromNaN
approved these changes
Sep 7, 2026
Member
|
Thank you @wachterjohannes. |
GromNaN
added a commit
that referenced
this pull request
Sep 10, 2026
…moifr) This PR was squashed before being merged into the 1.x branch. Discussion ---------- [make:command] Ask for the arguments and the options Closes #1699. The first half of that issue landed with #1746: `make:command` generates an `__invoke()` method. This is the second half, asking for the arguments and the options so the signature comes out ready rather than as a sample to edit. ``` $ php bin/console make:command app:send-report New argument name (press <return> to stop adding arguments): > recipient Type [string]: Description [Recipient]: Who to send the report to Is it required? (yes/no) [no]: yes New argument name (press <return> to stop adding arguments): > New option name (press <return> to stop adding options): > dry-run Type [bool]: Description [Dry Run]: Do not send anything ``` ```php public function __invoke( SymfonyStyle $io, #[Argument('Who to send the report to')] string $recipient, #[Option('Do not send anything')] bool $dryRun = false, ): int { ``` The name is typed the way it reads on the command line, so `dry-run` becomes `$dryRun`. Besides the scalar types and `array`, the type can be a backed enum. They can also be passed on the command line (thanks `@GromNaN`). The type defaults to `string` for an argument and `bool` for an option, the short name of an enum is enough when it is unique within `src/`, a `?` after the name makes an argument optional as in a PHP array shape, and passing any of them skips the questions: ``` $ php bin/console make:command app:send-report --argument=recipient --argument=cc?:array --option=dry-run --option=format:Format ``` A few decisions worth flagging: * **Answering nothing keeps the sample argument and option**, so `--no-interaction`, where `interact()` never runs, and the person who just presses return through the questions still get a command that shows both attributes at work. * **What the console component would refuse is refused up front.** A required argument after an optional one, any argument after an array one, a parameter named `io` (taken by `SymfonyStyle $io`), an argument and an option sharing a name, and an enum that is not backed all produce a command that fails to load. The questions skip or ask again, and the command line gets an error before anything is written. * **An enum named like an import is aliased**: an `App\Enum\Option` comes in as `EnumOption`, since `Option` is the attribute. * **The notes use `var_export()`**, so every type, enums included, is shown the same way. I saw the run of `--no-interaction` fixes that just landed (#1816, #1817, #1818), and this maker does collect state in `interact()` and read it in `generate()`, which is the shape those removed. The properties are initialised, so there is nothing to crash on, but `it_makes_a_command_non_interactively` pins that down rather than leaving it to reading. #### Testing Seven functional tests, up from three: the questions, the command line (enums included), and the definitions it rejects. `MakeCommandTest` green, PHPStan green with the CI tooling. Commits ------- 25d53f4 [make:command] Ask for the arguments and the options
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.
make:webhookalready declares itsnameargument, and already marks it non-interactive, so it looks scriptable. It is not:Cause
interact()read the argument and copied it onto the maker, andgenerate()read it back from there.Command::run()skipsinteract()under--no-interaction, so the copy never happened.$iowas stashed on the maker in the same way.Fix
generate()reads the argument it was given. The name check thatinteract()applied moved next to that read, so a name with illegal characters is rejected on both paths rather than only when someone is watching.$iois passed to the one private method that asks anything, and both properties are gone.symfony/webhookwas installed frominteract(), which is the one step that does not always run, and the generated request parser extendsAbstractRequestParserfrom that package. The install moved togenerate(), which always runs, rather than being called from both: a secondcomposer requirein the same process rebuilds the container underneath the running command, and the run then dies on a stale cache file. The one visible change interactively is that the install now happens after the questions instead of before.Why
Part of a series making the makers usable by coding agents, which cannot answer prompts. Same framing as #1814 and #1815.