Completed
Pull Request — master (#30)
by Titouan
20:05 queued 17:58
created

PuliRunner::__construct()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 36
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 6.0494

Importance

Changes 5
Bugs 3 Features 0
Metric Value
c 5
b 3
f 0
dl 0
loc 36
ccs 16
cts 18
cp 0.8889
rs 8.439
cc 6
eloc 16
nc 6
nop 1
crap 6.0494
1
<?php
2
3
/*
4
 * This file is part of the puli/composer-plugin package.
5
 *
6
 * (c) Bernhard Schussek <[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 Puli\ComposerPlugin;
13
14
use RuntimeException;
15
use Symfony\Component\Process\ExecutableFinder;
16
use Symfony\Component\Process\PhpExecutableFinder;
17
use Symfony\Component\Process\Process;
18
use Symfony\Component\Process\ProcessUtils;
19
use Webmozart\PathUtil\Path;
20
21
/**
22
 * Executes the "puli" command.
23
 *
24
 * @since  1.0
25
 *
26
 * @author Bernhard Schussek <[email protected]>
27
 */
28
class PuliRunner
29
{
30
    /**
31
     * @var string
32
     */
33
    private $puli;
34
35
    /**
36
     * Creates a new runner.
37
     *
38
     * @param string|null $binDir The path to Composer's "bin-dir".
39
     */
40 3
    public function __construct($binDir = null)
41
    {
42 3
        $phpFinder = new PhpExecutableFinder();
43
44 3
        if (!($php = $phpFinder->find())) {
45
            throw new RuntimeException('The "php" command could not be found.');
46
        }
47
48 3
        $puliFinder = new ExecutableFinder();
49
50
        // Search:
51
        // 1. in the current working directory
52
        // 2. in Composer's "bin-dir"
53
        // 3. in the system path
54 3
        $searchPath = array_merge(array(getcwd()), (array) $binDir);
55
56
        // Search "puli.phar" in the PATH and the current directory
57 3
        $puli = $puliFinder->find('puli.phar', null, $searchPath);
58
59 3
        if (!$puli) {
60
            // Search "puli" in the PATH and Composer's "bin-dir"
61 3
            $puli = $puliFinder->find('puli', null, $searchPath);
62
63 3
            if (!$puli) {
64
                throw new RuntimeException('The "puli"/"puli.phar" command could not be found.');
65
            }
66 3
        }
67
68 3
        $content = file_get_contents($puli, null, null, -1, 18);
69
70 3
        if ($content === '#!/usr/bin/env php' || 0 === strpos($content, '<?php')) {
71 2
            $this->puli = escapeshellcmd($php).' '.ProcessUtils::escapeArgument($puli);
72 2
        } else {
73 1
            $this->puli = escapeshellcmd($puli);
74
        }
75 3
    }
76
77
    /**
78
     * Runs a Puli command.
79
     *
80
     * @param string   $command The Puli command to run.
81
     * @param string[] $args    Arguments to quote and insert into the command.
82
     *                          For each key "key" in this array, the placeholder
83
     *                          "%key%" should be present in the command string.
84
     *
85
     * @return string The lines of the output.
86
     */
87
    public function run($command, array $args = array())
88
    {
89
        $replacements = array();
90
91
        foreach ($args as $key => $arg) {
92
            $replacements['%'.$key.'%'] = ProcessUtils::escapeArgument($arg);
93
        }
94
95
        // Disable colorization so that we can process the output
96
        // Enable exception traces by using the "-vv" switch
97
        $fullCommand = sprintf('%s %s --no-ansi -vv', $this->puli, strtr($command, $replacements));
98
99
        $process = new Process($fullCommand);
100
        $process->run();
101
102
        if (!$process->isSuccessful()) {
103
            throw PuliRunnerException::forProcess($process);
104
        }
105
106
        // Normalize line endings across systems
107
        return str_replace("\r\n", "\n", $process->getOutput());
108
    }
109
}
110