Test Failed
Pull Request — master (#85)
by Keoghan
06:00
created

DockerSync::replaceSync()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 7
c 1
b 0
f 0
dl 0
loc 15
ccs 0
cts 8
cp 0
rs 10
cc 2
nc 2
nop 2
crap 6
1
<?php
2
3
4
namespace App\Support\DockerSync;
5
6
7
use App\PorterLibrary;
8
use App\Models\PhpVersion;
9
use Illuminate\Support\Str;
10
use App\Support\Contracts\Cli;
11
use App\Support\Mechanics\MacOs;
12
use Symfony\Component\Yaml\Yaml;
13
use App\Support\Mechanics\Mechanic;
14
use Illuminate\Filesystem\Filesystem;
15
16
class DockerSync
17
{
18
    /** @var Mechanic */
19
    protected $mechanic;
20
    /** @var Cli */
21
    protected $cli;
22
    /** @var FileSystem */
23
    protected $files;
24
    /** @var string|null */
25
    protected $homePath;
26
    /** @var PorterLibrary */
27
    private $library;
28
29
    public function __construct(Mechanic $mechanic, Cli $cli, Filesystem $files, PorterLibrary $library)
30
    {
31
        $this->mechanic = $mechanic;
32
        $this->cli = $cli;
33
        $this->files = $files;
34
        $this->homePath = setting('home');
35
        $this->library = $library;
36
    }
37
38
    public function isActive()
39
    {
40
        return setting('use_docker-sync') === 'on';
41
    }
42
43
    public function install()
44
    {
45
        $this->checkForMacOs();
46
47
        $this->cli->passthru('gem install --user-install docker-sync');
48
    }
49
50
    protected function checkForMacOs(): void
51
    {
52
        if (get_class($this->mechanic) !== MacOs::class) {
53
            throw new CannotInstallDockerSync('The OS must be MacOs');
54
        }
55
    }
56
57
    public function adjustDockerComposeSetup(string $composeFile)
58
    {
59
        if (! $this->isActive()) {
60
            return;
61
        }
62
63
        $composeYaml = $this->getYaml($composeFile);
64
        $syncYamlFile = dirname($composeFile).'/docker-sync.yml';
65
        $syncYaml = [
66
            'version' => 2,
67
            'syncs' => $this->getSyncs(),
68
        ];
69
70
//        if (setting('use_mysql') === 'on') {
71
//            $composeYaml['services']['mysql']['volumes'][0] = $this->replaceSync($composeYaml['services']['mysql']['volumes'][0], 'mysql-data');
72
//        }
73
//
74
//        if (setting('use_redis') === 'on') {
75
//            $composeYaml['services']['redis']['volumes'][0] = $this->replaceSync($composeYaml['services']['redis']['volumes'][0], 'redis-data');
76
//        }
77
78
        foreach(PhpVersion::active()->get() as $version) {
79
            $composeYaml['services'][$version->cli_name]['volumes'][0] = $this->replaceSync($composeYaml['services'][$version->cli_name]['volumes'][0]);
80
            $composeYaml['services'][$version->fpm_name]['volumes'][0] = $this->replaceSync($composeYaml['services'][$version->fpm_name]['volumes'][0]);
81
        }
82
83
        $composeYaml['services']['node']['volumes'][0] = $this->replaceSync($composeYaml['services']['node']['volumes'][0]);
84
        $composeYaml['services']['nginx']['volumes'][0] = $this->replaceSync($composeYaml['services']['nginx']['volumes'][0]);
85
86
        $composeYaml['volumes'] = array_map(function () {
87
            return ['external' => true];
88
        }, $this->getSyncs());
89
90
        $this->putYaml($composeFile, $composeYaml);
91
//        $this->putYaml(str_replace('docker-compose', 'docker-compose-dev', $composeFile), $composeYaml);
92
        $this->putYaml($syncYamlFile, $syncYaml);
93
    }
94
95
    protected function getSyncs()
96
    {
97
        return [
98
            'home' => [
99
                'src' => $this->homePath,
100
                'watch_excludes'=> ['.*/.git', '.*/node_modules'],
101
            ],
102
//            'mysql-data' => $this->library->path().'/data/mysql',
103
//            'redis-data' => $this->library->path().'/data/redis',
104
        ];
105
    }
106
107
    protected function replaceSync($string, $sync = 'home')
108
    {
109
        $pathParts = explode(':', $string);
110
111
        $source = $pathParts[0];
112
        $target = $pathParts[1];
113
        // $settings = $pathParts[2] ?? '';
114
115
        $syncPath = $this->getSyncs()[$sync]['src'];
116
117
        if ($source !== $syncPath) {
118
            return $string;
119
        }
120
121
        return implode(':', [$sync, $target, 'nocopy']);
122
//        return [
123
//            'type' => 'volume',
124
//            'source' => $sync,
125
//            'target' => $target,
126
//            'volume' => ['nocopy' => true],
127
//        ];
128
    }
129
130
    public function getYaml(string $file)
131
    {
132
        return Yaml::parseFile($file);
133
    }
134
135
    public function putYaml(string $file, array $yaml)
136
    {
137
        $this->files->put($file, Yaml::dump($yaml, 5, 2));
138
    }
139
140
    public function startDaemon()
141
    {
142
        if (! $this->isActive()) {
143
            return;
144
        }
145
146
        $this->cli->execRealTime($this->getPath().'docker-sync start --config="'.$this->library->path().'/docker-sync.yml"');
147
    }
148
149
    public function stopDaemon()
150
    {
151
        if (! $this->isActive()) {
152
            return;
153
        }
154
155
        $this->cli->execRealTime($this->getPath().'docker-sync stop --config="'.$this->library->path().'/docker-sync.yml"');
156
    }
157
158
    public function getPath()
159
    {
160
        return str_replace("\n", "", $this->cli->exec("ruby -r rubygems -e 'puts Gem.user_dir'"))."/bin/";
161
    }
162
}
163