add implementation
All checks were successful
/ ls (push) Successful in 19s

This commit is contained in:
lubiana 2024-06-01 22:28:11 +02:00
parent 77fba06a1f
commit 13bfbbe528
Signed by: lubiana
SSH key fingerprint: SHA256:gkqM8DUX4Blf6P52fycW8ISTd+4eAHH+Uzu9iyc8hAM
20 changed files with 5598 additions and 0 deletions

View file

@ -0,0 +1,37 @@
on: [pull_request]
jobs:
ls:
runs-on: docker
container:
image: git.php.fail/lubiana/container/php:ci
steps:
- name: Manually checkout
env:
REPO: '${{ github.repository }}'
TOKEN: '${{ secrets.GITHUB_TOKEN }}'
GIT_SERVER: 'git.php.fail'
run: |
git clone --branch $GITHUB_HEAD_REF https://${TOKEN}@${GIT_SERVER}/${REPO}.git .
git fetch
git checkout $GITHUB_HEAD_REF
- name: composer install
env:
COMPOSER_CACHE_DIR: /opt/hostedtoolcache/.composer/cache/files
run: |
mkdir -p ${{ env.COMPOSER_CACHE_DIR }}
composer install
- name: lint
run: composer lint
- name: test
run: composer test
- name: GIT commit and push all changed files
env:
CI_COMMIT_MESSAGE: Continuous Integration Fixes
CI_COMMIT_AUTHOR: Continuous Integration
run: |
if [[ -n "$(git status -s)" ]]; then
git config --global user.name "${{ env.CI_COMMIT_AUTHOR }}"
git config --global user.email "gitbot@users.noreply.php.fail"
git commit -am "${{ env.CI_COMMIT_MESSAGE }}"
git push
fi

View file

@ -0,0 +1,41 @@
on:
push:
branches:
- 'main'
jobs:
ls:
runs-on: docker
container:
image: git.php.fail/lubiana/container/php:ci
steps:
- name: Manually checkout
env:
REPO: '${{ github.repository }}'
TOKEN: '${{ secrets.GITHUB_TOKEN }}'
BRANCH: '${{ env.GITHUB_REF_NAME }}'
GIT_SERVER: 'git.php.fail'
run: |
git clone --branch $GITHUB_REF_NAME https://${TOKEN}@${GIT_SERVER}/${REPO}.git .
git fetch
git checkout ${{ github.head_ref }}
- name: composer install
env:
COMPOSER_CACHE_DIR: /opt/hostedtoolcache/.composer/cache/files
run: |
mkdir -p ${{ env.COMPOSER_CACHE_DIR }}
composer install
- name: lint
run: composer lint
- name: test
run: composer test
- name: GIT commit and push all changed files
env:
CI_COMMIT_MESSAGE: Continuous Integration Fixes
CI_COMMIT_AUTHOR: Continuous Integration
run: |
if [[ -n "$(git status -s)" ]]; then
git config --global user.name "${{ env.CI_COMMIT_AUTHOR }}"
git config --global user.email "gitbot@users.noreply.php.fail"
git commit -am "${{ env.CI_COMMIT_MESSAGE }}"
git push
fi

4
.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
/vendor/
/.php-styler.cache
/.idea/
/var/

9
LICENSE Normal file
View file

@ -0,0 +1,9 @@
MIT License
Copyright (c) 2024 lubiana
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

9
code-quality-paths.php Normal file
View file

@ -0,0 +1,9 @@
<?php declare(strict_types=1);
return [
__DIR__ . '/src',
__DIR__ . '/tests',
__DIR__ . '/php-styler.php',
__DIR__ . '/ecs.php',
__DIR__ . '/rector.php',
];

50
composer.json Normal file
View file

@ -0,0 +1,50 @@
{
"name": "lubiana/doctrine-ulid",
"description": "adds ulid type to doctrine wihtout requiring doctrine symfony bridge",
"type": "library",
"autoload": {
"psr-4": {
"Lubiana\\DoctrineUlid\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"authors": [
{
"name": "lubiana",
"email": "lubiana@hannover.ccc.de"
}
],
"require-dev": {
"lubiana/code-quality": "^1.7",
"pmjones/php-styler": "^0.16.0",
"phpstan/phpstan": "^1.11",
"phpstan/phpstan-strict-rules": "^1.6",
"phpstan/extension-installer": "^1.3",
"pestphp/pest": "^2.34"
},
"config": {
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true,
"phpstan/extension-installer": true,
"pestphp/pest-plugin": true
}
},
"license": "MIT",
"scripts": {
"lint": [
"rector",
"php-styler apply",
"ecs --fix || ecs --fix"
],
"phpstan": "phpstan analyze",
"test": "pest"
},
"require": {
"symfony/uid": "^7.1",
"doctrine/orm": "^3.2"
}
}

5237
composer.lock generated Normal file

File diff suppressed because it is too large Load diff

11
ecs.php Normal file
View file

@ -0,0 +1,11 @@
<?php declare(strict_types=1);
use Lubiana\CodeQuality\LubiSetList;
use PhpCsFixer\Fixer\ClassNotation\FinalClassFixer;
use Symplify\EasyCodingStandard\Config\ECSConfig;
return ECSConfig::configure()
->withPaths(require __DIR__ . '/code-quality-paths.php')
->withRootFiles()
->withRules([FinalClassFixer::class])
->withSets([LubiSetList::ECS]);

