Skip to content

Commit

Permalink
Enhancement: Extract Version
Browse files Browse the repository at this point in the history
  • Loading branch information
localheinz committed Dec 6, 2023
1 parent 4ac417b commit 4b8f0e1
Show file tree
Hide file tree
Showing 14 changed files with 460 additions and 5 deletions.
19 changes: 14 additions & 5 deletions include/branches.inc
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
<?php

require_once __DIR__ . '/../src/autoload.php';
include_once __DIR__ . '/releases.inc';
include_once __DIR__ . '/version.inc';

use phpweb\Release;

/* Branch overrides. For situations where we've changed the exact dates for a
* branch's active support and security fix EOLs, these can be reflected here.
*
Expand Down Expand Up @@ -85,13 +89,18 @@ function format_interval($from, DateTime $to) {
return $eolPeriod;
}

function version_number_to_branch(string $version): ?string {
$parts = explode('.', $version);
if (count($parts) > 1) {
return "$parts[0].$parts[1]";
function version_number_to_branch(string $value): ?string {
try {
$version = Release\Version::fromString($value);
} catch (\InvalidArgumentException) {
return null;
}

return null;
return sprintf(
'%s.%s',
$version->major()->toString(),
$version->minor()->toString(),
);
}

function get_all_branches() {
Expand Down
32 changes: 32 additions & 0 deletions src/Release/Major.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace phpweb\Release;

final readonly class Major
{
private function __construct(private string $value)
{
}

/**
* @throws \InvalidArgumentException
*/
public static function fromString(string $value): self
{
if (1 !== preg_match('/^(0|[1-9]\d*)$/', $value)) {
throw new \InvalidArgumentException(\sprintf(
'Value "%s" does not appear to be a valid value for a major version.',
$value
));
}

return new self($value);
}

public function toString(): string
{
return $this->value;
}
}
32 changes: 32 additions & 0 deletions src/Release/Minor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace phpweb\Release;

final readonly class Minor
{
private function __construct(private string $value)
{
}

/**
* @throws \InvalidArgumentException
*/
public static function fromString(string $value): self
{
if (1 !== preg_match('/^(0|[1-9]\d*)$/', $value)) {
throw new \InvalidArgumentException(\sprintf(
'Value "%s" does not appear to be a valid value for a minor version.',
$value
));
}

return new self($value);
}

public function toString(): string
{
return $this->value;
}
}
32 changes: 32 additions & 0 deletions src/Release/Patch.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace phpweb\Release;

final readonly class Patch
{
private function __construct(private string $value)
{
}

/**
* @throws \InvalidArgumentException
*/
public static function fromString(string $value): self
{
if (1 !== preg_match('/^(0|[1-9]\d*)$/', $value)) {
throw new \InvalidArgumentException(\sprintf(
'Value "%s" does not appear to be a valid value for a patch version.',
$value
));
}

return new self($value);
}

public function toString(): string
{
return $this->value;
}
}
71 changes: 71 additions & 0 deletions src/Release/Version.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

declare(strict_types=1);

namespace phpweb\Release;

