Passed
Push — master ( 2dc816...22f991 )
by Samuel
02:53 queued 28s
created

PhpSsh::run()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 20
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 11
nc 3
nop 0
1
<?php
2
3
namespace Dock\Installer\System\Mac;
4
5
use Dock\Installer\InstallerTask;
6
use Dock\IO\ProcessRunner;
7
use Dock\IO\UserInteraction;
8
use SRIO\ChainOfResponsibility\DependentChainProcessInterface;
9
use Symfony\Component\Console\Question\Question;
10
11
class PhpSsh extends InstallerTask implements DependentChainProcessInterface
12
{
13
    /**
14
     * @var ProcessRunner
15
     */
16
    private $processRunner;
17
    /**
18
     * @var UserInteraction
19
     */
20
    private $userInteraction;
21
22
    /**
23
     * @param UserInteraction        $userInteraction
24
     * @param \Dock\IO\ProcessRunner $processRunner
25
     */
26
    public function __construct(UserInteraction $userInteraction, ProcessRunner $processRunner)
27
    {
28
        $this->userInteraction = $userInteraction;
29
        $this->processRunner = $processRunner;
30
    }
31
32
    /**
33
     * {@inheritdoc}
34
     */
35
    public function getName()
36
    {
37
        return 'phpSsh';
38
    }
39
40
    /**
41
     * {@inheritdoc}
42
     */
43
    public function dependsOn()
44
    {
45
        return ['homebrew'];
46
    }
47
48
    /**
49
     * {@inheritdoc}
50
     */
51
    public function run()
52
    {
53
        $this->userInteraction->writeTitle('Checking PHP SSH2 extension');
54
55
        if ($this->sshExtensionInstalled()) {
56
            return;
57
        }
58
59
        $this->userInteraction->write('PHP SSH2 extension is required.');
60
61
        $package = $this->promptForPackageName();
62
63
        if ($package == 'n') {
64
            $this->userInteraction->write('Skipping PHP SSH2 extension installation, do it yourself.');
65
        } else {
66
            $this->installHomebrewPackage($package);
67
        }
68
69
        throw new \RuntimeException('Please re-run this installation script to have enabled PHP-SSH2 extension');
70
    }
71
72
    /**
73
     * @return string
74
     */
75
    private function guessSsh2PhpPackage()
76
    {
77
        if (PHP_VERSION_ID > 70000) {
78
            $package = 'php70-ssh2';
79
        } elseif (PHP_VERSION_ID > 50600) {
80
            $package = 'php56-ssh2';
81
        } elseif (PHP_VERSION_ID > 50500) {
82
            $package = 'php55-ssh2';
83
        } elseif (PHP_VERSION_ID > 50400) {
84
            $package = 'php54-ssh2';
85
        } else {
86
            $package = 'php53-ssh2';
87
        }
88
89
        return $package;
90
    }
91
92
    /**
93
     * @param string $package
94
     *
95
     * @return bool
96
     */
97
    private function hasHomebrewPackage($package)
98
    {
99
        return $this->processRunner->run('brew install --dry-run '.$package, false)->isSuccessful();
100
    }
101
102
    /**
103
     * @return bool
104
     */
105
    private function sshExtensionInstalled()
106
    {
107
        return function_exists('ssh2_exec');
108
    }
109
110
    /**
111
     * @param $package
112
     */
113
    protected function installHomebrewPackage($package)
114
    {
115
        // Check if the package is known
116
        if (!$this->hasHomebrewPackage($package)) {
117
            $this->userInteraction->write(sprintf('Package "%s" not found, tapping default PHP brews', $package));
118
119
            $this->processRunner->run('brew tap homebrew/dupes');
120
            $this->processRunner->run('brew tap homebrew/versions');
121
            $this->processRunner->run('brew tap homebrew/homebrew-php');
122
        }
123
124
        $this->processRunner->run('brew install '.$package);
125
    }
126
127
    /**
128
     * @return string
129
     */
130
    protected function promptForPackageName()
131
    {
132
        $defaultPhpVersion = $this->guessSsh2PhpPackage();
133
        $question = new Question(
134
            sprintf(
135
                'Which homebrew package do you want to install (default "%s") ? ("n" for nothing)',
136
                $defaultPhpVersion
137
            ),
138
            $defaultPhpVersion
139
        );
140
        $package = $this->userInteraction->ask($question);
141
142
        return $package;
143
    }
144
}
145