13
php-styler.php Normal file
View file

@ -0,0 +1,13 @@
<?php declare(strict_types=1);
use PhpStyler\Config;
use PhpStyler\Files;
use PhpStyler\Styler;
$paths = (require __DIR__ . '/code-quality-paths.php');
return new Config(
styler: new Styler,
files: new Files(...$paths),
cache: __DIR__ . '/.php-styler.cache',
);

0
phpstan-baseline.neon Normal file
View file

6
phpstan.neon Normal file
View file

@ -0,0 +1,6 @@
includes:
- phpstan-baseline.neon
parameters:
level: 9
paths:
- src

18
phpunit.xml Normal file
View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.3/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
>
<testsuites>
<testsuite name="Test Suite">
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>
<source>
<include>
<directory suffix=".php">./app</directory>
<directory suffix=".php">./src</directory>
</include>
</source>
</phpunit>

12
rector.php Normal file
View file

@ -0,0 +1,12 @@
<?php declare(strict_types=1);
use Lubiana\CodeQuality\LubiSetList;
use Rector\CodingStyle\Rector\Closure\StaticClosureRector;
use Rector\Config\RectorConfig;
return RectorConfig::configure()
->withPaths(require __DIR__ . '/code-quality-paths.php')
->withSkip([
StaticClosureRector::class => [__DIR__ . '/tests'],
])
->withSets([LubiSetList::RECTOR]);

0
src/.gitkeep Normal file
View file

View file

@ -0,0 +1,21 @@
<?php declare(strict_types=1);
namespace Lubiana\DoctrineUlid\IdGenerator;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Id\AbstractIdGenerator;
use Symfony\Component\Uid\Factory\UlidFactory;
use Symfony\Component\Uid\Ulid;
final class UlidGenerator extends AbstractIdGenerator
{
public function __construct( private readonly ?UlidFactory $factory = null ){}
public function generateId(EntityManagerInterface $em, ?object $entity): mixed
{
if ($this->factory !== null) {
return $this->factory->create();
}
return new Ulid();
}
}

74
src/Types/UlidType.php Normal file
View file

@ -0,0 +1,74 @@
<?php declare(strict_types=1);
namespace Lubiana\DoctrineUlid\Types;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Exception\InvalidType;
use Doctrine\DBAL\Types\Exception\ValueNotConvertible;
use Doctrine\DBAL\Types\Type;
use Symfony\Component\Uid\Ulid;
final class UlidType extends Type
{
public const NAME = 'ulid';
/**
* @inheritDoc
*/
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
{
if ($this->hasNativeGuidType($platform)) {
return $platform->getGuidTypeDeclarationSQL($column);
}
return $platform->getBinaryTypeDeclarationSQL([
'length' => 16,
'fixed' => true,
]);
}
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?Ulid
{
if ($value instanceof Ulid || $value === null) {
return $value;
}
if (!is_string($value)) {
throw InvalidType::new($value, self::NAME, ['null', 'string', self::class]);
}
try {
return Ulid::fromString($value);
} catch (\InvalidArgumentException $e) {
throw ValueNotConvertible::new($value, self::NAME, null, $e);
}
}
public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): ?string
{
$toStringFunc = fn (Ulid $v) => $v->toRfc4122();
if (!$this->hasNativeGuidType($platform)) {
$toStringFunc = fn (Ulid $v) => $v->toBinary();
}
if ($value instanceof Ulid) {
return $toStringFunc($value);
}
if ($value === null || $value === '') {
return null;
}
if (!\is_string($value)) {
throw InvalidType::new($value, self::NAME, ['null', 'string', self::class]);
}
try {
return $toStringFunc(Ulid::fromString($value));
} catch (\InvalidArgumentException $e) {
throw ValueNotConvertible::new($value, self::NAME, null, $e);
}
}
private function hasNativeGuidType(AbstractPlatform $platform): bool
{
return $platform->getGuidTypeDeclarationSQL([]) !== $platform->getStringTypeDeclarationSQL(['fixed' => true, 'length' => 36]);
}
}

View file

@ -0,0 +1,8 @@
<?php declare(strict_types=1);
test(
'example',
function (): void {
expect(true)->toBeTrue();
},
);

30
tests/Pest.php Normal file
View file

@ -0,0 +1,30 @@
<?php declare(strict_types=1);
use Tests\TestCase;
/*
|--------------------------------------------------------------------------
| Test Case
|--------------------------------------------------------------------------
|
| The closure you provide to your test functions is always bound to a specific PHPUnit test
| case class. By default, that class is "PHPUnit\Framework\TestCase". Of course, you may
| need to change it using the "uses()" function to bind a different classes or traits.
|
*/
uses(TestCase::class)->in('Feature', 'Unit');
/*
|--------------------------------------------------------------------------
| Functions
|--------------------------------------------------------------------------
|
| While Pest is very powerful out-of-the-box, you may have some testing code specific to your
| project that you don't want to repeat in every file. Here you can also expose helpers as
| global functions to help you to reduce the number of lines of code in your test files.
|
*/
function something(): void
{
// ..
}

10
tests/TestCase.php Normal file
View file

@ -0,0 +1,10 @@
<?php declare(strict_types=1);
namespace Tests;
use PHPUnit\Framework\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
//
}

View file

@ -0,0 +1,8 @@
<?php declare(strict_types=1);
test(
'example',
function (): void {
expect(true)->toBeTrue();
},
);