From be417567372d7a9b29a5bfd22ae2e5792696e2be Mon Sep 17 00:00:00 2001 From: Dimitri Date: Tue, 21 Jan 2025 16:52:13 +0100 Subject: [PATCH 01/11] fix: Implicitly marking parameter as nullable is deprecated --- src/Version.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Version.php b/src/Version.php index 89dfe5f..ab98e41 100644 --- a/src/Version.php +++ b/src/Version.php @@ -6,11 +6,11 @@ use JsonSerializable; use Version\Assert\VersionAssert; -use Version\Extension\Build; -use Version\Exception\InvalidVersionString; use Version\Comparison\Comparator; -use Version\Comparison\SemverComparator; use Version\Comparison\Constraint\Constraint; +use Version\Comparison\SemverComparator; +use Version\Exception\InvalidVersionString; +use Version\Extension\Build; use Version\Extension\PreRelease; class Version implements JsonSerializable @@ -31,7 +31,8 @@ class Version implements JsonSerializable protected static ?Comparator $comparator = null; - final protected function __construct(int $major, int $minor, int $patch, PreRelease $preRelease = null, Build $build = null) + + final protected function __construct(int $major, int $minor, int $patch, ?PreRelease $preRelease = NULL, ?Build $build = NULL) { VersionAssert::that($major)->greaterOrEqualThan(0, 'Major version must be positive integer'); VersionAssert::that($minor)->greaterOrEqualThan(0, 'Minor version must be positive integer'); @@ -44,7 +45,8 @@ final protected function __construct(int $major, int $minor, int $patch, PreRele $this->build = $build; } - public static function from(int $major, int $minor = 0, int $patch = 0, PreRelease $preRelease = null, Build $build = null): Version + + public static function from(int $major, int $minor = 0, int $patch = 0, ?PreRelease $preRelease = NULL, ?Build $build = NULL): Version { return new static($major, $minor, $patch, $preRelease, $build); } From 021e49ab85ecbe6cc1e8ce077d47e18acae8e987 Mon Sep 17 00:00:00 2001 From: Dimitri Date: Wed, 22 Jan 2025 14:15:48 +0100 Subject: [PATCH 02/11] fix(tests): Implicitly marking parameter as nullable is deprecated, the explicit nullable type must be used instead --- tests/TestAsset/VersionIsIdentical.php | 104 +++++++++++++------------ 1 file changed, 55 insertions(+), 49 deletions(-) diff --git a/tests/TestAsset/VersionIsIdentical.php b/tests/TestAsset/VersionIsIdentical.php index d47bd35..e0ce930 100644 --- a/tests/TestAsset/VersionIsIdentical.php +++ b/tests/TestAsset/VersionIsIdentical.php @@ -1,55 +1,61 @@ expectedVersion = Version::from( - $expectedMajor, - $expectedMinor, - $expectedPatch, - is_string($expectedPreRelease) ? PreRelease::fromString($expectedPreRelease) : $expectedPreRelease, - is_string($expectedBuild) ? Build::fromString($expectedBuild) : $expectedBuild - ); - } + declare(strict_types=1); - protected function matches($version): bool - { - /* @var $version Version */ - - return ( - $version->getMajor() === $this->expectedVersion->getMajor() - && $version->getMinor() === $this->expectedVersion->getMinor() - && $version->getPatch() === $this->expectedVersion->getPatch() - && ( - ($version->isPreRelease() && $this->expectedVersion->isPreRelease() && $version->getPreRelease()->getIdentifiers() === $this->expectedVersion->getPreRelease()->getIdentifiers()) - || (!$version->isPreRelease() && !$this->expectedVersion->isPreRelease()) - ) - && ( - ($version->hasBuild() && $this->expectedVersion->hasBuild() && $version->getBuild()->getIdentifiers() === $this->expectedVersion->getBuild()->getIdentifiers()) - || (!$version->hasBuild() && !$this->expectedVersion->hasBuild()) - ) - ); - } + namespace Version\Tests\TestAsset; + + use PHPUnit\Framework\Constraint\Constraint; + use Version\Extension\Build; + use Version\Extension\PreRelease; + use Version\Version; - public function toString(): string + final class VersionIsIdentical extends Constraint { - return 'is identical to: ' . $this->expectedVersion->toString(); + private Version $expectedVersion; + + + public function __construct( + int $expectedMajor, + int $expectedMinor, + int $expectedPatch, + PreRelease|string|null $expectedPreRelease = NULL, + Build|string|null $expectedBuild = NULL + ) { + $this->expectedVersion = Version::from( + $expectedMajor, + $expectedMinor, + $expectedPatch, + is_string($expectedPreRelease) ? PreRelease::fromString($expectedPreRelease) : $expectedPreRelease, + is_string($expectedBuild) ? Build::fromString($expectedBuild) : $expectedBuild + ); + } + + + protected function matches($version): bool + { + /* @var $version Version */ + + return ( + $version->getMajor() === $this->expectedVersion->getMajor() + && $version->getMinor() === $this->expectedVersion->getMinor() + && $version->getPatch() === $this->expectedVersion->getPatch() + && ( + ($version->isPreRelease() && $this->expectedVersion->isPreRelease() && $version->getPreRelease()->getIdentifiers( + ) === $this->expectedVersion->getPreRelease()->getIdentifiers()) + || (!$version->isPreRelease() && !$this->expectedVersion->isPreRelease()) + ) + && ( + ($version->hasBuild() && $this->expectedVersion->hasBuild() && $version->getBuild()->getIdentifiers() === $this->expectedVersion->getBuild() + ->getIdentifiers( + )) + || (!$version->hasBuild() && !$this->expectedVersion->hasBuild()) + ) + ); + } + + + public function toString(): string + { + return 'is identical to: '.$this->expectedVersion->toString(); + } } -} From 7b6686a021e1ea2d11c4e4747f67cc16cfe55a8c Mon Sep 17 00:00:00 2001 From: Dimitri Date: Mon, 27 Jan 2025 14:13:03 +0100 Subject: [PATCH 03/11] refactor : update code to comply with repository standards --- src/Version.php | 4 +- tests/TestAsset/VersionIsIdentical.php | 102 ++++++++++++------------- 2 files changed, 53 insertions(+), 53 deletions(-) diff --git a/src/Version.php b/src/Version.php index ab98e41..9002dc6 100644 --- a/src/Version.php +++ b/src/Version.php @@ -32,7 +32,7 @@ class Version implements JsonSerializable protected static ?Comparator $comparator = null; - final protected function __construct(int $major, int $minor, int $patch, ?PreRelease $preRelease = NULL, ?Build $build = NULL) + final protected function __construct(int $major, int $minor, int $patch, ?PreRelease $preRelease = null, ?Build $build = null) { VersionAssert::that($major)->greaterOrEqualThan(0, 'Major version must be positive integer'); VersionAssert::that($minor)->greaterOrEqualThan(0, 'Minor version must be positive integer'); @@ -46,7 +46,7 @@ final protected function __construct(int $major, int $minor, int $patch, ?PreRel } - public static function from(int $major, int $minor = 0, int $patch = 0, ?PreRelease $preRelease = NULL, ?Build $build = NULL): Version + public static function from(int $major, int $minor = 0, int $patch = 0, ?PreRelease $preRelease = null, ?Build $build = null): Version { return new static($major, $minor, $patch, $preRelease, $build); } diff --git a/tests/TestAsset/VersionIsIdentical.php b/tests/TestAsset/VersionIsIdentical.php index e0ce930..8f0f818 100644 --- a/tests/TestAsset/VersionIsIdentical.php +++ b/tests/TestAsset/VersionIsIdentical.php @@ -1,61 +1,61 @@ expectedVersion = Version::from( + $expectedMajor, + $expectedMinor, + $expectedPatch, + is_string($expectedPreRelease) ? PreRelease::fromString($expectedPreRelease) : $expectedPreRelease, + is_string($expectedBuild) ? Build::fromString($expectedBuild) : $expectedBuild + ); + } - use PHPUnit\Framework\Constraint\Constraint; - use Version\Extension\Build; - use Version\Extension\PreRelease; - use Version\Version; - final class VersionIsIdentical extends Constraint + protected function matches($version): bool { - private Version $expectedVersion; - - - public function __construct( - int $expectedMajor, - int $expectedMinor, - int $expectedPatch, - PreRelease|string|null $expectedPreRelease = NULL, - Build|string|null $expectedBuild = NULL - ) { - $this->expectedVersion = Version::from( - $expectedMajor, - $expectedMinor, - $expectedPatch, - is_string($expectedPreRelease) ? PreRelease::fromString($expectedPreRelease) : $expectedPreRelease, - is_string($expectedBuild) ? Build::fromString($expectedBuild) : $expectedBuild - ); - } - - - protected function matches($version): bool - { - /* @var $version Version */ - - return ( - $version->getMajor() === $this->expectedVersion->getMajor() - && $version->getMinor() === $this->expectedVersion->getMinor() - && $version->getPatch() === $this->expectedVersion->getPatch() - && ( - ($version->isPreRelease() && $this->expectedVersion->isPreRelease() && $version->getPreRelease()->getIdentifiers( - ) === $this->expectedVersion->getPreRelease()->getIdentifiers()) + /* @var $version Version */ + + return ( + $version->getMajor() === $this->expectedVersion->getMajor() + && $version->getMinor() === $this->expectedVersion->getMinor() + && $version->getPatch() === $this->expectedVersion->getPatch() + && ( + ($version->isPreRelease() && $this->expectedVersion->isPreRelease() && $version->getPreRelease()->getIdentifiers( + ) === $this->expectedVersion->getPreRelease()->getIdentifiers()) || (!$version->isPreRelease() && !$this->expectedVersion->isPreRelease()) - ) - && ( - ($version->hasBuild() && $this->expectedVersion->hasBuild() && $version->getBuild()->getIdentifiers() === $this->expectedVersion->getBuild() - ->getIdentifiers( - )) + ) + && ( + ($version->hasBuild() && $this->expectedVersion->hasBuild() && $version->getBuild()->getIdentifiers() === $this->expectedVersion->getBuild() + ->getIdentifiers( + )) || (!$version->hasBuild() && !$this->expectedVersion->hasBuild()) - ) - ); - } + ) + ); + } - public function toString(): string - { - return 'is identical to: '.$this->expectedVersion->toString(); - } + public function toString(): string + { + return 'is identical to: '.$this->expectedVersion->toString(); } +} From 856549186a3130679fe90b18ff5aed7155f96f44 Mon Sep 17 00:00:00 2001 From: Dimitri Date: Mon, 27 Jan 2025 14:15:32 +0100 Subject: [PATCH 04/11] refactor : update code to comply with repository standards --- tests/TestAsset/VersionIsIdentical.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/TestAsset/VersionIsIdentical.php b/tests/TestAsset/VersionIsIdentical.php index 8f0f818..af1dbc2 100644 --- a/tests/TestAsset/VersionIsIdentical.php +++ b/tests/TestAsset/VersionIsIdentical.php @@ -30,7 +30,6 @@ public function __construct( ); } - protected function matches($version): bool { /* @var $version Version */ @@ -53,7 +52,6 @@ protected function matches($version): bool ); } - public function toString(): string { return 'is identical to: '.$this->expectedVersion->toString(); From bf7c73d71a5aafcad2d3c4801bfae50cc4103a91 Mon Sep 17 00:00:00 2001 From: Dimitri Date: Mon, 27 Jan 2025 14:21:26 +0100 Subject: [PATCH 05/11] refactor : update code to comply with repository standards --- src/Version.php | 390 ++++++++++++------------- tests/TestAsset/VersionIsIdentical.php | 100 +++---- 2 files changed, 242 insertions(+), 248 deletions(-) diff --git a/src/Version.php b/src/Version.php index 9002dc6..9f825d1 100644 --- a/src/Version.php +++ b/src/Version.php @@ -1,251 +1,249 @@ v|release\-)?(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)(?:\-(?P(?:0|[1-9]\d*|\d*[a-zA-Z\-][0-9a-zA-Z\-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z\-][0-9a-zA-Z\-]*))*))?(?:\+(?P[0-9a-zA-Z\-]+(?:\.[0-9a-zA-Z\-]+)*))?$#'; - - protected int $major; - - protected int $minor; + class Version implements JsonSerializable + { + public const REGEX = '#^(?Pv|release\-)?(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)(?:\-(?P(?:0|[1-9]\d*|\d*[a-zA-Z\-][0-9a-zA-Z\-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z\-][0-9a-zA-Z\-]*))*))?(?:\+(?P[0-9a-zA-Z\-]+(?:\.[0-9a-zA-Z\-]+)*))?$#'; - protected int $patch; + protected int $major; - protected ?PreRelease $preRelease; + protected int $minor; - protected ?Build $build; + protected int $patch; - protected string $prefix = ''; + protected ?PreRelease $preRelease; - protected static ?Comparator $comparator = null; + protected ?Build $build; + protected string $prefix = ''; - final protected function __construct(int $major, int $minor, int $patch, ?PreRelease $preRelease = null, ?Build $build = null) - { - VersionAssert::that($major)->greaterOrEqualThan(0, 'Major version must be positive integer'); - VersionAssert::that($minor)->greaterOrEqualThan(0, 'Minor version must be positive integer'); - VersionAssert::that($patch)->greaterOrEqualThan(0, 'Patch version must be positive integer'); - - $this->major = $major; - $this->minor = $minor; - $this->patch = $patch; - $this->preRelease = $preRelease; - $this->build = $build; - } + protected static ?Comparator $comparator = null; + final protected function __construct(int $major, int $minor, int $patch, ?PreRelease $preRelease = null, ?Build $build = null) + { + VersionAssert::that($major)->greaterOrEqualThan(0, 'Major version must be positive integer'); + VersionAssert::that($minor)->greaterOrEqualThan(0, 'Minor version must be positive integer'); + VersionAssert::that($patch)->greaterOrEqualThan(0, 'Patch version must be positive integer'); - public static function from(int $major, int $minor = 0, int $patch = 0, ?PreRelease $preRelease = null, ?Build $build = null): Version - { - return new static($major, $minor, $patch, $preRelease, $build); - } + $this->major = $major; + $this->minor = $minor; + $this->patch = $patch; + $this->preRelease = $preRelease; + $this->build = $build; + } - /** - * @throws InvalidVersionString - */ - public static function fromString(string $versionString): Version - { - if (!preg_match(self::REGEX, $versionString, $parts)) { - throw InvalidVersionString::notParsable($versionString); + public static function from(int $major, int $minor = 0, int $patch = 0, ?PreRelease $preRelease = null, ?Build $build = null): Version + { + return new static($major, $minor, $patch, $preRelease, $build); } - $version = new static( - (int) $parts['major'], - (int) $parts['minor'], - (int) $parts['patch'], - (isset($parts['preRelease']) && '' !== $parts['preRelease']) ? PreRelease::fromString($parts['preRelease']) : null, - (isset($parts['build']) && '' !== $parts['build']) ? Build::fromString($parts['build']) : null - ); - $version->prefix = $parts['prefix'] ?? ''; + /** + * @throws InvalidVersionString + */ + public static function fromString(string $versionString): Version + { + if (!preg_match(self::REGEX, $versionString, $parts)) { + throw InvalidVersionString::notParsable($versionString); + } + + $version = new static( + (int) $parts['major'], + (int) $parts['minor'], + (int) $parts['patch'], + (isset($parts['preRelease']) && '' !== $parts['preRelease']) ? PreRelease::fromString($parts['preRelease']) : null, + (isset($parts['build']) && '' !== $parts['build']) ? Build::fromString($parts['build']) : null + ); + $version->prefix = $parts['prefix'] ?? ''; + + return $version; + } - return $version; - } + public function getMajor(): int + { + return $this->major; + } - public function getMajor(): int - { - return $this->major; - } + public function getMinor(): int + { + return $this->minor; + } - public function getMinor(): int - { - return $this->minor; - } + public function getPatch(): int + { + return $this->patch; + } - public function getPatch(): int - { - return $this->patch; - } + public function getPreRelease(): ?PreRelease + { + return $this->preRelease; + } - public function getPreRelease(): ?PreRelease - { - return $this->preRelease; - } + public function getBuild(): ?Build + { + return $this->build; + } - public function getBuild(): ?Build - { - return $this->build; - } + public function isEqualTo(Version|string $version): bool + { + return $this->compareTo($version) === 0; + } - public function isEqualTo(Version|string $version): bool - { - return $this->compareTo($version) === 0; - } + public function isNotEqualTo(Version|string $version): bool + { + return !$this->isEqualTo($version); + } - public function isNotEqualTo(Version|string $version): bool - { - return !$this->isEqualTo($version); - } + public function isGreaterThan(Version|string $version): bool + { + return $this->compareTo($version) > 0; + } - public function isGreaterThan(Version|string $version): bool - { - return $this->compareTo($version) > 0; - } + public function isGreaterOrEqualTo(Version|string $version): bool + { + return $this->compareTo($version) >= 0; + } - public function isGreaterOrEqualTo(Version|string $version): bool - { - return $this->compareTo($version) >= 0; - } + public function isLessThan(Version|string $version): bool + { + return $this->compareTo($version) < 0; + } - public function isLessThan(Version|string $version): bool - { - return $this->compareTo($version) < 0; - } + public function isLessOrEqualTo(Version|string $version): bool + { + return $this->compareTo($version) <= 0; + } - public function isLessOrEqualTo(Version|string $version): bool - { - return $this->compareTo($version) <= 0; - } + /** + * @return int (1 if $this > $version, -1 if $this < $version, 0 if equal) + */ + public function compareTo(Version|string $version): int + { + if (is_string($version)) { + $version = static::fromString($version); + } - /** - * @return int (1 if $this > $version, -1 if $this < $version, 0 if equal) - */ - public function compareTo(Version|string $version): int - { - if (is_string($version)) { - $version = static::fromString($version); + return $this->getComparator()->compare($this, $version); } - return $this->getComparator()->compare($this, $version); - } + public function isMajorRelease(): bool + { + return $this->major > 0 && $this->minor === 0 && $this->patch === 0; + } - public function isMajorRelease(): bool - { - return $this->major > 0 && $this->minor === 0 && $this->patch === 0; - } + public function isMinorRelease(): bool + { + return $this->minor > 0 && $this->patch === 0; + } - public function isMinorRelease(): bool - { - return $this->minor > 0 && $this->patch === 0; - } + public function isPatchRelease(): bool + { + return $this->patch > 0; + } - public function isPatchRelease(): bool - { - return $this->patch > 0; - } + public function isPreRelease(): bool + { + return $this->preRelease !== null; + } - public function isPreRelease(): bool - { - return $this->preRelease !== null; - } + public function hasBuild(): bool + { + return $this->build !== null; + } - public function hasBuild(): bool - { - return $this->build !== null; - } + public function incrementMajor(): Version + { + return new static($this->major + 1, 0, 0); + } - public function incrementMajor(): Version - { - return new static($this->major + 1, 0, 0); - } + public function incrementMinor(): Version + { + return new static($this->major, $this->minor + 1, 0); + } - public function incrementMinor(): Version - { - return new static($this->major, $this->minor + 1, 0); - } + public function incrementPatch(): Version + { + return new static($this->major, $this->minor, $this->patch + 1); + } - public function incrementPatch(): Version - { - return new static($this->major, $this->minor, $this->patch + 1); - } + public function withPreRelease(PreRelease|string|null $preRelease): Version + { + if (is_string($preRelease)) { + $preRelease = PreRelease::fromString($preRelease); + } - public function withPreRelease(PreRelease|string|null $preRelease): Version - { - if (is_string($preRelease)) { - $preRelease = PreRelease::fromString($preRelease); + return new static($this->major, $this->minor, $this->patch, $preRelease); } - return new static($this->major, $this->minor, $this->patch, $preRelease); - } + public function withBuild(Build|string|null $build): Version + { + if (is_string($build)) { + $build = Build::fromString($build); + } - public function withBuild(Build|string|null $build): Version - { - if (is_string($build)) { - $build = Build::fromString($build); + return new static($this->major, $this->minor, $this->patch, $this->preRelease, $build); } - return new static($this->major, $this->minor, $this->patch, $this->preRelease, $build); - } + public function matches(Constraint $constraint): bool + { + return $constraint->assert($this); + } - public function matches(Constraint $constraint): bool - { - return $constraint->assert($this); - } + public function toString(): string + { + return + $this->prefix + . $this->major + . '.' . $this->minor + . '.' . $this->patch + . (($this->preRelease !== null) ? '-' . $this->preRelease->toString() : '') + . (($this->build !== null) ? '+' . $this->build->toString() : '') + ; + } - public function toString(): string - { - return - $this->prefix - . $this->major - . '.' . $this->minor - . '.' . $this->patch - . (($this->preRelease !== null) ? '-' . $this->preRelease->toString() : '') - . (($this->build !== null) ? '+' . $this->build->toString() : '') - ; - } + public function __toString(): string + { + return $this->toString(); + } - public function __toString(): string - { - return $this->toString(); - } + public function jsonSerialize(): string + { + return $this->toString(); + } - public function jsonSerialize(): string - { - return $this->toString(); - } + public function toArray(): array + { + return [ + 'major' => $this->major, + 'minor' => $this->minor, + 'patch' => $this->patch, + 'preRelease' => ($this->preRelease !== null) ? $this->preRelease->getIdentifiers() : null, + 'build' => ($this->build !== null) ? $this->build->getIdentifiers() : null, + ]; + } - public function toArray(): array - { - return [ - 'major' => $this->major, - 'minor' => $this->minor, - 'patch' => $this->patch, - 'preRelease' => ($this->preRelease !== null) ? $this->preRelease->getIdentifiers() : null, - 'build' => ($this->build !== null) ? $this->build->getIdentifiers() : null, - ]; - } + public static function setComparator(?Comparator $comparator): void + { + static::$comparator = $comparator; + } - public static function setComparator(?Comparator $comparator): void - { - static::$comparator = $comparator; - } + protected function getComparator(): Comparator + { + if (static::$comparator === null) { + static::$comparator = new SemverComparator(); + } - protected function getComparator(): Comparator - { - if (static::$comparator === null) { - static::$comparator = new SemverComparator(); + return static::$comparator; } - - return static::$comparator; } -} diff --git a/tests/TestAsset/VersionIsIdentical.php b/tests/TestAsset/VersionIsIdentical.php index af1dbc2..f88e623 100644 --- a/tests/TestAsset/VersionIsIdentical.php +++ b/tests/TestAsset/VersionIsIdentical.php @@ -1,59 +1,55 @@ expectedVersion = Version::from( - $expectedMajor, - $expectedMinor, - $expectedPatch, - is_string($expectedPreRelease) ? PreRelease::fromString($expectedPreRelease) : $expectedPreRelease, - is_string($expectedBuild) ? Build::fromString($expectedBuild) : $expectedBuild - ); - } + declare(strict_types=1); + + namespace Version\Tests\TestAsset; + + use PHPUnit\Framework\Constraint\Constraint; + use Version\Extension\Build; + use Version\Extension\PreRelease; + use Version\Version; - protected function matches($version): bool + final class VersionIsIdentical extends Constraint { - /* @var $version Version */ - - return ( - $version->getMajor() === $this->expectedVersion->getMajor() - && $version->getMinor() === $this->expectedVersion->getMinor() - && $version->getPatch() === $this->expectedVersion->getPatch() - && ( - ($version->isPreRelease() && $this->expectedVersion->isPreRelease() && $version->getPreRelease()->getIdentifiers( - ) === $this->expectedVersion->getPreRelease()->getIdentifiers()) + private Version $expectedVersion; + + public function __construct( + int $expectedMajor, + int $expectedMinor, + int $expectedPatch, + PreRelease|string|null $expectedPreRelease = null, + Build|string|null $expectedBuild = null + ) { + $this->expectedVersion = Version::from( + $expectedMajor, + $expectedMinor, + $expectedPatch, + is_string($expectedPreRelease) ? PreRelease::fromString($expectedPreRelease) : $expectedPreRelease, + is_string($expectedBuild) ? Build::fromString($expectedBuild) : $expectedBuild + ); + } + + protected function matches($version): bool + { + /* @var $version Version */ + + return ( + $version->getMajor() === $this->expectedVersion->getMajor() + && $version->getMinor() === $this->expectedVersion->getMinor() + && $version->getPatch() === $this->expectedVersion->getPatch() + && ( + ($version->isPreRelease() && $this->expectedVersion->isPreRelease() && $version->getPreRelease()->getIdentifiers() === $this->expectedVersion->getPreRelease()->getIdentifiers()) || (!$version->isPreRelease() && !$this->expectedVersion->isPreRelease()) - ) - && ( - ($version->hasBuild() && $this->expectedVersion->hasBuild() && $version->getBuild()->getIdentifiers() === $this->expectedVersion->getBuild() - ->getIdentifiers( - )) + ) + && ( + ($version->hasBuild() && $this->expectedVersion->hasBuild() && $version->getBuild()->getIdentifiers() === $this->expectedVersion->getBuild()->getIdentifiers()) || (!$version->hasBuild() && !$this->expectedVersion->hasBuild()) - ) - ); - } - - public function toString(): string - { - return 'is identical to: '.$this->expectedVersion->toString(); + ) + ); + } + + public function toString(): string + { + return 'is identical to: ' . $this->expectedVersion->toString(); + } } -} From 7508ad5b7b83d6649d3e8338046aaab3f4af0dcd Mon Sep 17 00:00:00 2001 From: Dimitri Date: Mon, 27 Jan 2025 14:39:27 +0100 Subject: [PATCH 06/11] fix(PhpStan): Remove deprecated config checkMissingIterableValueType and checkGenericClassInNonGenericObjectType Replace with : ignoreErrors: - identifier: missingType.generics - identifier: missingType.iterableValue --- phpstan.neon.dist | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 88f195f..602d0a1 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -3,13 +3,13 @@ parameters: paths: - src - tests - checkMissingIterableValueType: false - checkGenericClassInNonGenericObjectType: false earlyTerminatingMethodCalls: Version\Comparison\Constraint\OperationConstraintParser: - error ignoreErrors: - '~Method [a-zA-Z0-9\\_]+::matches\(\) has parameter \$[a-zA-Z0-9]+ with no type specified.~' + - identifier: missingType.generics + - identifier: missingType.iterableValue includes: From d06d66c8f1a973c204a1a7afb6e591c32a4390f9 Mon Sep 17 00:00:00 2001 From: Dimitri Date: Mon, 27 Jan 2025 14:47:28 +0100 Subject: [PATCH 07/11] fix(PhpStan): Resolve PHPStan warning for non-nullable 'prefix' offset in array --- src/Version.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Version.php b/src/Version.php index 9f825d1..b052437 100644 --- a/src/Version.php +++ b/src/Version.php @@ -6,11 +6,11 @@ use JsonSerializable; use Version\Assert\VersionAssert; - use Version\Extension\Build; - use Version\Exception\InvalidVersionString; use Version\Comparison\Comparator; - use Version\Comparison\SemverComparator; use Version\Comparison\Constraint\Constraint; + use Version\Comparison\SemverComparator; + use Version\Exception\InvalidVersionString; + use Version\Extension\Build; use Version\Extension\PreRelease; class Version implements JsonSerializable @@ -65,7 +65,7 @@ public static function fromString(string $versionString): Version (isset($parts['preRelease']) && '' !== $parts['preRelease']) ? PreRelease::fromString($parts['preRelease']) : null, (isset($parts['build']) && '' !== $parts['build']) ? Build::fromString($parts['build']) : null ); - $version->prefix = $parts['prefix'] ?? ''; + $version->prefix = $parts[ 'prefix' ]; return $version; } From 496e4427c3e817e05c4cb4c745aa970a82bb1334 Mon Sep 17 00:00:00 2001 From: Dimitri Date: Mon, 27 Jan 2025 14:56:49 +0100 Subject: [PATCH 08/11] refactor : update code to comply with repository standards --- src/Version.php | 387 ++++++++++++------------- tests/TestAsset/VersionIsIdentical.php | 99 +++---- 2 files changed, 243 insertions(+), 243 deletions(-) diff --git a/src/Version.php b/src/Version.php index b052437..5d3d566 100644 --- a/src/Version.php +++ b/src/Version.php @@ -1,249 +1,248 @@ v|release\-)?(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)(?:\-(?P(?:0|[1-9]\d*|\d*[a-zA-Z\-][0-9a-zA-Z\-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z\-][0-9a-zA-Z\-]*))*))?(?:\+(?P[0-9a-zA-Z\-]+(?:\.[0-9a-zA-Z\-]+)*))?$#'; +class Version implements JsonSerializable +{ + public const REGEX = '#^(?Pv|release\-)?(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)(?:\-(?P(?:0|[1-9]\d*|\d*[a-zA-Z\-][0-9a-zA-Z\-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z\-][0-9a-zA-Z\-]*))*))?(?:\+(?P[0-9a-zA-Z\-]+(?:\.[0-9a-zA-Z\-]+)*))?$#'; - protected int $major; + protected int $major; - protected int $minor; + protected int $minor; - protected int $patch; + protected int $patch; - protected ?PreRelease $preRelease; + protected ?PreRelease $preRelease; - protected ?Build $build; + protected ?Build $build; - protected string $prefix = ''; + protected string $prefix = ''; - protected static ?Comparator $comparator = null; + protected static ?Comparator $comparator = null; - final protected function __construct(int $major, int $minor, int $patch, ?PreRelease $preRelease = null, ?Build $build = null) - { - VersionAssert::that($major)->greaterOrEqualThan(0, 'Major version must be positive integer'); - VersionAssert::that($minor)->greaterOrEqualThan(0, 'Minor version must be positive integer'); - VersionAssert::that($patch)->greaterOrEqualThan(0, 'Patch version must be positive integer'); + final protected function __construct(int $major, int $minor, int $patch, ?PreRelease $preRelease = null, ?Build $build = null) + { + VersionAssert::that($major)->greaterOrEqualThan(0, 'Major version must be positive integer'); + VersionAssert::that($minor)->greaterOrEqualThan(0, 'Minor version must be positive integer'); + VersionAssert::that($patch)->greaterOrEqualThan(0, 'Patch version must be positive integer'); + + $this->major = $major; + $this->minor = $minor; + $this->patch = $patch; + $this->preRelease = $preRelease; + $this->build = $build; + } - $this->major = $major; - $this->minor = $minor; - $this->patch = $patch; - $this->preRelease = $preRelease; - $this->build = $build; - } + public static function from(int $major, int $minor = 0, int $patch = 0, ?PreRelease $preRelease = null, ?Build $build = null): Version + { + return new static($major, $minor, $patch, $preRelease, $build); + } - public static function from(int $major, int $minor = 0, int $patch = 0, ?PreRelease $preRelease = null, ?Build $build = null): Version - { - return new static($major, $minor, $patch, $preRelease, $build); + /** + * @throws InvalidVersionString + */ + public static function fromString(string $versionString): Version + { + if (!preg_match(self::REGEX, $versionString, $parts)) { + throw InvalidVersionString::notParsable($versionString); } - /** - * @throws InvalidVersionString - */ - public static function fromString(string $versionString): Version - { - if (!preg_match(self::REGEX, $versionString, $parts)) { - throw InvalidVersionString::notParsable($versionString); - } - - $version = new static( - (int) $parts['major'], - (int) $parts['minor'], - (int) $parts['patch'], - (isset($parts['preRelease']) && '' !== $parts['preRelease']) ? PreRelease::fromString($parts['preRelease']) : null, - (isset($parts['build']) && '' !== $parts['build']) ? Build::fromString($parts['build']) : null - ); - $version->prefix = $parts[ 'prefix' ]; - - return $version; - } + $version = new static( + (int)$parts['major'], + (int)$parts['minor'], + (int)$parts['patch'], + (isset($parts['preRelease']) && '' !== $parts['preRelease']) ? PreRelease::fromString($parts['preRelease']) : null, + (isset($parts['build']) && '' !== $parts['build']) ? Build::fromString($parts['build']) : null + ); + $version->prefix = $parts['prefix']; - public function getMajor(): int - { - return $this->major; - } + return $version; + } - public function getMinor(): int - { - return $this->minor; - } + public function getMajor(): int + { + return $this->major; + } - public function getPatch(): int - { - return $this->patch; - } + public function getMinor(): int + { + return $this->minor; + } - public function getPreRelease(): ?PreRelease - { - return $this->preRelease; - } + public function getPatch(): int + { + return $this->patch; + } - public function getBuild(): ?Build - { - return $this->build; - } + public function getPreRelease(): ?PreRelease + { + return $this->preRelease; + } - public function isEqualTo(Version|string $version): bool - { - return $this->compareTo($version) === 0; - } + public function getBuild(): ?Build + { + return $this->build; + } - public function isNotEqualTo(Version|string $version): bool - { - return !$this->isEqualTo($version); - } + public function isEqualTo(Version|string $version): bool + { + return $this->compareTo($version) === 0; + } - public function isGreaterThan(Version|string $version): bool - { - return $this->compareTo($version) > 0; - } + public function isNotEqualTo(Version|string $version): bool + { + return !$this->isEqualTo($version); + } - public function isGreaterOrEqualTo(Version|string $version): bool - { - return $this->compareTo($version) >= 0; - } + public function isGreaterThan(Version|string $version): bool + { + return $this->compareTo($version) > 0; + } - public function isLessThan(Version|string $version): bool - { - return $this->compareTo($version) < 0; - } + public function isGreaterOrEqualTo(Version|string $version): bool + { + return $this->compareTo($version) >= 0; + } - public function isLessOrEqualTo(Version|string $version): bool - { - return $this->compareTo($version) <= 0; - } + public function isLessThan(Version|string $version): bool + { + return $this->compareTo($version) < 0; + } - /** - * @return int (1 if $this > $version, -1 if $this < $version, 0 if equal) - */ - public function compareTo(Version|string $version): int - { - if (is_string($version)) { - $version = static::fromString($version); - } + public function isLessOrEqualTo(Version|string $version): bool + { + return $this->compareTo($version) <= 0; + } - return $this->getComparator()->compare($this, $version); + /** + * @return int (1 if $this > $version, -1 if $this < $version, 0 if equal) + */ + public function compareTo(Version|string $version): int + { + if (is_string($version)) { + $version = static::fromString($version); } - public function isMajorRelease(): bool - { - return $this->major > 0 && $this->minor === 0 && $this->patch === 0; - } + return $this->getComparator()->compare($this, $version); + } - public function isMinorRelease(): bool - { - return $this->minor > 0 && $this->patch === 0; - } + public function isMajorRelease(): bool + { + return $this->major > 0 && $this->minor === 0 && $this->patch === 0; + } - public function isPatchRelease(): bool - { - return $this->patch > 0; - } + public function isMinorRelease(): bool + { + return $this->minor > 0 && $this->patch === 0; + } - public function isPreRelease(): bool - { - return $this->preRelease !== null; - } + public function isPatchRelease(): bool + { + return $this->patch > 0; + } - public function hasBuild(): bool - { - return $this->build !== null; - } + public function isPreRelease(): bool + { + return $this->preRelease !== null; + } - public function incrementMajor(): Version - { - return new static($this->major + 1, 0, 0); - } + public function hasBuild(): bool + { + return $this->build !== null; + } - public function incrementMinor(): Version - { - return new static($this->major, $this->minor + 1, 0); - } + public function incrementMajor(): Version + { + return new static($this->major + 1, 0, 0); + } - public function incrementPatch(): Version - { - return new static($this->major, $this->minor, $this->patch + 1); - } + public function incrementMinor(): Version + { + return new static($this->major, $this->minor + 1, 0); + } - public function withPreRelease(PreRelease|string|null $preRelease): Version - { - if (is_string($preRelease)) { - $preRelease = PreRelease::fromString($preRelease); - } + public function incrementPatch(): Version + { + return new static($this->major, $this->minor, $this->patch + 1); + } - return new static($this->major, $this->minor, $this->patch, $preRelease); + public function withPreRelease(PreRelease|string|null $preRelease): Version + { + if (is_string($preRelease)) { + $preRelease = PreRelease::fromString($preRelease); } - public function withBuild(Build|string|null $build): Version - { - if (is_string($build)) { - $build = Build::fromString($build); - } + return new static($this->major, $this->minor, $this->patch, $preRelease); + } - return new static($this->major, $this->minor, $this->patch, $this->preRelease, $build); + public function withBuild(Build|string|null $build): Version + { + if (is_string($build)) { + $build = Build::fromString($build); } - public function matches(Constraint $constraint): bool - { - return $constraint->assert($this); - } + return new static($this->major, $this->minor, $this->patch, $this->preRelease, $build); + } - public function toString(): string - { - return - $this->prefix - . $this->major - . '.' . $this->minor - . '.' . $this->patch - . (($this->preRelease !== null) ? '-' . $this->preRelease->toString() : '') - . (($this->build !== null) ? '+' . $this->build->toString() : '') - ; - } + public function matches(Constraint $constraint): bool + { + return $constraint->assert($this); + } - public function __toString(): string - { - return $this->toString(); - } + public function toString(): string + { + return + $this->prefix + . $this->major + . '.' . $this->minor + . '.' . $this->patch + . (($this->preRelease !== null) ? '-' . $this->preRelease->toString() : '') + . (($this->build !== null) ? '+' . $this->build->toString() : ''); + } - public function jsonSerialize(): string - { - return $this->toString(); - } + public function __toString(): string + { + return $this->toString(); + } - public function toArray(): array - { - return [ - 'major' => $this->major, - 'minor' => $this->minor, - 'patch' => $this->patch, - 'preRelease' => ($this->preRelease !== null) ? $this->preRelease->getIdentifiers() : null, - 'build' => ($this->build !== null) ? $this->build->getIdentifiers() : null, - ]; - } + public function jsonSerialize(): string + { + return $this->toString(); + } - public static function setComparator(?Comparator $comparator): void - { - static::$comparator = $comparator; - } + public function toArray(): array + { + return [ + 'major' => $this->major, + 'minor' => $this->minor, + 'patch' => $this->patch, + 'preRelease' => ($this->preRelease !== null) ? $this->preRelease->getIdentifiers() : null, + 'build' => ($this->build !== null) ? $this->build->getIdentifiers() : null, + ]; + } - protected function getComparator(): Comparator - { - if (static::$comparator === null) { - static::$comparator = new SemverComparator(); - } + public static function setComparator(?Comparator $comparator): void + { + static::$comparator = $comparator; + } - return static::$comparator; + protected function getComparator(): Comparator + { + if (static::$comparator === null) { + static::$comparator = new SemverComparator(); } + + return static::$comparator; } +} \ No newline at end of file diff --git a/tests/TestAsset/VersionIsIdentical.php b/tests/TestAsset/VersionIsIdentical.php index f88e623..e2d3650 100644 --- a/tests/TestAsset/VersionIsIdentical.php +++ b/tests/TestAsset/VersionIsIdentical.php @@ -1,55 +1,56 @@ expectedVersion = Version::from( + $expectedMajor, + $expectedMinor, + $expectedPatch, + is_string($expectedPreRelease) ? PreRelease::fromString($expectedPreRelease) : $expectedPreRelease, + is_string($expectedBuild) ? Build::fromString($expectedBuild) : $expectedBuild + ); + } - use PHPUnit\Framework\Constraint\Constraint; - use Version\Extension\Build; - use Version\Extension\PreRelease; - use Version\Version; + protected function matches($version): bool + { + /* @var $version Version */ + + return ( + $version->getMajor() === $this->expectedVersion->getMajor() + && $version->getMinor() === $this->expectedVersion->getMinor() + && $version->getPatch() === $this->expectedVersion->getPatch() + && ( + ($version->isPreRelease() && $this->expectedVersion->isPreRelease() && $version->getPreRelease()->getIdentifiers() === $this->expectedVersion->getPreRelease()->getIdentifiers()) + || (!$version->isPreRelease() && !$this->expectedVersion->isPreRelease()) + ) + && ( + ($version->hasBuild() && $this->expectedVersion->hasBuild() && $version->getBuild()->getIdentifiers() === $this->expectedVersion->getBuild()->getIdentifiers()) + || (!$version->hasBuild() && !$this->expectedVersion->hasBuild()) + ) + ); + } - final class VersionIsIdentical extends Constraint + public function toString(): string { - private Version $expectedVersion; - - public function __construct( - int $expectedMajor, - int $expectedMinor, - int $expectedPatch, - PreRelease|string|null $expectedPreRelease = null, - Build|string|null $expectedBuild = null - ) { - $this->expectedVersion = Version::from( - $expectedMajor, - $expectedMinor, - $expectedPatch, - is_string($expectedPreRelease) ? PreRelease::fromString($expectedPreRelease) : $expectedPreRelease, - is_string($expectedBuild) ? Build::fromString($expectedBuild) : $expectedBuild - ); - } - - protected function matches($version): bool - { - /* @var $version Version */ - - return ( - $version->getMajor() === $this->expectedVersion->getMajor() - && $version->getMinor() === $this->expectedVersion->getMinor() - && $version->getPatch() === $this->expectedVersion->getPatch() - && ( - ($version->isPreRelease() && $this->expectedVersion->isPreRelease() && $version->getPreRelease()->getIdentifiers() === $this->expectedVersion->getPreRelease()->getIdentifiers()) - || (!$version->isPreRelease() && !$this->expectedVersion->isPreRelease()) - ) - && ( - ($version->hasBuild() && $this->expectedVersion->hasBuild() && $version->getBuild()->getIdentifiers() === $this->expectedVersion->getBuild()->getIdentifiers()) - || (!$version->hasBuild() && !$this->expectedVersion->hasBuild()) - ) - ); - } - - public function toString(): string - { - return 'is identical to: ' . $this->expectedVersion->toString(); - } + return 'is identical to: ' . $this->expectedVersion->toString(); } +} \ No newline at end of file From 53625deaa17a0ced5f2ccc217f444b069ee96a9c Mon Sep 17 00:00:00 2001 From: Dimitri Date: Mon, 27 Jan 2025 15:12:22 +0100 Subject: [PATCH 09/11] fix : Add newline at end of file VersionIsIdentical --- tests/TestAsset/VersionIsIdentical.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/TestAsset/VersionIsIdentical.php b/tests/TestAsset/VersionIsIdentical.php index e2d3650..dfaeb25 100644 --- a/tests/TestAsset/VersionIsIdentical.php +++ b/tests/TestAsset/VersionIsIdentical.php @@ -53,4 +53,4 @@ public function toString(): string { return 'is identical to: ' . $this->expectedVersion->toString(); } -} \ No newline at end of file +} From c94ec3a250f373c4aa93f1ca5c00e8e6f0b23b38 Mon Sep 17 00:00:00 2001 From: Dimitri Date: Mon, 27 Jan 2025 15:13:15 +0100 Subject: [PATCH 10/11] fix : Add newline at end of file Version --- src/Version.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Version.php b/src/Version.php index 5d3d566..5b12e1d 100644 --- a/src/Version.php +++ b/src/Version.php @@ -245,4 +245,4 @@ protected function getComparator(): Comparator return static::$comparator; } -} \ No newline at end of file +} From a3910fe3d18c18f166a5937c0a7a52202e96820c Mon Sep 17 00:00:00 2001 From: Dimitri Date: Mon, 27 Jan 2025 15:14:25 +0100 Subject: [PATCH 11/11] chore : Run php cs fixer --- tests/TestAsset/VersionIsIdentical.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/TestAsset/VersionIsIdentical.php b/tests/TestAsset/VersionIsIdentical.php index dfaeb25..799eae0 100644 --- a/tests/TestAsset/VersionIsIdentical.php +++ b/tests/TestAsset/VersionIsIdentical.php @@ -19,8 +19,7 @@ public function __construct( int $expectedPatch, PreRelease|string|null $expectedPreRelease = null, Build|string|null $expectedBuild = null - ) - { + ) { $this->expectedVersion = Version::from( $expectedMajor, $expectedMinor,