Skip to content

Commit

Permalink
Laravel & Symfony console commands (#16)
Browse files Browse the repository at this point in the history
* Pass output to Laravel & Symfony console commands
  • Loading branch information
TitasGailius authored Apr 27, 2020
1 parent f94eb34 commit a65f3b9
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 3 deletions.
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ An Elegant wrapper around Symfony's Process component.
- [Output to Array](#output-to-array)
- [Output Stream (Recommended)](#output-stream)
- [Output Lines](#output-lines)
- [Output via Laravel Artisan Command](#output-via-laravel-artisan-command)
- [Output via Symfony Console Command](#output-via-symfony-console-command)
- [Throwing Exceptions](#throwing-exceptions)
- [Data](#data)
- [Working Directory](#working-directory)
Expand Down Expand Up @@ -104,6 +106,30 @@ Alternatively, you may use the `content` method to get the contents of the line:
$line->content();
```

### Output via Laravel Artisan Command

If you run Terminal from the Laravel's Artisan command, you may send the output to the console by
passing an instance of the Command to the `output` method:

```php
public function handle()
{
Terminal::output($this)->run('echo Hello, World');
}
```

### Output via Symfony Console Command

If you run Terminal from the Symfony's Console command, you may send the output to the console by
passing an instance of the OutputInterface to the `output` method:

```php
protected function execute(InputInterface $input, OutputInterface $output)
{
Terminal::output($output)->run('echo Hello, World');
}
```

### Throwing Exceptions

If you would like to throw an exception when the command is not successful, you may use the `throw` method:
Expand Down
46 changes: 43 additions & 3 deletions src/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -158,16 +158,56 @@ public function withEnvironmentVariables(array $environmentVariables)
/**
* Set output handler.
*
* @param callable $output
* @param mixed $output
* @return $this
*/
public function output(callable $output)
public function output($output)
{
$this->output = $output;
$this->output = $this->parseOutput($output);

return $this;
}

/**
* Parse a given output.
*
* @param mixed $output
* @return callable
*/
protected function parseOutput($output)
{
if (is_callable($output)) {
return $output;
}

if ($output instanceof \Symfony\Component\Console\Output\OutputInterface) {
return $this->wrapOutput([$output, 'write']);
}

if ($output instanceof \Illuminate\Console\Command) {
return $this->wrapOutput([$output->getOutput(), 'write']);
}

throw new InvalidArgumentException(sprintf(
'Terminal output must be a %s, an instance of "%s" or an instance of "%s" but "%s" was given.',
'callable', 'Symfony\Component\Console\Output\OutputInterface', 'Illuminate\Console\Command',
($type = gettype($output)) === 'object' ? get_class($output) : $type
));
}

/**
* Wrap output callback.
*
* @param callable $callback
* @return callable
*/
protected function wrapOutput(callable $callback): callable
{
return function ($type, $data) use ($callback) {
return call_user_func($callback, $data);
};
}

/**
* Set input.
*
Expand Down
59 changes: 59 additions & 0 deletions tests/BuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,65 @@ public function testToString()
);
}

/**
* Test that termina can handle Symfony' OutputInterface.
*
* @return void
*/
public function testOutputAsSymfonyOutputInterface()
{
$output = Mockery::mock('Symfony\Component\Console\Output\OutputInterface', function ($mock) {
$mock->shouldReceive('write')
->once()
->with("Hello\n")
->andReturn(null);
});

(new Builder)->output($output)->run('echo Hello');
}

/**
* Test that termina can handle Symfony' OutputInterface.
*
* @return void
*/
public function testOutputAsLaravelCommad()
{
$output = Mockery::mock('Illuminate\Console\Command', function ($mock) {
$mock->shouldReceive('getOutput->write')
->once()
->with("Hello\n")
->andReturn(null);
});

(new Builder)->output($output)->run('echo Hello');
}

/**
* Get invalid outputs.
*
* @return array
*/
public function invalidOutputs(): array
{
return [
[123],
['string'],
[new \stdClass],
];
}

/**
* Test Terminal output validation.
*
* @dataProvider invalidOutputs
*/
public function testOutputValidation($output)
{
$this->expectException('InvalidArgumentException');
(new Builder)->output($value)->run('echo Hello');
}

/**
* Create a new builder instance with a mocked process instance.
*
Expand Down

0 comments on commit a65f3b9

Please sign in to comment.