CommandLine::redirectOutputTo()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
/**
4
 * This file is part of SebastianFeldmann\Cli.
5
 *
6
 * (c) Sebastian Feldmann <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace SebastianFeldmann\Cli;
13
14
use RuntimeException;
15
16
/**
17
 * Class CommandLine
18
 *
19
 * @package SebastianFeldmann\Cli
20
 * @author  Sebastian Feldmann <[email protected]>
21
 * @link    https://github.com/sebastianfeldmann/cli
22
 * @since   Class available since Release 0.9.0
23
 */
24
class CommandLine implements Command
25
{
26
    /**
27
     * List of system commands to execute
28
     *
29
     * @var \SebastianFeldmann\Cli\Command[]
30
     */
31
    private $commands = [];
32
33
    /**
34
     * Redirect the output
35
     *
36
     * @var string
37
     */
38
    private $redirectOutput;
39
40
    /**
41
     * Output pipeline
42
     *
43
     * @var \SebastianFeldmann\Cli\Command[]
44
     */
45
    private $pipeline = [];
46
47
    /**
48
     * Should 'pipefail' be set?
49
     *
50
     * @var bool
51
     */
52
    private $pipeFail = false;
53
54
    /**
55
     * List of acceptable exit codes.
56
     *
57
     * @var array
58
     */
59
    private $acceptedExitCodes = [0];
60
61
    /**
62
     * Set the list of accepted exit codes
63
     *
64
     * @param  int[] $codes
65 1
     * @return void
66
     */
67 1
    public function acceptExitCodes(array $codes): void
68 1
    {
69
        $this->acceptedExitCodes = $codes;
70
    }
71
72
    /**
73
     * Redirect the stdOut.
74
     *
75
     * @param  string $path
76 1
     * @return void
77
     */
78 1
    public function redirectOutputTo($path): void
79 1
    {
80
        $this->redirectOutput = $path;
81
    }
82
83
    /**
84
     * Should the output be redirected
85
     *
86 1
     * @return bool
87
     */
88 1
    public function isOutputRedirected(): bool
89
    {
90
        return !empty($this->redirectOutput);
91
    }
92
93
    /**
94
     * Redirect getter.
95
     *
96 1
     * @return string
97
     */
98 1
    public function getRedirectPath(): string
99
    {
100
        return $this->redirectOutput;
101
    }
102
103
    /**
104
     * Pipe the command into given command
105
     *
106
     * @param  \SebastianFeldmann\Cli\Command $cmd
107 2
     * @return void
108
     */
109 2
    public function pipeOutputTo(Command $cmd): void
110
    {
111
        if (!$this->canPipe()) {
112 2
            throw new RuntimeException('Can\'t pipe output');
113 2
        }
114
        $this->pipeline[] = $cmd;
115
    }
116
117
    /**
118
     * Get the 'pipefail' option command snippet
119
     *
120 4
     * @return string
121
     */
122 4
    public function getPipeFail(): string
123
    {
124
        return ($this->isPiped() && $this->pipeFail) ? 'set -o pipefail; ' : '';
125
    }
126
127
    /**
128
     * Can the pipe '|' operator be used
129
     *
130 2
     * @return bool
131
     */
132 2
    public function canPipe(): bool
133
    {
134
        return !defined('PHP_WINDOWS_VERSION_BUILD');
135
    }
136
137
    /**
138
     * Is there a command pipeline
139
     *
140 4
     * @return bool
141
     */
142 4
    public function isPiped(): bool
143
    {
144
        return !empty($this->pipeline);
145
    }
146
147
    /**
148
     * Should the pipefail option be set
149
     *
150 1
     * @param bool $pipeFail
151
     */
152 1
    public function pipeFail(bool $pipeFail)
153 1
    {
154
        $this->pipeFail = $pipeFail;
155
    }
156
157
    /**
158
     * Return command pipeline
159
     *
160 4
     * @return string
161
     */
162 4
    public function getPipeline(): string
163
    {
164
        return $this->isPiped() ? ' | ' . implode(' | ', $this->pipeline) : '';
165
    }
166
167
    /**
168
     * Adds a cli command to list of commands to execute
169
     *
170
     * @param  \SebastianFeldmann\Cli\Command $cmd
171 5
     * @return void
172
     */
173 5
    public function addCommand(Command $cmd): void
174 5
    {
175
        $this->commands[] = $cmd;
176
    }
177
178
    /**
179
     * Generates the system command
180
     *
181 5
     * @return string
182
     */
183 5
    public function getCommand(): string
184 5
    {
185 1
        $amount = count($this->commands);
186
        if ($amount < 1) {
187 4
            throw new RuntimeException('no command to execute');
188 4
        }
189 4
        $cmd = $this->getPipeFail()
190 4
             . ($amount > 1 ? '(' . implode(' && ', $this->commands) . ')' : $this->commands[0])
191
             . $this->getPipeline()
192 4
             . (!empty($this->redirectOutput) ? ' > ' . $this->redirectOutput : '');
193
194
        return $cmd;
195
    }
196
197
    /**
198
     * Returns a list of exit codes that are valid
199
     *
200 1
     * @return array
201
     */
202 1
    public function getAcceptableExitCodes(): array
203
    {
204
        return $this->acceptedExitCodes;
205
    }
206
207
    /**
208
     * Returns the command to execute
209
     *
210 1
     * @return string
211
     */
212 1
    public function __toString(): string
213
    {
214
        return $this->getCommand();
215
    }
216
}
217