Passed
Pull Request — 2.x (#1388)
by Harings
12:18
created

UpgradeCommand::dumpAutoloader()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
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 12
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
        if (config('app.env') === 'production') {
24
            $this->error('Do not run this on production.');
25
            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...
26
        }
27
        $this->info('This command will refactor code in your codebase.');
28
        $this->info(
29
            'Before you start the upgrade, please make sure you have a backup. Do not run this command on production!'
30
        );
31
        if (!$this->confirm('Are you sure you want to start the upgrade?', false)) {
32
            $this->error('Cancelled');
33
            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...
34
        }
35
36
        $this->fsAsStorage = Storage::build([
37
            'driver' => 'local',
38
            '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

38
            'root' => app()->/** @scrutinizer ignore-call */ basePath(),
Loading history...
39
        ]);
40
41
        $this->moveRoutesFile();
42
        $this->moveResourcesAdminFolder();
43
        $this->moveRepositoriesToSubdirectory();
44
        $this->moveControllerAdminDirectories();
45
46
        $this->dumpAutoloader();
47
        $this->runRector('app');
48
        $this->runRector('resources');
49
        $this->runRector('routes');
50
        $this->runRector('config');
51
    }
52
53
    protected function moveRoutesFile(): void
54
    {
55
        if (!$this->fsAsStorage->exists('routes/admin.php')) {
56
            $this->warn('Not moving routes/admin.php, file not present.');
57
            return;
58
        }
59
        $this->info('Moving routes/admin.php to routes/twill.php');
60
        $this->fsAsStorage->move('routes/admin.php', 'routes/twill.php');
61
        $this->newLine();
62
    }
63
64
    protected function moveResourcesAdminFolder(): void
65
    {
66
        if ($this->fsAsStorage->exists('resources/views/twill')) {
67
            $this->warn('Not moving resources/views/admin, resources/views/twill already exists.');
68
            return;
69
        }
70
        $this->info('Moving resources/views/admin/* to resources/views/twill/*');
71
        $this->fsAsStorage->move('resources/views/admin', 'resources/views/twill');
72
        $this->newLine();
73
    }
74
75
    protected function moveRepositoriesToSubdirectory(): void
76
    {
77
        if ($this->fsAsStorage->exists('app/Repositories/Twill')) {
78
            $this->warn('Not moving app/Repositories, app/Repositories/Twill already exists.');
79
            return;
80
        }
81
        $this->info('Moving app/Repositories/* to app/Repositories/Twill/*');
82
        $this->fsAsStorage->makeDirectory('app/Repositories/Twill');
83
        foreach ($this->fsAsStorage->files('app/Repositories') as $file) {
84
            $this->fsAsStorage->move($file, Str::replaceFirst('app/Repositories/', 'app/Repositories/Twill/', $file));
85
        }
86
87
        $this->newLine();
88
    }
89
90
    protected function moveControllerAdminDirectories(): void
91
    {
92
        if ($this->fsAsStorage->exists('app/Http/Controllers/Twill')) {
93
            $this->warn('Not moving app/Http/Controllers/Admin, app/Http/Controllers/Twill already exists.');
94
            return;
95
        }
96
        $this->info('Moving app/Http/Controllers/Admin to app/Http/Controllers/Twill');
97
        $this->fsAsStorage->move('app/Http/Controllers/Admin', 'app/Http/Controllers/Twill');
98
        $this->info('Moving app/Http/Requests/Admin to app/Http/Requests/Twill');
99
        $this->fsAsStorage->move('app/Http/Requests/Admin', 'app/Http/Requests/Twill');
100
        $this->newLine();
101
    }
102
103
    protected function dumpAutoloader(): void
104
    {
105
        $this->info('Dumping composer autoloader');
106
        $process = new \Symfony\Component\Process\Process(
107
            ['composer', 'dump-autoload']
108
        );
109
        $process->run();
110
111
        if (!$process->isSuccessful()) {
112
            $this->error('Failed running composer dump-autoload');
113
            $this->error($process->getOutput());
114
            $this->error($process->getErrorOutput());
115
        }
116
    }
117
118
    protected function runRector(string $directory): void
119
    {
120
        $this->info('Running rector refactoring in ' . $directory);
121
122
        $process = new \Symfony\Component\Process\Process(
123
            ['php', 'vendor/bin/rector', 'process', $directory, '--config=vendor/area17/twill/rector.php']
124
        );
125
        $process->run();
126
127
        if (!$process->isSuccessful()) {
128
            $this->error('Failed running rector in ' . $directory);
129
            $this->error($process->getOutput());
130
            $this->error($process->getErrorOutput());
131
            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...
132
        }
133
134
        $this->info('Successfully ran refactorings in ' . $directory);
135
        $this->info($process->getOutput());
136
    }
137
}
138