Skip to content

Commit

Permalink
refactor #4 Clean code refactoring (sstok)
Browse files Browse the repository at this point in the history
This PR was merged into the 1.0-dev branch.
labels: bc-break

Discussion
----------

- Remove usage of magic numbers
- Encapsulate incremental logic into sub-routines
- Rename `increase()` to `getNextIncreaseOf()` to indicate this version returns. [BC BREAK]
- Add some additional tests

Commits
-------

c26e951 Rename Version::increase to getNextIncreaseOf
d68853a Improve the internal logic of Version
  • Loading branch information
sstok authored Nov 14, 2018
2 parents 85fd4d0 + d68853a commit f3092e6
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 54 deletions.
1 change: 1 addition & 0 deletions .php_cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ return PhpCsFixer\Config::create()
'ordered_imports' => true,
'phpdoc_annotation_without_dot' => true,
'phpdoc_order' => true,
'native_function_invocation' => false,

// This breaks for variable @var blocks
'phpdoc_to_comment' => false,
Expand Down
7 changes: 7 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
UPGRADE
=======

## Upgrade FROM 0.2 to 0.3

* The method `increase` of `Version` is renamed to `getNextIncreaseOf`.

118 changes: 66 additions & 52 deletions src/Version.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@

final class Version
{
public const STABILITY_ALPHA = 0;
public const STABILITY_BETA = 1;
public const STABILITY_RC = 2;
public const STABILITY_STABLE = 3;

/**
* Match most common version formats.
*
Expand All @@ -36,13 +41,17 @@ final class Version
*
* @var int[]
*/
private static $stabilityIndexes = ['alpha' => 0, 'beta' => 1, 'rc' => 2, 'stable' => 3];
private static $stabilityIndexes = [
'alpha' => self::STABILITY_ALPHA,
'beta' => self::STABILITY_BETA,
'rc' => self::STABILITY_RC,
'stable' => self::STABILITY_STABLE,
];

private function __construct(int $major, int $minor, int $patch, int $stability, int $metaver = 0)
{
if (0 === $major) {
$stability = 0;
$metaver = 1;
$stability = self::STABILITY_ALPHA;
}

$this->major = $major;
Expand All @@ -51,11 +60,11 @@ private function __construct(int $major, int $minor, int $patch, int $stability,
$this->stability = $stability;
$this->metaver = $metaver;

if (3 === $stability && $this->metaver > 0) {
if (self::STABILITY_STABLE === $stability && $this->metaver > 0) {
throw new \InvalidArgumentException('Meta version of the stability flag cannot be set for stable.');
}

if ($major > 0 && $stability < 3) {
if ($major > 0 && $stability < self::STABILITY_STABLE) {
$this->full = sprintf(
'%d.%d.%d-%s%d',
$this->major,
Expand Down Expand Up @@ -89,7 +98,7 @@ public static function fromString(string $version): self
throw new \InvalidArgumentException(
sprintf(
'Unable to parse version "%s" Expects an SemVer compatible version without build-metadata. '.
'Eg. "1.0.0", "1.0", "1.0" or "1.0.0-beta1", "1.0.0-beta-1"',
'Either "1.0.0", "1.0", "1.0" or "1.0.0-beta1", "1.0.0-beta-1"',
$version
)
);
Expand All @@ -115,42 +124,40 @@ public function getNextVersionCandidates(): array
// Use alpha as stability with metaver 1, 0.2-alpha2 is simple ignored.
// If anyone really uses this... not our problem :)
if (0 === $this->major) {
$candidates[] = new self(0, $this->minor, $this->patch + 1, 0, 1); // patch increase
$candidates[] = new self(0, $this->minor + 1, 0, 0, 1); // minor increase
$candidates[] = new self(1, 0, 0, 1, 1); // 1.0.0-BETA1
$candidates[] = $this->getNextIncreaseOf('patch');
$candidates[] = $this->getNextIncreaseOf('minor');
$candidates[] = self::fromString('1.0.0-BETA1');

// stable (RC usually follows *after* beta, but jumps to stable are accepted)
// RC is technically valid, but not very common and therefor ignored.
$candidates[] = new self(1, 0, 0, 3);
$candidates[] = self::fromString('1.0.0');

// No future candidates considered.
return $candidates;
}

// Latest is unstable, may increase stability or metaver (nothing else)
// 1.0.1-beta1 is not accepted, an (un)stability only applies for x.0.0
if ($this->stability < 3) {
if ($this->stability < self::STABILITY_STABLE) {
$candidates[] = new self($this->major, $this->minor, 0, $this->stability, $this->metaver + 1);

for ($s = $this->stability + 1; $s < 3; ++$s) {
$candidates[] = new self($this->major, $this->minor, 0, $s, 1);
}

$candidates[] = new self($this->major, $this->minor, 0, 3);
$candidates[] = new self($this->major, $this->minor, 0, self::STABILITY_STABLE);

return $candidates;
}

// Stable, so a patch, major or new minor (with lower stability) version is possible
// RC is excluded.
$candidates[] = new self($this->major, $this->minor, $this->patch + 1, 3);
$candidates[] = new self($this->major, $this->minor + 1, 0, 1, 1); // BETA1 for next minor
$candidates[] = new self($this->major, $this->minor + 1, 0, 3); // stable next minor
// Stable, so a patch, major or new minor (with lower stability) version is possible, RC is excluded.
$candidates[] = $this->getNextIncreaseOf('patch');
$candidates[] = $this->getNextIncreaseOf('beta');
$candidates[] = $this->getNextIncreaseOf('minor');

// New (un)stable major (excluding RC)
$candidates[] = new self($this->major + 1, 0, 0, 0, 1); // alpha
$candidates[] = new self($this->major + 1, 0, 0, 1, 1); // beta
$candidates[] = new self($this->major + 1, 0, 0, 3); // stable
$candidates[] = new self($this->major + 1, 0, 0, self::STABILITY_ALPHA, 1);
$candidates[] = new self($this->major + 1, 0, 0, self::STABILITY_BETA, 1);
$candidates[] = new self($this->major + 1, 0, 0, self::STABILITY_STABLE);

return $candidates;
}
Expand All @@ -163,44 +170,42 @@ public function equalTo(self $second): bool
/**
* 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. Using 'patch' on an unstable release will increase the metaver instead.
* Note:
*
* * Using 'major' on a beta release produces a stable release for *that* major version.
* * Using 'stable' on an existing stable will increase the minor version.
* * Using 'patch' on an unstable release increases the metaver instead.
*
* @param string $stability Eg. alpha, beta, rc, stable, major, minor, patch
* @param string $stability either alpha, beta, rc, stable, major, minor or patch
*
* @return Version A new version instance with the changes applied
* @return self A new version instance with the changes applied
*/
public function increase(string $stability): self
public function getNextIncreaseOf(string $stability): self
{
switch ($stability) {
case 'patch':
if ($this->major > 0 && $this->metaver > 0) {
return $this->increaseNext();
return $this->getIncreaseOfNextPossibleMinorOrMeta();
}

return new self($this->major, $this->minor, $this->patch + 1, 3);
return new self($this->major, $this->minor, $this->patch + 1, self::STABILITY_STABLE);

case 'minor':
return new self($this->major, $this->minor + 1, 0, 3);
return new self($this->major, $this->minor + 1, 0, self::STABILITY_STABLE);

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);
return $this->getIncreaseByMajor();

case 'alpha':
case 'beta':
case 'rc':
return $this->increaseMetaver($stability);
return $this->getIncreaseOfMetaver($stability);

case 'stable':
return $this->increaseStable();
return $this->getIncreaseOfStable();

case 'next':
return $this->increaseNext();
return $this->getIncreaseOfNextPossibleMinorOrMeta();

default:
throw new \InvalidArgumentException(
Expand All @@ -213,34 +218,43 @@ public function increase(string $stability): self
}
}

private function increaseMetaver(string $stability): self
private function getIncreaseOfNextPossibleMinorOrMeta(): self
{
if ($this->stability === self::$stabilityIndexes[$stability]) {
return new self($this->major, $this->minor, 0, $this->stability, $this->metaver + 1);
if ($this->major > 0 && $this->stability < self::STABILITY_STABLE) {
return new self($this->major, $this->minor, $this->patch, $this->stability, $this->metaver + 1);
}

if (self::$stabilityIndexes[$stability] > $this->stability) {
return new self($this->major, $this->minor, 0, self::$stabilityIndexes[$stability], 1);
return new self($this->major, $this->minor + 1, 0, self::STABILITY_STABLE);
}

private function getIncreaseByMajor(): self
{
if ($this->stability < self::STABILITY_STABLE) {
return new self(max($this->major, 1), 0, 0, self::STABILITY_STABLE);
}

return new self($this->major, $this->minor + 1, 0, self::$stabilityIndexes[$stability], 1);
return new self($this->major + 1, 0, 0, self::STABILITY_STABLE);
}

private function increaseStable(): self
private function getIncreaseOfMetaver(string $stability): self
{
if ($this->stability < 3) {
return new self(max($this->major, 1), 0, 0, 3);
if ($this->stability === self::$stabilityIndexes[$stability]) {
return new self($this->major, $this->minor, 0, $this->stability, $this->metaver + 1);
}

if (self::$stabilityIndexes[$stability] > $this->stability) {
return new self($this->major, $this->minor, 0, self::$stabilityIndexes[$stability], 1);
}

return new self($this->major, $this->minor + 1, 0, 3);
return new self($this->major, $this->minor + 1, 0, self::$stabilityIndexes[$stability], 1);
}

private function increaseNext(): self
private function getIncreaseOfStable(): self
{
if ($this->major > 0 && $this->stability < 3) {
return new self($this->major, $this->minor, $this->patch, $this->stability, $this->metaver + 1);
if ($this->stability < self::STABILITY_STABLE) {
return new self(max($this->major, 1), 0, 0, self::STABILITY_STABLE);
}

return new self($this->major, $this->minor + 1, 0, 3);
return new self($this->major, $this->minor + 1, 0, self::STABILITY_STABLE);
}
}
7 changes: 5 additions & 2 deletions tests/VersionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,11 @@ public function provideExpectedNextVersionCandidates(): array
return [
'alpha 0' => ['0.1.0', ['0.1.1', '0.2.0', '1.0.0-BETA1', '1.0.0']],
'beta' => ['1.0.0-beta-5', ['1.0.0-BETA6', '1.0.0-RC1', '1.0.0']],
'beta 2' => ['2.0.0-beta-5', ['2.0.0-BETA6', '2.0.0-RC1', '2.0.0']],
'beta 3' => ['v3.5-beta1', ['v3.5-beta2', 'v3.5-RC1', 'v3.5']],
'rc' => ['1.0.0-RC5', ['1.0.0-RC6', '1.0.0']],
'stable major' => ['1.0.0', ['1.0.1', '1.1.0-BETA1', '1.1.0', '2.0.0-ALPHA1', '2.0.0-BETA1', '2.0.0']],
'stable major 2' => ['2.0.0', ['2.0.1', '2.1.0-BETA1', '2.1.0', '3.0.0-ALPHA1', '3.0.0-BETA1', '3.0.0']],
'stable with minor' => ['1.1.0', ['1.1.1', '1.2.0-BETA1', '1.2.0', '2.0.0-ALPHA1', '2.0.0-BETA1', '2.0.0']],
'stable with minor and patch' => ['1.1.1', ['1.1.2', '1.2.0-BETA1', '1.2.0', '2.0.0-ALPHA1', '2.0.0-BETA1', '2.0.0']],
'stable with patch' => ['1.0.1', ['1.0.2', '1.1.0-BETA1', '1.1.0', '2.0.0-ALPHA1', '2.0.0-BETA1', '2.0.0']],
Expand Down Expand Up @@ -198,7 +201,7 @@ public function provideExpectedIncreasedVersion(): array
*/
public function it_increases_to_next_version(string $current, string $expected, $stability)
{
self::assertEquals(Version::fromString($expected), Version::fromString($current)->increase($stability));
self::assertEquals(Version::fromString($expected), Version::fromString($current)->getNextIncreaseOf($stability));
}

/** @test */
Expand All @@ -207,6 +210,6 @@ public function it_cannot_increases_for_unsupported()
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Unknown stability "next-stable", accepts "alpha", "beta", "rc", "stable", "major", "next", "minor", "patch".');

Version::fromString('1.0.0-beta1')->increase('next-stable');
Version::fromString('1.0.0-beta1')->getNextIncreaseOf('next-stable');
}
}

0 comments on commit f3092e6

Please sign in to comment.