Failed Conditions
Pull Request — master (#85)
by Keoghan
06:09
created

DockerSync::adjustDockerComposeSetup()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 27
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 3.0021

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 17
c 2
b 0
f 0
dl 0
loc 27
ccs 15
cts 16
cp 0.9375
rs 9.7
cc 3
nc 3
nop 1
crap 3.0021
1
<?php
2
3
namespace App\Support\DockerSync;
4
5
use App\Models\PhpVersion;
6
use App\PorterLibrary;
7
use App\Support\Contracts\Cli;
8
use App\Support\Mechanics\MacOs;
9
use App\Support\Mechanics\Mechanic;
10
use Illuminate\Filesystem\Filesystem;
11
use Illuminate\Support\Str;
12
use Symfony\Component\Yaml\Yaml;
13
14
class DockerSync
15
{
16
    /** @var Mechanic */
17
    protected $mechanic;
18
    /** @var Cli */
19
    protected $cli;
20
    /** @var FileSystem */
21
    protected $files;
22
    /** @var PorterLibrary */
23
    private $library;
24
25 191
    public function __construct(Mechanic $mechanic, Cli $cli, Filesystem $files, PorterLibrary $library)
26
    {
27 191
        $this->mechanic = $mechanic;
28 191
        $this->cli = $cli;
29 191
        $this->files = $files;
30 191
        $this->library = $library;
31 191
    }
32
33
    /**
34
     * Check if docker-sync is active
35
     * @return bool
36
     */
37 14
    public function isActive()
38
    {
39 14
        return setting('use_docker-sync') === 'on';
40
    }
41
42
    /**
43
     * Install docker-sync
44
     *
45
     * @throws CannotInstallDockerSync
46
     */
47 3
    public function install()
48
    {
49 3
        $this->checkForMacOs();
50
51 1
        $this->cli->passthru('gem install --user-install docker-sync');
52 1
    }
53
54
    /**
55
     * Check this command is running on MacOS
56
     * @throws CannotInstallDockerSync
57
     */
58 3
    protected function checkForMacOs(): void
59
    {
60 3
        if (get_class($this->mechanic) !== MacOs::class) {
61 2
            throw new CannotInstallDockerSync('The OS must be MacOs');
62
        }
63 1
    }
64
65
    /**
66
     * Adjust the docker-compose file to point to sync volumes, create docker-sync.yaml
67
     *
68
     * MySQL and Redis usage not explored as yet.
69
     *
70
     * @param  string  $composeFile
71
     *
72
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
73
     */
74 1
    public function adjustDockerComposeSetup(string $composeFile)
75
    {
76 1
        if (!$this->isActive()) {
77
            return;
78
        }
79
80 1
        $composeYaml = $this->getYaml($composeFile);
81 1
        $syncYamlFile = dirname($composeFile).'/docker-sync.yml';
82
        $syncYaml = [
83 1
            'version' => 2,
84 1
            'syncs'   => $this->getSyncs(),
85
        ];
86
87 1
        foreach (PhpVersion::active()->get() as $version) {
88 1
            $composeYaml['services'][$version->cli_name]['volumes'][0] = $this->replaceSync($composeYaml['services'][$version->cli_name]['volumes'][0]);
89 1
            $composeYaml['services'][$version->fpm_name]['volumes'][0] = $this->replaceSync($composeYaml['services'][$version->fpm_name]['volumes'][0]);
90
        }
91
92 1
        $composeYaml['services']['node']['volumes'][0] = $this->replaceSync($composeYaml['services']['node']['volumes'][0]);
93 1
        $composeYaml['services']['nginx']['volumes'][0] = $this->replaceSync($composeYaml['services']['nginx']['volumes'][0]);
94
95
        $composeYaml['volumes'] = array_map(function () {
96 1
            return ['external' => true];
97 1
        }, $this->getSyncs());
98
99 1
        $this->putYaml($composeFile, $composeYaml);
100 1
        $this->putYaml($syncYamlFile, $syncYaml);
101 1
    }
102
103 1
    protected function getSyncs()
104
    {
105
        return [
106 1
            'home' => [
107 1
                'src'           => setting('home'),
108
                'watch_excludes'=> ['.*/.git', '.*/node_modules'],
109
            ],
110
        ];
111
    }
112
113 1
    protected function replaceSync($string, $sync = 'home')
114
    {
115 1
        $pathParts = explode(':', $string);
116
117 1
        $source = $pathParts[0];
118 1
        $target = $pathParts[1];
119
120 1
        $syncPath = $this->getSyncs()[$sync]['src'];
121
122 1
        if ($source !== $syncPath) {
0 ignored issues
show
introduced by
The condition $source !== $syncPath is always true.
Loading history...
123
            return $string;
124
        }
125
126 1
        return implode(':', [$sync, $target, 'nocopy']);
127
    }
128
129
    /**
130
     * Get the yaml from the file
131
     *
132
     * @param  string  $file
133
     *
134
     * @return mixed
135
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
136
     */
137 1
    public function getYaml(string $file)
138
    {
139 1
        return Yaml::parse($this->files->get($file));
140
    }
141
142
    /**
143
     * Save array to yaml file
144
     *
145
     * @param  string  $file
146
     * @param  array   $yaml
147
     */
148 1
    public function putYaml(string $file, array $yaml)
149
    {
150 1
        $this->files->put($file, Yaml::dump($yaml, 5, 2));
151 1
    }
152
153
    /**
154
     * Start the docker-syn daemon
155
     */
156 5
    public function startDaemon()
157
    {
158 5
        if (!$this->isActive()) {
159 5
            return;
160
        }
161
162 1
        $this->cli->execRealTime($this->getPath().'docker-sync start --config="'.$this->library->path().'/docker-sync.yml"');
163 1
    }
164
165
    /**
166
     * Stop the docker-sync daemon
167
     */
168 5
    public function stopDaemon()
169
    {
170 5
        if (!$this->isActive()) {
171 5
            return;
172
        }
173
174 1
        $this->cli->execRealTime($this->getPath().'docker-sync stop --config="'.$this->library->path().'/docker-sync.yml"');
175 1
    }
176
177
    /**
178
     * Get the path for docker-sync
179
     *
180
     * @return string
181
     */
182 2
    public function getPath()
183
    {
184 2
        return str_replace("\n", '', $this->cli->exec("ruby -r rubygems -e 'puts Gem.user_dir'")).'/bin/';
185
    }
186
}
187