Completed
Push — master ( 0ba61a...2a1d46 )
by Nicolas
05:06
created

Installer::getRepoUrl()   C

Complexity

Conditions 7
Paths 7

Size

Total Lines 32
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 0
Metric Value
cc 7
eloc 18
nc 7
nop 0
dl 0
loc 32
ccs 0
cts 23
cp 0
crap 56
rs 6.7272
c 0
b 0
f 0
1
<?php
2
3
namespace Nwidart\Modules\Process;
4
5
use Illuminate\Console\Command;
6
use Illuminate\Support\Str;
7
use Nwidart\Modules\Repository;
8
use Symfony\Component\Process\Process;
9
10
class Installer
11
{
12
    /**
13
     * The module name.
14
     *
15
     * @var string
16
     */
17
    protected $name;
18
19
    /**
20
     * The version of module being installed.
21
     *
22
     * @var string
23
     */
24
    protected $version;
25
26
    /**
27
     * The module repository instance.
28
     *
29
     * @var \Nwidart\Modules\Repository
30
     */
31
    protected $repository;
32
33
    /**
34
     * The console command instance.
35
     *
36
     * @var \Illuminate\Console\Command
37
     */
38
    protected $console;
39
40
    /**
41
     * The destionation path.
42
     *
43
     * @var string
44
     */
45
    protected $path;
46
47
    /**
48
     * The process timeout.
49
     *
50
     * @var int
51
     */
52
    protected $timeout = 3360;
53
54
    /**
55
     * The constructor.
56
     *
57
     * @param string $name
58
     * @param string $version
59
     * @param string $type
60
     * @param bool   $tree
61
     */
62
    public function __construct($name, $version = null, $type = null, $tree = false)
63
    {
64
        $this->name = $name;
65
        $this->version = $version;
66
        $this->type = $type;
0 ignored issues
show
Bug introduced by
The property type does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
67
        $this->tree = $tree;
0 ignored issues
show
Bug introduced by
The property tree does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
68
    }
69
70
    /**
71
     * Set destination path.
72
     *
73
     * @param string $path
74
     *
75
     * @return $this
76
     */
77
    public function setPath($path)
78
    {
79
        $this->path = $path;
80
81
        return $this;
82
    }
83
84
    /**
85
     * Set the module repository instance.
86
     *
87
     * @param \Nwidart\Modules\Repository $repository
88
     *
89
     * @return $this
90
     */
91
    public function setRepository(Repository $repository)
92
    {
93
        $this->repository = $repository;
94
95
        return $this;
96
    }
97
98
    /**
99
     * Set console command instance.
100
     *
101
     * @param \Illuminate\Console\Command $console
102
     *
103
     * @return $this
104
     */
105
    public function setConsole(Command $console)
106
    {
107
        $this->console = $console;
108
109
        return $this;
110
    }
111
112
    /**
113
     * Set process timeout.
114
     *
115
     * @param int $timeout
116
     *
117
     * @return $this
118
     */
119
    public function setTimeout($timeout)
120
    {
121
        $this->timeout = $timeout;
122
123
        return $this;
124
    }
125
126
    /**
127
     * Run the installation process.
128
     *
129
     * @return \Symfony\Component\Process\Process
130
     */
131
    public function run()
132
    {
133
        $process = $this->getProcess();
134
135
        $process->setTimeout($this->timeout);
136
137
        if ($this->console instanceof Command) {
138
            $process->run(function ($type, $line) {
139
                $this->console->line($line);
140
            });
141
        }
142
143
        return $process;
144
    }
145
146
    /**
147
     * Get process instance.
148
     *
149
     * @return \Symfony\Component\Process\Process
150
     */
151
    public function getProcess()
152
    {
153
        if ($this->type) {
154
            if ($this->tree) {
155
                return $this->installViaSubtree();
156
            }
157
158
            return $this->installViaGit();
159
        }
160
161
        return $this->installViaComposer();
162
    }
163
164
    /**
165
     * Get destination path.
166
     *
167
     * @return string
168
     */
169
    public function getDestinationPath()
170
    {
171
        if ($this->path) {
172
            return $this->path;
173
        }
174
175
        return $this->repository->getModulePath($this->getModuleName());
176
    }
177
178
    /**
179
     * Get git repo url.
180
     *
181
     * @return string|null
182
     */
183
    public function getRepoUrl()
184
    {
185
        switch ($this->type) {
186
            case 'github':
187
                return "[email protected]:{$this->name}.git";
188
189
            case 'github-https':
190
                return "https://github.com/{$this->name}.git";
191
192
            case 'gitlab':
193
                return "[email protected]:{$this->name}.git";
194
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
195
196
            case 'bitbucket':
197
                return "[email protected]:{$this->name}.git";
198
199
            default:
0 ignored issues
show
Coding Style introduced by
The default body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a default statement must start on the line immediately following the statement.

switch ($expr) {
    default:
        doSomething(); //right
        break;
}


switch ($expr) {
    default:

        doSomething(); //wrong
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
200
201
                // Check of type 'scheme://host/path'
202
                if (filter_var($this->type, FILTER_VALIDATE_URL)) {
203
                    return $this->type;
204
                }
205
206
                // Check of type 'user@host'
207
                if (filter_var($this->type, FILTER_VALIDATE_EMAIL)) {
208
                    return "{$this->type}:{$this->name}.git";
209
                }
210
211
                return;
212
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
213
        }
214
    }
215
216
    /**
217
     * Get branch name.
218
     *
219
     * @return string
220
     */
221
    public function getBranch()
222
    {
223
        return is_null($this->version) ? 'master' : $this->version;
224
    }
225
226
    /**
227
     * Get module name.
228
     *
229
     * @return string
230
     */
231
    public function getModuleName()
232
    {
233
        $parts = explode('/', $this->name);
234
235
        return Str::studly(end($parts));
236
    }
237
238
    /**
239
     * Get composer package name.
240
     *
241
     * @return string
242
     */
243
    public function getPackageName()
244
    {
245
        if (is_null($this->version)) {
246
            return $this->name . ':dev-master';
247
        }
248
249
        return $this->name . ':' . $this->version;
250
    }
251
252
    /**
253
     * Install the module via git.
254
     *
255
     * @return \Symfony\Component\Process\Process
256
     */
257 View Code Duplication
    public function installViaGit()
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
258
    {
259
        return new Process(sprintf(
260
            'cd %s && git clone %s %s && cd %s && git checkout %s',
261
            base_path(),
262
            $this->getRepoUrl(),
263
            $this->getDestinationPath(),
264
            $this->getDestinationPath(),
265
            $this->getBranch()
266
        ));
267
    }
268
269
    /**
270
     * Install the module via git subtree.
271
     *
272
     * @return \Symfony\Component\Process\Process
273
     */
274 View Code Duplication
    public function installViaSubtree()
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
275
    {
276
        return new Process(sprintf(
277
            'cd %s && git remote add %s %s && git subtree add --prefix=%s --squash %s %s',
278
            base_path(),
279
            $this->getModuleName(),
280
            $this->getRepoUrl(),
281
            $this->getDestinationPath(),
282
            $this->getModuleName(),
283
            $this->getBranch()
284
        ));
285
    }
286
287
    /**
288
     * Install the module via composer.
289
     *
290
     * @return \Symfony\Component\Process\Process
291
     */
292
    public function installViaComposer()
293
    {
294
        return new Process(sprintf(
295
            'cd %s && composer require %s',
296
            base_path(),
297
            $this->getPackageName()
298
        ));
299
    }
300
}
301