Skip to content

Commit cf1e45b

Browse files
MakeDomain command and Install Clean Architecture - [WIP]
1 parent 0f097c8 commit cf1e45b

File tree

6 files changed

+569
-0
lines changed

6 files changed

+569
-0
lines changed
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
<?php
2+
3+
namespace PlinCode\LaravelCleanArchitecture\Commands;
4+
5+
use Illuminate\Console\Command;
6+
use Illuminate\Filesystem\Filesystem;
7+
8+
class InstallCleanArchitectureCommand extends Command
9+
{
10+
protected $signature = 'clean-arch:install
11+
{--force : Overwrite existing files}';
12+
13+
protected $description = 'Install Clean Architecture structure in Laravel project';
14+
15+
protected Filesystem $files;
16+
17+
public function __construct(Filesystem $files)
18+
{
19+
parent::__construct();
20+
$this->files = $files;
21+
}
22+
23+
public function handle(): int
24+
{
25+
$this->info('🚀 Installing Clean Architecture...');
26+
27+
// Create directory structure
28+
$this->createDirectoryStructure();
29+
30+
// Create base classes
31+
$this->createBaseClasses();
32+
33+
// Update composer.json autoload
34+
$this->updateComposerAutoload();
35+
36+
// Create config file
37+
$this->createConfigFile();
38+
39+
// Create README
40+
$this->createReadme();
41+
42+
$this->info('✅ Clean Architecture installed successfully!');
43+
$this->newLine();
44+
$this->info('Next steps:');
45+
$this->info('1. Run: composer dump-autoload');
46+
$this->info('2. Create your first domain: php artisan clean-arch:make-domain Users');
47+
$this->info('3. Check the generated README.md for documentation');
48+
49+
return self::SUCCESS;
50+
}
51+
52+
protected function createDirectoryStructure(): void
53+
{
54+
$directories = [
55+
'app/Application/Actions',
56+
'app/Application/Services',
57+
'app/Application/Jobs',
58+
'app/Application/Console/Commands',
59+
'app/Application/Listeners',
60+
'app/Domain',
61+
'app/Infrastructure/API/Controllers',
62+
'app/Infrastructure/API/Requests',
63+
'app/Infrastructure/API/Resources',
64+
'app/Infrastructure/UI/Web/Controllers',
65+
'app/Infrastructure/UI/Web/Views',
66+
'app/Infrastructure/Mail',
67+
'app/Infrastructure/Notifications',
68+
'app/Infrastructure/Observers',
69+
'app/Infrastructure/Exceptions',
70+
'app/Infrastructure/Middleware',
71+
];
72+
73+
foreach ($directories as $directory) {
74+
if (! $this->files->isDirectory(base_path($directory))) {
75+
$this->files->makeDirectory(base_path($directory), 0755, true);
76+
$this->info("Created directory: {$directory}");
77+
}
78+
}
79+
}
80+
81+
protected function createBaseClasses(): void
82+
{
83+
$this->createBaseModel();
84+
$this->createBaseController();
85+
$this->createBaseAction();
86+
$this->createBaseService();
87+
$this->createBaseRequest();
88+
$this->createExceptionClasses();
89+
}
90+
91+
protected function createBaseModel(): void
92+
{
93+
$stub = $this->getStub('base-model');
94+
if (! $this->files->isDirectory(app_path('Domain/Shared'))) {
95+
$this->files->makeDirectory(app_path('Domain/Shared'), 0755, true);
96+
}
97+
$this->files->put(
98+
app_path('Domain/Shared/BaseModel.php'),
99+
$stub
100+
);
101+
$this->info('Created: Domain/Shared/BaseModel.php');
102+
}
103+
104+
protected function createBaseController(): void
105+
{
106+
$stub = $this->getStub('base-controller');
107+
$this->files->put(
108+
app_path('Infrastructure/API/Controllers/Controller.php'),
109+
$stub
110+
);
111+
$this->info('Created: Infrastructure/API/Controllers/Controller.php');
112+
}
113+
114+
protected function createBaseAction(): void
115+
{
116+
$stub = $this->getStub('base-action');
117+
$this->files->put(
118+
app_path('Application/Actions/BaseAction.php'),
119+
$stub
120+
);
121+
$this->info('Created: Application/Actions/BaseAction.php');
122+
}
123+
124+
protected function createBaseService(): void
125+
{
126+
$stub = $this->getStub('base-service');
127+
if (! $this->files->isDirectory(app_path('Application/Services'))) {
128+
$this->files->makeDirectory(app_path('Application/Services'), 0755, true);
129+
}
130+
$this->files->put(
131+
app_path('Application/Services/BaseService.php'),
132+
$stub
133+
);
134+
$this->info('Created: Application/Services/BaseService.php');
135+
}
136+
137+
protected function createBaseRequest(): void
138+
{
139+
$stub = $this->getStub('base-request');
140+
$this->files->put(
141+
app_path('Infrastructure/API/Requests/BaseRequest.php'),
142+
$stub
143+
);
144+
$this->info('Created: Infrastructure/API/Requests/BaseRequest.php');
145+
}
146+
147+
protected function createExceptionClasses(): void
148+
{
149+
$exceptions = [
150+
'DomainException' => 'domain-exception',
151+
'ValidationException' => 'validation-exception',
152+
'BusinessLogicException' => 'business-logic-exception',
153+
];
154+
155+
foreach ($exceptions as $className => $stub) {
156+
$content = $this->getStub($stub);
157+
$this->files->put(
158+
app_path("Infrastructure/Exceptions/{$className}.php"),
159+
$content
160+
);
161+
$this->info("Created: Infrastructure/Exceptions/{$className}.php");
162+
}
163+
}
164+
165+
protected function updateComposerAutoload(): void
166+
{
167+
$composerPath = base_path('composer.json');
168+
$composer = json_decode($this->files->get($composerPath), true);
169+
170+
if (! isset($composer['autoload']['psr-4']['App\\'])) {
171+
$composer['autoload']['psr-4']['App\\'] = 'app/';
172+
$this->files->put($composerPath, json_encode($composer, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
173+
$this->info('Updated composer.json autoload');
174+
}
175+
}
176+
177+
protected function createConfigFile(): void
178+
{
179+
$stub = $this->getStub('config');
180+
if (! $this->files->isDirectory(config_path())) {
181+
$this->files->makeDirectory(config_path(), 0755, true);
182+
}
183+
$this->files->put(config_path('clean-architecture.php'), $stub);
184+
$this->info('Created: config/clean-architecture.php');
185+
}
186+
187+
protected function createReadme(): void
188+
{
189+
$stub = $this->getStub('readme');
190+
$this->files->put(base_path('CLEAN_ARCHITECTURE.md'), $stub);
191+
$this->info('Created: CLEAN_ARCHITECTURE.md');
192+
}
193+
194+
protected function getStub(string $stub): string
195+
{
196+
$stubPath = __DIR__ . "/../../stubs/{$stub}.stub";
197+
198+
if (! $this->files->exists($stubPath)) {
199+
throw new \Exception("Stub file not found: {$stubPath}");
200+
}
201+
202+
return $this->files->get($stubPath);
203+
}
204+
}

0 commit comments

Comments
 (0)