Passed
Branch develop (1ecfd6)
by Nuno
02:37
created

RenameCommand::updateComposer()   A

Complexity

Conditions 3
Paths 1

Size

Total Lines 42

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 3.004

Importance

Changes 0
Metric Value
dl 0
loc 42
ccs 24
cts 26
cp 0.9231
rs 9.248
c 0
b 0
f 0
cc 3
nc 1
nop 1
crap 3.004
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * This file is part of Laravel Zero.
7
 *
8
 * (c) Nuno Maduro <[email protected]>
9
 *
10
 *  For the full copyright and license information, please view the LICENSE
11
 *  file that was distributed with this source code.
12
 */
13
14
namespace LaravelZero\Framework\Commands\App;
15
16
use function sprintf;
17
use Illuminate\Support\Str;
18
use Illuminate\Support\Facades\File;
19
use LaravelZero\Framework\Commands\Command;
20
21
final class RenameCommand extends Command
22
{
23
    /**
24
     * {@inheritdoc}
25
     */
26
    protected $signature = 'app:rename {name? : The new name}';
27
28
    /**
29
     * {@inheritdoc}
30
     */
31
    protected $description = 'Change the application name';
32
33
    /**
34
     * {@inheritdoc}
35
     */
36 1
    public function handle(): void
37
    {
38 1
        $this->info('Renaming the application...');
39
40 1
        $this->rename();
41 1
    }
42
43
    /**
44
     * Updates the binary name and the application
45
     * name on the composer.json.
46
     *
47
     * @return $this
48
     */
49 1
    private function rename(): RenameCommand
50
    {
51 1
        $name = $this->asksForApplicationName();
52
53 1
        if (File::exists($this->app->basePath($name))) {
0 ignored issues
show
Bug introduced by
The method basePath() does not exist on null. ( Ignorable by Annotation )

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

53
        if (File::exists($this->app->/** @scrutinizer ignore-call */ basePath($name))) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
54
            $this->app->abort(403, 'Folder or file already exists.');
55
        } else {
56 1
            $this->renameBinary($name)
57 1
                ->updateComposer($name);
58
        }
59
60 1
        return $this;
61
    }
62
63
    /**
64
     * Asks for the application name.
65
     *
66
     * If there is no interaction, we take the folder basename.
67
     *
68
     * @return string
69
     */
70 1
    private function asksForApplicationName(): string
71
    {
72 1
        if (empty($name = $this->input->getArgument('name'))) {
73
            $name = $this->ask('What is your application name?');
74
        }
75
76 1
        if (empty($name)) {
77
            $name = trim(basename($this->app->basePath()));
78
        }
79
80 1
        return Str::lower($name);
81
    }
82
83
    /**
84
     * Update composer json with related information.
85
     *
86
     * @param string $name
87
     *
88
     * @return $this
89
     */
90 1
    private function updateComposer(string $name): RenameCommand
91
    {
92 1
        $this->task(
0 ignored issues
show
Bug introduced by
The method task() does not exist on LaravelZero\Framework\Commands\App\RenameCommand. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

92
        $this->/** @scrutinizer ignore-call */ 
93
               task(
Loading history...
93 1
            'Updating config/app.php "name" property',
94
            function () use ($name) {
95 1
                $neededLine = "'name' => '" . Str::ucfirst($this->getCurrentBinaryName()) . "'";
96
97 1
                if (! Str::contains($contents = $this->getConfig(), $neededLine)) {
98
                    return false;
99
                }
100 1
                File::put(
101 1
                    $this->app->configPath('app.php'),
102 1
                    Str::replaceFirst(
103 1
                        $neededLine,
104 1
                        "'name' => '" . Str::ucfirst($name) . "'",
105 1
                        $contents
106
                    )
107
                );
108 1
            }
109
        );
110
111 1
        $this->task(
112 1
            'Updating composer "bin"',
113
            function () use ($name) {
114 1
                $neededLine = '"bin": ["' . $this->getCurrentBinaryName() . '"]';
115
116 1
                if (! Str::contains($contents = $this->getComposer(), $neededLine)) {
117
                    return false;
118
                }
119
120 1
                File::put(
121 1
                    $this->app->basePath('composer.json'),
122 1
                    Str::replaceFirst(
123 1
                        $neededLine,
124 1
                        '"bin": ["' . $name . '"]',
125 1
                        $contents
126
                    )
127
                );
128 1
            }
129
        );
130
131 1
        return $this;
132
    }
133
134
    /**
135
     * Renames the application binary.
136
     *
137
     * @param string $name
138
     *
139
     * @return $this
140
     */
141 1
    private function renameBinary(string $name): RenameCommand
142
    {
143 1
        $this->task(
144 1
            sprintf('Renaming application to "%s"', $name),
145
            function () use ($name) {
146 1
                return File::move($this->app->basePath($this->getCurrentBinaryName()), $this->app->basePath($name));
147 1
            }
148
        );
149
150 1
        return $this;
151
    }
152
153
    /**
154
     * Returns the current binary name.
155
     *
156
     * @return string
157
     */
158 1
    private function getCurrentBinaryName(): string
159
    {
160 1
        $composer = $this->getComposer();
161
162 1
        return current(@json_decode($composer)->bin);
163
    }
164
165
    /**
166
     * Returns the composer.json file contents.
167
     *
168
     * @return string
169
     */
170 1
    private function getComposer(): string
171
    {
172 1
        $filePath = $this->app->basePath('composer.json');
173
174 1
        if (! File::exists($filePath)) {
175
            $this->app->abort(400, 'The file composer.json not found');
176
        }
177
178 1
        return File::get($filePath);
179
    }
180
181
    /**
182
     * Returns the config file contents.
183
     *
184
     * @return string
185
     */
186 1
    private function getConfig(): string
187
    {
188 1
        $filePath = $this->app->configPath('app.php');
189
190 1
        if (! File::exists($filePath)) {
191
            $this->app->abort(400, 'The file config/app.php not found');
192
        }
193
194 1
        return File::get($filePath);
195
    }
196
}
197