Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
ProcessBuilder
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
4 / 4
6
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 withArgument
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getArguments
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 build
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5/**
6 * Fast Forward Development Tools for PHP projects.
7 *
8 * This file is part of fast-forward/dev-tools project.
9 *
10 * @author   Felipe SayĆ£o Lobato Abreu <github@mentordosnerds.com>
11 * @license  https://opensource.org/licenses/MIT MIT License
12 *
13 * @see      https://github.com/php-fast-forward/
14 * @see      https://github.com/php-fast-forward/dev-tools
15 * @see      https://github.com/php-fast-forward/dev-tools/issues
16 * @see      https://php-fast-forward.github.io/dev-tools/
17 * @see      https://datatracker.ietf.org/doc/html/rfc2119
18 */
19
20namespace FastForward\DevTools\Process;
21
22use Symfony\Component\Process\Process;
23
24/**
25 * Builds immutable process definitions from a command and a collection of arguments.
26 *
27 * This builder SHALL preserve previously supplied arguments by returning a new
28 * instance on each mutation-like operation. Implementations of this concrete
29 * builder MUST keep argument ordering stable so that the generated process
30 * reflects the exact sequence in which arguments were provided.
31 */
32  class ProcessBuilder implements ProcessBuilderInterface
33{
34    /**
35     * Creates a new immutable process builder instance.
36     *
37     * The provided arguments SHALL be stored in the same order in which they are
38     * received and MUST be used when building the final process instance.
39     *
40     * @param list<string> $arguments the arguments already collected by the builder
41     */
42    public function __construct(
43        private array $arguments = [],
44    ) {}
45
46    /**
47     * Returns a new builder instance with an additional argument appended.
48     *
49     * When a value is provided, the argument SHALL be normalized to the
50     * "{argument}={value}" format before being appended. When no value is
51     * provided, the raw argument token MUST be appended as-is.
52     *
53     * This method MUST NOT mutate the current builder instance and SHALL return
54     * a new instance containing the accumulated arguments.
55     *
56     * @param string $argument the argument name or token to append
57     * @param string|null $value the optional value associated with the argument
58     *
59     * @return ProcessBuilderInterface a new builder instance containing the appended argument
60     */
61    public function withArgument(string $argument, ?string $value = null): ProcessBuilderInterface
62    {
63        if (null !== $value) {
64            $argument = \sprintf('%s=%s', $argument, $value);
65        }
66
67        return new self([...$this->arguments, $argument]);
68    }
69
70    /**
71     * Returns the arguments currently collected by the builder.
72     *
73     * The returned list SHALL preserve insertion order and MAY be used for
74     * inspection, debugging, or testing purposes.
75     *
76     * @return list<string> the collected process arguments
77     */
78    public function getArguments(): array
79    {
80        return $this->arguments;
81    }
82
83    /**
84     * Builds a process instance for the specified command.
85     *
86     * The command string SHALL be split into tokens using a space separator and
87     * combined with all previously collected builder arguments. The resulting
88     * process MUST preserve the final token order exactly as assembled by this
89     * method.
90     *
91     * @param string|array $command the base command used to initialize the process
92     *
93     * @return Process the configured process instance ready for execution
94     */
95    public function build(string|array $command): Process
96    {
97        if (\is_string($command)) {
98            $command = explode(' ', $command);
99        }
100
101        return new Process(command: [...$command, ...$this->arguments], timeout: 0);
102    }
103}