diff --git a/src/Helper/Version.php b/src/Helper/Version.php index 9bd5a70..0fe8f9b 100644 --- a/src/Helper/Version.php +++ b/src/Helper/Version.php @@ -162,4 +162,70 @@ public function equalTo(Version $second): bool { return $this->full === $second->full; } + + /** + * Returns the increased Version based on the stability. + * + * Note. Using 'major' on a beta release will create a stable release + * for that major version. Using 'stable' on an existing stable will increase + * minor. + * + * @param string $stability Eg. alpha, beta, rc, stable, major, minor, patch + * + * @return Version A new version instance with the changes applied + */ + public function increase(string $stability): Version + { + switch ($stability) { + case 'patch': + if ($this->major > 0 && $this->metaver > 0) { + throw new \InvalidArgumentException('Cannot increase patch for an unstable version.'); + } + + return new self($this->major, $this->minor, $this->patch + 1, 3); + + case 'minor': + return new self($this->major, $this->minor + 1, 0, 3); + + case 'major': + if ($this->stability < 3) { + return new self($this->major > 0 ? $this->major : $this->major + 1, 0, 0, 3); + } + + return new self($this->major + 1, 0, 0, 3); + + case 'alpha': + case 'beta': + case 'rc': + return $this->increaseMetaver($stability); + + case 'stable': + return $this->increaseStable(); + + default: + throw new \InvalidArgumentException('Unknown or unsupported stability provided: '.$stability); + } + } + + private function increaseMetaver(string $stability): Version + { + if ($this->stability === self::$stabilises[$stability]) { + return new self($this->major, $this->minor, 0, $this->stability, $this->metaver + 1); + } + + if (self::$stabilises[$stability] > $this->stability) { + return new self($this->major, $this->minor, 0, self::$stabilises[$stability], 1); + } + + return new self($this->major, $this->minor + 1, 0, self::$stabilises[$stability], 1); + } + + private function increaseStable(): Version + { + if ($this->stability < 3) { + return new self(max($this->major, 1), 0, 0, 3); + } + + return new self($this->major, $this->minor + 1, 0, 3); + } } diff --git a/tests/Helper/VersionTest.php b/tests/Helper/VersionTest.php index b079bc3..333ec57 100644 --- a/tests/Helper/VersionTest.php +++ b/tests/Helper/VersionTest.php @@ -137,4 +137,63 @@ public function it_provides_next_version_candidates($current, $expected) self::assertEquals($expected, $candidates); } + + public function provideExpectedIncreasedVersion(): array + { + return [ + 'patch with patch 0' => ['0.1.0', '0.1.1', 'patch'], + 'patch with patch 1' => ['0.1.1', '0.1.2', 'patch'], + + // Minor, patch must be reset + 'minor with patch 0' => ['0.1.0', '0.2.0', 'minor'], + 'minor with patch 1' => ['0.1.1', '0.2.0', 'minor'], + + // Major, minor and patch must be reset + 'major.0.0' => ['0.1.0', '1.0.0', 'major'], + 'major.1.0' => ['0.1.0', '1.0.0', 'major'], + 'major.1.1' => ['0.1.1', '1.0.0', 'major'], + 'major from beta' => ['1.0.0-beta1', '1.0.0', 'major'], + 'major from 1.0' => ['1.0.0', '2.0.0', 'major'], + 'major from 2.0-beta' => ['2.0.0-beta1', '2.0.0', 'major'], + + // Alpha + 'next alpha' => ['1.0.0-alpha1', '1.0.0-alpha2', 'alpha'], + 'new alpha' => ['1.0.0', '1.1.0-alpha1', 'alpha'], + + // Beta + 'next beta' => ['1.0.0-beta1', '1.0.0-beta2', 'beta'], + 'new beta' => ['1.0.0', '1.1.0-beta1', 'beta'], + 'new beta from alpha' => ['1.0.0-alpha1', '1.0.0-beta1', 'beta'], + + // RC + 'next rc' => ['1.0.0-rc1', '1.0.0-rc2', 'rc'], + 'new rc' => ['1.0.0', '1.1.0-rc1', 'rc'], + 'new rc from alpha' => ['1.0.0-alpha1', '1.0.0-rc1', 'rc'], + 'new rc from beta' => ['1.0.0-beta1', '1.0.0-rc1', 'rc'], + + // Stable + 'new stable from 0.0' => ['0.1.0', '1.0.0', 'stable'], + 'new stable from alpha' => ['1.0.0-alpha6', '1.0.0', 'stable'], + 'new stable from beta' => ['1.0.0-beta1', '1.0.0', 'stable'], + 'new stable from current stable' => ['1.0.0', '1.1.0', 'stable'], + ]; + } + + /** + * @test + * @dataProvider provideExpectedIncreasedVersion + */ + public function it_increases_to_next_version(string $current, string $expected, $stability) + { + self::assertEquals(Version::fromString($expected), Version::fromString($current)->increase($stability)); + } + + /** @test */ + public function it_cannot_increases_patch_on_unstable() + { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Cannot increase patch for an unstable version.'); + + Version::fromString('1.0.0-beta1')->increase('patch'); + } }