Completed
Pull Request — develop (#165)
by
unknown
01:52
created

Caller::getRawOutput()   A

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 0
crap 1
1
<?php
2
3
/**
4
 * GitElephant - An abstraction layer for git written in PHP
5
 * Copyright (C) 2013  Matteo Giachino
6
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation, either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program.  If not, see [http://www.gnu.org/licenses/].
19
 */
20
21
namespace GitElephant\Command\Caller;
22
23
use \Symfony\Component\Process\Process;
24
use \GitElephant\Command\Caller\CallerInterface;
25
use \GitElephant\Exception\InvalidRepositoryPathException;
26
27
/**
28
 * Caller
29
 *
30
 * @author Matteo Giachino <[email protected]>
31
 * @author Tim Bernhard <[email protected]>
32
 */
33
class Caller extends AbstractCaller
34
{
35
    /**
36
     * the repository path
37
     *
38
     * @var string
39
     */
40
    private $repositoryPath;
41
42
    /**
43
     * raw output
44
     *
45
     * @var string
46
     */
47
    private $rawOutput;
48
49
    /**
50
     * Class constructor
51
     *
52
     * @param string|null   $gitPath the physical path to the git binary
53
     * @param string        $repositoryPath the physical base path for the repository
54
     */
55 107
    public function __construct($gitPath, $repositoryPath)
56
    {
57 107
        if (is_null($gitPath)) {
58
            // unix only!
59 107
            $gitPath = exec('which git');
60
        }
61 107
        $this->setBinaryPath($gitPath);
62 107
        if (!is_dir($repositoryPath)) {
63 1
            throw new InvalidRepositoryPathException($repositoryPath);
64
        }
65 107
        $this->repositoryPath = $repositoryPath;
66 107
    }
67
68
    /**
69
     * Executes a command
70
     *
71
     * @param string $cmd               the command to execute
72
     * @param bool   $git               if the command is git or a generic command
73
     * @param string $cwd               the directory where the command must be executed
74
     * @param array  $acceptedExitCodes exit codes accepted to consider the command execution successful
75
     *
76
     * @throws \RuntimeException
77
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
78
     * @throws \Symfony\Component\Process\Exception\ProcessTimedOutException
79
     * @throws \Symfony\Component\Process\Exception\RuntimeException
80
     * @throws \Symfony\Component\Process\Exception\LogicException
81
     * @return Caller
82
     */
83 102
    public function execute(string $cmd, bool $git = true, string $cwd = null, array $acceptedExitCodes = array(0)): CallerInterface
84
    {
85 102
        if ($git) {
86 102
            $cmd = $this->getBinaryPath() . ' ' . $cmd;
87
        }
88 102
        if (stripos(PHP_OS, 'WIN') !== 0) {
89
            // We rely on the C locale in all output we parse.
90 102
            $cmd = 'LC_ALL=C ' . $cmd;
91
        }
92 102
        if (is_null($cwd) || !is_dir($cwd)) {
93 102
            $cwd = $this->repositoryPath;
94
        }
95
96 102
        if (method_exists(Process::class, 'fromShellCommandline')) {
97 102
            $process = Process::fromShellCommandline($cmd, $cwd);
98
        } else {
99
            // compatibility fix required for Symfony/Process < 4.
100
            $process = new Process($cmd, $cwd);
101
        }
102 102
        $process->setTimeout(15000);
103 102
        $process->run();
104 102
        if (!in_array($process->getExitCode(), $acceptedExitCodes)) {
105 1
            $text = 'Exit code: ' . $process->getExitCode();
106 1
            $text .= ' while executing: "' . $cmd;
107 1
            $text .= '" with reason: ' . $process->getErrorOutput();
108 1
            $text .= "\n" . $process->getOutput();
109 1
            throw new \RuntimeException($text);
110
        }
111 101
        $this->rawOutput = $process->getOutput();
112
        // rtrim values
113 101
        $values = array_map('rtrim', explode(PHP_EOL, $process->getOutput()));
114 101
        $this->outputLines = $values;
115 101
        return $this;
116
    }
117
118
    /**
119
     * returns the output of the last executed command
120
     *
121
     * @return string
122
     */
123 7
    public function getOutput(): string
124
    {
125 7
        return implode("\n", $this->outputLines);
126
    }
127
128
    /**
129
     * returns the output of the last executed command as an array of lines
130
     *
131
     * @param bool $stripBlankLines remove the blank lines
132
     *
133
     * @return array
134
     */
135 91
    public function getOutputLines(bool $stripBlankLines = false): array
136
    {
137 91
        if ($stripBlankLines) {
138 81
            $output = array();
139 81
            foreach ($this->outputLines as $line) {
140 81
                if ('' !== $line) {
141 81
                    $output[] = $line;
142
                }
143
            }
144
145 81
            return $output;
146
        }
147 45
        return $this->outputLines;
148
    }
149
150
    /**
151
     * Get RawOutput
152
     *
153
     * @return string
154
     */
155 1
    public function getRawOutput(): string
156
    {
157 1
        return $this->rawOutput;
158
    }
159
}
160