Failed Conditions
Pull Request — master (#68)
by Keoghan
04:22
created

Open   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 82
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 10
eloc 36
c 2
b 0
f 0
dl 0
loc 82
ccs 0
cts 35
cp 0
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
B handle() 0 38 7
A checkItWillResolveProperly() 0 14 3
1
<?php
2
3
namespace App\Commands\Ngrok;
4
5
use App\Porter;
6
use App\Models\Site;
7
use App\Commands\BaseCommand;
8
use App\Support\Mechanics\Mechanic;
9
use App\Support\Mechanics\Exceptions\UnableToRetrieveIP;
10
11
class Open extends BaseCommand
12
{
13
    /**
14
     * The signature of the command.
15
     *
16
     * @var string
17
     */
18
    protected $signature = 'ngrok {site?} {--region=eu} {--no-inspection}';
19
20
    /**
21
     * The description of the command.
22
     *
23
     * @var string
24
     */
25
    protected $description = 'Open ngrok connection to forward your dev environment to an external url';
26
27
    /**
28
     * Execute the console command.
29
     *
30
     * @return void
31
     */
32
    public function handle(): void
33
    {
34
        $site = Site::resolveFromPathOrCurrentWorkingDirectory($this->argument('site'));
0 ignored issues
show
Bug introduced by
It seems like $this->argument('site') can also be of type array; however, parameter $path of App\Models\Site::resolve...rrentWorkingDirectory() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

34
        $site = Site::resolveFromPathOrCurrentWorkingDirectory(/** @scrutinizer ignore-type */ $this->argument('site'));
Loading history...
35
        $wasSecure = false;
36
37
        if (! $site) {
38
            $this->error('No site at this location, and no site path provided.');
39
            return;
40
        }
41
42
        if (! $this->checkItWillResolveProperly()) {
43
            return;
44
        }
45
46
        if ($site->secure) {
47
            $this->info('Removing SSL for site (required for free ngrok version)');
48
            $site->unsecure();
49
            $wasSecure = true;
50
        }
51
52
        app(Porter::class)->stop('ngrok');
53
54
        $tls = ' -bind-tls='.($wasSecure ? 'true' : 'false');
55
        $region = ' -region='. $this->option('region');
56
        $inspect = ' -inspect='.($this->option('no-inspection') ? 'false' : 'true');
57
58
        $this->dockerCompose
59
            ->runContainer('ngrok')
60
            ->append("ngrok http -host-header=rewrite{$region}{$tls}{$inspect} {$site->url}:80")
61
            ->interactive()
62
            ->perform();
63
64
        if ($wasSecure) {
65
            $this->info('Restoring SSL for site');
66
            $site->secure();
67
        }
68
69
        app(Porter::class)->stop('ngrok');
70
    }
71
72
    /**
73
     * Checking that Porter is using the dns:set-host IP. If we don't ngrok
74
     * requests will only resolve to 127.0.0.1 which is internal to the
75
     * ngrok container, and results in a useless 502 error.
76
     *
77
     * @return bool
78
     */
79
    public function checkItWillResolveProperly()
80
    {
81
        try {
82
            if (app(Mechanic::class)->isUsingDefaultHostAddress()) {
83
                $this->info('You need to use an alternative loopback address.');
84
                $this->info('Please run porter dns:set-host and review the documentation here: https://github.com/konsulting/porter#dns');
85
                return false;
86
            }
87
        } catch (UnableToRetrieveIP $e) {
88
            $this->info('Please run porter dns:flush and try again. You may need to give it a little while.');
89
            return false;
90
        }
91
92
        return true;
93
    }
94
}
95