Installer::setConsole()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
c 1
b 0
f 0
dl 0
loc 5
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
namespace Rawilk\LaravelModules\Process;
4
5
use Illuminate\Console\Command;
6
use Illuminate\Support\Str;
7
use Rawilk\LaravelModules\Contracts\Repository;
8
use Symfony\Component\Process\Process;
9
10
class Installer
11
{
12
    /** @var \Illuminate\Console\Command */
13
    protected $console;
14
15
    /** @var string */
16
    protected $name;
17
18
    /** @var string */
19
    protected $path;
20
21
    /** @var \Rawilk\LaravelModules\Contracts\Repository */
22
    protected $repository;
23
24
    /** @var int */
25
    protected $timeout = 3360;
26
27
    /** @var bool */
28
    private $tree;
29
30
    /** @var string|null */
31
    private $type;
32
33
    /** @var string */
34
    protected $version;
35
36
    /**
37
     * @param string $name
38
     * @param string|null $version
39
     * @param string|null $type
40
     * @param bool $tree
41
     */
42
    public function __construct(string $name, ?string $version = null, ?string $type = null, bool $tree = false)
43
    {
44
        $this->name = $name;
45
        $this->version = $version;
46
        $this->type = $type;
47
        $this->tree = $tree;
48
    }
49
50
    public function getBranch(): string
51
    {
52
        return $this->version ?? 'master';
53
    }
54
55
    public function getDestinationPath(): string
56
    {
57
        if ($this->path) {
58
            return $this->path;
59
        }
60
61
        return $this->repository->getModulePath($this->getModuleName());
62
    }
63
64
    public function getModuleName(): string
65
    {
66
        $parts = explode('/', $this->name);
67
68
        return Str::studly(end($parts));
69
    }
70
71
    public function getPackageName(): string
72
    {
73
        if ($this->version === null) {
74
            return "{$this->name}:dev-master";
75
        }
76
77
78
        return "{$this->name}:{$this->version}";
79
    }
80
81
    public function getProcess(): Process
82
    {
83
        if ($this->type) {
84
            if ($this->tree) {
85
                return $this->installViaSubtree();
86
            }
87
88
            return $this->installViaGit();
89
        }
90
91
        return $this->installViaComposer();
92
    }
93
94
    public function getRepoUrl(): ?string
95
    {
96
        switch ($this->type) {
97
            case 'github':
98
                return "[email protected]:{$this->name}.git";
99
            case 'github-https':
100
                return "https://github.com/{$this->name}.git";
101
            case 'gitlab':
102
                return "[email protected]:{$this->name}.git";
103
            case 'bitbucket':
104
                return "[email protected]:{$this->name}.git";
105
            default:
106
                // Check of type 'scheme://host/path'
107
                if (filter_var($this->type, FILTER_VALIDATE_URL)) {
108
                    return $this->type;
109
                }
110
111
                // Check of type 'user@host'
112
                if (filter_var($this->type, FILTER_VALIDATE_EMAIL)) {
113
                    return "{$this->type}:{$this->name}.git";
114
                }
115
116
                return null;
117
        }
118
    }
119
120
    public function installViaComposer(): Process
121
    {
122
        return Process::fromShellCommandline(sprintf(
123
            'cd %s && composer require %s',
124
            base_path(),
125
            $this->getPackageName()
126
        ));
127
    }
128
129
    public function installViaGit(): Process
130
    {
131
        return Process::fromShellCommandline(sprintf(
132
            'cd %s && git clone %s %s && cd %s && git checkout %s',
133
            base_path(),
134
            $this->getRepoUrl(),
135
            $this->getDestinationPath(),
136
            $this->getDestinationPath(),
137
            $this->getBranch()
138
        ));
139
    }
140
141
    public function installViaSubtree(): Process
142
    {
143
        return Process::fromShellCommandline(sprintf(
144
            'cd %s && git remote add %s %s && git subtree add --prefix=%s --squash %s %s',
145
            base_path(),
146
            $this->getModuleName(),
147
            $this->getRepoUrl(),
148
            $this->getDestinationPath(),
149
            $this->getModuleName(),
150
            $this->getBranch()
151
        ));
152
    }
153
154
    public function run(): Process
155
    {
156
        $process = $this->getProcess();
157
158
        $process->setTimeout($this->timeout);
159
160
        if ($this->console instanceof Command) {
0 ignored issues
show
introduced by
$this->console is always a sub-type of Illuminate\Console\Command.
Loading history...
161
            $process->run(function ($type, $line) {
162
                $this->console->line($line);
163
            });
164
        }
165
166
        return $process;
167
    }
168
169
    public function setConsole(Command $console): self
170
    {
171
        $this->console = $console;
172
173
        return $this;
174
    }
175
176
    public function setPath(string $path): self
177
    {
178
        $this->path = $path;
179
180
        return $this;
181
    }
182
183
    public function setRepository(Repository $repository): self
184
    {
185
        $this->repository = $repository;
186
187
        return $this;
188
    }
189
190
    public function setTimeout(int $timeout): self
191
    {
192
        $this->timeout = $timeout;
193
194
        return $this;
195
    }
196
}
197