Passed
Pull Request — 2.x (#1388)
by Harings
14:20
created

UpgradeCommand::moveRoutesFile()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 6
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 9
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->moveRepositoriesToSubdirectory();
50
        $this->moveControllerAdminDirectories();
51
52
        $this->dumpAutoloader();
53
        $this->runRector();
54
    }
55
56
    protected function moveRoutesFile(): void
57
    {
58
        if (!$this->fsAsStorage->exists('routes/admin.php')) {
59
            $this->warn('Not moving routes/admin.php, file not present.');
60
            return;
61
        }
62
        $this->info('Moving routes/admin.php to routes/twill.php');
63
        $this->fsAsStorage->move('routes/admin.php', 'routes/twill.php');
64
        $this->newLine();
65
    }
66
67
    protected function moveResourcesAdminFolder(): void
68
    {
69
        if ($this->fsAsStorage->exists('resources/views/twill')) {
70
            $this->warn('Not moving resources/views/admin, resources/views/twill already exists.');
71
            return;
72
        }
73
        $this->info('Moving resources/views/admin/* to resources/views/twill/*');
74
        $this->fsAsStorage->move('resources/views/admin', 'resources/views/twill');
75
        $this->newLine();
76
    }
77
78
    protected function moveRepositoriesToSubdirectory(): void
79
    {
80
        if ($this->fsAsStorage->exists('app/Repositories/Twill')) {
81
            $this->warn('Not moving app/Repositories, app/Repositories/Twill already exists.');
82
            return;
83
        }
84
        $this->info('Moving app/Repositories/* to app/Repositories/Twill/*');
85
        $this->fsAsStorage->makeDirectory('app/Repositories/Twill');
86
        foreach ($this->fsAsStorage->files('app/Repositories') as $file) {
87
            $this->fsAsStorage->move($file, Str::replaceFirst('app/Repositories/', 'app/Repositories/Twill/', $file));
88
        }
89
90
        $this->newLine();
91
    }
92
93
    protected function moveControllerAdminDirectories(): void
94
    {
95
        if ($this->fsAsStorage->exists('app/Http/Controllers/Twill')) {
96
            $this->warn('Not moving app/Http/Controllers/Admin, app/Http/Controllers/Twill already exists.');
97
            return;
98
        }
99
        $this->info('Moving app/Http/Controllers/Admin to app/Http/Controllers/Twill');
100
        $this->fsAsStorage->move('app/Http/Controllers/Admin', 'app/Http/Controllers/Twill');
101
        $this->info('Moving app/Http/Requests/Admin to app/Http/Requests/Twill');
102
        $this->fsAsStorage->move('app/Http/Requests/Admin', 'app/Http/Requests/Twill');
103
        $this->newLine();
104
    }
105
106
    protected function dumpAutoloader(): void
107
    {
108
        sleep(1);
109
        $this->info('Dumping composer autoloader');
110
        $process = new \Symfony\Component\Process\Process(
111
            ['composer', 'dump-autoload'],
112
            null,
113
            null,
114
            null,
115
            null
116
        );
117
        $process->run();
118
119
        if (!$process->isSuccessful()) {
120
            $this->error('Failed running composer dump-autoload');
121
            $this->error($process->getOutput());
122
            $this->error($process->getErrorOutput());
123
        }
124
    }
125
126
    protected function runRector(): void
127
    {
128
        $this->info('Running rector refactorings');
129
130
        $process = new \Symfony\Component\Process\Process(
131
            ['php', 'vendor/bin/rector', 'process', '--config=vendor/area17/twill/rector.php'],
132
            null,
133
            null,
134
            null,
135
            null
136
        );
137
        $process->run();
138
139
        if (!$process->isSuccessful()) {
140
            $this->error('Failed running rector');
141
            $this->error($process->getOutput());
142
            $this->error($process->getErrorOutput());
143
            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...
144
        }
145
146
        $this->info('Successfully ran refactorings');
147
        $this->info($process->getOutput());
148
    }
149
}
150