Completed
Push — master ( 5b86aa...6ccdab )
by Bernhard
02:21
created

PuliRunner::__construct()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 32
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 6.0703

Importance

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