From 91c354e598761c5a898f91ce35682886c08a9932 Mon Sep 17 00:00:00 2001 From: Thoriq Firdaus <2067467+tfirdaus@users.noreply.github.com> Date: Mon, 22 Dec 2025 01:40:21 +0700 Subject: [PATCH 1/4] Update config --- .vscode/settings.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 5aa0a8f..acc3941 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -74,7 +74,7 @@ "editor.defaultFormatter": "vscode.json-language-features" }, "[php]": { - "editor.defaultFormatter": "valeryanm.vscode-phpsab" + "editor.defaultFormatter": "wongjn.php-sniffer" }, "files.exclude": { "**/.git": true, @@ -92,6 +92,5 @@ "**/CVS/**" ], "intelephense.compatibility.preferPsalmPhpstanPrefixedAnnotations": true, - "phpsab.snifferMode": "onSave", - "phpsab.snifferShowSources": true, + "phpSniffer.run": "onSave", } From 9d93d0bc508ed605d9fb972bce56c9a992202fc0 Mon Sep 17 00:00:00 2001 From: Thoriq Firdaus <2067467+tfirdaus@users.noreply.github.com> Date: Mon, 22 Dec 2025 01:40:33 +0700 Subject: [PATCH 2/4] Add support for incrementing prerelease --- app/Commands/IncrementCommand.php | 24 ++++++++++-- tests/bashunit/test_increment.sh | 12 +++++- .../phpunit/Commands/IncrementCommandTest.php | 39 +++++++++++++++++++ 3 files changed, 71 insertions(+), 4 deletions(-) diff --git a/app/Commands/IncrementCommand.php b/app/Commands/IncrementCommand.php index bdd39db..0d40446 100644 --- a/app/Commands/IncrementCommand.php +++ b/app/Commands/IncrementCommand.php @@ -28,7 +28,7 @@ protected function configure(): void $this->setDescription('Increment a version'); $this->setAliases(['incr']); $this->addArgument('version', InputArgument::REQUIRED, 'Version to increment'); - $this->addOption('part', 'p', InputArgument::OPTIONAL, 'Part to increment (major, minor, patch)', 'patch'); + $this->addOption('part', 'p', InputArgument::OPTIONAL, 'Part to increment (major, minor, patch, and prerelease)', 'patch'); $this->addOption('build', 'b', InputArgument::OPTIONAL, 'Build metadata to append to the version'); $this->addOption('pre', null, InputArgument::OPTIONAL, 'Pre-release identifier to append to the version'); $this->setHelp(<<<'HELP' @@ -104,11 +104,29 @@ private function increment(Version $version, string $part, $pre = null, $build = $version = $version->incrementPatch(); break; + case 'prerelease': + $currentPrerelease = $version->getPreRelease(); + + if ($currentPrerelease === null) { + throw new InvalidArgumentException('Unable to increment prerelease on a version without a prerelease tag.'); + } + + if ($pre !== null && is_string($pre) && $pre !== '') { + throw new InvalidArgumentException('Specifying a prerelease tag when incrementing the prerelease part is not allowed.'); + } + + $identifier = $currentPrerelease->getIdentifiers(); + $preTag = $identifier[0]; + $preVersion = (int) ($identifier[1] ?? 0) + 1; + $version = $version->withPreRelease(sprintf('%s.%d', $preTag, $preVersion)); + + break; + default: - throw new InvalidArgumentException(sprintf("Invalid part '%s' provided. Expected 'major', 'minor', or 'patch'.", $part)); + throw new InvalidArgumentException(sprintf("Invalid part '%s' provided. Expected 'major', 'minor', 'patch', or 'prerelease'.", $part)); } - if (is_string($pre) && $pre !== '') { + if ($part !== 'prerelease' && is_string($pre) && $pre !== '') { $version = $version->withPreRelease($pre); } diff --git a/tests/bashunit/test_increment.sh b/tests/bashunit/test_increment.sh index e527c7c..e62da10 100644 --- a/tests/bashunit/test_increment.sh +++ b/tests/bashunit/test_increment.sh @@ -17,7 +17,7 @@ function test_increment_major() { } # @data_provider data_increment_with_pre_release -function test_increment_with_pre_release() { +function test_increment_with_prerelease() { ver=$(bin/version increment $1 --pre alpha); assert_equals $ver $2; } @@ -34,6 +34,16 @@ function test_increment_with_pre_release_and_build() { assert_equals $ver $2; } +# @data_provider data_increment_prerelease +function test_increment_with_prerelease_and_build() { + ver=$(bin/version increment $1 --part prerelease); + assert_equals $ver $2; +} + +function data_increment_prerelease() { + echo "1.0.0-beta" "1.0.0-beta.1"; +} + function data_increment_patch() { echo "0.0.0" "0.0.1"; echo "1.0.0" "1.0.1"; diff --git a/tests/phpunit/Commands/IncrementCommandTest.php b/tests/phpunit/Commands/IncrementCommandTest.php index eccb810..91d44cd 100644 --- a/tests/phpunit/Commands/IncrementCommandTest.php +++ b/tests/phpunit/Commands/IncrementCommandTest.php @@ -84,6 +84,45 @@ public function testIncrementWithPreRelease(): void ); } + /** + * @dataProvider dataIncrementPrerelease + */ + public function testIncrementPrerelease(string $version, string $expect): void + { + $this->tester->execute(['version' => $version, '--part' => 'prerelease']); + + self::assertStringContainsString( + $expect, + $this->tester->getDisplay(), + ); + } + + public static function dataIncrementPrerelease(): iterable + { + yield ['1.0.0-beta', '1.0.0-beta.1']; + yield ['1.0.0-alpha.1', '1.0.0-alpha.2']; + } + + public function testIncrementPrereleaseWithPreTag(): void + { + $this->tester->execute(['version' => '1.0.0-beta', '--part' => 'prerelease', '--pre' => 'rc']); + + self::assertStringContainsString( + "[ERROR] Specifying a prerelease tag when incrementing the prerelease part is not allowed.", + $this->tester->getDisplay(), + ); + } + + public function testIncrementPrereleaseWithoutReleaseTag(): void + { + $this->tester->execute(['version' => '1.0.0', '--part' => 'prerelease']); + + self::assertStringContainsString( + "[ERROR] Unable to increment prerelease on a version without a prerelease tag.", + $this->tester->getDisplay(), + ); + } + public static function dataInvalidVersionArgument(): iterable { yield ['v']; From 09cf2d2810eb47331e48fd765f26cc4db04e69b0 Mon Sep 17 00:00:00 2001 From: Thoriq Firdaus <2067467+tfirdaus@users.noreply.github.com> Date: Mon, 22 Dec 2025 01:46:38 +0700 Subject: [PATCH 3/4] Fix prerelease increment logic to handle numeric values correctly --- app/Commands/IncrementCommand.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/app/Commands/IncrementCommand.php b/app/Commands/IncrementCommand.php index 0d40446..50e42bc 100644 --- a/app/Commands/IncrementCommand.php +++ b/app/Commands/IncrementCommand.php @@ -14,8 +14,10 @@ use Throwable; use Version\Version; +use function is_numeric; use function is_string; use function sprintf; +use function trim; final class IncrementCommand extends Command { @@ -116,9 +118,14 @@ private function increment(Version $version, string $part, $pre = null, $build = } $identifier = $currentPrerelease->getIdentifiers(); - $preTag = $identifier[0]; - $preVersion = (int) ($identifier[1] ?? 0) + 1; - $version = $version->withPreRelease(sprintf('%s.%d', $preTag, $preVersion)); + $preTag = isset($identifier[0]) && is_string($identifier[0]) ? trim($identifier[0]) : null; + + if ($preTag === null || $preTag === '') { + throw new InvalidArgumentException('Unable to determine the prerelease tag for incrementing.'); + } + + $preVersion = isset($identifier[1]) && is_numeric($identifier[1]) ? (int) $identifier[1] : 0; + $version = $version->withPreRelease(sprintf('%s.%d', $preTag, $preVersion + 1)); break; From 36c83636520ae37e8f60d61be81353e85671b8ed Mon Sep 17 00:00:00 2001 From: Thoriq Firdaus <2067467+tfirdaus@users.noreply.github.com> Date: Mon, 22 Dec 2025 01:57:37 +0700 Subject: [PATCH 4/4] Fix canonical string --- composer.json | 2 +- tests/phpunit/Commands/CommandTestCase.php | 44 +++++++++++++++++++ tests/phpunit/Commands/EqualCommandTest.php | 5 ++- .../Commands/GreaterThanCommandTest.php | 5 ++- .../phpunit/Commands/IncrementCommandTest.php | 21 ++++----- .../phpunit/Commands/LessThanCommandTest.php | 5 ++- .../phpunit/Commands/ValidateCommandTest.php | 7 +-- 7 files changed, 69 insertions(+), 20 deletions(-) create mode 100644 tests/phpunit/Commands/CommandTestCase.php diff --git a/composer.json b/composer.json index 1a984f4..e682da1 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ }, "autoload-dev": { "psr-4": { - "Syntatis\\Tests\\": "tests/" + "Syntatis\\Tests\\": ["tests/", "tests/phpunit/"] } }, "require": { diff --git a/tests/phpunit/Commands/CommandTestCase.php b/tests/phpunit/Commands/CommandTestCase.php new file mode 100644 index 0000000..10959e9 --- /dev/null +++ b/tests/phpunit/Commands/CommandTestCase.php @@ -0,0 +1,44 @@ +tester->getDisplay(), + self::normalizeOutput($this->tester->getDisplay()), ); } diff --git a/tests/phpunit/Commands/GreaterThanCommandTest.php b/tests/phpunit/Commands/GreaterThanCommandTest.php index 49d7bea..9cccdb1 100644 --- a/tests/phpunit/Commands/GreaterThanCommandTest.php +++ b/tests/phpunit/Commands/GreaterThanCommandTest.php @@ -4,13 +4,14 @@ namespace Syntatis\Tests\Commands; +use Syntatis\Tests\Commands\CommandTestCase; use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Tester\CommandTester; use Syntatis\Version\CLI\Commander; use function sprintf; -class GreaterThanCommandTest extends TestCase +class GreaterThanCommandTest extends CommandTestCase { private Commander $commander; private CommandTester $tester; @@ -30,7 +31,7 @@ public function testComparison(string $versionA, string $versionB, string $expec self::assertStringContainsString( $expect, - $this->tester->getDisplay(), + self::normalizeOutput($this->tester->getDisplay()), ); } diff --git a/tests/phpunit/Commands/IncrementCommandTest.php b/tests/phpunit/Commands/IncrementCommandTest.php index 91d44cd..5bf5752 100644 --- a/tests/phpunit/Commands/IncrementCommandTest.php +++ b/tests/phpunit/Commands/IncrementCommandTest.php @@ -4,13 +4,14 @@ namespace Syntatis\Tests\Commands; +use Syntatis\Tests\Commands\CommandTestCase; use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Tester\CommandTester; use Syntatis\Version\CLI\Commander; use function sprintf; -class IncrementCommandTest extends TestCase +class IncrementCommandTest extends CommandTestCase { private Commander $commander; private CommandTester $tester; @@ -30,7 +31,7 @@ public function testInvalidVersionArgument(string $version): void self::assertStringContainsString( sprintf("[ERROR] Version string '%s' is not valid and cannot be parsed", $version), - $this->tester->getDisplay(), + self::normalizeOutput($this->tester->getDisplay()), ); } @@ -40,7 +41,7 @@ public function testIncrementPatch(): void self::assertStringContainsString( '1.0.1', - $this->tester->getDisplay(), + self::normalizeOutput($this->tester->getDisplay()), ); } @@ -50,7 +51,7 @@ public function testIncrementMinor(): void self::assertStringContainsString( '1.1.0', - $this->tester->getDisplay(), + self::normalizeOutput($this->tester->getDisplay()), ); } @@ -60,7 +61,7 @@ public function testIncrementMajor(): void self::assertStringContainsString( '2.0.0', - $this->tester->getDisplay(), + self::normalizeOutput($this->tester->getDisplay()), ); } @@ -70,7 +71,7 @@ public function testIncrementWithBuildMetadata(): void self::assertStringContainsString( '1.0.1+123', - $this->tester->getDisplay(), + self::normalizeOutput($this->tester->getDisplay()), ); } @@ -80,7 +81,7 @@ public function testIncrementWithPreRelease(): void self::assertStringContainsString( '1.0.1-beta', - $this->tester->getDisplay(), + self::normalizeOutput($this->tester->getDisplay()), ); } @@ -93,7 +94,7 @@ public function testIncrementPrerelease(string $version, string $expect): void self::assertStringContainsString( $expect, - $this->tester->getDisplay(), + self::normalizeOutput($this->tester->getDisplay()), ); } @@ -109,7 +110,7 @@ public function testIncrementPrereleaseWithPreTag(): void self::assertStringContainsString( "[ERROR] Specifying a prerelease tag when incrementing the prerelease part is not allowed.", - $this->tester->getDisplay(), + self::normalizeOutput($this->tester->getDisplay()), ); } @@ -119,7 +120,7 @@ public function testIncrementPrereleaseWithoutReleaseTag(): void self::assertStringContainsString( "[ERROR] Unable to increment prerelease on a version without a prerelease tag.", - $this->tester->getDisplay(), + self::normalizeOutput($this->tester->getDisplay()), ); } diff --git a/tests/phpunit/Commands/LessThanCommandTest.php b/tests/phpunit/Commands/LessThanCommandTest.php index 54e96d9..e573b20 100644 --- a/tests/phpunit/Commands/LessThanCommandTest.php +++ b/tests/phpunit/Commands/LessThanCommandTest.php @@ -4,13 +4,14 @@ namespace Syntatis\Tests\Commands; +use Syntatis\Tests\Commands\CommandTestCase; use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Tester\CommandTester; use Syntatis\Version\CLI\Commander; use function sprintf; -class LessThanCommandTest extends TestCase +class LessThanCommandTest extends CommandTestCase { private Commander $commander; private CommandTester $tester; @@ -30,7 +31,7 @@ public function testComparison(string $versionA, string $versionB, string $expec self::assertStringContainsString( $expect, - $this->tester->getDisplay(), + self::normalizeOutput($this->tester->getDisplay()), ); } diff --git a/tests/phpunit/Commands/ValidateCommandTest.php b/tests/phpunit/Commands/ValidateCommandTest.php index 18d0e01..edd2048 100644 --- a/tests/phpunit/Commands/ValidateCommandTest.php +++ b/tests/phpunit/Commands/ValidateCommandTest.php @@ -4,13 +4,14 @@ namespace Syntatis\Tests\Commands; +use Syntatis\Tests\Commands\CommandTestCase; use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Tester\CommandTester; use Syntatis\Version\CLI\Commander; use function sprintf; -class ValidateCommandTest extends TestCase +class ValidateCommandTest extends CommandTestCase { private Commander $commander; private CommandTester $tester; @@ -30,7 +31,7 @@ public function testInvalidVersionArgument(string $version): void self::assertStringContainsString( sprintf("[ERROR] Version string '%s' is not valid and cannot be parsed", $version), - $this->tester->getDisplay(), + self::normalizeOutput($this->tester->getDisplay()), ); } @@ -41,7 +42,7 @@ public function testValidVersionArgument(string $version): void self::assertStringContainsString( sprintf("[OK] Version string '%s' is valid and can be parsed", $version), - $this->tester->getDisplay(), + self::normalizeOutput($this->tester->getDisplay()), ); }