Completed
Push — stable ( 86ecc3...3a45ea )
by Nuno
07:34
created

Renamer::asksForApplicationName()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3.3332

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 4
nop 0
dl 0
loc 12
ccs 4
cts 6
cp 0.6667
crap 3.3332
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file is part of Laravel Zero.
5
 *
6
 * (c) Nuno Maduro <[email protected]>
7
 *
8
 *  For the full copyright and license information, please view the LICENSE
9
 *  file that was distributed with this source code.
10
 */
11
12
namespace LaravelZero\Framework\Commands\App;
13
14
use Illuminate\Support\Str;
15
use Illuminate\Support\Facades\File;
16
use LaravelZero\Framework\Commands\Command;
17
18
/**
19
 * This is the Laravel Zero Framework Renamer Command implementation.
20
 */
21
class Renamer extends Command
22
{
23
    /**
24
     * {@inheritdoc}
25
     */
26
    protected $signature = 'app:rename {name? : The new name}';
27
28
    /**
29
     * {@inheritdoc}
30
     */
31
    protected $description = 'Perform an application rename';
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
    protected function rename(): Renamer
50
    {
51 1
        $name = $this->asksForApplicationName();
52
53 1
        if (File::exists(base_path($name))) {
54
            $this->app->abort(403, 'Folder or file already exists.');
55
        } else {
56 1
            $this->renameBinary($name)->updateComposer($name);
57
        }
58
59 1
        return $this;
60
    }
61
62
    /**
63
     * Asks for the application name.
64
     *
65
     * If there is no interaction, we take the folder basename.
66
     *
67
     * @return string
68
     */
69 1
    protected function asksForApplicationName(): string
70
    {
71 1
        if (empty($name = $this->input->getArgument('name'))) {
72
            $name = $this->ask('What is your application name?');
73
        }
74
75 1
        if (empty($name)) {
76
            $name = trim(basename($this->app->basePath()));
77
        }
78
79 1
        return Str::lower($name);
80
    }
81
82
    /**
83
     * Update composer json with related information.
84
     *
85
     * @param string $name
86
     *
87
     * @return $this
88
     */
89 1
    protected function updateComposer(string $name): Renamer
90
    {
91 1
        $this->task(
0 ignored issues
show
Documentation Bug introduced by
The method task does not exist on object<LaravelZero\Frame...k\Commands\App\Renamer>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
92 1
            'Updating config/app.php "name" property',
93 1 View Code Duplication
            function () use ($name) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
94
95 1
                $neededLine = "'name' => '" . Str::ucfirst($this->getCurrentBinaryName()) . "'";
96
97 1
                if (Str::contains($contents = $this->getConfig(), $neededLine)) {
98 1
                    File::put(
99 1
                        config_path('app.php'),
100 1
                        Str::replaceFirst(
101 1
                            $neededLine,
102 1
                            "'name' => '" . Str::ucfirst($name) . "'",
103 1
                            $contents
104
                        )
105
                    );
106
107 1
                    return true;
108
                }
109
110
                return false;
111 1
            }
112
        );
113
114 1
        $this->task(
0 ignored issues
show
Documentation Bug introduced by
The method task does not exist on object<LaravelZero\Frame...k\Commands\App\Renamer>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
115 1
            'Updating composer "bin"',
116 1 View Code Duplication
            function () use ($name) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
117
118 1
                $neededLine = '"bin": ["'.$this->getCurrentBinaryName().'"]';
119
120 1
                if (Str::contains($contents = $this->getComposer(), $neededLine)) {
121 1
                    File::put(
122 1
                        base_path('composer.json'),
123 1
                        Str::replaceFirst(
124 1
                            $neededLine,
125 1
                            '"bin": ["'.$name.'"]',
126 1
                            $contents
127
                        )
128
                    );
129
130 1
                    return true;
131
                }
132
133
                return false;
134 1
            }
135
        );
136
137 1
        return $this;
138
    }
139
140
    /**
141
     * Renames the application binary.
142
     *
143
     * @param string $name
144
     *
145
     * @return $this
146
     */
147 1
    protected function renameBinary(string $name): Renamer
148
    {
149 1
        $this->task(
0 ignored issues
show
Documentation Bug introduced by
The method task does not exist on object<LaravelZero\Frame...k\Commands\App\Renamer>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
150 1
            sprintf('Renaming application to "%s"', $name),
151 1
            function () use ($name) {
152 1
                return File::move($this->app->basePath($this->getCurrentBinaryName()), $this->app->basePath($name));
0 ignored issues
show
Unused Code introduced by
The call to Application::basePath() has too many arguments starting with $this->getCurrentBinaryName().

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
Unused Code introduced by
The call to Application::basePath() has too many arguments starting with $name.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
153 1
            }
154
        );
155
156 1
        return $this;
157
    }
158
159
    /**
160
     * Returns the current binary name.
161
     *
162
     * @return string
163
     */
164 1
    protected function getCurrentBinaryName(): string
165
    {
166 1
        $composer = $this->getComposer();
167
168 1
        return current(@json_decode($composer)->bin);
169
    }
170
171
    /**
172
     * Get composer file.
173
     *
174
     * @return string
175
     */
176 1
    protected function getComposer(): string
177
    {
178 1
        $file = $this->app->basePath('composer.json');
0 ignored issues
show
Unused Code introduced by
The call to Application::basePath() has too many arguments starting with 'composer.json'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
179
180 1
        if (! File::exists($file)) {
181
            abort(400, 'The file composer.json not found');
182
        }
183
184 1
        return File::get($file);
185
    }
186
187
    /**
188
     * Get config file.
189
     *
190
     * @return string
191
     */
192 1
    protected function getConfig(): string
193
    {
194 1
        $file = config_path('app.php');
195
196 1
        if (! File::exists($file)) {
197
            abort(400, 'The file config/app.php not found');
198
        }
199
200 1
        return File::get($file);
201
    }
202
}
203