final readonly class Version
{
private function __construct(
private Major $major,
private Minor $minor,
private Patch $patch,
) {
}

public static function create(
Major $major,
Minor $minor,
Patch $patch,
): self {
return new self(
$major,
$minor,
$patch,
);
}

/**
* @throws \InvalidArgumentException
*/
public static function fromString(string $value): self
{
if (1 !== preg_match('/^(?P<major>(0|[1-9]\d*))\.(?P<minor>(0|[1-9]\d*))\.(?P<patch>(0|[1-9]\d*))$/', $value, $matches)) {
throw new \InvalidArgumentException(\sprintf(
'Value "%s" does not appear to be a valid value for a version.',
$value
));
}

return new self(
Major::fromString($matches['major']),
Minor::fromString($matches['minor']),
Patch::fromString($matches['patch']),
);
}

public function major(): Major
{
return $this->major;
}

public function minor(): Minor
{
return $this->minor;
}

public function patch(): Patch
{
return $this->patch;
}

public function toString(): string
{
return sprintf(
'%s.%s.%s',
$this->major->toString(),
$this->minor->toString(),
$this->patch->toString(),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
--TEST--
Major::fromString() rejects invalid values
--FILE--
<?php

declare(strict_types=1);

use phpweb\Release;

require_once __DIR__ . '/../../../../src/autoload.php';

$values = [
'string-blank' => ' ',
'string-empty' => '',
'string-leading-zero' => '01',
'string-word' => 'foo',
];

$invalidValues = array_filter($values, static function (string $value): bool {
try {
Release\Major::fromString($value);
} catch (\InvalidArgumentException) {
return true;
}

return false;
});

var_dump($invalidValues);
?>
--EXPECT--
array(4) {
["string-blank"]=>
string(1) " "
["string-empty"]=>
string(0) ""
["string-leading-zero"]=>
string(2) "01"
["string-word"]=>
string(3) "foo"
}
17 changes: 17 additions & 0 deletions tests/UserNotes/Release/Major/from-string-returns-major.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
--TEST--
Major::fromString() returns Major
--FILE--
<?php

declare(strict_types=1);

use phpweb\Release;

require_once __DIR__ . '/../../../../src/autoload.php';

$major = Release\Major::fromString('8');

var_dump($major->toString());
?>
--EXPECT--
string(1) "8"
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
--TEST--
Minor::fromString() rejects invalid values
--FILE--
<?php

declare(strict_types=1);

use phpweb\Release;

require_once __DIR__ . '/../../../../src/autoload.php';

$values = [
'string-blank' => ' ',
'string-empty' => '',
'string-leading-zero' => '01',
'string-word' => 'foo',
];

$invalidValues = array_filter($values, static function (string $value): bool {
try {
Release\Minor::fromString($value);
} catch (\InvalidArgumentException) {
return true;
}

return false;
});

var_dump($invalidValues);
?>
--EXPECT--
array(4) {
["string-blank"]=>
string(1) " "
["string-empty"]=>
string(0) ""
["string-leading-zero"]=>
string(2) "01"
["string-word"]=>
string(3) "foo"
}
17 changes: 17 additions & 0 deletions tests/UserNotes/Release/Minor/from-string-returns-minor.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
--TEST--
Minor::fromString() returns Minor
--FILE--
<?php

declare(strict_types=1);

use phpweb\Release;

require_once __DIR__ . '/../../../../src/autoload.php';

$minor = Release\Minor::fromString('3');

var_dump($minor->toString());
?>
--EXPECT--
string(1) "3"
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
--TEST--
Patch::fromString() rejects invalid values
--FILE--
<?php

declare(strict_types=1);

use phpweb\Release;

require_once __DIR__ . '/../../../../src/autoload.php';

$values = [
'string-blank' => ' ',
'string-empty' => '',
'string-leading-zero' => '01',
'string-word' => 'foo',
];

$invalidValues = array_filter($values, static function (string $value): bool {
try {
Release\Patch::fromString($value);
} catch (\InvalidArgumentException) {
return true;
}

return false;
});

var_dump($invalidValues);
?>
--EXPECT--
array(4) {
["string-blank"]=>
string(1) " "
["string-empty"]=>
string(0) ""
["string-leading-zero"]=>
string(2) "01"
["string-word"]=>
string(3) "foo"
}
17 changes: 17 additions & 0 deletions tests/UserNotes/Release/Patch/from-string-returns-patch.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
--TEST--
Patch::fromString() returns Patch
--FILE--
<?php

declare(strict_types=1);

use phpweb\Release;

require_once __DIR__ . '/../../../../src/autoload.php';

$patch = Release\Patch::fromString('8');

var_dump($patch->toString());
?>
--EXPECT--
string(1) "8"
Loading

0 comments on commit 4b8f0e1

Please sign in to comment.