master

laravel/framework

Last updated at: 29/12/2023 09:23

Pipe.php

TLDR

This file defines the Pipe class in the Illuminate\Process namespace. The Pipe class represents a series of piped processes. It allows adding processes to the pipe, running the processes, and dynamically proxying method calls to a new pending process.

Methods

__construct

Creates a new instance of the Pipe class.

  • Parameters:
    • Factory $factory: The process factory instance.
    • callable $callback: The callback that resolves the pending processes.

as

Adds a process to the pipe with a key.

  • Parameters:
    • string $key: The key for the process.
  • Returns: \Illuminate\Process\PendingProcess: The pending process instance.

run

Runs the processes in the pipe.

  • Parameters:
    • ?callable $output = null: An optional callable for handling the process output.
  • Returns: \Illuminate\Contracts\Process\ProcessResult: The result of the process run.

__call

Dynamically proxies method calls to a new pending process.

  • Parameters:
    • string $method: The name of the method being called.
    • array $parameters: The parameters passed to the method.
  • Returns: \Illuminate\Process\PendingProcess: The pending process instance.

Classes

None

<?php

namespace Illuminate\Process;

use InvalidArgumentException;

/**
 * @mixin \Illuminate\Process\Factory
 * @mixin \Illuminate\Process\PendingProcess
 */
class Pipe
{
    /**
     * The process factory instance.
     *
     * @var \Illuminate\Process\Factory
     */
    protected $factory;

    /**
     * The callback that resolves the pending processes.
     *
     * @var callable
     */
    protected $callback;

    /**
     * The array of pending processes.
     *
     * @var array
     */
    protected $pendingProcesses = [];

    /**
     * Create a new series of piped processes.
     *
     * @param  \Illuminate\Process\Factory  $factory
     * @param  callable  $callback
     * @return void
     */
    public function __construct(Factory $factory, callable $callback)
    {
        $this->factory = $factory;
        $this->callback = $callback;
    }

    /**
     * Add a process to the pipe with a key.
     *
     * @param  string  $key
     * @return \Illuminate\Process\PendingProcess
     */
    public function as(string $key)
    {
        return tap($this->factory->newPendingProcess(), function ($pendingProcess) use ($key) {
            $this->pendingProcesses[$key] = $pendingProcess;
        });
    }

    /**
     * Runs the processes in the pipe.
     *
     * @param  callable|null  $output
     * @return \Illuminate\Contracts\Process\ProcessResult
     */
    public function run(?callable $output = null)
    {
        call_user_func($this->callback, $this);

        return collect($this->pendingProcesses)
                ->reduce(function ($previousProcessResult, $pendingProcess, $key) use ($output) {
                    if (! $pendingProcess instanceof PendingProcess) {
                        throw new InvalidArgumentException('Process pipe must only contain pending processes.');
                    }

                    if ($previousProcessResult && $previousProcessResult->failed()) {
                        return $previousProcessResult;
                    }

                    return $pendingProcess->when(
                        $previousProcessResult,
                        fn () => $pendingProcess->input($previousProcessResult->output())
                    )->run(output: $output ? function ($type, $buffer) use ($key, $output) {
                        $output($type, $buffer, $key);
                    } : null);
                });
    }

    /**
     * Dynamically proxy methods calls to a new pending process.
     *
     * @param  string  $method
     * @param  array  $parameters
     * @return \Illuminate\Process\PendingProcess
     */
    public function __call($method, $parameters)
    {
        return tap($this->factory->{$method}(...$parameters), function ($pendingProcess) {
            $this->pendingProcesses[] = $pendingProcess;
        });
    }
}