Passed
Pull Request — 3.x (#1388)
by Harings
15:34
created

UpgradeCommand::moveControllerAdminDirectories()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 8
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 11
rs 10
1
<?php
2
3
namespace A17\Twill\Commands;
4
5
use Composer\XdebugHandler\Process;
6
use Illuminate\Console\Command;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, A17\Twill\Commands\Command. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
7
use Illuminate\Support\Facades\Storage;
8
use Illuminate\Support\Str;
9
10
class UpgradeCommand extends Command
11
{
12
    protected $signature = 'twill:upgrade';
13
14
    protected $description = 'Performs the required changes to upgrade twill to version 3.x';
15
16
    /**
17
     * @var \Illuminate\Filesystem\FilesystemAdapter
18
     */
19
    protected $fsAsStorage = null;
20
21
    public function handle()
22
    {
23
        $this->fsAsStorage = Storage::build([
24
            'driver' => 'local',
25
            'root' => app()->basePath(),
0 ignored issues
show
introduced by
The method basePath() does not exist on Illuminate\Container\Container. Are you sure you never get this type here, but always one of the subclasses? ( Ignorable by Annotation )

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

25
            'root' => app()->/** @scrutinizer ignore-call */ basePath(),
Loading history...
26
        ]);
27
28
        if (!$this->fsAsStorage->exists('vendor/bin/rector')) {
29
            $this->error('Rector is not installed, please install it using:');
30
            $this->info('composer require rector/rector --dev');
31
            $this->line('Then rerun the command.');
32
            exit(1);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
33
        }
34
        if (config('app.env') === 'production') {
35
            $this->error('Do not run this on production.');
36
            exit(1);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
37
        }
38
        $this->info('This command will refactor code in your codebase.');
39
        $this->info(
40
            'Before you start the upgrade, please make sure you have a backup. Do not run this command on production!'
41
        );
42
        if (!$this->confirm('Are you sure you want to start the upgrade?', false)) {
43
            $this->error('Cancelled');
44
            exit(1);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
45
        }
46
47
        $this->moveRoutesFile();
48
        $this->moveResourcesAdminFolder();
49
        $this->moveControllerAdminDirectories();
50
51
        $this->dumpAutoloader();
52
        $this->runRector();
53
    }
54
55
    protected function moveRoutesFile(): void
56
    {
57
        if (!$this->fsAsStorage->exists('routes/admin.php')) {
58
            $this->warn('Not moving routes/admin.php, file not present.');
59
            return;
60
        }
61
        $this->info('Moving routes/admin.php to routes/twill.php');
62
        $this->fsAsStorage->move('routes/admin.php', 'routes/twill.php');
63
        $this->newLine();
64
    }
65
66
    protected function moveResourcesAdminFolder(): void
67
    {
68
        if ($this->fsAsStorage->exists('resources/views/twill')) {
69
            $this->warn('Not moving resources/views/admin, resources/views/twill already exists.');
70
            return;
71
        }
72
        $this->info('Moving resources/views/admin/* to resources/views/twill*');
73
        $this->fsAsStorage->move('resources/views/admin', 'resources/views/twill');
74
        $this->newLine();
75
    }
76
77
    protected function moveControllerAdminDirectories(): void
78
    {
79
        if ($this->fsAsStorage->exists('app/Http/Controllers/Twill')) {
80
            $this->warn('Not moving app/Http/Controllers/Admin, app/Http/Controllers/Twill already exists.');
81
            return;
82
        }
83
        $this->info('Moving app/Http/Controllers/Admin to app/Http/Controllers/Twill');
84
        $this->fsAsStorage->move('app/Http/Controllers/Admin', 'app/Http/Controllers/Twill');
85
        $this->info('Moving app/Http/Requests/Admin to app/Http/Requests/Twill');
86
        $this->fsAsStorage->move('app/Http/Requests/Admin', 'app/Http/Requests/Twill');
87
        $this->newLine();
88
    }
89
90
    protected function dumpAutoloader(): void
91
    {
92
        sleep(1);
93
        $this->info('Dumping composer autoloader');
94
        $process = new \Symfony\Component\Process\Process(
95
            ['composer', 'dump-autoload'],
96
            null,
97
            null,
98
            null,
99
            null
100
        );
101
        $process->run();
102
103
        if (!$process->isSuccessful()) {
104
            $this->error('Failed running composer dump-autoload');
105
            $this->error($process->getOutput());
106
            $this->error($process->getErrorOutput());
107
        }
108
    }
109
110
    protected function runRector(): void
111
    {
112
        $this->info('Running rector refactorings');
113
114
        $process = new \Symfony\Component\Process\Process(
115
            ['php', 'vendor/bin/rector', 'process', '--config=vendor/area17/twill/rector.php'],
116
            null,
117
            null,
118
            null,
119
            null
120
        );
121
        $process->run();
122
123
        if (!$process->isSuccessful()) {
124
            $this->error('Failed running rector');
125
            $this->error($process->getOutput());
126
            $this->error($process->getErrorOutput());
127
            exit(1);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
128
        }
129
130
        $this->info('Successfully ran refactorings');
131
        $this->info($process->getOutput());
132
    }
133
}
134