Removed Version class, please use Composer's SemVer instead.

This commit is contained in:
flash 2024-07-31 21:01:22 +00:00
parent 4806b35c6b
commit 57b939103e
11 changed files with 30 additions and 362 deletions

View file

@ -1 +1 @@
0.2407.312054
0.2407.312100

View file

@ -1,12 +1,11 @@
<?php
// MariaDBBackend.php
// Created: 2021-04-30
// Updated: 2024-04-10
// Updated: 2024-07-31
namespace Index\Data\MariaDB;
use InvalidArgumentException;
use Index\Version;
use Index\Data\IDbBackend;
use Index\Data\IDbConnection;
use Index\Data\IDbConnectionInfo;
@ -24,21 +23,21 @@ class MariaDBBackend implements IDbBackend {
/**
* @internal
*/
public static function intToVersion(int $version): Version {
public static function intToVersion(int $version): string {
$sub = $version % 100;
$version = floor($version / 100);
$minor = $version % 100;
$version = floor($version / 100);
$major = $version % 100;
return new Version($major, $minor, $sub);
return sprintf('%d.%d.%d', $major, $minor, $sub);
}
/**
* Gets the version of the underlying client library.
*
* @return Version Version of the client library.
* @return string Version of the client library.
*/
public function getClientVersion(): Version {
public function getClientVersion(): string {
return self::intToVersion(mysqli_get_client_version());
}

View file

@ -1,7 +1,7 @@
<?php
// MariaDBConnection.php
// Created: 2021-04-30
// Updated: 2023-11-09
// Updated: 2024-07-31
namespace Index\Data\MariaDB;
@ -9,7 +9,6 @@ use mysqli;
use mysqli_sql_exception;
use InvalidArgumentException;
use RuntimeException;
use Index\Version;
use Index\Data\BeginTransactionFailedException;
use Index\Data\DataException;
use Index\Data\IDbConnection;
@ -216,9 +215,9 @@ class MariaDBConnection implements IDbConnection, IDbTransactions {
/**
* Gets the version of the server.
*
* @return Version Version of the server.
* @return string Version of the server.
*/
public function getServerVersion(): Version {
public function getServerVersion(): string {
return MariaDBBackend::intToVersion($this->connection->server_version);
}

View file

@ -1,13 +1,12 @@
<?php
// SQLiteBackend.php
// Created: 2021-05-02
// Updated: 2024-04-10
// Updated: 2024-07-31
namespace Index\Data\SQLite;
use SQLite3;
use InvalidArgumentException;
use Index\Version;
use Index\Data\IDbBackend;
use Index\Data\IDbConnection;
use Index\Data\IDbConnectionInfo;
@ -23,10 +22,10 @@ class SQLiteBackend implements IDbBackend {
/**
* Gets the version of the underlying library.
*
* @return Version Version of the library.
* @return string Version of the library.
*/
public function getVersion(): Version {
return Version::parse(SQLite3::version()['versionString']);
public function getVersion(): string {
return SQLite3::version()['versionString'];
}
/**

View file

@ -1,11 +1,10 @@
<?php
// HttpMessage.php
// Created: 2022-02-08
// Updated: 2022-02-27
// Updated: 2024-07-31
namespace Index\Http;
use Index\Version;
use Index\IO\Stream;
use Index\Http\Content\IHttpContent;
use Index\Http\Content\BencodedContent;
@ -15,17 +14,17 @@ use Index\Http\Content\StreamContent;
use Index\Http\Content\StringContent;
abstract class HttpMessage {
private Version $version;
private string $version;
private HttpHeaders $headers;
private ?IHttpContent $content;
public function __construct(Version $version, HttpHeaders $headers, ?IHttpContent $content) {
public function __construct(string $version, HttpHeaders $headers, ?IHttpContent $content) {
$this->version = $version;
$this->headers = $headers;
$this->content = $content;
}
public function getHttpVersion(): Version {
public function getHttpVersion(): string {
return $this->version;
}

View file

@ -1,18 +1,17 @@
<?php
// HttpMessageBuilder.php
// Created: 2022-02-08
// Updated: 2024-03-28
// Updated: 2024-07-31
namespace Index\Http;
use Index\Version;
use Index\IO\Stream;
use Index\Http\Content\IHttpContent;
use Index\Http\Content\StreamContent;
use Index\Http\Content\StringContent;
class HttpMessageBuilder {
private ?Version $version = null;
private ?string $version = null;
private HttpHeadersBuilder $headers;
private ?IHttpContent $content = null;
@ -20,11 +19,11 @@ class HttpMessageBuilder {
$this->headers = new HttpHeadersBuilder;
}
protected function getHttpVersion(): Version {
return $this->version ?? new Version(1, 1);
protected function getHttpVersion(): string {
return $this->version ?? '1.1';
}
public function setHttpVersion(Version $version): void {
public function setHttpVersion(string $version): void {
$this->version = $version;
}

View file

@ -1,13 +1,12 @@
<?php
// HttpRequest.php
// Created: 2022-02-08
// Updated: 2023-09-11
// Updated: 2024-07-31
namespace Index\Http;
use InvalidArgumentException;
use RuntimeException;
use Index\Version;
use Index\MediaType;
use Index\Http\Content\IHttpContent;
use Index\Http\Content\JsonContent;
@ -21,7 +20,7 @@ class HttpRequest extends HttpMessage {
private array $cookies;
public function __construct(
Version $version,
string $version,
string $method,
string $path,
array $params,
@ -79,7 +78,7 @@ class HttpRequest extends HttpMessage {
public static function fromRequest(): HttpRequest {
$build = new HttpRequestBuilder;
$build->setHttpVersion(new Version(...array_map('intval', explode('.', substr($_SERVER['SERVER_PROTOCOL'], 5)))));
$build->setHttpVersion($_SERVER['SERVER_PROTOCOL']);
$build->setMethod($_SERVER['REQUEST_METHOD']);
// this currently doesn't "properly" support the scenario where a full url is specified in the http request

View file

@ -1,11 +1,10 @@
<?php
// HttpResponse.php
// Created: 2022-02-08
// Updated: 2022-02-10
// Updated: 2024-07-31
namespace Index\Http;
use Index\Version;
use Index\Http\Content\IHttpContent;
class HttpResponse extends HttpMessage {
@ -13,7 +12,7 @@ class HttpResponse extends HttpMessage {
private string $statusText;
public function __construct(
Version $version,
string $version,
int $statusCode,
string $statusText,
HttpHeaders $headers,

View file

@ -1,7 +1,7 @@
<?php
// HttpRouter.php
// Created: 2024-03-28
// Updated: 2024-04-02
// Updated: 2024-07-31
namespace Index\Http\Routing;
@ -238,11 +238,9 @@ class HttpRouter implements IRouter {
}
public static function output(HttpResponse $response, bool $includeBody): void {
$version = $response->getHttpVersion();
header(sprintf(
'HTTP/%d.%d %03d %s',
$version->getMajor(),
$version->getMinor(),
'HTTP/%s %03d %s',
$response->getHttpVersion(),
$response->getStatusCode(),
$response->getStatusText()
));

View file

@ -1,245 +0,0 @@
<?php
// Version.php
// Created: 2021-04-29
// Updated: 2023-01-01
namespace Index;
use InvalidArgumentException;
use Stringable;
/**
* A Semantic Versioning implementation. Following version 2.0.0 of the specification.
*
* @see https://semver.org/spec/v2.0.0.html
*/
class Version implements Stringable, IComparable, IEquatable {
private int $major;
private int $minor;
private int $patch;
private array $prerelease;
private array $build;
private ?string $versionString = null;
private static ?Version $empty = null;
/**
* Constructor for Version.
*
* @param int $major A positive integer indicating the major version.
* @param int $minor A positive integer indicating the minor version.
* @param int $patch A positive integer indicating the patch version.
* @param string $prerelease A dot separated string indicating prerelease information.
* @param string $build A dot separated string indicating build information.
* @throws InvalidArgumentException A negative integer was provided.
* @return Version
*/
public function __construct(int $major, int $minor = 0, int $patch = 0, string $prerelease = '', string $build = '') {
if($major < 0 || $minor < 0 || $patch < 0)
throw new InvalidArgumentException('$major, $minor and $patch should be positive integers.');
$this->major = $major;
$this->minor = $minor;
$this->patch = $patch;
$this->prerelease = empty($prerelease) ? [] : explode('.', $prerelease);
$this->build = empty($build) ? [] : explode('.', $build);
}
/**
* Gets the value of the major version component.
*
* @return int Major version component.
*/
public function getMajor(): int {
return $this->major;
}
/**
* Gets the value of the minor version component.
*
* @return int Minor version component.
*/
public function getMinor(): int {
return $this->minor;
}
/**
* Gets the value of the patch version component.
*
* @return int Patch version component.
*/
public function getPatch(): int {
return $this->patch;
}
/**
* Gets the split value of the prerelease component.
*
* @return array array containing the prerelease parts.
*/
public function getPrerelease(): array {
return $this->prerelease;
}
/**
* Gets the split value of the build component.
*
* @return array array contains the build parts.
*/
public function getBuild(): array {
return $this->build;
}
/**
* Tests if this Version instance represents a prerelease according to the SemVer spec.
*
* @return bool true if the version indicates a prerelease, false if not.
*/
public function isPrerelease(): bool {
return $this->major < 1 || !empty($this->prerelease);
}
/**
* Creates a new instance of Version with the major component incremented.
*
* This will implicitly drop prerelease and build info and reset the minor and patch component.
*
* @return Version the newly created instance of Version.
*/
public function incrementMajor(): Version {
return new Version($this->major + 1, 0, 0);
}
/**
* Creates a new instance of Version with the minor component incremented.
*
* This will implicitly drop the prerelease and build info and reset the patch component.
*
* @return Version the newly created instance of Version.
*/
public function incrementMinor(): Version {
return new Version($this->major, $this->minor + 1, 0);
}
/**
* Creates a new instance of Version with the patch component incremented.
*
* This will implicitly drop the prerelease and build info.
*
* @return Version the newly created instance of Version.
*/
public function incrementPatch(): Version {
return new Version($this->major, $this->minor, $this->patch + 1);
}
/**
* Checks this instance of Version with another for equality.
*
* The build component is ignored, as per the SemVer spec.
*
* @param mixed $other Another instance of Version.
* @return bool true if the instances are equal, false if not.
*/
public function equals(mixed $other): bool {
return $other instanceof Version
&& $other->major === $this->major
&& $other->minor === $this->minor
&& $other->patch === $this->patch
&& XArray::sequenceEquals($this->prerelease, $other->prerelease);
}
/**
* Compares this instance of Version with another.
*
* The build component is ignored and prerelease component is compared as per the SemVer spec.
*
* @param mixed $other Another instance of Version.
*/
public function compare(mixed $other): int {
if(!($other instanceof Version))
return PHP_INT_MIN;
$diff = $this->major <=> $other->major;
if($diff) return $diff;
$diff = $this->minor <=> $other->minor;
if($diff) return $diff;
$diff = $this->patch <=> $other->patch;
if($diff) return $diff;
$tpi = XArray::extractIterator($this->prerelease);
$opi = XArray::extractIterator($other->prerelease);
$tpi->rewind();
$opi->rewind();
$valid = $tpi->valid();
$diff = $opi->valid() <=> $valid;
if($diff) return $diff;
while($valid) {
$diff = $opi->current()->compare($tpi->current());
if($diff) return $diff;
$tpi->next();
$opi->next();
$valid = $tpi->valid();
$diff = $opi->valid() <=> $valid;
if($diff) return $diff;
}
return 0;
}
public function __toString(): string {
if($this->versionString === null) {
$string = $this->major . '.' . $this->minor . '.' . $this->patch;
if(!empty($this->prerelease))
$string .= '-' . implode('.', $this->prerelease);
if(!empty($this->build))
$string .= '+' . implode('.', $this->build);
$this->versionString = $string;
}
return $this->versionString;
}
/**
* Returns an empty Version instance.
*
* @return Version Instance of Version with all values set to 0.
*/
public static function empty(): Version {
if(self::$empty === null)
self::$empty = new Version(0);
return self::$empty;
}
/**
* Parses a version string.
*
* Parses a version string with a regex adapted from SemVer's documentation. Modified to allow an optional v prefix.
*
* @see https://semver.org/spec/v2.0.0.html#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
* @param string $versionString String containing a version number.
* @throws InvalidArgumentException Provided string does not represent a valid version.
* @return Version An instance of Version representing the provided version string.
*/
public static function parse(string $versionString): Version {
// Regex adapted from https://semver.org/spec/v2.0.0.html#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
if(!preg_match('#^v?(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?: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<build>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$#', $versionString, $matches))
throw new InvalidArgumentException('$versionString is not a valid version string.');
return new Version(
(int)$matches['major'],
(int)$matches['minor'],
(int)$matches['patch'],
$matches['prerelease'] ?? '',
$matches['build'] ?? ''
);
}
}

View file

@ -1,78 +0,0 @@
<?php
// VersionTest.php
// Created: 2021-04-30
// Updated: 2024-07-31
declare(strict_types=1);
use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\UsesClass;
use Index\Version;
use Index\XArray;
#[CoversClass(Version::class)]
#[UsesClass(XArray::class)]
final class VersionTest extends TestCase {
public function testParse(): void {
$tests = [
'1.0.0',
'v2.4.2',
'1.0.0-alpha',
'1.0.0-alpha.1',
'1.0.0-0.3.7',
'1.0.0-0.3.7',
'v1.0.0-alpha+001',
'1.0.0-beta+exp.sha.5114f85',
'v1.0.0+21AF26D3--117B344092BD',
];
foreach($tests as $test) {
$version = Version::parse($test);
$this->assertEquals($test, (string)$test);
}
$build = Version::parse('v1.0.0+21AF26D3--117B344092BD');
$pre = Version::parse('1.0.0-alpha');
$both = Version::parse('1.0.0-beta+exp.sha.5114f85');
$this->assertFalse($build->isPrerelease());
$this->assertTrue($pre->isPrerelease());
$this->assertTrue($both->isPrerelease());
$this->assertTrue(XArray::sequenceEquals($build->getBuild(), ['21AF26D3--117B344092BD']));
$this->assertTrue(XArray::sequenceEquals($pre->getPrerelease(), ['alpha']));
$this->assertTrue(XArray::sequenceEquals($both->getPrerelease(), ['beta']));
$this->assertTrue(XArray::sequenceEquals($both->getBuild(), ['exp', 'sha', '5114f85']));
}
public function testCompare(): void {
$v1_0_0_alpha = Version::parse('v1.0.0-alpha');
$v1_0_0 = Version::parse('1.0.0');
$v1_0_0_build = Version::parse('1.0.0+build');
$v2_0_0 = Version::parse('v2.0.0');
$v2_1_0 = new Version(2, 1);
$v2_1_1 = new Version(2, 1, 1);
$this->assertEquals(0, $v1_0_0->compare($v1_0_0_build));
$this->assertEquals(-1, $v2_0_0->compare($v2_1_0));
$this->assertEquals(-1, $v2_0_0->compare($v2_1_0));
$this->assertEquals(-1, $v1_0_0->compare($v2_0_0));
$this->assertEquals(-1, $v1_0_0_alpha->compare($v1_0_0));
}
public function testEquals(): void {
$v1_0_0_alpha = Version::parse('v1.0.0-alpha');
$v1_0_0 = Version::parse('1.0.0');
$v1_0_0_build = Version::parse('1.0.0+build');
$v2_0_0 = Version::parse('v2.0.0');
$v2_1_0 = new Version(2, 1);
$v2_1_1 = new Version(2, 1, 1);
$this->assertTrue($v1_0_0->equals($v1_0_0_build));
$this->assertFalse($v2_0_0->equals($v2_1_0));
$this->assertFalse($v2_0_0->equals($v2_1_0));
$this->assertFalse($v1_0_0->equals($v2_0_0));
$this->assertFalse($v1_0_0_alpha->equals($v1_0_0));
}
}