refactor!: clean up stdio interface
with an interface no less!
This commit is contained in:
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Nih\CommandBuilder;
|
||||
|
||||
use Override;
|
||||
use Stringable;
|
||||
use ValueError;
|
||||
|
||||
@@ -20,9 +21,9 @@ final class Command implements Stringable
|
||||
private bool $environmentInherit = true;
|
||||
private ?string $cwd = null;
|
||||
|
||||
private ?Stdio $stdin = null;
|
||||
private ?Stdio $stdout = null;
|
||||
private ?Stdio $stderr = null;
|
||||
private ?StdioInterface $stdin = null;
|
||||
private ?StdioInterface $stdout = null;
|
||||
private ?StdioInterface $stderr = null;
|
||||
|
||||
/**
|
||||
* Constructs a new Command for launching the program at path program, with
|
||||
@@ -202,14 +203,8 @@ final class Command implements Stringable
|
||||
* Defaults to inherit when used with spawn or status, and defaults to piped
|
||||
* when used with output.
|
||||
*/
|
||||
public function stdin(Stdio $stdin): static
|
||||
public function stdin(StdioInterface $stdin): static
|
||||
{
|
||||
$stdin = match ($stdin->type) {
|
||||
Stdio::INHERIT => Stdio::stream(STDIN),
|
||||
Stdio::PIPE => new Stdio(Stdio::PIPE, ['pipe', 'r']),
|
||||
default => $stdin,
|
||||
};
|
||||
|
||||
$this->stdin = $stdin;
|
||||
return $this;
|
||||
}
|
||||
@@ -220,14 +215,8 @@ final class Command implements Stringable
|
||||
* Defaults to inherit when used with spawn or status, and defaults to piped
|
||||
* when used with output.
|
||||
*/
|
||||
public function stdout(Stdio $stdout): static
|
||||
public function stdout(StdioInterface $stdout): static
|
||||
{
|
||||
$stdout = match ($stdout->type) {
|
||||
Stdio::INHERIT => Stdio::stream(STDOUT),
|
||||
Stdio::PIPE => new Stdio(Stdio::PIPE, ['pipe', 'w']),
|
||||
default => $stdout,
|
||||
};
|
||||
|
||||
$this->stdout = $stdout;
|
||||
return $this;
|
||||
}
|
||||
@@ -238,14 +227,8 @@ final class Command implements Stringable
|
||||
* Defaults to inherit when used with spawn or status, and defaults to piped
|
||||
* when used with output.
|
||||
*/
|
||||
public function stderr(Stdio $stderr): static
|
||||
public function stderr(StdioInterface $stderr): static
|
||||
{
|
||||
$stderr = match ($stderr->type) {
|
||||
Stdio::INHERIT => Stdio::stream(STDERR),
|
||||
Stdio::PIPE => new Stdio(Stdio::PIPE, ['pipe', 'w']),
|
||||
default => $stderr,
|
||||
};
|
||||
|
||||
$this->stderr = $stderr;
|
||||
return $this;
|
||||
}
|
||||
@@ -267,20 +250,18 @@ final class Command implements Stringable
|
||||
* Executes the command as a child process, returning a handle to it.
|
||||
*
|
||||
* By default, stdin, stdout and stderr are inherited from the parent.
|
||||
*
|
||||
* @param bool $shell Run the command with or without a shell
|
||||
*/
|
||||
public function spawn(): Child
|
||||
{
|
||||
return $this->spawnWithDescriptorSpec([
|
||||
$this->stdin instanceof Stdio
|
||||
? $this->stdin->descriptorSpec
|
||||
$this->stdin instanceof StdioInterface
|
||||
? $this->stdin->getDescriptionSpec(0)
|
||||
: STDIN,
|
||||
$this->stdout instanceof Stdio
|
||||
? $this->stdout->descriptorSpec
|
||||
$this->stdout instanceof StdioInterface
|
||||
? $this->stdout->getDescriptionSpec(1)
|
||||
: STDOUT,
|
||||
$this->stderr instanceof Stdio
|
||||
? $this->stderr->descriptorSpec
|
||||
$this->stderr instanceof StdioInterface
|
||||
? $this->stderr->getDescriptionSpec(2)
|
||||
: STDERR,
|
||||
]);
|
||||
}
|
||||
@@ -290,8 +271,6 @@ final class Command implements Stringable
|
||||
* collecting its status.
|
||||
*
|
||||
* By default, stdin, stdout and stderr are inherited from the parent.
|
||||
*
|
||||
* @param bool $shell Run the command with or without a shell
|
||||
*/
|
||||
public function status(): ExitStatus
|
||||
{
|
||||
@@ -304,20 +283,18 @@ final class Command implements Stringable
|
||||
*
|
||||
* By default, stdout and stderr are captured (and used to provide the
|
||||
* resulting output). Stdin is not inherited from the parent.
|
||||
*
|
||||
* @param bool $shell Run the command with or without a shell
|
||||
*/
|
||||
public function output(): Output
|
||||
{
|
||||
return $this->spawnWithDescriptorSpec([
|
||||
$this->stdin instanceof Stdio
|
||||
? $this->stdin->descriptorSpec
|
||||
$this->stdin instanceof StdioInterface
|
||||
? $this->stdin->getDescriptionSpec(0)
|
||||
: ['pipe', 'r'],
|
||||
$this->stdout instanceof Stdio
|
||||
? $this->stdout->descriptorSpec
|
||||
$this->stdout instanceof StdioInterface
|
||||
? $this->stdout->getDescriptionSpec(1)
|
||||
: ['pipe', 'w'],
|
||||
$this->stderr instanceof Stdio
|
||||
? $this->stderr->descriptorSpec
|
||||
$this->stderr instanceof StdioInterface
|
||||
? $this->stderr->getDescriptionSpec(2)
|
||||
: ['pipe', 'w'],
|
||||
])->waitWithOutput();
|
||||
}
|
||||
@@ -365,6 +342,7 @@ final class Command implements Stringable
|
||||
return $this->cwd;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function __toString(): string
|
||||
{
|
||||
return implode(' ', [
|
||||
@@ -375,17 +353,6 @@ final class Command implements Stringable
|
||||
|
||||
private function spawnWithDescriptorSpec(array $descriptorSpec): Child
|
||||
{
|
||||
// Validate stream resources in descriptor spec.
|
||||
foreach ($descriptorSpec as $descriptor => $spec) {
|
||||
if (!is_array($spec) && !is_resource($spec)) {
|
||||
throw new CommandException(sprintf(
|
||||
'Descriptor %d is not a valid stream resource: %s',
|
||||
$descriptor,
|
||||
get_debug_type($spec),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// Find executable if path is not absolute.
|
||||
$program = $this->program;
|
||||
if ($program[0] !== DIRECTORY_SEPARATOR) {
|
||||
|
||||
Reference in New Issue
Block a user