1
|
|
|
<?php |
2
|
|
|
declare(strict_types=1); |
3
|
|
|
|
4
|
|
|
/** |
5
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
6
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
7
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
8
|
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
9
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
10
|
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
11
|
|
|
* THE SOFTWARE. |
12
|
|
|
* |
13
|
|
|
* This software consists of voluntary contributions made by many individuals |
14
|
|
|
* and is licensed under the MIT license. |
15
|
|
|
* |
16
|
|
|
* Copyright (c) 2015-2020 Yuuki Takezawa |
17
|
|
|
* |
18
|
|
|
*/ |
19
|
|
|
|
20
|
|
|
namespace Ytake\LaravelAspect\Console; |
21
|
|
|
|
22
|
|
|
use Illuminate\Support\Str; |
23
|
|
|
use Illuminate\Console\Command; |
24
|
|
|
use Illuminate\Filesystem\Filesystem; |
25
|
|
|
use Symfony\Component\Console\Input\InputArgument; |
26
|
|
|
|
27
|
|
|
use function trim; |
28
|
|
|
use function str_replace; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* Class ModulePublishCommand |
32
|
|
|
* |
33
|
|
|
* @codeCoverageIgnore |
34
|
|
|
*/ |
35
|
|
|
class ModulePublishCommand extends Command |
36
|
|
|
{ |
37
|
|
|
/** @var string */ |
38
|
|
|
protected $name = 'ytake:aspect-module-publish'; |
39
|
|
|
|
40
|
|
|
/** @var string */ |
41
|
|
|
protected $description = 'Publish any aspect modules from ytake/laravel-aspect'; |
42
|
|
|
|
43
|
|
|
/** @var Filesystem */ |
44
|
|
|
protected $filesystem; |
45
|
|
|
|
46
|
|
|
/** @var string */ |
47
|
|
|
protected $classPath = 'Modules'; |
48
|
|
|
|
49
|
|
|
/** @var array package modules */ |
50
|
|
|
protected $modules = [ |
51
|
|
|
'CacheableModule' => 'Ytake\LaravelAspect\Modules\CacheableModule', |
52
|
|
|
'CacheEvictModule' => 'Ytake\LaravelAspect\Modules\CacheEvictModule', |
53
|
|
|
'CachePutModule' => 'Ytake\LaravelAspect\Modules\CachePutModule', |
54
|
|
|
'TransactionalModule' => 'Ytake\LaravelAspect\Modules\TransactionalModule', |
55
|
|
|
'LoggableModule' => 'Ytake\LaravelAspect\Modules\LoggableModule', |
56
|
|
|
'LogExceptionsModule' => 'Ytake\LaravelAspect\Modules\LogExceptionsModule', |
57
|
|
|
'PostConstructModule' => 'Ytake\LaravelAspect\Modules\PostConstructModule', |
58
|
|
|
'RetryOnFailureModule' => 'Ytake\LaravelAspect\Modules\RetryOnFailureModule', |
59
|
|
|
'MessageDrivenModule' => 'Ytake\LaravelAspect\Modules\MessageDrivenModule', |
60
|
|
|
'QueryLogModule' => 'Ytake\LaravelAspect\Modules\QueryLogModule', |
61
|
|
|
]; |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* @param Filesystem $filesystem |
65
|
|
|
*/ |
66
|
|
|
public function __construct(Filesystem $filesystem) |
67
|
|
|
{ |
68
|
|
|
parent::__construct(); |
69
|
|
|
$this->filesystem = $filesystem; |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException |
74
|
|
|
* @throws \ReflectionException |
75
|
|
|
*/ |
76
|
|
|
public function handle(): void |
77
|
|
|
{ |
78
|
|
|
foreach ($this->modules as $className => $module) { |
79
|
|
|
$path = $this->getPath($this->parseClassName($className, $this->argument('module_dir'))); |
|
|
|
|
80
|
|
|
|
81
|
|
|
if ($this->filesystem->exists($path)) { |
82
|
|
|
continue; |
83
|
|
|
} |
84
|
|
|
$stub = $this->filesystem->get($this->stub()); |
85
|
|
|
$extendClassName = $this->getExtendsClassName($module); |
86
|
|
|
$source = str_replace( |
87
|
|
|
[ |
88
|
|
|
'DummyNamespace', |
89
|
|
|
'DummyClass', |
90
|
|
|
'DummyAspectModuleClass', |
91
|
|
|
'DummyModuleClass', |
92
|
|
|
], |
93
|
|
|
[ |
94
|
|
|
$this->laravel->getNamespace() . $this->argument('module_dir'), |
95
|
|
|
$className, |
96
|
|
|
$module . ' as ' . $extendClassName, |
97
|
|
|
$extendClassName, |
98
|
|
|
], |
99
|
|
|
$stub |
100
|
|
|
); |
101
|
|
|
$this->makeDirectory($path); |
102
|
|
|
$this->filesystem->put($path, $source); |
103
|
|
|
$this->info($path . ' created successfully.'); |
104
|
|
|
} |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* @return array |
109
|
|
|
*/ |
110
|
|
|
protected function getArguments() |
111
|
|
|
{ |
112
|
|
|
return [ |
113
|
|
|
['module_dir', InputArgument::OPTIONAL, 'The name of the class directory', $this->classPath], |
114
|
|
|
]; |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
/** |
118
|
|
|
* @param string $name |
119
|
|
|
* |
120
|
|
|
* @return string |
121
|
|
|
*/ |
122
|
|
|
protected function getPath(string $name): string |
123
|
|
|
{ |
124
|
|
|
$name = str_replace($this->laravel->getNamespace(), '', $name); |
125
|
|
|
|
126
|
|
|
return $this->laravel['path'] . '/' . str_replace('\\', '/', $name) . '.php'; |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
/** |
130
|
|
|
* Parse the name and format according to the root namespace. |
131
|
|
|
* |
132
|
|
|
* @param string $name |
133
|
|
|
* @param string|null $moduleDirectory |
134
|
|
|
* |
135
|
|
|
* @return string |
136
|
|
|
*/ |
137
|
|
|
protected function parseClassName(string $name, string $moduleDirectory = null): string |
138
|
|
|
{ |
139
|
|
|
$rootNamespace = $this->laravel->getNamespace(); |
140
|
|
|
|
141
|
|
|
if (Str::startsWith($name, $rootNamespace)) { |
142
|
|
|
return $name; |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
if (Str::contains($name, '/')) { |
146
|
|
|
$name = str_replace('/', '\\', $name); |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
return $this->parseClassName( |
150
|
|
|
trim($rootNamespace, '\\') . '\\' . $moduleDirectory . '\\' . $name |
151
|
|
|
); |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
/** |
155
|
|
|
* added custom aspect module, override package modules |
156
|
|
|
* |
157
|
|
|
* @param string $module |
158
|
|
|
* |
159
|
|
|
* @return ModulePublishCommand |
160
|
|
|
*/ |
161
|
|
|
protected function addModule(string $module): self |
162
|
|
|
{ |
163
|
|
|
$this->modules[$module]; |
164
|
|
|
|
165
|
|
|
return $this; |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
/** |
169
|
|
|
* Build the directory for the class if necessary. |
170
|
|
|
* |
171
|
|
|
* @param string $path |
172
|
|
|
*/ |
173
|
|
|
protected function makeDirectory(string $path): void |
174
|
|
|
{ |
175
|
|
|
if (!$this->filesystem->isDirectory(dirname($path))) { |
176
|
|
|
$this->filesystem->makeDirectory(dirname($path), 0777, true, true); |
177
|
|
|
} |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
/** |
181
|
|
|
* @param string $module |
182
|
|
|
* |
183
|
|
|
* @return string |
184
|
|
|
* @throws \ReflectionException |
185
|
|
|
*/ |
186
|
|
|
protected function getExtendsClassName(string $module): string |
187
|
|
|
{ |
188
|
|
|
$shortName = (new \ReflectionClass($module))->getShortName(); |
189
|
|
|
$extendClassName = "Package{$shortName}"; |
190
|
|
|
|
191
|
|
|
return $extendClassName; |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
/** |
195
|
|
|
* @return string |
196
|
|
|
*/ |
197
|
|
|
protected function stub(): string |
198
|
|
|
{ |
199
|
|
|
/** module stub file path */ |
200
|
|
|
return __DIR__ . '/stub/ModuleStub.stub'; |
201
|
|
|
} |
202
|
|
|
} |
203
|
|
|
|
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.