Completed
Push — master ( 7bf58d...9f8ca5 )
by
unknown
20s queued 12s
created

ShellBuilder::addCondition()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PHPSu\ShellCommandBuilder;
6
7
use PHPSu\ShellCommandBuilder\Collection\CollectionTuple;
8
use PHPSu\ShellCommandBuilder\Collection\Pipeline;
9
use PHPSu\ShellCommandBuilder\Collection\Redirection;
10
use PHPSu\ShellCommandBuilder\Collection\ShellList;
11
use PHPSu\ShellCommandBuilder\Conditional\BasicExpression;
12
use PHPSu\ShellCommandBuilder\Definition\ControlOperator;
13
use PHPSu\ShellCommandBuilder\Definition\GroupType;
14
use PHPSu\ShellCommandBuilder\Exception\ShellBuilderException;
15
use TypeError;
16
17
final class ShellBuilder implements ShellInterface
18
{
19
    /** @var array<ShellInterface|CollectionTuple>  */
20
    private $commandList = [];
21
    /** @var int */
22
    private $groupType;
23
    /** @var bool */
24
    private $asynchronously = false;
25
26
    /**
27
     * This is a shortcut for quicker fluid access to the shell builder
28
     * @return static
29
     */
30
    public static function new(): self
31
    {
32
        return new ShellBuilder();
33
    }
34
35
    public function __construct(int $groupType = GroupType::NO_GROUP)
36
    {
37
        $this->groupType = $groupType;
38
    }
39
40
    public function createCommand(string $name, bool $withNewBuilder = false): ShellCommand
41
    {
42
        return new ShellCommand($name, $withNewBuilder ? new self() : $this);
43
    }
44
45
    public function runAsynchronously(bool $isAsync = true): self
46
    {
47
        $this->asynchronously = $isAsync;
48
        return $this;
49
    }
50
51
    /**
52
     * @param string|ShellInterface $command
53
     * @return $this
54
     * @throws ShellBuilderException
55
     */
56
    public function add($command): self
57
    {
58
        $command = $this->parseCommand($command, true);
59
        if (empty($this->commandList)) {
60
            $this->commandList[] = $command;
61
            return $this;
62
        }
63
        $this->commandList[] = ShellList::add($command);
64
        return $this;
65
    }
66
67
    /**
68
     * @param string|ShellInterface $command
69
     * @return $this
70
     * @throws ShellBuilderException
71
     */
72
    public function and($command): self
73
    {
74
        $this->commandList[] = ShellList::addAnd($this->parseCommand($command));
75
        return $this;
76
    }
77
78
    /**
79
     * @param string|ShellInterface $command
80
     * @return $this
81
     * @throws ShellBuilderException
82
     */
83
    public function or($command): self
84
    {
85
        $this->commandList[] = ShellList::addOr($this->parseCommand($command));
86
        return $this;
87
    }
88
89
    /**
90
     * @param string|ShellInterface $command
91
     * @return $this
92
     * @throws ShellBuilderException
93
     */
94
    public function async($command): self
95
    {
96
        $this->commandList[] = ShellList::async($this->parseCommand($command));
97
        return $this;
98
    }
99
100
    /**
101
     * @param string|ShellInterface $command
102
     * @return $this
103
     * @throws ShellBuilderException
104
     */
105
    public function pipe($command): self
106
    {
107
        $this->commandList[] = Pipeline::pipe($this->parseCommand($command));
108
        return $this;
109
    }
110
111
    /**
112
     * @param string|ShellInterface $command
113
     * @return $this
114
     * @throws ShellBuilderException
115
     */
116
    public function pipeWithForward($command): self
117
    {
118
        $this->commandList[] = Pipeline::pipeErrorForward($this->parseCommand($command));
119
        return $this;
120
    }
121
122
    /**
123
     * @param string|ShellInterface $command
124
     * @param bool $append
125
     * @return $this
126
     * @throws ShellBuilderException
127
     */
128
    public function redirectOutput($command, bool $append = false): self
129
    {
130
        $command = $this->parseCommand($command);
131
        $this->commandList[] = Redirection::redirectOutput($command, $append);
132
        return $this;
133
    }
134
135
    /**
136
     * @param string|ShellInterface $command
137
     * @return $this
138
     * @throws ShellBuilderException
139
     */
140
    public function redirectInput($command): self
141
    {
142
        $command = $this->parseCommand($command);
143
        $this->commandList[] = Redirection::redirectInput($command);
144
        return $this;
145
    }
146
147
    /**
148
     * @param string|ShellInterface $command
149
     * @return $this
150
     * @throws ShellBuilderException
151
     */
152
    public function redirectError($command): self
153
    {
154
        $command = $this->parseCommand($command);
155
        $this->commandList[] = Redirection::redirectError($command);
156
        return $this;
157
    }
158
159
    /**
160
     * @param string|ShellInterface $command
161
     * @param bool $toLeft
162
     * @return $this
163
     * @throws ShellBuilderException
164
     */
165
    public function redirect($command, bool $toLeft = true): self
166
    {
167
        $command = $this->parseCommand($command);
168
        $this->commandList[] = Redirection::redirectBetweenFiles($command, $toLeft);
169
        return $this;
170
    }
171
172
    public function redirectErrorToOutput(): self
173
    {
174
        $this->commandList[] = Redirection::redirectErrorToOutput();
175
        return $this;
176
    }
177
178
    public function addCondition(BasicExpression $condition): self
179
    {
180
        $this->commandList[] = $condition;
181
        return $this;
182
    }
183
184
    public function createGroup(bool $inSameShell = false): self
185
    {
186
        return new self($inSameShell ? GroupType::SAMESHELL_GROUP : GroupType::SUBSHELL_GROUP);
187
    }
188
189
    /**
190
     * @param string|ShellInterface $command
191
     * @param bool $allowEmpty
192
     * @return ShellInterface
193
     * @throws ShellBuilderException
194
     */
195
    private function parseCommand($command, bool $allowEmpty = false): ShellInterface
196
    {
197
        if (is_string($command)) {
198
            $command = $this->createCommand($command);
199
        }
200
        try {
201
            $this->validateCommand($command, $allowEmpty);
202
        } catch (TypeError $typeError) {
203
            throw new ShellBuilderException('Provided the wrong type - only ShellCommand and ShellBuilder allowed');
204
        }
205
        return $command;
206
    }
207
208
    /** @noinspection PhpUnusedParameterInspection */
209
    private function validateCommand(ShellInterface $command, bool $allowEmpty): void
0 ignored issues
show
Unused Code introduced by
The parameter $command is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

209
    private function validateCommand(/** @scrutinizer ignore-unused */ ShellInterface $command, bool $allowEmpty): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
210
    {
211
        if (!$allowEmpty && empty($this->commandList)) {
212
            throw new ShellBuilderException('You have to first add a command before you can combine it');
213
        }
214
    }
215
216
    /**
217
     * @return array<mixed>
218
     */
219
    public function __toArray(): array
220
    {
221
        $commands = [];
222
        foreach ($this->commandList as $item) {
223
            $commands[] = $item instanceof ShellInterface ? $item->__toArray() : $item;
224
        }
225
        return $commands;
226
    }
227
228
    public function __toString(): string
229
    {
230
        $result = '';
231
        if ($this->asynchronously) {
232
            $result = 'coproc ';
233
        }
234
        foreach ($this->commandList as $command) {
235
            $result .= $command;
236
        }
237
        if ($this->groupType === GroupType::SAMESHELL_GROUP) {
238
            return sprintf(
239
                '%s%s;%s',
240
                ControlOperator::CURLY_BLOCK_DEFINITON_OPEN,
241
                $result,
242
                ControlOperator::CURLY_BLOCK_DEFINITON_CLOSE
243
            );
244
        }
245
        if ($this->groupType === GroupType::SUBSHELL_GROUP) {
246
            return sprintf(
247
                '%s%s%s',
248
                ControlOperator::BLOCK_DEFINITON_OPEN,
249
                $result,
250
                ControlOperator::BLOCK_DEFINITON_CLOSE
251
            );
252
        }
253
        return $result;
254
    }
255
}
256