Completed
Pull Request — master (#30)
by Titouan
02:31
created

PuliRunner::__construct()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 35
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 35
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 3
            $puli = $puliFinder->find('puli', null, $searchPath);
61
62 3
            if (!$puli) {
63
                throw new RuntimeException('The "puli"/"puli.phar" command could not be found.');
64
            }
65 3
        }
66
67 3
        $content = file_get_contents($puli, null, null, -1, 18);
68
69 3
        if ($content === '#!/usr/bin/env php' || 0 === strpos($content, '<?php')) {
70 2
            $this->puli = escapeshellcmd($php).' '.ProcessUtils::escapeArgument($puli);
71 2
        } else {
72 1
            $this->puli = escapeshellcmd($puli);
73
        }
74 3
    }
75
76
    /**
77
     * Runs a Puli command.
78
     *
79
     * @param string   $command The Puli command to run.
80
     * @param string[] $args    Arguments to quote and insert into the command.
81
     *                          For each key "key" in this array, the placeholder
82
     *                          "%key%" should be present in the command string.
83
     *
84
     * @return string The lines of the output.
85
     */
86
    public function run($command, array $args = array())
87
    {
88
        $replacements = array();
89
90
        foreach ($args as $key => $arg) {
91
            $replacements['%'.$key.'%'] = ProcessUtils::escapeArgument($arg);
92
        }
93
94
        // Disable colorization so that we can process the output
95
        // Enable exception traces by using the "-vv" switch
96
        $fullCommand = sprintf('%s %s --no-ansi -vv', $this->puli, strtr($command, $replacements));
97
98
        $process = new Process($fullCommand);
99
        $process->run();
100
101
        if (!$process->isSuccessful()) {
102
            throw PuliRunnerException::forProcess($process);
103
        }
104
105
        // Normalize line endings across systems
106
        return str_replace("\r\n", "\n", $process->getOutput());
107
    }
108
}
109