Skip to content

Artisan Console Components should use STDERR for auxiliary output #56602

@Radiergummi

Description

@Radiergummi

Laravel Version

12.21.0

PHP Version

8.4

Database Driver & Version

Description

The Artisan Console Components, which render things like interactive question prompts, progress bars, and so on, use the default Output instance only. Instead, they should—if it is available—use the Error Output to write text not part of the command's output.

For a concrete example, imagine a command with a --json flag that will return some JSON data to be piped to another command or written to a file. The command can take a while though, so it would be great to use the task() helper to show step progress, especially when running in non-JSON mode.
This won't work, though: The task output will be included in the output file and thus break the JSON.

$ php artisan some:command > output.json
$ head -n+3 output.json
Doing work ...................................... 1s DONE
[
  {

If the console components were writing non-output related messages to stderr instead, this would work beautifully: Process logs (like task progress) is rendered on the terminal, while the JSON output gets sent to the pipe:

$ php artisan some:command > output.json
Doing work ...................................... 1s DONE
$ head -n+3 output.json
[
  {
    "nice": "valid JSON!"

If there is a desire to improve this, I'd be willing to create a PR.

Steps To Reproduce

Here's a sample command that shows the behaviour:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Symfony\Component\Console\Attribute\AsCommand;

use function json_encode;
use function sleep;

use const JSON_PRETTY_PRINT;

#[AsCommand('some:command')]
class SomeCommand extends Command
{
    protected $signature = 'some:command {--json}';

    public function handle(): int
    {
        $this->components->task('Doing work', fn () => sleep(1));

        if ($this->option('json')) {
            $this->output->writeln(json_encode([['nice' => 'valid JSON!']], JSON_PRETTY_PRINT));

            return 0;
        }

        $this->table(['Key', 'Value'], [['nice', 'a table!']]);

        return 0;
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions