diff --git a/app/Console/Commands/VersionFetch.php b/app/Console/Commands/VersionFetch.php index f4c2a0c..d8d5f13 100644 --- a/app/Console/Commands/VersionFetch.php +++ b/app/Console/Commands/VersionFetch.php @@ -10,15 +10,15 @@ class VersionFetch extends Command { protected $signature = 'version:fetch'; - protected $description = 'Update the build number based on the git commit count of master.'; + protected $description = 'Sync version/build metadata into settings using composer.json version and git build count.'; public function handle(): int { - $version = Setting::where('key', 'version')->value('value'); + $version = $this->resolveComposerVersion(); $build = $this->resolveBuildCount(); if ($version === null) { - $this->error('Unable to determine version from settings.'); + $this->error('Unable to determine version from composer.json.'); return self::FAILURE; } @@ -27,21 +27,56 @@ class VersionFetch extends Command return self::FAILURE; } + Setting::updateOrCreate( + ['key' => 'version'], + ['value' => $version], + ); + Setting::updateOrCreate( ['key' => 'build'], ['value' => (string) $build], ); - if (!$this->syncComposerMetadata($version, $build)) { + if (!$this->syncComposerBuild($build)) { $this->error('Failed to sync version/build to composer.json.'); return self::FAILURE; } - $this->info("Build number updated to {$build}."); + $this->info("Version/build synced: {$version} (build {$build})."); return self::SUCCESS; } + private function resolveComposerVersion(): ?string + { + $composerPath = base_path('composer.json'); + + if (!is_file($composerPath) || !is_readable($composerPath)) { + return null; + } + + $raw = file_get_contents($composerPath); + if ($raw === false) { + return null; + } + + $data = json_decode($raw, true); + if (!is_array($data)) { + return null; + } + + $version = trim((string) ($data['version'] ?? '')); + if ($version === '') { + return null; + } + + if (!preg_match('/^\d+\.\d+(?:\.\d+)?(?:[-._][0-9A-Za-z.-]+)?$/', $version)) { + return null; + } + + return $version; + } + private function resolveBuildCount(): ?int { $commands = [ @@ -64,7 +99,7 @@ class VersionFetch extends Command return null; } - private function syncComposerMetadata(string $version, int $build): bool + private function syncComposerBuild(int $build): bool { $composerPath = base_path('composer.json'); @@ -82,7 +117,6 @@ class VersionFetch extends Command return false; } - $data['version'] = $version; $data['build'] = (string) $build; $encoded = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); diff --git a/tests/Unit/ConsoleCommandTest.php b/tests/Unit/ConsoleCommandTest.php index 04098e9..1fc9314 100644 --- a/tests/Unit/ConsoleCommandTest.php +++ b/tests/Unit/ConsoleCommandTest.php @@ -20,10 +20,10 @@ it('version set fails when invalid version', function (): void { expect($exitCode)->toBe(1); }); -it('version fetch fails when no version', function (): void { +it('version fetch succeeds without db version when composer version exists', function (): void { Setting::where('key', 'version')->delete(); $exitCode = \Illuminate\Support\Facades\Artisan::call('version:fetch'); - expect($exitCode)->toBe(1); + expect($exitCode)->toBe(0); }); it('version release fails when missing config', function (): void { diff --git a/tests/Unit/VersionFetchCommandTest.php b/tests/Unit/VersionFetchCommandTest.php index a67c96d..f2acba8 100644 --- a/tests/Unit/VersionFetchCommandTest.php +++ b/tests/Unit/VersionFetchCommandTest.php @@ -53,13 +53,16 @@ namespace { it('fetches build count and syncs composer metadata', function (): void { withComposerBackupForFetch(function (): void { - Setting::updateOrCreate(['key' => 'version'], ['value' => '1.2.3']); + Setting::updateOrCreate(['key' => 'version'], ['value' => '0.0.0']); + $composer = json_decode((string) file_get_contents(base_path('composer.json')), true); + $expectedVersion = (string) ($composer['version'] ?? ''); $exitCode = Artisan::call('version:fetch'); expect($exitCode)->toBe(0); $build = Setting::where('key', 'build')->value('value'); expect(is_numeric($build))->toBeTrue(); + expect(Setting::where('key', 'version')->value('value'))->toBe($expectedVersion); }); });