From a3cfaa8176606a4b3f593cff1291b0594590499e Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Fri, 8 May 2026 21:49:43 +0700 Subject: [PATCH 1/3] [0.1.0] Add --preset option on init command --- README.md | 8 +++++++ bin/structarmed.php | 52 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 9c4895b..891f0d7 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,10 @@ composer require --dev boundwize/structarmed ```bash vendor/bin/structarmed init +vendor/bin/structarmed init --preset=ddd +vendor/bin/structarmed init --preset=mvc +vendor/bin/structarmed init --preset=psr4 +vendor/bin/structarmed init --preset=all ``` Generates a `structarmed.php` in your project root. Edit it to match your structure, then run: @@ -177,6 +181,10 @@ vendor/bin/structarmed analyze --report=json # Generate initial config vendor/bin/structarmed init +vendor/bin/structarmed init --preset=ddd +vendor/bin/structarmed init --preset=mvc +vendor/bin/structarmed init --preset=psr4 +vendor/bin/structarmed init --preset=all ``` ## Layer resolution diff --git a/bin/structarmed.php b/bin/structarmed.php index 0db36f4..b04767c 100644 --- a/bin/structarmed.php +++ b/bin/structarmed.php @@ -20,13 +20,13 @@ } } -$basePath = getcwd(); -$command = $argv[1] ?? null; +$basePath = getcwd(); +$command = $argv[1] ?? null; $printUsage = static function (): void { echo <<<'TXT' Usage: - structarmed init + structarmed init [--preset=ddd|mvc|psr4|all] structarmed analyse|analyze [path ...] [--config=path/to/structarmed.php] [--report=console|json] TXT; @@ -39,6 +39,41 @@ // Handle `init` command — generate a sample config if ($command === 'init') { + $preset = 'psr4'; + $arguments = array_slice($argv, 2); + + for ($i = 0; $i < count($arguments); $i++) { + $argument = $arguments[$i]; + + if (str_starts_with($argument, '--preset=')) { + $preset = strtolower(substr($argument, strlen('--preset='))); + continue; + } + + if ($argument === '--preset') { + $preset = strtolower($arguments[++$i] ?? ''); + continue; + } + + echo sprintf("Unknown option: %s\n\n", $argument); + $printUsage(); + exit(1); + } + + $presetConfig = match ($preset) { + 'ddd' => ' ->withPreset(Preset::DDD());', + 'mvc' => ' ->withPreset(Preset::MVC());', + 'psr4' => ' ->withPreset(Preset::PSR4());', + 'all' => ' ->withPresets(Preset::PSR4(), Preset::DDD(), Preset::MVC());', + default => null, + }; + + if ($presetConfig === null) { + echo sprintf("Invalid preset: %s\n\n", $preset); + $printUsage(); + exit(1); + } + $target = $basePath . '/structarmed.php'; if (file_exists($target)) { @@ -55,8 +90,8 @@ use Boundwize\StructArmed\Preset\Preset; return Architecture::define() - ->withPreset(Preset::PSR4()); PHP); + file_put_contents($target, $presetConfig . "\n", FILE_APPEND); echo "Created structarmed.php\n"; exit(0); @@ -68,7 +103,7 @@ exit(1); } -$options = []; +$options = []; $scanPaths = []; $arguments = array_slice($argv, 2); @@ -99,7 +134,6 @@ echo sprintf("Unknown option: %s\n\n", $argument); $printUsage(); exit(1); - continue; } $scanPaths[] = $argument; @@ -132,10 +166,10 @@ } // Run analysis -$start = microtime(true); -$analyser = new Analyser($basePath); +$start = microtime(true); +$analyser = new Analyser($basePath); $violations = $analyser->analyse($architecture, $scanPaths); -$elapsed = microtime(true) - $start; +$elapsed = microtime(true) - $start; // Render report $report = match ($reportType) { From 903f407febbb1d3a8f6ceb6bb13b0d015dc4d006 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Fri, 8 May 2026 21:49:46 +0700 Subject: [PATCH 2/3] [0.1.0] Add --preset option on init command --- tests/Cli/InitCommandTest.php | 145 ++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 tests/Cli/InitCommandTest.php diff --git a/tests/Cli/InitCommandTest.php b/tests/Cli/InitCommandTest.php new file mode 100644 index 0000000..062c20a --- /dev/null +++ b/tests/Cli/InitCommandTest.php @@ -0,0 +1,145 @@ +, string}> + */ + public static function presetProvider(): iterable + { + yield 'default' => [ + [], + ' ->withPreset(Preset::PSR4());', + ]; + + yield 'ddd' => [ + ['--preset=ddd'], + ' ->withPreset(Preset::DDD());', + ]; + + yield 'mvc' => [ + ['--preset=mvc'], + ' ->withPreset(Preset::MVC());', + ]; + + yield 'psr4' => [ + ['--preset=psr4'], + ' ->withPreset(Preset::PSR4());', + ]; + + yield 'all' => [ + ['--preset=all'], + ' ->withPresets(Preset::PSR4(), Preset::DDD(), Preset::MVC());', + ]; + } + + /** + * @param list $arguments + */ + #[DataProvider('presetProvider')] + public function testInitGeneratesConfigForPreset(array $arguments, string $expectedPreset): void + { + $basePath = $this->createTempDirectory(); + + try { + [$exitCode, $output] = $this->runInit($basePath, $arguments); + + $this->assertSame(0, $exitCode, $output); + $this->assertStringContainsString('Created structarmed.php', $output); + $this->assertStringContainsString( + $expectedPreset, + (string) file_get_contents($basePath . '/structarmed.php') + ); + } finally { + $this->removeTempDirectory($basePath); + } + } + + public function testInitRejectsInvalidPreset(): void + { + $basePath = $this->createTempDirectory(); + + try { + [$exitCode, $output] = $this->runInit($basePath, ['--preset=unknown']); + + $this->assertSame(1, $exitCode); + $this->assertStringContainsString('Invalid preset: unknown', $output); + $this->assertFileDoesNotExist($basePath . '/structarmed.php'); + } finally { + $this->removeTempDirectory($basePath); + } + } + + /** + * @param list $arguments + * @return array{int, string} + */ + private function runInit(string $basePath, array $arguments): array + { + $previousDirectory = getcwd(); + $output = []; + $exitCode = 0; + $command = sprintf( + '%s %s init %s', + escapeshellarg(PHP_BINARY), + escapeshellarg(dirname(__DIR__, 2) . '/bin/structarmed.php'), + implode(' ', array_map(escapeshellarg(...), $arguments)) + ); + + chdir($basePath); + + try { + exec($command . ' 2>&1', $output, $exitCode); + } finally { + chdir((string) $previousDirectory); + } + + return [$exitCode, implode("\n", $output)]; + } + + private function createTempDirectory(): string + { + $basePath = sys_get_temp_dir() . '/structarmed-init-' . bin2hex(random_bytes(6)); + mkdir($basePath); + + return $basePath; + } + + private function removeTempDirectory(string $basePath): void + { + if (file_exists($basePath . '/structarmed.php')) { + unlink($basePath . '/structarmed.php'); + } + + if (is_dir($basePath)) { + rmdir($basePath); + } + } +} From 91cfb1bef1b2e77d46904dfb48abad023642d4a4 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Fri, 8 May 2026 21:52:28 +0700 Subject: [PATCH 3/3] fix indent --- bin/structarmed.php | 2 +- tests/Cli/InitCommandTest.php | 20 ++++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/bin/structarmed.php b/bin/structarmed.php index b04767c..0b3f5a5 100644 --- a/bin/structarmed.php +++ b/bin/structarmed.php @@ -91,7 +91,7 @@ return Architecture::define() PHP); - file_put_contents($target, $presetConfig . "\n", FILE_APPEND); + file_put_contents($target, "\n" . $presetConfig . "\n", FILE_APPEND); echo "Created structarmed.php\n"; exit(0); diff --git a/tests/Cli/InitCommandTest.php b/tests/Cli/InitCommandTest.php index 062c20a..5b95a1d 100644 --- a/tests/Cli/InitCommandTest.php +++ b/tests/Cli/InitCommandTest.php @@ -73,8 +73,8 @@ public function testInitGeneratesConfigForPreset(array $arguments, string $expec $this->assertSame(0, $exitCode, $output); $this->assertStringContainsString('Created structarmed.php', $output); - $this->assertStringContainsString( - $expectedPreset, + $this->assertSame( + $this->expectedConfig($expectedPreset), (string) file_get_contents($basePath . '/structarmed.php') ); } finally { @@ -132,6 +132,22 @@ private function createTempDirectory(): string return $basePath; } + private function expectedConfig(string $presetConfig): string + { + return <<