Skip to content

fix: stop announcing a shadowed built-in on every command - #46

Merged
refsz merged 1 commit into
mainfrom
fix/shadow-notice-not-a-warning
Aug 20, 2026
Merged

fix: stop announcing a shadowed built-in on every command#46
refsz merged 1 commit into
mainfrom
fix/shadow-notice-not-a-warning

Conversation

@refsz

@refsz refsz commented Aug 20, 2026

Copy link
Copy Markdown
Owner

Reported from real use of 0.2.1. A project with its own init task saw this before every command, including ones with nothing to do with init:

$ sputnik drush
Task 'init' in /project/tasks/InitTask.php shadows the built-in init command, which is no longer reachable
🛰  Sputnik v0.2.1 │ .sputnik.dist.neon │ dev

▸ drush · Run any drush command
  (1/2) > ddev exec vendor/bin/drush list

My mistake in #45: I treated both discovery messages as the same kind. They are not.

  • A skipped task means something the author wrote does not work. That stays true on the next command, so it belongs in the output every time.
  • A shadowed init works exactly as asked. Nothing is broken.

And the shadow notice has almost no audience: a project that has tasks has been initialised already, so the built-in scaffold being unreachable costs nothing. The one moment it helps is when someone is wondering why sputnik init no longer scaffolds — which is a -v question.

So discovery separates the two: getWarnings() prints always, getNotices() with -v. Both still travel through the container cache, since discovery only runs when that cache is cold.

The part I got wrong twice

The first attempt gated on isVerbose() inside Kernel::createApplication(), and the notice never appeared even with -v. Reason: Symfony parses -v in run(), which happens after the application is assembled — verbosity is simply not known at that point.

The E2E test caught it, which is why the reporting now lives in Application::doRun(), where the input has been parsed. That also moved the warnings there, so both come from one place.

Verified in the reporting project

sputnik list             (silent)
sputnik list -v          Task 'init' in .../InitTask.php shadows the built-in init command

And the counter-check that blocked names stay loud — a temporary task named list in the same project:

sputnik list             Skipped task 'list' in .../ZzTmpList.php: the name is reserved
                         by a built-in command - rename the task or give it a group prefix

Still on every run. Temporary task removed afterwards.

Tests

  • testShadowingIsANoticeNotAWarning — shadowing produces a notice and no warning
  • testASkippedTaskStaysAWarning — the skip produces a warning and no notice
  • E2E asserts the shadow line is absent by default and present with -v, so a future change cannot quietly put it back into every command
vendor/bin/phpunit                        767 tests, 1314 assertions, OK
vendor/bin/phpstan analyse                [OK] No errors
vendor/bin/php-cs-fixer fix --dry-run     0 of 156 files
vendor/bin/rector --dry-run               [OK]
mkdocs build --strict                     clean

🤖 Generated with Claude Code

https://claude.ai/code/session_018CTvnzcNYmFgm2HQcm821A

Reported from real use: a project with its own init task saw this line before
every command, including ones with nothing to do with init.

    $ sputnik drush
    Task 'init' in /project/tasks/InitTask.php shadows the built-in init command
    ...
    > ddev exec vendor/bin/drush list

I had treated both discovery messages the same, and they are not the same. A
skipped task means something the author wrote does not work, and that stays true
on the next command - it belongs in the output every time. A shadowed init works
exactly as asked; nothing is broken. Repeating it before unrelated commands is
noise, and it has almost no audience anyway: a project that has tasks has been
initialised already, so the built-in scaffold being unreachable costs nothing.

So discovery now separates warnings from notices. Warnings print always, notices
with -v.

The reporting moved from Kernel::createApplication() into Application::doRun():
-v is parsed by run(), so verbosity is simply not known while the application is
being assembled. The first attempt gated on isVerbose() during assembly and the
notice never appeared, which the E2E test caught.

Verified in the reporting project:

    sputnik list        (silent)
    sputnik list -v     Task 'init' in .../InitTask.php shadows ...
    a task named 'list' Skipped task 'list' in ... - rename ...   (still every run)
@refsz
refsz merged commit c05de7e into main Aug 20, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant