From 0d325f9a0ecb2279ad56d126d1cf8fddeb3b27c9 Mon Sep 17 00:00:00 2001 From: Andrea Giannantonio Date: Sat, 6 Jun 2020 01:20:12 +0200 Subject: [PATCH 01/20] Init Poser v2.0 --- .gitignore | 1 - bin/yaml-lint | 1 + composer.json | 12 +++++----- docker-compose.yml | 10 ++++++++ docker-compose.yml.dist | 17 -------------- docker/php-fpm/Dockerfile | 23 +++++++++++++++++++ phpspec.yml | 2 +- spec/PUGX/Poser/PoserSpec.php | 6 ++--- spec/PUGX/Poser/Render/SvgFlatRenderSpec.php | 6 ++--- .../Poser/Render/SvgFlatSquareRenderSpec.php | 6 ++--- spec/PUGX/Poser/Render/SvgRenderSpec.php | 8 +++---- src/UI/Command.php | 2 ++ 12 files changed, 56 insertions(+), 38 deletions(-) create mode 120000 bin/yaml-lint create mode 100644 docker-compose.yml delete mode 100644 docker-compose.yml.dist create mode 100644 docker/php-fpm/Dockerfile diff --git a/.gitignore b/.gitignore index 2f7a40c..a93b5e3 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,3 @@ /bin/phpspec /vendor composer.lock -docker-compose.yml diff --git a/bin/yaml-lint b/bin/yaml-lint new file mode 120000 index 0000000..73c0353 --- /dev/null +++ b/bin/yaml-lint @@ -0,0 +1 @@ +../vendor/symfony/yaml/Resources/bin/yaml-lint \ No newline at end of file diff --git a/composer.json b/composer.json index 12c2f4b..c19d33c 100644 --- a/composer.json +++ b/composer.json @@ -23,15 +23,15 @@ "psr-4": { "PUGX\\Poser\\": "src/" } }, "require": { - "php": ">=5.3", + "php": ">=7.4", "ext-gd": "*", - "symfony/console": "~2.0|~3.0|~4.0" + "ext-simplexml": "*", + "symfony/console": "^4.0|^5.0" }, "require-dev": { - "phpspec/phpspec": "^2.5", - "behat/behat": "^3.4", - "friendsofphp/php-cs-fixer": "@stable", - "coduo/phpspec-data-provider-extension": "^1.0" + "phpspec/phpspec": "^6.1", + "behat/behat": "^3.7", + "friendsofphp/php-cs-fixer": "^2.16" }, "config": { "bin-dir": "bin" diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..42a29a4 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,10 @@ +version: '3.7' +services: + + fpm: + build: + context: docker/php-fpm + network: host + working_dir: /application + volumes: + - .:/application:cached diff --git a/docker-compose.yml.dist b/docker-compose.yml.dist deleted file mode 100644 index cfeb446..0000000 --- a/docker-compose.yml.dist +++ /dev/null @@ -1,17 +0,0 @@ -version: '2' - -services: - fpm: - image: jmleroux/fpm:php-7.1 - environment: - COMPOSER_HOME: /home/docker/.composer - PHP_IDE_CONFIG: 'serverName=jmleroux-cli' - PHP_XDEBUG_ENABLED: 0 - PHP_XDEBUG_IDE_KEY: XDEBUG_IDE_KEY - PHP_XDEBUG_REMOTE_HOST: xxx.xxx.xxx.xxx - XDEBUG_CONFIG: 'remote_host=xxx.xxx.xxx.xxx' - user: docker - volumes: - - ./:/srv/jmleroux - - ~/.composer:/home/docker/.composer - working_dir: /srv/jmleroux diff --git a/docker/php-fpm/Dockerfile b/docker/php-fpm/Dockerfile new file mode 100644 index 0000000..e9413e7 --- /dev/null +++ b/docker/php-fpm/Dockerfile @@ -0,0 +1,23 @@ +FROM phpdockerio/php74-fpm:latest +WORKDIR "/application" + +# Fix debconf warnings upon build +ARG DEBIAN_FRONTEND=noninteractive + +# Install selected extensions and other stuff +RUN apt-get update \ + && apt-get -y --no-install-recommends install php-xdebug php7.4-bcmath php7.4-gd php7.4-intl php-msgpack php-yaml \ + && apt-get clean; rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/* + +# Install git +RUN apt-get update \ + && apt-get -y install git \ + && apt-get clean; rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/* + +RUN mkdir -p /home/dev/.composer \ + && chown -R 1000:1000 /home/dev/ + +ENV COMPOSER_CACHE_DIR='/home/dev/.composer' + +# Install prestissimo +RUN composer global require hirak/prestissimo diff --git a/phpspec.yml b/phpspec.yml index 45b448b..f12ac65 100644 --- a/phpspec.yml +++ b/phpspec.yml @@ -1,2 +1,2 @@ extensions: - - Coduo\PhpSpec\DataProvider\DataProviderExtension +# - Coduo\PhpSpec\DataProvider\DataProviderExtension diff --git a/spec/PUGX/Poser/PoserSpec.php b/spec/PUGX/Poser/PoserSpec.php index a91bb3f..b205b43 100644 --- a/spec/PUGX/Poser/PoserSpec.php +++ b/spec/PUGX/Poser/PoserSpec.php @@ -37,15 +37,15 @@ function it_should_be_able_to_generate_an_svg_image_from_URI() } - public function getMatchers() + public function getMatchers(): array { - return array( + return [ 'beAValidSVGImageContaining' => function($object, $subject, $status) { $regex = '/^$/'; $matches = array(); return preg_match($regex, $object, $matches, PREG_OFFSET_CAPTURE, 0); }, - ); + ]; } } diff --git a/spec/PUGX/Poser/Render/SvgFlatRenderSpec.php b/spec/PUGX/Poser/Render/SvgFlatRenderSpec.php index 734957d..79df0aa 100644 --- a/spec/PUGX/Poser/Render/SvgFlatRenderSpec.php +++ b/spec/PUGX/Poser/Render/SvgFlatRenderSpec.php @@ -21,9 +21,9 @@ function it_should_render_a_svg() $this->render($badge)->shouldBeAValidSVGImage(); } - public function getMatchers() + public function getMatchers(): array { - return array( + return [ 'beAValidSVGImage' => function($subject) { $regex = '/^$/'; @@ -31,7 +31,7 @@ public function getMatchers() return preg_match($regex, (string) $subject, $matches, PREG_OFFSET_CAPTURE, 0); } - ); + ]; } function it_should_render_a_license_mit_exactly_like_this_svg() diff --git a/spec/PUGX/Poser/Render/SvgFlatSquareRenderSpec.php b/spec/PUGX/Poser/Render/SvgFlatSquareRenderSpec.php index c476785..7f7c487 100644 --- a/spec/PUGX/Poser/Render/SvgFlatSquareRenderSpec.php +++ b/spec/PUGX/Poser/Render/SvgFlatSquareRenderSpec.php @@ -21,9 +21,9 @@ function it_should_render_a_svg() $this->render($badge)->shouldBeAValidSVGImage(); } - public function getMatchers() + public function getMatchers(): array { - return array( + return [ 'beAValidSVGImage' => function ($subject) { $regex = '/^$/'; @@ -31,7 +31,7 @@ public function getMatchers() return preg_match($regex, (string) $subject, $matches, PREG_OFFSET_CAPTURE, 0); } - ); + ]; } function it_should_render_a_license_mit_exactly_like_this_svg() diff --git a/spec/PUGX/Poser/Render/SvgRenderSpec.php b/spec/PUGX/Poser/Render/SvgRenderSpec.php index 50dc13c..32f5045 100644 --- a/spec/PUGX/Poser/Render/SvgRenderSpec.php +++ b/spec/PUGX/Poser/Render/SvgRenderSpec.php @@ -37,9 +37,9 @@ function it_should_not_render_non_svg_xml($calculator) $this->shouldThrow(new \RuntimeException('Generated xml is not a SVG'))->duringRender($badge); } - public function getMatchers() + public function getMatchers(): array { - return array( + return [ 'beAValidSVGImage' => function ($subject) { $regex = '/^$/'; @@ -47,6 +47,6 @@ public function getMatchers() return preg_match($regex, (string) $subject, $matches, PREG_OFFSET_CAPTURE, 0); } - ); + ]; } -} +} diff --git a/src/UI/Command.php b/src/UI/Command.php index 4cd308b..d1c47c6 100644 --- a/src/UI/Command.php +++ b/src/UI/Command.php @@ -101,6 +101,8 @@ protected function execute(InputInterface $input, OutputInterface $output) $this->printHeaderOnce($output); throw $e; } + + return 0; } protected function flushImage(OutputInterface $output, $imageContent) From 3394e635a57987519b58ee3606e5a019f53fd5ff Mon Sep 17 00:00:00 2001 From: Andrea Giannantonio Date: Mon, 8 Jun 2020 13:35:31 +0200 Subject: [PATCH 02/20] Add configs for php-cs-fixer and run --- .gitignore | 1 + .php_cs | 23 ++++++ composer.json | 5 ++ features/bootstrap/FeatureContext.php | 41 +++++----- spec/PUGX/Poser/BadgeSpec.php | 26 +++---- spec/PUGX/Poser/PoserSpec.php | 22 +++--- spec/PUGX/Poser/Render/SvgFlatRenderSpec.php | 17 ++--- .../Poser/Render/SvgFlatSquareRenderSpec.php | 15 ++-- spec/PUGX/Poser/Render/SvgRenderSpec.php | 15 ++-- src/Badge.php | 75 ++++++++++--------- src/Calculator/GDTextSizeCalculator.php | 9 ++- .../TextSizeCalculatorInterface.php | 2 +- src/Image.php | 10 +-- src/Poser.php | 13 ++-- src/Render/LocalSvgRenderer.php | 24 +++--- src/Render/RenderInterface.php | 2 - src/Render/SvgFlatRender.php | 4 +- src/Render/SvgFlatSquareRender.php | 4 +- src/Render/SvgRender.php | 6 +- src/UI/Command.php | 36 ++++----- src/UI/SingleCommandApplication.php | 7 +- 21 files changed, 188 insertions(+), 169 deletions(-) create mode 100644 .php_cs diff --git a/.gitignore b/.gitignore index a93b5e3..5f45e2a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ /bin/php-cs-fixer /bin/phpspec /vendor +.php_cs.cache composer.lock diff --git a/.php_cs b/.php_cs new file mode 100644 index 0000000..85cd048 --- /dev/null +++ b/.php_cs @@ -0,0 +1,23 @@ +in(__DIR__) + ->exclude(['vendor']) +; + +return PhpCsFixer\Config::create() + ->setRiskyAllowed(true) + ->setRules([ + '@Symfony' => true, + '@Symfony:risky' => true, + '@PHP71Migration:risky' => true, + '@PHPUnit60Migration:risky' => true, + 'array_syntax' => ['syntax' => 'short'], + 'ordered_imports' => true, + 'declare_strict_types' => false, + 'native_function_invocation' => true, + 'concat_space' => ['spacing' => 'one'], + ]) + ->setFinder($finder) +; diff --git a/composer.json b/composer.json index c19d33c..c4d52d9 100644 --- a/composer.json +++ b/composer.json @@ -37,6 +37,11 @@ "bin-dir": "bin" }, "bin": ["bin/poser"], + "scripts": { + "php-cs-fixer": [ + "bin/php-cs-fixer fix -v" + ] + }, "extra": { "branch-alias": { "dev-master": "1.3.x-dev" diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index c0299e9..f545d35 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -1,8 +1,6 @@ binFolder . $command; $this->return = -1; - ob_start(); - passthru("cd {$this->binFolder};php $command", $this->return); - $this->output = ob_get_clean(); + \ob_start(); + \passthru("cd {$this->binFolder};php $command", $this->return); + $this->output = \ob_get_clean(); } /** * @Then the same output should be like the content of :filePath */ - public function theSameOutputShouldBeLikeTheContentOf($filePath) + public function theSameOutputShouldBeLikeTheContentOf($filePath): void { - $filePath = __DIR__.'/../'.$filePath; - $content = file_get_contents($filePath); + $filePath = __DIR__ . '/../' . $filePath; + $content = \file_get_contents($filePath); $this->assertEquals($content, $this->output); } + /** * @Then it should pass */ - public function itShouldPass() + public function itShouldPass(): void { if (0 != $this->return) { - throw new \Exception('Error executing '.$this->return); + throw new \Exception('Error executing ' . $this->return); } } /** * @Then the content of :given should be equal to :expected */ - public function theContentOfShouldBeEqualTo($given, $expected) + public function theContentOfShouldBeEqualTo($given, $expected): void { $givenPath = $given; - $given = file_get_contents($givenPath); + $given = \file_get_contents($givenPath); - $expectedPath = __DIR__.'/../'.$expected; - $expected = file_get_contents($expectedPath); - unlink($givenPath); + $expectedPath = __DIR__ . '/../' . $expected; + $expected = \file_get_contents($expectedPath); + \unlink($givenPath); $this->assertEquals($given, $expected); } - private function assertEquals($given, $expected) + private function assertEquals($given, $expected): void { - $expected = preg_replace('/\s+/', '', $expected); - $given = preg_replace('/\s+/', '', $given); + $expected = \preg_replace('/\s+/', '', $expected); + $given = \preg_replace('/\s+/', '', $given); $perc = 0; - similar_text($expected, $given, $perc); + \similar_text($expected, $given, $perc); if ($perc < 94) { - throw new \Exception('String similarity:'.$perc.'%. String expected:'.$expected.PHP_EOL.' given:'.$given); + throw new \Exception('String similarity:' . $perc . '%. String expected:' . $expected . PHP_EOL . ' given:' . $given); } } } diff --git a/spec/PUGX/Poser/BadgeSpec.php b/spec/PUGX/Poser/BadgeSpec.php index df8bdde..f38bd95 100644 --- a/spec/PUGX/Poser/BadgeSpec.php +++ b/spec/PUGX/Poser/BadgeSpec.php @@ -4,29 +4,28 @@ use PhpSpec\Exception\Exception; use PhpSpec\ObjectBehavior; -use Prophecy\Argument; use PUGX\Poser\Badge; class BadgeSpec extends ObjectBehavior { - function it_is_initializable() + public function it_is_initializable(): void { $this->beConstructedWith('a', 'b', '97CA00', 'svg'); $this->shouldHaveType('Pugx\Poser\Badge'); } - function it_should_be_constructed_by_fromURI_factory_method() + public function it_should_be_constructed_by_fromURI_factory_method(): void { $this->beConstructedWith('a', 'b', '97CA00', 'svg'); $assert = 'version-stable-97CA00.svg'; $it = Badge::fromURI($assert); if ((string) $it !== $assert) { - throw new Exception(sprintf("from[%s] having[%s]\n", $assert, (string) $it)); + throw new Exception(\sprintf("from[%s] having[%s]\n", $assert, (string) $it)); } } - function it_should_be_constructed_by_fromURI_factory_method_escaping_correctly_underscores() + public function it_should_be_constructed_by_fromURI_factory_method_escaping_correctly_underscores(): void { $this->beConstructedWith('a', 'b', '97CA00', 'svg'); $input = 'I__m__liugg__io-b-97CA00.svg'; @@ -34,11 +33,11 @@ function it_should_be_constructed_by_fromURI_factory_method_escaping_correctly_u $it = Badge::fromURI($input); if ((string) $it !== $assertInput) { - throw new Exception(sprintf("from[%s] wants[%s] having[%s]\n", $input, $assertInput, (string) $it)); + throw new Exception(\sprintf("from[%s] wants[%s] having[%s]\n", $input, $assertInput, (string) $it)); } } - function it_should_be_constructed_by_fromURI_factory_method_escaping_correctly_with_single_underscore() + public function it_should_be_constructed_by_fromURI_factory_method_escaping_correctly_with_single_underscore(): void { $this->beConstructedWith('a', 'b', '97CA00', 'svg'); $input = 'I_m_liuggio-b-97CA00.svg'; @@ -46,11 +45,11 @@ function it_should_be_constructed_by_fromURI_factory_method_escaping_correctly_w $it = Badge::fromURI($input); if ((string) $it !== $assertInput) { - throw new Exception(sprintf("from[%s] wants[%s] having[%s]\n", $input, $assertInput, (string) $it)); + throw new Exception(\sprintf("from[%s] wants[%s] having[%s]\n", $input, $assertInput, (string) $it)); } } - function it_should_be_constructed_by_fromURI_factory_method_escaping_correctly_with_dashes() + public function it_should_be_constructed_by_fromURI_factory_method_escaping_correctly_with_dashes(): void { $this->beConstructedWith('a', 'b', '97CA00', 'svg'); $input = 'I--m--liuggio-b-97CA00.svg'; @@ -58,15 +57,16 @@ function it_should_be_constructed_by_fromURI_factory_method_escaping_correctly_w $it = Badge::fromURI($input); if ((string) $it !== $assertInput) { - throw new Exception(sprintf("from[%s] wants[%s] having[%s]\n", $input, $assertInput, (string) $it)); + throw new Exception(\sprintf("from[%s] wants[%s] having[%s]\n", $input, $assertInput, (string) $it)); } } /** * @dataProvider positiveConversionExamples */ - function it_should_validate_available_color_schemes($colorName, $expectedValue) + public function it_should_validate_available_color_schemes($colorName, $expectedValue): void { + \var_dump($colorName); $this->beConstructedWith('a', 'b', $colorName, 'svg'); $this->getHexColor()->shouldBeString(); } @@ -75,9 +75,9 @@ public function positiveConversionExamples() { $colorNames = Badge::getColorNamesAvailable(); - $data = array(); + $data = []; foreach ($colorNames as $colorName) { - $data[] = array($colorName, null); + $data[] = [$colorName, null]; } return $data; diff --git a/spec/PUGX/Poser/PoserSpec.php b/spec/PUGX/Poser/PoserSpec.php index b205b43..a58fac8 100644 --- a/spec/PUGX/Poser/PoserSpec.php +++ b/spec/PUGX/Poser/PoserSpec.php @@ -3,23 +3,22 @@ namespace spec\PUGX\Poser; use PhpSpec\ObjectBehavior; -use Prophecy\Argument; use PUGX\Poser\Render\SvgFlatRender; class PoserSpec extends ObjectBehavior { - function let() + public function let(): void { $render = new SvgFlatRender(); - $this->beConstructedWith(array($render)); + $this->beConstructedWith([$render]); } - function it_is_initializable() + public function it_is_initializable(): void { $this->shouldHaveType('PUGX\Poser\Poser'); } - function it_should_be_able_to_generate_an_svg_image() + public function it_should_be_able_to_generate_an_svg_image(): void { $subject = 'stable'; $status = 'v2.0'; @@ -29,23 +28,22 @@ function it_should_be_able_to_generate_an_svg_image() $this->generate($subject, $status, $color, $format)->shouldBeAValidSVGImageContaining($subject, $status); } - function it_should_be_able_to_generate_an_svg_image_from_URI() + public function it_should_be_able_to_generate_an_svg_image_from_URI(): void { $subject = 'stable-v2.0-97CA00.svg'; $this->generateFromURI($subject)->shouldBeAValidSVGImageContaining('stable', 'v2.0'); } - public function getMatchers(): array { return [ - 'beAValidSVGImageContaining' => function($object, $subject, $status) { - $regex = '/^$/'; - $matches = array(); + 'beAValidSVGImageContaining' => function ($object, $subject, $status) { + $regex = '/^$/'; + $matches = []; - return preg_match($regex, $object, $matches, PREG_OFFSET_CAPTURE, 0); - }, + return \preg_match($regex, $object, $matches, PREG_OFFSET_CAPTURE, 0); + }, ]; } } diff --git a/spec/PUGX/Poser/Render/SvgFlatRenderSpec.php b/spec/PUGX/Poser/Render/SvgFlatRenderSpec.php index 79df0aa..f922c1c 100644 --- a/spec/PUGX/Poser/Render/SvgFlatRenderSpec.php +++ b/spec/PUGX/Poser/Render/SvgFlatRenderSpec.php @@ -8,14 +8,14 @@ class SvgFlatRenderSpec extends ObjectBehavior { - function let($calculator) + public function let($calculator): void { $calculator->beADoubleOf('\PUGX\Poser\Calculator\TextSizeCalculatorInterface'); $calculator->calculateWidth(Argument::any())->willReturn(20); $this->beConstructedWith($calculator); } - function it_should_render_a_svg() + public function it_should_render_a_svg(): void { $badge = Badge::fromURI('version-stable-97CA00.svg'); $this->render($badge)->shouldBeAValidSVGImage(); @@ -24,20 +24,19 @@ function it_should_render_a_svg() public function getMatchers(): array { return [ - 'beAValidSVGImage' => function($subject) { - + 'beAValidSVGImage' => function ($subject) { $regex = '/^$/'; - $matches = array(); + $matches = []; - return preg_match($regex, (string) $subject, $matches, PREG_OFFSET_CAPTURE, 0); - } + return \preg_match($regex, (string) $subject, $matches, PREG_OFFSET_CAPTURE, 0); + }, ]; } - function it_should_render_a_license_mit_exactly_like_this_svg() + public function it_should_render_a_license_mit_exactly_like_this_svg(): void { $fixture = __DIR__ . '/../../../Fixtures/flat.svg'; - $template = file_get_contents($fixture); + $template = \file_get_contents($fixture); $badge = Badge::fromURI('license-MIT-blue.svg'); $this->render($badge)->__toString()->shouldBeLike($template); } diff --git a/spec/PUGX/Poser/Render/SvgFlatSquareRenderSpec.php b/spec/PUGX/Poser/Render/SvgFlatSquareRenderSpec.php index 7f7c487..74db3dc 100644 --- a/spec/PUGX/Poser/Render/SvgFlatSquareRenderSpec.php +++ b/spec/PUGX/Poser/Render/SvgFlatSquareRenderSpec.php @@ -8,14 +8,14 @@ class SvgFlatSquareRenderSpec extends ObjectBehavior { - function let($calculator) + public function let($calculator): void { $calculator->beADoubleOf('\PUGX\Poser\Calculator\TextSizeCalculatorInterface'); $calculator->calculateWidth(Argument::any())->willReturn(20); $this->beConstructedWith($calculator); } - function it_should_render_a_svg() + public function it_should_render_a_svg(): void { $badge = Badge::fromURI('version-stable-97CA00.svg'); $this->render($badge)->shouldBeAValidSVGImage(); @@ -25,19 +25,18 @@ public function getMatchers(): array { return [ 'beAValidSVGImage' => function ($subject) { - $regex = '/^$/'; - $matches = array(); + $matches = []; - return preg_match($regex, (string) $subject, $matches, PREG_OFFSET_CAPTURE, 0); - } + return \preg_match($regex, (string) $subject, $matches, PREG_OFFSET_CAPTURE, 0); + }, ]; } - function it_should_render_a_license_mit_exactly_like_this_svg() + public function it_should_render_a_license_mit_exactly_like_this_svg(): void { $fixture = __DIR__ . '/../../../Fixtures/flat-square.svg'; - $template = file_get_contents($fixture); + $template = \file_get_contents($fixture); $badge = Badge::fromURI('license-MIT-blue.svg'); $this->render($badge)->__toString()->shouldBeLike($template); } diff --git a/spec/PUGX/Poser/Render/SvgRenderSpec.php b/spec/PUGX/Poser/Render/SvgRenderSpec.php index 32f5045..ad9f1ff 100644 --- a/spec/PUGX/Poser/Render/SvgRenderSpec.php +++ b/spec/PUGX/Poser/Render/SvgRenderSpec.php @@ -8,20 +8,20 @@ class SvgRenderSpec extends ObjectBehavior { - function let($calculator) + public function let($calculator): void { $calculator->beADoubleOf('\PUGX\Poser\Calculator\TextSizeCalculatorInterface'); $calculator->calculateWidth(Argument::any())->willReturn(20); $this->beConstructedWith($calculator); } - function it_should_render_a_svg() + public function it_should_render_a_svg(): void { $badge = Badge::fromURI('version-stable-97CA00.svg'); $this->render($badge)->shouldBeAValidSVGImage(); } - function it_should_not_render_an_invalid_svg($calculator) + public function it_should_not_render_an_invalid_svg($calculator): void { $templatesDir = __DIR__ . '/../../../Fixtures/invalid_template'; $this->beConstructedWith($calculator, $templatesDir); @@ -29,7 +29,7 @@ function it_should_not_render_an_invalid_svg($calculator) $this->shouldThrow(new \RuntimeException('Generated string is not a valid XML'))->duringRender($badge); } - function it_should_not_render_non_svg_xml($calculator) + public function it_should_not_render_non_svg_xml($calculator): void { $templatesDir = __DIR__ . '/../../../Fixtures/xml_template'; $this->beConstructedWith($calculator, $templatesDir); @@ -41,12 +41,11 @@ public function getMatchers(): array { return [ 'beAValidSVGImage' => function ($subject) { - $regex = '/^$/'; - $matches = array(); + $matches = []; - return preg_match($regex, (string) $subject, $matches, PREG_OFFSET_CAPTURE, 0); - } + return \preg_match($regex, (string) $subject, $matches, PREG_OFFSET_CAPTURE, 0); + }, ]; } } diff --git a/src/Badge.php b/src/Badge.php index f7b0024..b25a7c2 100644 --- a/src/Badge.php +++ b/src/Badge.php @@ -5,17 +5,17 @@ class Badge { const DEFAULT_FORMAT = 'svg'; - private static $colorScheme = array( - "brightgreen" => "44cc11", - "green" => "97CA00", - "yellow" => "dfb317", - "yellowgreen" => "a4a61d", - "orange" => "fe7d37", - "red" => "e05d44", - "blue" => "007ec6", - "grey" => "555555", - "lightgray" => "9f9f9f" - ); + private static $colorScheme = [ + 'brightgreen' => '44cc11', + 'green' => '97CA00', + 'yellow' => 'dfb317', + 'yellowgreen' => 'a4a61d', + 'orange' => 'fe7d37', + 'red' => 'e05d44', + 'blue' => '007ec6', + 'grey' => '555555', + 'lightgray' => '9f9f9f', + ]; private $subject; private $status; @@ -25,12 +25,12 @@ class Badge public function __construct($subject, $status, $color, $format = self::DEFAULT_FORMAT) { $this->subject = $this->escapeValue($subject); - $this->status = $this->escapeValue($status); - $this->format = $this->escapeValue($format); - $this->color = $this->getColorHex($color); + $this->status = $this->escapeValue($status); + $this->format = $this->escapeValue($format); + $this->color = $this->getColorHex($color); if (!$this->isValidColorHex($this->color)) { - throw new \InvalidArgumentException(sprintf('Color not valid %s', $this->color)); + throw new \InvalidArgumentException(\sprintf('Color not valid %s', $this->color)); } } @@ -41,41 +41,42 @@ public function __construct($subject, $status, $color, $format = self::DEFAULT_F */ public static function getColorNamesAvailable() { - return array_keys(self::$colorScheme); + return \array_keys(self::$colorScheme); } /** * Factory method the creates a Badge from an URI - * eg. I_m-liuggio-yellow.svg + * eg. I_m-liuggio-yellow.svg. * * @param string $URI * * @return Badge + * * @throws \InvalidArgumentException */ public static function fromURI($URI) { $regex = '/^(([^-]|--)+)-(([^-]|--)+)-(([^-]|--)+)\.(svg|png|gif|jpg)$/'; - $match = array(); + $match = []; - if (1 != preg_match($regex, $URI, $match) && (7 != count($match))) { - throw new \InvalidArgumentException('The URI given is not a valid URI'.$URI); + if (1 != \preg_match($regex, $URI, $match) && (7 != \count($match))) { + throw new \InvalidArgumentException('The URI given is not a valid URI' . $URI); } $subject = $match[1]; - $status = $match[3]; - $color = $match[5]; - $format = $match[7]; + $status = $match[3]; + $color = $match[5]; + $format = $match[7]; return new self($subject, $status, $color, $format); } /** - * @return string the Hexadecimal #FFFFFF. + * @return string the Hexadecimal #FFFFFF */ public function getHexColor() { - return '#'.$this->color; + return '#' . $this->color; } /** @@ -104,8 +105,8 @@ public function getSubject() public function __toString() { - return sprintf( - "%s-%s-%s.%s", + return \sprintf( + '%s-%s-%s.%s', $this->subject, $this->status, $this->color, @@ -115,37 +116,37 @@ public function __toString() private function escapeValue($value) { - $pattern = array( + $pattern = [ // '/([^_])_([^_])/g', // damn it global doesn't work in PHP '/([^_])_$/', '/^_([^_])/', '/__/', '/--+/', - ); - $replacement = array( + ]; + $replacement = [ //'$1 $2', '$1 ', ' $1', '°§*¼', '-', - ); - $ret = preg_replace($pattern, $replacement, $value); - $ret = str_replace('_', ' ', $ret); // this fix the php pgrep_replace is not global :( - $ret = str_replace('°§*¼', '_', $ret); // this fix the php pgrep_replace is not global :( + ]; + $ret = \preg_replace($pattern, $replacement, $value); + $ret = \str_replace('_', ' ', $ret); // this fix the php pgrep_replace is not global :( + $ret = \str_replace('°§*¼', '_', $ret); // this fix the php pgrep_replace is not global :( return $ret; } private function getColorHex($color) { - return array_key_exists($color, self::$colorScheme) ? self::$colorScheme[$color] : $color; + return \array_key_exists($color, self::$colorScheme) ? self::$colorScheme[$color] : $color; } private function isValidColorHex($color) { - $color = ltrim($color, "#"); + $color = \ltrim($color, '#'); $regex = '/^[0-9a-fA-F]{6}$/'; - return preg_match($regex, $color); + return \preg_match($regex, $color); } } diff --git a/src/Calculator/GDTextSizeCalculator.php b/src/Calculator/GDTextSizeCalculator.php index a1be882..bdaa0a2 100644 --- a/src/Calculator/GDTextSizeCalculator.php +++ b/src/Calculator/GDTextSizeCalculator.php @@ -8,11 +8,12 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ + namespace PUGX\Poser\Calculator; class GDTextSizeCalculator implements TextSizeCalculatorInterface { - const TEXT_FONT = '/Font/DejaVuSans.ttf'; + const TEXT_FONT = '/Font/DejaVuSans.ttf'; /** @var string */ protected $fontPath; @@ -33,13 +34,13 @@ public function __construct() public function calculateWidth($text, $size = self::TEXT_SIZE) { $size = $this->convertToPt($size); - $box = imagettfbbox($size, 0, $this->fontPath, $text); + $box = \imagettfbbox($size, 0, $this->fontPath, $text); - return round(abs($box[2] - $box[0]) + self::SHIELD_PADDING_EXTERNAL + self::SHIELD_PADDING_INTERNAL, 1); + return \round(\abs($box[2] - $box[0]) + self::SHIELD_PADDING_EXTERNAL + self::SHIELD_PADDING_INTERNAL, 1); } private function convertToPt($pixels) { - return round($pixels * 0.75, 1); + return \round($pixels * 0.75, 1); } } diff --git a/src/Calculator/TextSizeCalculatorInterface.php b/src/Calculator/TextSizeCalculatorInterface.php index ae79caa..b33b8ee 100644 --- a/src/Calculator/TextSizeCalculatorInterface.php +++ b/src/Calculator/TextSizeCalculatorInterface.php @@ -13,7 +13,7 @@ interface TextSizeCalculatorInterface { - const TEXT_SIZE = 11; + const TEXT_SIZE = 11; const SHIELD_PADDING_EXTERNAL = 6; const SHIELD_PADDING_INTERNAL = 4; diff --git a/src/Image.php b/src/Image.php index 9db643c..95f5988 100644 --- a/src/Image.php +++ b/src/Image.php @@ -12,7 +12,7 @@ namespace PUGX\Poser; /** - * Class Image, an Image value Object + * Class Image, an Image value Object. * * @author Claudio D'Alicandro * @author Giulio De Donato @@ -20,11 +20,11 @@ class Image { /** - * @var string $content + * @var string */ private $content; /** - * @var string $format + * @var string */ private $format; @@ -39,7 +39,7 @@ private function __construct($content, $format) } /** - * Returns the image content as binary string + * Returns the image content as binary string. */ public function __toString() { @@ -47,7 +47,7 @@ public function __toString() } /** - * Factory method + * Factory method. * * @param string $content * @param string $format diff --git a/src/Poser.php b/src/Poser.php index 1889f02..9991a59 100644 --- a/src/Poser.php +++ b/src/Poser.php @@ -15,9 +15,9 @@ class Poser */ public function __construct($renders) { - $this->renders = array(); - if (!is_array($renders)) { - $renders = array($renders); + $this->renders = []; + if (!\is_array($renders)) { + $renders = [$renders]; } foreach ($renders as $render) { @@ -47,6 +47,7 @@ public function generate($subject, $status, $color, $format) * eg license-MIT-blue.svg or I_m-liuggio-yellow.svg. * * @param $string + * * @return Image */ public function generateFromURI($string) @@ -63,10 +64,10 @@ public function generateFromURI($string) */ public function validFormats() { - return array_keys($this->renders); + return \array_keys($this->renders); } - private function addFormatRender(RenderInterface $render) + private function addFormatRender(RenderInterface $render): void { foreach ($render->supportedFormats() as $format) { $this->renders[$format] = $render; @@ -81,7 +82,7 @@ private function addFormatRender(RenderInterface $render) private function getRenderFor($format) { if (!isset($this->renders[$format])) { - throw new \InvalidArgumentException(sprintf('No render founds for this format [%s]', $format)); + throw new \InvalidArgumentException(\sprintf('No render founds for this format [%s]', $format)); } return $this->renders[$format]; diff --git a/src/Render/LocalSvgRenderer.php b/src/Render/LocalSvgRenderer.php index 0d25c4a..f793381 100644 --- a/src/Render/LocalSvgRenderer.php +++ b/src/Render/LocalSvgRenderer.php @@ -39,7 +39,7 @@ abstract class LocalSvgRenderer implements RenderInterface /** * @param TextSizeCalculatorInterface $textSizeCalculator - * @param null|string $templatesDirectory + * @param string|null $templatesDirectory */ public function __construct(TextSizeCalculatorInterface $textSizeCalculator = null, $templatesDirectory = null) { @@ -55,8 +55,6 @@ public function __construct(TextSizeCalculatorInterface $textSizeCalculator = nu } /** - * @param Badge $badge - * * @return mixed */ public function render(Badge $badge) @@ -79,13 +77,13 @@ abstract protected function getTemplateName(); */ private function getTemplate($format) { - $filepath = sprintf('%s/%s.svg', $this->templatesDirectory, $format); + $filepath = \sprintf('%s/%s.svg', $this->templatesDirectory, $format); - if (!file_exists($filepath)) { - throw new \InvalidArgumentException(sprintf('No template for format %s', $format)); + if (!\file_exists($filepath)) { + throw new \InvalidArgumentException(\sprintf('No template for format %s', $format)); } - return file_get_contents($filepath); + return \file_get_contents($filepath); } /** @@ -100,7 +98,7 @@ private function stringWidth($text) /** * @param string $render - * @param array $parameters + * @param array $parameters * @param string $format * * @return Image @@ -108,7 +106,7 @@ private function stringWidth($text) private function renderSvg($render, $parameters, $format) { foreach ($parameters as $key => $variable) { - $render = str_replace(sprintf('{{ %s }}', $key), $variable, $render); + $render = \str_replace(\sprintf('{{ %s }}', $key), $variable, $render); } try { @@ -124,13 +122,11 @@ private function renderSvg($render, $parameters, $format) } /** - * @param Badge $badge - * * @return array */ private function buildParameters(Badge $badge) { - $parameters = array(); + $parameters = []; $parameters['vendorWidth'] = $this->stringWidth($badge->getSubject()); $parameters['valueWidth'] = $this->stringWidth($badge->getStatus()); @@ -139,8 +135,8 @@ private function buildParameters(Badge $badge) $parameters['valueColor'] = $badge->getHexColor(); $parameters['vendor'] = $badge->getSubject(); $parameters['value'] = $badge->getStatus(); - $parameters['vendorStartPosition'] = round($parameters['vendorWidth'] / 2, 1) + 1; - $parameters['valueStartPosition'] = $parameters['vendorWidth'] + round($parameters['valueWidth'] / 2, 1) - 1; + $parameters['vendorStartPosition'] = \round($parameters['vendorWidth'] / 2, 1) + 1; + $parameters['valueStartPosition'] = $parameters['vendorWidth'] + \round($parameters['valueWidth'] / 2, 1) - 1; return $parameters; } diff --git a/src/Render/RenderInterface.php b/src/Render/RenderInterface.php index b27d78e..d879f22 100644 --- a/src/Render/RenderInterface.php +++ b/src/Render/RenderInterface.php @@ -18,8 +18,6 @@ interface RenderInterface /** * Render a badge. * - * @param Badge $badge - * * @return \PUGX\Poser\Image */ public function render(Badge $badge); diff --git a/src/Render/SvgFlatRender.php b/src/Render/SvgFlatRender.php index 9ef9e93..58a5752 100644 --- a/src/Render/SvgFlatRender.php +++ b/src/Render/SvgFlatRender.php @@ -12,7 +12,7 @@ namespace PUGX\Poser\Render; /** - * Class SvgFlatGenerator + * Class SvgFlatGenerator. * * @author Giulio De Donato */ @@ -25,7 +25,7 @@ class SvgFlatRender extends LocalSvgRenderer */ public function supportedFormats() { - return array('flat', 'svg'); + return ['flat', 'svg']; } protected function getTemplateName() diff --git a/src/Render/SvgFlatSquareRender.php b/src/Render/SvgFlatSquareRender.php index 439fbb2..b60940d 100644 --- a/src/Render/SvgFlatSquareRender.php +++ b/src/Render/SvgFlatSquareRender.php @@ -12,7 +12,7 @@ namespace PUGX\Poser\Render; /** - * Class SvgFlatGenerator + * Class SvgFlatGenerator. * * @author Giulio De Donato */ @@ -25,7 +25,7 @@ class SvgFlatSquareRender extends LocalSvgRenderer */ public function supportedFormats() { - return array('flat-square'); + return ['flat-square']; } protected function getTemplateName() diff --git a/src/Render/SvgRender.php b/src/Render/SvgRender.php index 64812ea..89ed1e5 100644 --- a/src/Render/SvgRender.php +++ b/src/Render/SvgRender.php @@ -11,10 +11,8 @@ namespace PUGX\Poser\Render; -use PUGX\Poser\Badge; - /** - * Class SvgGenerator + * Class SvgGenerator. * * @author Claudio D'Alicandro * @author Giulio De Donato @@ -28,7 +26,7 @@ class SvgRender extends LocalSvgRenderer */ public function supportedFormats() { - return array('plastic'); + return ['plastic']; } protected function getTemplateName() diff --git a/src/UI/Command.php b/src/UI/Command.php index d1c47c6..9691a43 100644 --- a/src/UI/Command.php +++ b/src/UI/Command.php @@ -2,16 +2,16 @@ namespace PUGX\Poser\UI; +use PUGX\Poser\Badge; +use PUGX\Poser\Poser; use PUGX\Poser\Render\SvgFlatRender; use PUGX\Poser\Render\SvgFlatSquareRender; +use PUGX\Poser\Render\SvgRender; use Symfony\Component\Console\Command\Command as BaseCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; -use PUGX\Poser\Badge; -use PUGX\Poser\Poser; -use PUGX\Poser\Render\SvgRender; class Command extends BaseCommand { @@ -32,18 +32,18 @@ class Command extends BaseCommand /** @var string */ protected $header; - private function init() + private function init(): void { - $this->poser = new Poser(array( + $this->poser = new Poser([ new SvgRender(), new SvgFlatRender(), - new SvgFlatSquareRender() - )); + new SvgFlatSquareRender(), + ]); $this->format = 'flat'; $this->header = self::HEADER; } - protected function configure() + protected function configure(): void { $this->init(); @@ -63,13 +63,13 @@ protected function configure() ->addArgument( 'color', InputArgument::OPTIONAL, - 'The hexadecimal color eg. `97CA00` or the name ['.join(', ', Badge::getColorNamesAvailable()).']' + 'The hexadecimal color eg. `97CA00` or the name [' . \implode(', ', Badge::getColorNamesAvailable()) . ']' ) ->addOption( 'format', 'f', InputOption::VALUE_REQUIRED, - 'The format of the image eg. `svg`, formats available ['.join(', ', $this->poser->validFormats()).']' + 'The format of the image eg. `svg`, formats available [' . \implode(', ', $this->poser->validFormats()) . ']' ) ->addOption( 'path', @@ -105,17 +105,17 @@ protected function execute(InputInterface $input, OutputInterface $output) return 0; } - protected function flushImage(OutputInterface $output, $imageContent) + protected function flushImage(OutputInterface $output, $imageContent): void { $output->write((string) $imageContent); $this->header = ''; } - protected function storeImage(OutputInterface $output, $path, $imageContent) + protected function storeImage(OutputInterface $output, $path, $imageContent): void { $this->printHeaderOnce($output); try { - $fp = @fopen($path, "x"); + $fp = @\fopen($path, 'x'); } catch (\Exception $e) { $fp = false; } @@ -123,16 +123,16 @@ protected function storeImage(OutputInterface $output, $path, $imageContent) if (false == $fp) { throw new \Exception("Error on creating the file maybe file [$path] already exists?"); } - $written = @fwrite($fp, $imageContent); - if ($written <1 || $written != strlen($imageContent)) { + $written = @\fwrite($fp, $imageContent); + if ($written < 1 || $written != \strlen($imageContent)) { throw new \Exception('Error on writing to file.'); } - @fclose($fp); + @\fclose($fp); - $output->write(sprintf('Image created at %s', $path)); + $output->write(\sprintf('Image created at %s', $path)); } - protected function printHeaderOnce(OutputInterface $output) + protected function printHeaderOnce(OutputInterface $output): void { if (!empty($this->header)) { $output->write($this->header); diff --git a/src/UI/SingleCommandApplication.php b/src/UI/SingleCommandApplication.php index 545977f..5ef1b11 100644 --- a/src/UI/SingleCommandApplication.php +++ b/src/UI/SingleCommandApplication.php @@ -2,9 +2,9 @@ namespace PUGX\Poser\UI; +use Symfony\Component\Console\Application; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Application; /** * Application providing access to just one command. @@ -26,7 +26,8 @@ class SingleCommandApplication extends Application { /** - * Name of the single accessible command of this application + * Name of the single accessible command of this application. + * * @var string */ private $commandName; @@ -79,7 +80,7 @@ public function add(Command $command) { // Fail if we already set up the single accessible command. if ($this->commandName) { - throw new \LogicException("You should not add additional commands to a SingleCommandApplication instance."); + throw new \LogicException('You should not add additional commands to a SingleCommandApplication instance.'); } return parent::add($command); From 285cbd376b5f00c3b1666ba435810d68d4bfe5cf Mon Sep 17 00:00:00 2001 From: Andrea Giannantonio Date: Mon, 8 Jun 2020 18:35:43 +0200 Subject: [PATCH 03/20] fixup phpspec data provider --- composer.json | 9 ++++++++- phpspec.yml | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index c4d52d9..b44d30f 100644 --- a/composer.json +++ b/composer.json @@ -22,6 +22,12 @@ "autoload": { "psr-4": { "PUGX\\Poser\\": "src/" } }, + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/madisoft/phpspec-data-provider-extension" + } + ], "require": { "php": ">=7.4", "ext-gd": "*", @@ -31,7 +37,8 @@ "require-dev": { "phpspec/phpspec": "^6.1", "behat/behat": "^3.7", - "friendsofphp/php-cs-fixer": "^2.16" + "friendsofphp/php-cs-fixer": "^2.16", + "moave/phpspec-data-provider-extension": "dev-master" }, "config": { "bin-dir": "bin" diff --git a/phpspec.yml b/phpspec.yml index f12ac65..7b688c4 100644 --- a/phpspec.yml +++ b/phpspec.yml @@ -1,2 +1,3 @@ extensions: -# - Coduo\PhpSpec\DataProvider\DataProviderExtension + Coduo\PhpSpec\DataProvider\DataProviderExtension: ~ + From 319e6f00db2d09a0d86a5341a7149d76c7b3ade4 Mon Sep 17 00:00:00 2001 From: Andrea Giannantonio Date: Tue, 9 Jun 2020 15:21:16 +0200 Subject: [PATCH 04/20] Add CircleCI --- .circleci/config.yml | 83 +++++++++++++++++++++++++++++++++++++ .circleci/images/Dockerfile | 17 ++++++++ .gitignore | 1 + .scrutinizer.yml | 23 ---------- .travis.yml | 38 ----------------- LICENSE | 2 +- README.md | 7 ++-- composer.json | 11 +++-- phpspec-coverage.yml | 9 ++++ phpspec-scrutinizer.yml | 8 ---- 10 files changed, 121 insertions(+), 78 deletions(-) create mode 100644 .circleci/config.yml create mode 100644 .circleci/images/Dockerfile delete mode 100644 .scrutinizer.yml delete mode 100644 .travis.yml create mode 100644 phpspec-coverage.yml delete mode 100644 phpspec-scrutinizer.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..9ee0294 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,83 @@ +version: 2.1 + +executors: + poser_executor: # declares a reusable executor + docker: + - image: pugx/poser:2.0 + working_directory: ~/app + +jobs: + checkout_code: + executor: poser_executor + steps: + - checkout + - save_cache: + key: v1-repo-{{ .Environment.CIRCLE_SHA1 }} + paths: + - ~/app + + php_dependencies: + executor: poser_executor + steps: + - restore_cache: + keys: + - v1-repo-{{ .Environment.CIRCLE_SHA1 }} + - run: + name: install project dependencies + command: composer install -n --no-progress --no-suggest + - save_cache: + paths: + - ~/app/bin + - ~/app/vendor + key: v1-php-dependencies-{{ .Environment.CIRCLE_SHA1 }} + + lint_checks: + executor: poser_executor + steps: + - restore_cache: + keys: + - v1-repo-{{ .Environment.CIRCLE_SHA1 }} + - restore_cache: + name: Restore PHP Dependencies Cache + keys: + - v1-php-dependencies-{{ .Environment.CIRCLE_SHA1 }} + - run: + name: run php-cs-fixer checks + command: bin/php-cs-fixer fix --verbose --diff --dry-run + + phpspec_and_behat: + executor: poser_executor + steps: + - restore_cache: + keys: + - v1-repo-{{ .Environment.CIRCLE_SHA1 }} + - restore_cache: + name: Restore PHP Dependencies Cache + keys: + - v1-php-dependencies-{{ .Environment.CIRCLE_SHA1 }} + - run: + name: run phpspec tests + command: bin/phpspec run --format=pretty + - run: + name: run phpspec coverage tests + command: bin/phpspec run -f progress -c phpspec-coverage.yml + - store_artifacts: + path: coverage + - run: + name: run behat checks + command: bin/behat + +workflows: + version: 2 + build-and-test: + jobs: + - checkout_code + - php_dependencies: + requires: + - checkout_code + - lint_checks: + requires: + - php_dependencies + - phpspec_and_behat: + requires: + - php_dependencies diff --git a/.circleci/images/Dockerfile b/.circleci/images/Dockerfile new file mode 100644 index 0000000..5bf5d59 --- /dev/null +++ b/.circleci/images/Dockerfile @@ -0,0 +1,17 @@ +FROM circleci/php:7.4-fpm-browsers + +USER root + +# install system packages +RUN apt-get install -qqy libzip-dev libpng-dev libjpeg-dev libfreetype6-dev + +# configure php packages +RUN docker-php-ext-configure gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/ + +# install php requirements +RUN docker-php-ext-install zip iconv gd + +USER circleci + +# install prestissimo +RUN composer global require hirak/prestissimo diff --git a/.gitignore b/.gitignore index 5f45e2a..231acdc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ /bin/behat /bin/php-cs-fixer /bin/phpspec +/coverage /vendor .php_cs.cache composer.lock diff --git a/.scrutinizer.yml b/.scrutinizer.yml deleted file mode 100644 index df21dd3..0000000 --- a/.scrutinizer.yml +++ /dev/null @@ -1,23 +0,0 @@ -checks: - php: - code_rating: true - duplication: true - -filter: - paths: - - src/* - -build: - dependencies: - before: - - composer require "henrikbjorn/phpspec-code-coverage" "~0.2" - environment: - php: - version: 5.6 - tests: - override: - - - command: 'bin/phpspec run -f progress -c phpspec-scrutinizer.yml' - coverage: - file: 'coverage.clover' - format: 'php-clover' diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index d4f3702..0000000 --- a/.travis.yml +++ /dev/null @@ -1,38 +0,0 @@ -language: php - -php: - - 5.4 - - 5.5 - - 5.6 - - 7.0 - - 7.1 - - hhvm - -matrix: - allow_failures: - - php: 5.5 - - php: hhvm - -cache: - directories: - - $HOME/.composer/cache/files - -before_install: - - phpenv config-rm xdebug.ini || echo "xdebug not available for PHP $TRAVIS_PHP_VERSION" - -install: - - composer --prefer-dist --no-interaction update - -script: - - bin/phpspec run --format=pretty - - bin/behat - - bin/php-cs-fixer --dry-run -v fix src --rules=@PSR2 - - -notifications: - email: - - liuggio@gmail.com - - jmleroux.pro@gmail.com - -git: - depth: 10 diff --git a/LICENSE b/LICENSE index c2f70a7..37e6808 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2013 Giulio De Donato +Copyright (c) 2004-2020 Giulio De Donato Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 56117ce..e890a71 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -PHP badges poser -================ +# PHP badges poser [![CircleCI](https://circleci.com/gh/badges/poser/tree/release%2Fv2.svg?style=svg)](https://circleci.com/gh/badges/poser/tree/release%2Fv2) This is a php library that creates badges like ![Badge Poser](https://cdn.rawgit.com/badges/poser/master/badge-poser.svg) and ![I'm a badge](https://cdn.rawgit.com/badges/poser/master/i_m-badge.svg) and ![dark](https://cdn.rawgit.com/badges/poser/master/today-dark.svg), according to [Shields specification](https://github.com/badges/shields#specification). @@ -111,8 +110,8 @@ We provide a `docker-compose.yml.dist` file to allow you to run tests in a Docke cp docker-compose.yml.dist docker-compose.yml docker-compose up -d docker-compose exec fpm composer install -docker-compose exec fpm bin/phpspec run --format=pretty -docker-compose exec fpm bin/behat +docker-compose exec fpm composer phpspec +docker-compose exec fpm composer behat ``` The provided Docker compose file is for a PHP 7.1 environment, but you can modifiy it to use PHP 5.6. diff --git a/composer.json b/composer.json index b44d30f..d3003d4 100644 --- a/composer.json +++ b/composer.json @@ -38,16 +38,19 @@ "phpspec/phpspec": "^6.1", "behat/behat": "^3.7", "friendsofphp/php-cs-fixer": "^2.16", - "moave/phpspec-data-provider-extension": "dev-master" + "moave/phpspec-data-provider-extension": "dev-master", + "friends-of-phpspec/phpspec-code-coverage": "^4.3" }, "config": { "bin-dir": "bin" }, "bin": ["bin/poser"], "scripts": { - "php-cs-fixer": [ - "bin/php-cs-fixer fix -v" - ] + "php-cs-fixer-dry-run": "bin/php-cs-fixer fix --verbose --diff --dry-run --ansi", + "php-cs-fixer": "bin/php-cs-fixer fix -v --ansi", + "phpspec": "bin/phpspec run --format=pretty --ansi", + "phpspec-coverage": "bin/phpspec run -f progress -c phpspec-coverage.yml --ansi", + "behat": "bin/behat" }, "extra": { "branch-alias": { diff --git a/phpspec-coverage.yml b/phpspec-coverage.yml new file mode 100644 index 0000000..fcc7bf1 --- /dev/null +++ b/phpspec-coverage.yml @@ -0,0 +1,9 @@ +extensions: + Coduo\PhpSpec\DataProvider\DataProviderExtension: ~ + FriendsOfPhpSpec\PhpSpec\CodeCoverage\CodeCoverageExtension: + format: + - html + - php + output: + html: coverage/phpspec-html + php: coverage/phpspec-php/phpspec.cov diff --git a/phpspec-scrutinizer.yml b/phpspec-scrutinizer.yml deleted file mode 100644 index 2cb903a..0000000 --- a/phpspec-scrutinizer.yml +++ /dev/null @@ -1,8 +0,0 @@ -extensions: - - Coduo\PhpSpec\DataProvider\DataProviderExtension - - PhpSpec\Extension\CodeCoverageExtension -code_coverage: - format: - - clover - output: - clover: coverage.clover From 1d60f98fb58b70687c77ecccec37608002c70bd6 Mon Sep 17 00:00:00 2001 From: Andrea Giannantonio Date: Wed, 10 Jun 2020 10:05:40 +0200 Subject: [PATCH 05/20] remove to cvs yaml-lint --- .gitignore | 1 + bin/yaml-lint | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 120000 bin/yaml-lint diff --git a/.gitignore b/.gitignore index 231acdc..9cc305e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ /bin/behat /bin/php-cs-fixer /bin/phpspec +/bin/yaml-lint /coverage /vendor .php_cs.cache diff --git a/bin/yaml-lint b/bin/yaml-lint deleted file mode 120000 index 73c0353..0000000 --- a/bin/yaml-lint +++ /dev/null @@ -1 +0,0 @@ -../vendor/symfony/yaml/Resources/bin/yaml-lint \ No newline at end of file From fd67aabe472c53624d304ed59aac473636da1363 Mon Sep 17 00:00:00 2001 From: Andrea Giannantonio Date: Thu, 11 Jun 2020 12:29:33 +0200 Subject: [PATCH 06/20] refactoring library full typed --- .php_cs | 6 ++ features/bootstrap/FeatureContext.php | 15 ++-- spec/PUGX/Poser/BadgeSpec.php | 14 ++-- spec/PUGX/Poser/PoserSpec.php | 6 +- spec/PUGX/Poser/Render/SvgFlatRenderSpec.php | 4 +- .../Poser/Render/SvgFlatSquareRenderSpec.php | 4 +- src/Badge.php | 78 +++++++++---------- src/Calculator/GDTextSizeCalculator.php | 15 ++-- .../TextSizeCalculatorInterface.php | 13 +--- src/Image.php | 33 ++------ src/Poser.php | 21 ++--- src/Render/LocalSvgRenderer.php | 71 +++++------------ src/Render/RenderInterface.php | 9 +-- src/Render/SvgFlatRender.php | 6 +- src/Render/SvgFlatSquareRender.php | 6 +- src/Render/SvgRender.php | 6 +- src/UI/Command.php | 31 ++++---- src/UI/SingleCommandApplication.php | 12 ++- 18 files changed, 140 insertions(+), 210 deletions(-) diff --git a/.php_cs b/.php_cs index 85cd048..b87a883 100644 --- a/.php_cs +++ b/.php_cs @@ -18,6 +18,12 @@ return PhpCsFixer\Config::create() 'declare_strict_types' => false, 'native_function_invocation' => true, 'concat_space' => ['spacing' => 'one'], + 'binary_operator_spaces' => ['align_double_arrow' => true, 'align_equals' => true], + 'single_blank_line_at_eof' => true, + 'phpdoc_align' => ['align' => 'vertical'], + 'phpdoc_separation' => true, + 'phpdoc_summary' => false, + 'random_api_migration' => true, ]) ->setFinder($finder) ; diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index f545d35..763af55 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -7,6 +7,9 @@ */ class FeatureContext implements SnippetAcceptingContext { + private string $binFolder; + private string $output; + /** * Initializes context. * @@ -16,7 +19,7 @@ class FeatureContext implements SnippetAcceptingContext public function __construct() { $this->binFolder = __DIR__ . '/../../bin/'; - $this->output = ''; + $this->output = ''; } /** @@ -24,7 +27,7 @@ public function __construct() */ public function iRun($command): void { - $poser = $this->binFolder . $command; + $poser = $this->binFolder . $command; $this->return = -1; \ob_start(); \passthru("cd {$this->binFolder};php $command", $this->return); @@ -37,7 +40,7 @@ public function iRun($command): void public function theSameOutputShouldBeLikeTheContentOf($filePath): void { $filePath = __DIR__ . '/../' . $filePath; - $content = \file_get_contents($filePath); + $content = \file_get_contents($filePath); $this->assertEquals($content, $this->output); } @@ -58,10 +61,10 @@ public function itShouldPass(): void public function theContentOfShouldBeEqualTo($given, $expected): void { $givenPath = $given; - $given = \file_get_contents($givenPath); + $given = \file_get_contents($givenPath); $expectedPath = __DIR__ . '/../' . $expected; - $expected = \file_get_contents($expectedPath); + $expected = \file_get_contents($expectedPath); \unlink($givenPath); $this->assertEquals($given, $expected); @@ -70,7 +73,7 @@ public function theContentOfShouldBeEqualTo($given, $expected): void private function assertEquals($given, $expected): void { $expected = \preg_replace('/\s+/', '', $expected); - $given = \preg_replace('/\s+/', '', $given); + $given = \preg_replace('/\s+/', '', $given); $perc = 0; \similar_text($expected, $given, $perc); diff --git a/spec/PUGX/Poser/BadgeSpec.php b/spec/PUGX/Poser/BadgeSpec.php index f38bd95..ffa3ceb 100644 --- a/spec/PUGX/Poser/BadgeSpec.php +++ b/spec/PUGX/Poser/BadgeSpec.php @@ -18,7 +18,7 @@ public function it_should_be_constructed_by_fromURI_factory_method(): void { $this->beConstructedWith('a', 'b', '97CA00', 'svg'); $assert = 'version-stable-97CA00.svg'; - $it = Badge::fromURI($assert); + $it = Badge::fromURI($assert); if ((string) $it !== $assert) { throw new Exception(\sprintf("from[%s] having[%s]\n", $assert, (string) $it)); @@ -28,9 +28,9 @@ public function it_should_be_constructed_by_fromURI_factory_method(): void public function it_should_be_constructed_by_fromURI_factory_method_escaping_correctly_underscores(): void { $this->beConstructedWith('a', 'b', '97CA00', 'svg'); - $input = 'I__m__liugg__io-b-97CA00.svg'; + $input = 'I__m__liugg__io-b-97CA00.svg'; $assertInput = 'I_m_liugg_io-b-97CA00.svg'; - $it = Badge::fromURI($input); + $it = Badge::fromURI($input); if ((string) $it !== $assertInput) { throw new Exception(\sprintf("from[%s] wants[%s] having[%s]\n", $input, $assertInput, (string) $it)); @@ -40,9 +40,9 @@ public function it_should_be_constructed_by_fromURI_factory_method_escaping_corr public function it_should_be_constructed_by_fromURI_factory_method_escaping_correctly_with_single_underscore(): void { $this->beConstructedWith('a', 'b', '97CA00', 'svg'); - $input = 'I_m_liuggio-b-97CA00.svg'; + $input = 'I_m_liuggio-b-97CA00.svg'; $assertInput = 'I m liuggio-b-97CA00.svg'; - $it = Badge::fromURI($input); + $it = Badge::fromURI($input); if ((string) $it !== $assertInput) { throw new Exception(\sprintf("from[%s] wants[%s] having[%s]\n", $input, $assertInput, (string) $it)); @@ -52,9 +52,9 @@ public function it_should_be_constructed_by_fromURI_factory_method_escaping_corr public function it_should_be_constructed_by_fromURI_factory_method_escaping_correctly_with_dashes(): void { $this->beConstructedWith('a', 'b', '97CA00', 'svg'); - $input = 'I--m--liuggio-b-97CA00.svg'; + $input = 'I--m--liuggio-b-97CA00.svg'; $assertInput = 'I-m-liuggio-b-97CA00.svg'; - $it = Badge::fromURI($input); + $it = Badge::fromURI($input); if ((string) $it !== $assertInput) { throw new Exception(\sprintf("from[%s] wants[%s] having[%s]\n", $input, $assertInput, (string) $it)); diff --git a/spec/PUGX/Poser/PoserSpec.php b/spec/PUGX/Poser/PoserSpec.php index a58fac8..de73396 100644 --- a/spec/PUGX/Poser/PoserSpec.php +++ b/spec/PUGX/Poser/PoserSpec.php @@ -21,9 +21,9 @@ public function it_is_initializable(): void public function it_should_be_able_to_generate_an_svg_image(): void { $subject = 'stable'; - $status = 'v2.0'; - $color = '97CA00'; - $format = 'svg'; + $status = 'v2.0'; + $color = '97CA00'; + $format = 'svg'; $this->generate($subject, $status, $color, $format)->shouldBeAValidSVGImageContaining($subject, $status); } diff --git a/spec/PUGX/Poser/Render/SvgFlatRenderSpec.php b/spec/PUGX/Poser/Render/SvgFlatRenderSpec.php index f922c1c..183f339 100644 --- a/spec/PUGX/Poser/Render/SvgFlatRenderSpec.php +++ b/spec/PUGX/Poser/Render/SvgFlatRenderSpec.php @@ -35,9 +35,9 @@ public function getMatchers(): array public function it_should_render_a_license_mit_exactly_like_this_svg(): void { - $fixture = __DIR__ . '/../../../Fixtures/flat.svg'; + $fixture = __DIR__ . '/../../../Fixtures/flat.svg'; $template = \file_get_contents($fixture); - $badge = Badge::fromURI('license-MIT-blue.svg'); + $badge = Badge::fromURI('license-MIT-blue.svg'); $this->render($badge)->__toString()->shouldBeLike($template); } } diff --git a/spec/PUGX/Poser/Render/SvgFlatSquareRenderSpec.php b/spec/PUGX/Poser/Render/SvgFlatSquareRenderSpec.php index 74db3dc..7cdbbe8 100644 --- a/spec/PUGX/Poser/Render/SvgFlatSquareRenderSpec.php +++ b/spec/PUGX/Poser/Render/SvgFlatSquareRenderSpec.php @@ -35,9 +35,9 @@ public function getMatchers(): array public function it_should_render_a_license_mit_exactly_like_this_svg(): void { - $fixture = __DIR__ . '/../../../Fixtures/flat-square.svg'; + $fixture = __DIR__ . '/../../../Fixtures/flat-square.svg'; $template = \file_get_contents($fixture); - $badge = Badge::fromURI('license-MIT-blue.svg'); + $badge = Badge::fromURI('license-MIT-blue.svg'); $this->render($badge)->__toString()->shouldBeLike($template); } } diff --git a/src/Badge.php b/src/Badge.php index b25a7c2..e6aa7f7 100644 --- a/src/Badge.php +++ b/src/Badge.php @@ -4,30 +4,31 @@ class Badge { - const DEFAULT_FORMAT = 'svg'; - private static $colorScheme = [ + public const DEFAULT_FORMAT = 'svg'; + + private static array $colorScheme = [ 'brightgreen' => '44cc11', - 'green' => '97CA00', - 'yellow' => 'dfb317', + 'green' => '97CA00', + 'yellow' => 'dfb317', 'yellowgreen' => 'a4a61d', - 'orange' => 'fe7d37', - 'red' => 'e05d44', - 'blue' => '007ec6', - 'grey' => '555555', - 'lightgray' => '9f9f9f', + 'orange' => 'fe7d37', + 'red' => 'e05d44', + 'blue' => '007ec6', + 'grey' => '555555', + 'lightgray' => '9f9f9f', ]; - private $subject; - private $status; - private $color; - private $format; + private string $subject; + private string $status; + private string $color; + private string $format; - public function __construct($subject, $status, $color, $format = self::DEFAULT_FORMAT) + public function __construct(string $subject, string $status, string $color, string $format = self::DEFAULT_FORMAT) { $this->subject = $this->escapeValue($subject); - $this->status = $this->escapeValue($status); - $this->format = $this->escapeValue($format); - $this->color = $this->getColorHex($color); + $this->status = $this->escapeValue($status); + $this->format = $this->escapeValue($format); + $this->color = $this->getColorHex($color); if (!$this->isValidColorHex($this->color)) { throw new \InvalidArgumentException(\sprintf('Color not valid %s', $this->color)); @@ -36,10 +37,8 @@ public function __construct($subject, $status, $color, $format = self::DEFAULT_F /** * An array of the color names available. - * - * @return array */ - public static function getColorNamesAvailable() + public static function getColorNamesAvailable(): array { return \array_keys(self::$colorScheme); } @@ -48,25 +47,21 @@ public static function getColorNamesAvailable() * Factory method the creates a Badge from an URI * eg. I_m-liuggio-yellow.svg. * - * @param string $URI - * - * @return Badge - * * @throws \InvalidArgumentException */ - public static function fromURI($URI) + public static function fromURI(string $URI): self { $regex = '/^(([^-]|--)+)-(([^-]|--)+)-(([^-]|--)+)\.(svg|png|gif|jpg)$/'; $match = []; - if (1 != \preg_match($regex, $URI, $match) && (7 != \count($match))) { + if (1 !== \preg_match($regex, $URI, $match) && (7 !== \count($match))) { throw new \InvalidArgumentException('The URI given is not a valid URI' . $URI); } $subject = $match[1]; - $status = $match[3]; - $color = $match[5]; - $format = $match[7]; + $status = $match[3]; + $color = $match[5]; + $format = $match[7]; return new self($subject, $status, $color, $format); } @@ -74,7 +69,7 @@ public static function fromURI($URI) /** * @return string the Hexadecimal #FFFFFF */ - public function getHexColor() + public function getHexColor(): string { return '#' . $this->color; } @@ -82,28 +77,22 @@ public function getHexColor() /** * @return string the format of the image eg. `svg`. */ - public function getFormat() + public function getFormat(): string { return $this->format; } - /** - * @return string - */ - public function getStatus() + public function getStatus(): string { return $this->status; } - /** - * @return string - */ - public function getSubject() + public function getSubject(): string { return $this->subject; } - public function __toString() + public function __toString(): string { return \sprintf( '%s-%s-%s.%s', @@ -114,7 +103,7 @@ public function __toString() ); } - private function escapeValue($value) + private function escapeValue(string $value): string { $pattern = [ // '/([^_])_([^_])/g', // damn it global doesn't work in PHP @@ -137,12 +126,15 @@ private function escapeValue($value) return $ret; } - private function getColorHex($color) + private function getColorHex(string $color): string { return \array_key_exists($color, self::$colorScheme) ? self::$colorScheme[$color] : $color; } - private function isValidColorHex($color) + /** + * @return false|int + */ + private function isValidColorHex(string $color) { $color = \ltrim($color, '#'); $regex = '/^[0-9a-fA-F]{6}$/'; diff --git a/src/Calculator/GDTextSizeCalculator.php b/src/Calculator/GDTextSizeCalculator.php index bdaa0a2..a1fd659 100644 --- a/src/Calculator/GDTextSizeCalculator.php +++ b/src/Calculator/GDTextSizeCalculator.php @@ -13,10 +13,10 @@ class GDTextSizeCalculator implements TextSizeCalculatorInterface { - const TEXT_FONT = '/Font/DejaVuSans.ttf'; + public const TEXT_FONT = '/Font/DejaVuSans.ttf'; /** @var string */ - protected $fontPath; + protected string $fontPath; public function __construct() { @@ -25,21 +25,16 @@ public function __construct() /** * Calculate the width of the text box. - * - * @param string $text - * @param int $size - * - * @return float */ - public function calculateWidth($text, $size = self::TEXT_SIZE) + public function calculateWidth(string $text, int $size = self::TEXT_SIZE): float { $size = $this->convertToPt($size); - $box = \imagettfbbox($size, 0, $this->fontPath, $text); + $box = \imagettfbbox($size, 0, $this->fontPath, $text); return \round(\abs($box[2] - $box[0]) + self::SHIELD_PADDING_EXTERNAL + self::SHIELD_PADDING_INTERNAL, 1); } - private function convertToPt($pixels) + private function convertToPt(int $pixels): float { return \round($pixels * 0.75, 1); } diff --git a/src/Calculator/TextSizeCalculatorInterface.php b/src/Calculator/TextSizeCalculatorInterface.php index b33b8ee..1141625 100644 --- a/src/Calculator/TextSizeCalculatorInterface.php +++ b/src/Calculator/TextSizeCalculatorInterface.php @@ -13,17 +13,12 @@ interface TextSizeCalculatorInterface { - const TEXT_SIZE = 11; - const SHIELD_PADDING_EXTERNAL = 6; - const SHIELD_PADDING_INTERNAL = 4; + public const TEXT_SIZE = 11; + public const SHIELD_PADDING_EXTERNAL = 6; + public const SHIELD_PADDING_INTERNAL = 4; /** * Calculate the width of the text box. - * - * @param string $text - * @param int $size - * - * @return float */ - public function calculateWidth($text, $size = self::TEXT_SIZE); + public function calculateWidth(string $text, int $size = self::TEXT_SIZE): float; } diff --git a/src/Image.php b/src/Image.php index 95f5988..c26148b 100644 --- a/src/Image.php +++ b/src/Image.php @@ -19,50 +19,33 @@ */ class Image { - /** - * @var string - */ - private $content; - /** - * @var string - */ - private $format; + private string $content; - /** - * @param string $content - * @param string $format - */ - private function __construct($content, $format) + private string $format; + + private function __construct(string $content, string $format) { $this->content = $content; - $this->format = $format; + $this->format = $format; } /** * Returns the image content as binary string. */ - public function __toString() + public function __toString(): string { return (string) $this->content; } /** * Factory method. - * - * @param string $content - * @param string $format - * - * @return Image */ - public static function createFromString($content, $format) + public static function createFromString(string $content, string $format): self { return new self($content, $format); } - /** - * @return string - */ - public function getFormat() + public function getFormat(): string { return $this->format; } diff --git a/src/Poser.php b/src/Poser.php index 9991a59..9cb8e25 100644 --- a/src/Poser.php +++ b/src/Poser.php @@ -6,7 +6,7 @@ class Poser { - private $renders; + private array $renders; /** * Constructor. @@ -32,10 +32,8 @@ public function __construct($renders) * @param $status * @param $color * @param $format - * - * @return Image */ - public function generate($subject, $status, $color, $format) + public function generate(string $subject, string $status, string $color, string $format): Image { $badge = new Badge($subject, $status, $color, $format); @@ -47,10 +45,8 @@ public function generate($subject, $status, $color, $format) * eg license-MIT-blue.svg or I_m-liuggio-yellow.svg. * * @param $string - * - * @return Image */ - public function generateFromURI($string) + public function generateFromURI(string $string): Image { $badge = Badge::fromURI($string); @@ -59,10 +55,8 @@ public function generateFromURI($string) /** * All the formats available. - * - * @return array */ - public function validFormats() + public function validFormats(): array { return \array_keys($this->renders); } @@ -74,12 +68,7 @@ private function addFormatRender(RenderInterface $render): void } } - /** - * @param $format - * - * @return RenderInterface - */ - private function getRenderFor($format) + private function getRenderFor(string $format): RenderInterface { if (!isset($this->renders[$format])) { throw new \InvalidArgumentException(\sprintf('No render founds for this format [%s]', $format)); diff --git a/src/Render/LocalSvgRenderer.php b/src/Render/LocalSvgRenderer.php index f793381..ff3ec77 100644 --- a/src/Render/LocalSvgRenderer.php +++ b/src/Render/LocalSvgRenderer.php @@ -25,23 +25,13 @@ */ abstract class LocalSvgRenderer implements RenderInterface { - const VENDOR_COLOR = '#555'; + public const VENDOR_COLOR = '#555'; - /** - * @var TextSizeCalculatorInterface - */ - private $textSizeCalculator; + private ?TextSizeCalculatorInterface $textSizeCalculator = null; - /** - * @var string - */ - private $templatesDirectory; + private ?string $templatesDirectory = null; - /** - * @param TextSizeCalculatorInterface $textSizeCalculator - * @param string|null $templatesDirectory - */ - public function __construct(TextSizeCalculatorInterface $textSizeCalculator = null, $templatesDirectory = null) + public function __construct(?TextSizeCalculatorInterface $textSizeCalculator = null, ?string $templatesDirectory = null) { $this->textSizeCalculator = $textSizeCalculator; if (null === $this->textSizeCalculator) { @@ -54,28 +44,20 @@ public function __construct(TextSizeCalculatorInterface $textSizeCalculator = nu } } - /** - * @return mixed - */ - public function render(Badge $badge) + public function render(Badge $badge): Image { - $template = $this->getTemplate($this->getTemplateName()); + $template = $this->getTemplate($this->getTemplateName()); $parameters = $this->buildParameters($badge); return $this->renderSvg($template, $parameters, $badge->getFormat()); } - /** - * @return string - */ - abstract protected function getTemplateName(); + abstract protected function getTemplateName(): string; /** - * @param $format - * * @return string SVG content of the template */ - private function getTemplate($format) + private function getTemplate(string $format): string { $filepath = \sprintf('%s/%s.svg', $this->templatesDirectory, $format); @@ -86,24 +68,12 @@ private function getTemplate($format) return \file_get_contents($filepath); } - /** - * @param $text - * - * @return float - */ - private function stringWidth($text) + private function stringWidth(string $text): float { return $this->textSizeCalculator->calculateWidth($text); } - /** - * @param string $render - * @param array $parameters - * @param string $format - * - * @return Image - */ - private function renderSvg($render, $parameters, $format) + private function renderSvg(string $render, array $parameters, string $format): Image { foreach ($parameters as $key => $variable) { $render = \str_replace(\sprintf('{{ %s }}', $key), $variable, $render); @@ -121,22 +91,19 @@ private function renderSvg($render, $parameters, $format) return Image::createFromString($render, $format); } - /** - * @return array - */ - private function buildParameters(Badge $badge) + private function buildParameters(Badge $badge): array { $parameters = []; - $parameters['vendorWidth'] = $this->stringWidth($badge->getSubject()); - $parameters['valueWidth'] = $this->stringWidth($badge->getStatus()); - $parameters['totalWidth'] = $parameters['valueWidth'] + $parameters['vendorWidth']; - $parameters['vendorColor'] = static::VENDOR_COLOR; - $parameters['valueColor'] = $badge->getHexColor(); - $parameters['vendor'] = $badge->getSubject(); - $parameters['value'] = $badge->getStatus(); + $parameters['vendorWidth'] = $this->stringWidth($badge->getSubject()); + $parameters['valueWidth'] = $this->stringWidth($badge->getStatus()); + $parameters['totalWidth'] = $parameters['valueWidth'] + $parameters['vendorWidth']; + $parameters['vendorColor'] = static::VENDOR_COLOR; + $parameters['valueColor'] = $badge->getHexColor(); + $parameters['vendor'] = $badge->getSubject(); + $parameters['value'] = $badge->getStatus(); $parameters['vendorStartPosition'] = \round($parameters['vendorWidth'] / 2, 1) + 1; - $parameters['valueStartPosition'] = $parameters['vendorWidth'] + \round($parameters['valueWidth'] / 2, 1) - 1; + $parameters['valueStartPosition'] = $parameters['vendorWidth'] + \round($parameters['valueWidth'] / 2, 1) - 1; return $parameters; } diff --git a/src/Render/RenderInterface.php b/src/Render/RenderInterface.php index d879f22..a0b5e20 100644 --- a/src/Render/RenderInterface.php +++ b/src/Render/RenderInterface.php @@ -12,18 +12,17 @@ namespace PUGX\Poser\Render; use PUGX\Poser\Badge; +use PUGX\Poser\Image; interface RenderInterface { /** - * Render a badge. - * - * @return \PUGX\Poser\Image + * Render a badge */ - public function render(Badge $badge); + public function render(Badge $badge): Image; /** * @return array the list of the supported format eg array('svg') */ - public function supportedFormats(); + public function supportedFormats(): array; } diff --git a/src/Render/SvgFlatRender.php b/src/Render/SvgFlatRender.php index 58a5752..3119138 100644 --- a/src/Render/SvgFlatRender.php +++ b/src/Render/SvgFlatRender.php @@ -21,14 +21,14 @@ class SvgFlatRender extends LocalSvgRenderer /** * A list of all supported formats. * - * @return array + * @return array|string[] */ - public function supportedFormats() + public function supportedFormats(): array { return ['flat', 'svg']; } - protected function getTemplateName() + protected function getTemplateName(): string { return 'flat'; } diff --git a/src/Render/SvgFlatSquareRender.php b/src/Render/SvgFlatSquareRender.php index b60940d..7531bfb 100644 --- a/src/Render/SvgFlatSquareRender.php +++ b/src/Render/SvgFlatSquareRender.php @@ -21,14 +21,14 @@ class SvgFlatSquareRender extends LocalSvgRenderer /** * A list of all supported formats. * - * @return array + * @return array|string[] */ - public function supportedFormats() + public function supportedFormats(): array { return ['flat-square']; } - protected function getTemplateName() + protected function getTemplateName(): string { return 'flat-square'; } diff --git a/src/Render/SvgRender.php b/src/Render/SvgRender.php index 89ed1e5..6b72169 100644 --- a/src/Render/SvgRender.php +++ b/src/Render/SvgRender.php @@ -22,14 +22,14 @@ class SvgRender extends LocalSvgRenderer /** * A list of all supported formats. * - * @return array + * @return array|string[] */ - public function supportedFormats() + public function supportedFormats(): array { return ['plastic']; } - protected function getTemplateName() + protected function getTemplateName(): string { return 'plastic'; } diff --git a/src/UI/Command.php b/src/UI/Command.php index 9691a43..57f7be6 100644 --- a/src/UI/Command.php +++ b/src/UI/Command.php @@ -15,7 +15,7 @@ class Command extends BaseCommand { - const HEADER = " ________________ + public const HEADER = " ________________ |_ _ _| _ _ _ _ _ _ _ | |_)(_|(_|(_|(/_ |_)(_)_\(/_| | _| _|______________| @@ -23,14 +23,11 @@ class Command extends BaseCommand http://poser.pug.org "; - /** @var Poser */ - private $poser; + private Poser $poser; - /** @var string */ - protected $format; + protected string $format; - /** @var string */ - protected $header; + protected string $header; private function init(): void { @@ -79,14 +76,17 @@ protected function configure(): void ); } - protected function execute(InputInterface $input, OutputInterface $output) + /** + * @throws \Exception + */ + protected function execute(InputInterface $input, OutputInterface $output): int { $subject = $input->getArgument('subject'); - $status = $input->getArgument('status'); - $color = $input->getArgument('color'); + $status = $input->getArgument('status'); + $color = $input->getArgument('color'); if ($input->getOption('format')) { - $this->format = $input->getOption('format'); + $this->format = (string) $input->getOption('format'); } try { @@ -105,13 +105,16 @@ protected function execute(InputInterface $input, OutputInterface $output) return 0; } - protected function flushImage(OutputInterface $output, $imageContent): void + protected function flushImage(OutputInterface $output, string $imageContent): void { - $output->write((string) $imageContent); + $output->write($imageContent); $this->header = ''; } - protected function storeImage(OutputInterface $output, $path, $imageContent): void + /** + * @throws \Exception + */ + protected function storeImage(OutputInterface $output, string $path, string $imageContent): void { $this->printHeaderOnce($output); try { diff --git a/src/UI/SingleCommandApplication.php b/src/UI/SingleCommandApplication.php index 5ef1b11..2fca0aa 100644 --- a/src/UI/SingleCommandApplication.php +++ b/src/UI/SingleCommandApplication.php @@ -27,10 +27,8 @@ class SingleCommandApplication extends Application { /** * Name of the single accessible command of this application. - * - * @var string */ - private $commandName; + private ?string $commandName = null; /** * Constructor to build a "single command" application, given a command. @@ -40,13 +38,13 @@ class SingleCommandApplication extends Application * @param Command $command The single (accessible) command for this application * @param string $version The version of the application */ - public function __construct(Command $command, $version = 'UNKNOWN') + public function __construct(Command $command, string $version = 'UNKNOWN') { parent::__construct($command->getName(), $version); // Add the given command as single (accessible) command. $this->add($command); - $this->commandName = $command->getName(); + $this->commandName = (string) $command->getName(); // Override the Application's definition so that it does not // require a command name as first argument. @@ -56,7 +54,7 @@ public function __construct(Command $command, $version = 'UNKNOWN') /** * {@inheritdoc} */ - protected function getCommandName(InputInterface $input) + protected function getCommandName(InputInterface $input): ?string { return $this->commandName; } @@ -76,7 +74,7 @@ protected function getCommandName(InputInterface $input) * * @throws \LogicException */ - public function add(Command $command) + public function add(Command $command): ?Command { // Fail if we already set up the single accessible command. if ($this->commandName) { From 709a438685bf7967cf9b8a9e4d83da4f62b3dc7c Mon Sep 17 00:00:00 2001 From: Andrea Giannantonio Date: Thu, 11 Jun 2020 18:15:20 +0200 Subject: [PATCH 07/20] Update readme --- CONTRIBUTING.md | 56 ++++++++++++++++++++++++++++++++ README.md | 85 ++++++++++++++++--------------------------------- composer.json | 2 +- 3 files changed, 84 insertions(+), 59 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..f816beb --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,56 @@ +# Contributing + +Active contribution and patches are very welcome. +See the [github issues](https://github.com/badges/poser/issues?state=open). +To keep things in shape we have quite a bunch of examples and features. If you're submitting pull requests please +make sure that they are still passing and if you add functionality please +take a look at the coverage as well it should be pretty high :) + +- First fork or clone the repository + +```bash +git clone git://github.com/badges/poser.git +cd poser +``` + +- Install vendors: + +```bash +composer install +``` + +- Run specs: + +```bash +composer phpspec +``` + +- Then run behat: + +```bash +composer behat +``` + + +## Using Docker + +```bash +docker-compose up --build -d +docker-compose exec fpm composer install +docker-compose exec fpm composer phpspec +docker-compose exec fpm composer behat +``` + + +## Pull Request + +Please before to push a PR execute php-cs-fixer for the code check-style and run all tests + +```bash +$ composer php-cs-fixer +$ composer phpspec +$ composer behat +``` + + +## ENJOY diff --git a/README.md b/README.md index e890a71..a862ca4 100644 --- a/README.md +++ b/README.md @@ -6,19 +6,21 @@ according to [Shields specification](https://github.com/badges/shields#specifica This library is used by https://poser.pugx.org [![Latest Stable Version](https://poser.pugx.org/badges/poser/version.svg)](https://packagist.org/packages/badges/poser) [![Latest Unstable Version](https://poser.pugx.org/badges/poser/v/unstable.svg)](//packagist.org/packages/badges/poser) [![Total Downloads](https://poser.pugx.org/badges/poser/downloads.svg)](https://packagist.org/packages/badges/poser) -[![Build Status](https://travis-ci.org/badges/poser.svg?branch=master)](https://travis-ci.org/badges/poser) +[![CircleCI Build](https://poser.pugx.org/badges/poser/circleci)](//packagist.org/packages/badges/poser) ## Dependencies -* PHP 5.3 or higher +* PHP 7.4 or higher * GD extension +to use the library with lower php version use the tag [v1.4](https://github.com/badges/poser/tree/v1.4.0) + ## Use as command #### 1. Create a project ``` bash -$ composer create-project badges/poser ~1.2 +$ composer create-project badges/poser $ ln -s poser/bin/poser /usr/local/bin/poser ``` @@ -34,28 +36,31 @@ Flush an image ## Usage as library -#### 1. Add to composer +#### 1. Add to composer dependencies -`composer require badges/poser ~1.2` +`$ composer require badges/poser` #### 2. Use in your project as lib -``` php - use PUGX\Poser\Render\SvgRender; - use PUGX\Poser\Poser; +```php +use PUGX\Poser\Render\SvgRender; +use PUGX\Poser\Poser; - $render = new SvgRender(); - $poser = new Poser(array($render)); +$render = new SvgRender(); +$poser = new Poser($render); - echo $poser->generate('license', 'MIT', '428F7E', 'plastic'); - // or - echo $poser->generateFromURI('license-MIT-428F7E.plastic'); - // or - $image = $poser->generate('license', 'MIT', '428F7E', 'plastic'); +echo $poser->generate('license', 'MIT', '428F7E', 'plastic'); +// or +echo $poser->generateFromURI('license-MIT-428F7E.plastic'); +// or +$image = $poser->generate('license', 'MIT', '428F7E', 'plastic'); - echo $image->getFormat(); +echo $image->getFormat(); ``` +The allowed format are: `plastic`, `flat` and `flat-square`. + + ## Encoding Dashes `--` → `-` Dash @@ -64,59 +69,23 @@ Underscores `__` → `_` Underscore `_` or Space → Space + ## More For *more info* please see the [behat features](./features/) and the examples in the [php-spec folder](./spec/) -## Contribution - -Active contribution and patches are very welcome. -See the [github issues](https://github.com/PUGX/poser/issues?state=open). -To keep things in shape we have quite a bunch of examples and features. If you're submitting pull requests please -make sure that they are still passing and if you add functionality please -take a look at the coverage as well it should be pretty high :) -- First fork or clone the repository +## Why a composer badge? -``` -git clone git://github.com/badges/poser.git -cd poser -``` - -- Install vendors: - -``` bash -composer install -``` +Not only because all the other languages already have it, but having the latest stable release in the readme could save time. -- Run specs: -``` bash -./bin/phpspec run --format=pretty -``` - -- Then run behat: - -``` bash -./bin/behat -``` - -## Using Docker - -We provide a `docker-compose.yml.dist` file to allow you to run tests in a Docker container. - -```bash -cp docker-compose.yml.dist docker-compose.yml -docker-compose up -d -docker-compose exec fpm composer install -docker-compose exec fpm composer phpspec -docker-compose exec fpm composer behat -``` +## Contributing -The provided Docker compose file is for a PHP 7.1 environment, but you can modifiy it to use PHP 5.6. +Active contribution and patches are very welcome. +Please refer to [CONTRIBUTING](CONTRIBUTING.md) -See https://store.docker.com/community/images/jmleroux/fpm/tags ## License diff --git a/composer.json b/composer.json index d3003d4..a15c6ee 100644 --- a/composer.json +++ b/composer.json @@ -54,7 +54,7 @@ }, "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "dev-master": "2.x-dev" } } } From bcf2aedc6ef73711028ffc6d8c47f3db16682618 Mon Sep 17 00:00:00 2001 From: antonkomarev Date: Tue, 21 Jul 2020 17:04:19 +0300 Subject: [PATCH 08/20] Rename SvgRender to SvgPlasticRender --- README.md | 4 ++-- .../Render/{SvgRenderSpec.php => SvgPlasticRenderSpec.php} | 2 +- src/Render/{SvgRender.php => SvgPlasticRender.php} | 4 ++-- src/UI/Command.php | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) rename spec/PUGX/Poser/Render/{SvgRenderSpec.php => SvgPlasticRenderSpec.php} (97%) rename src/Render/{SvgRender.php => SvgPlasticRender.php} (89%) diff --git a/README.md b/README.md index a862ca4..8cc2ec3 100644 --- a/README.md +++ b/README.md @@ -43,10 +43,10 @@ Flush an image #### 2. Use in your project as lib ```php -use PUGX\Poser\Render\SvgRender; +use PUGX\Poser\Render\SvgPlasticRender; use PUGX\Poser\Poser; -$render = new SvgRender(); +$render = new SvgPlasticRender(); $poser = new Poser($render); echo $poser->generate('license', 'MIT', '428F7E', 'plastic'); diff --git a/spec/PUGX/Poser/Render/SvgRenderSpec.php b/spec/PUGX/Poser/Render/SvgPlasticRenderSpec.php similarity index 97% rename from spec/PUGX/Poser/Render/SvgRenderSpec.php rename to spec/PUGX/Poser/Render/SvgPlasticRenderSpec.php index ad9f1ff..76747da 100644 --- a/spec/PUGX/Poser/Render/SvgRenderSpec.php +++ b/spec/PUGX/Poser/Render/SvgPlasticRenderSpec.php @@ -6,7 +6,7 @@ use Prophecy\Argument; use PUGX\Poser\Badge; -class SvgRenderSpec extends ObjectBehavior +class SvgPlasticRenderSpec extends ObjectBehavior { public function let($calculator): void { diff --git a/src/Render/SvgRender.php b/src/Render/SvgPlasticRender.php similarity index 89% rename from src/Render/SvgRender.php rename to src/Render/SvgPlasticRender.php index 6b72169..5530c4f 100644 --- a/src/Render/SvgRender.php +++ b/src/Render/SvgPlasticRender.php @@ -12,12 +12,12 @@ namespace PUGX\Poser\Render; /** - * Class SvgGenerator. + * Class SvgPlasticGenerator. * * @author Claudio D'Alicandro * @author Giulio De Donato */ -class SvgRender extends LocalSvgRenderer +class SvgPlasticRender extends LocalSvgRenderer { /** * A list of all supported formats. diff --git a/src/UI/Command.php b/src/UI/Command.php index 57f7be6..4b6a5fa 100644 --- a/src/UI/Command.php +++ b/src/UI/Command.php @@ -6,7 +6,7 @@ use PUGX\Poser\Poser; use PUGX\Poser\Render\SvgFlatRender; use PUGX\Poser\Render\SvgFlatSquareRender; -use PUGX\Poser\Render\SvgRender; +use PUGX\Poser\Render\SvgPlasticRender; use Symfony\Component\Console\Command\Command as BaseCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -32,7 +32,7 @@ class Command extends BaseCommand private function init(): void { $this->poser = new Poser([ - new SvgRender(), + new SvgPlasticRender(), new SvgFlatRender(), new SvgFlatSquareRender(), ]); From 6726d6d04fb45f9edfdb9fd6f035bf8560275ffc Mon Sep 17 00:00:00 2001 From: antonkomarev Date: Tue, 21 Jul 2020 23:49:12 +0300 Subject: [PATCH 09/20] Use class notation in tests --- spec/PUGX/Poser/BadgeSpec.php | 2 +- spec/PUGX/Poser/PoserSpec.php | 3 ++- spec/PUGX/Poser/Render/SvgFlatRenderSpec.php | 3 ++- spec/PUGX/Poser/Render/SvgFlatSquareRenderSpec.php | 3 ++- spec/PUGX/Poser/Render/SvgPlasticRenderSpec.php | 3 ++- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/spec/PUGX/Poser/BadgeSpec.php b/spec/PUGX/Poser/BadgeSpec.php index ffa3ceb..da2fcee 100644 --- a/spec/PUGX/Poser/BadgeSpec.php +++ b/spec/PUGX/Poser/BadgeSpec.php @@ -11,7 +11,7 @@ class BadgeSpec extends ObjectBehavior public function it_is_initializable(): void { $this->beConstructedWith('a', 'b', '97CA00', 'svg'); - $this->shouldHaveType('Pugx\Poser\Badge'); + $this->shouldHaveType(Badge::class); } public function it_should_be_constructed_by_fromURI_factory_method(): void diff --git a/spec/PUGX/Poser/PoserSpec.php b/spec/PUGX/Poser/PoserSpec.php index de73396..d207797 100644 --- a/spec/PUGX/Poser/PoserSpec.php +++ b/spec/PUGX/Poser/PoserSpec.php @@ -3,6 +3,7 @@ namespace spec\PUGX\Poser; use PhpSpec\ObjectBehavior; +use PUGX\Poser\Poser; use PUGX\Poser\Render\SvgFlatRender; class PoserSpec extends ObjectBehavior @@ -15,7 +16,7 @@ public function let(): void public function it_is_initializable(): void { - $this->shouldHaveType('PUGX\Poser\Poser'); + $this->shouldHaveType(Poser::class); } public function it_should_be_able_to_generate_an_svg_image(): void diff --git a/spec/PUGX/Poser/Render/SvgFlatRenderSpec.php b/spec/PUGX/Poser/Render/SvgFlatRenderSpec.php index 183f339..d3460bf 100644 --- a/spec/PUGX/Poser/Render/SvgFlatRenderSpec.php +++ b/spec/PUGX/Poser/Render/SvgFlatRenderSpec.php @@ -5,12 +5,13 @@ use PhpSpec\ObjectBehavior; use Prophecy\Argument; use PUGX\Poser\Badge; +use PUGX\Poser\Calculator\TextSizeCalculatorInterface; class SvgFlatRenderSpec extends ObjectBehavior { public function let($calculator): void { - $calculator->beADoubleOf('\PUGX\Poser\Calculator\TextSizeCalculatorInterface'); + $calculator->beADoubleOf(TextSizeCalculatorInterface::class); $calculator->calculateWidth(Argument::any())->willReturn(20); $this->beConstructedWith($calculator); } diff --git a/spec/PUGX/Poser/Render/SvgFlatSquareRenderSpec.php b/spec/PUGX/Poser/Render/SvgFlatSquareRenderSpec.php index 7cdbbe8..a141505 100644 --- a/spec/PUGX/Poser/Render/SvgFlatSquareRenderSpec.php +++ b/spec/PUGX/Poser/Render/SvgFlatSquareRenderSpec.php @@ -5,12 +5,13 @@ use PhpSpec\ObjectBehavior; use Prophecy\Argument; use PUGX\Poser\Badge; +use PUGX\Poser\Calculator\TextSizeCalculatorInterface; class SvgFlatSquareRenderSpec extends ObjectBehavior { public function let($calculator): void { - $calculator->beADoubleOf('\PUGX\Poser\Calculator\TextSizeCalculatorInterface'); + $calculator->beADoubleOf(TextSizeCalculatorInterface::class); $calculator->calculateWidth(Argument::any())->willReturn(20); $this->beConstructedWith($calculator); } diff --git a/spec/PUGX/Poser/Render/SvgPlasticRenderSpec.php b/spec/PUGX/Poser/Render/SvgPlasticRenderSpec.php index 76747da..9285b3f 100644 --- a/spec/PUGX/Poser/Render/SvgPlasticRenderSpec.php +++ b/spec/PUGX/Poser/Render/SvgPlasticRenderSpec.php @@ -5,12 +5,13 @@ use PhpSpec\ObjectBehavior; use Prophecy\Argument; use PUGX\Poser\Badge; +use PUGX\Poser\Calculator\TextSizeCalculatorInterface; class SvgPlasticRenderSpec extends ObjectBehavior { public function let($calculator): void { - $calculator->beADoubleOf('\PUGX\Poser\Calculator\TextSizeCalculatorInterface'); + $calculator->beADoubleOf(TextSizeCalculatorInterface::class); $calculator->calculateWidth(Argument::any())->willReturn(20); $this->beConstructedWith($calculator); } From babb04241c2d070e37033c2f77412961d6cc5976 Mon Sep 17 00:00:00 2001 From: antonkomarev Date: Tue, 21 Jul 2020 23:50:41 +0300 Subject: [PATCH 10/20] Fix dev autoloader --- composer.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/composer.json b/composer.json index a15c6ee..fbbb284 100644 --- a/composer.json +++ b/composer.json @@ -22,6 +22,9 @@ "autoload": { "psr-4": { "PUGX\\Poser\\": "src/" } }, + "autoload-dev": { + "psr-4": { "spec\\PUGX\\": "spec/PUGX/" } + }, "repositories": [ { "type": "vcs", From 6087778344cc6a6ac36ac92c6850d8fe9833983a Mon Sep 17 00:00:00 2001 From: antonkomarev Date: Wed, 22 Jul 2020 00:00:41 +0300 Subject: [PATCH 11/20] Remove var_dump from tests --- spec/PUGX/Poser/BadgeSpec.php | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/PUGX/Poser/BadgeSpec.php b/spec/PUGX/Poser/BadgeSpec.php index ffa3ceb..013fc91 100644 --- a/spec/PUGX/Poser/BadgeSpec.php +++ b/spec/PUGX/Poser/BadgeSpec.php @@ -66,7 +66,6 @@ public function it_should_be_constructed_by_fromURI_factory_method_escaping_corr */ public function it_should_validate_available_color_schemes($colorName, $expectedValue): void { - \var_dump($colorName); $this->beConstructedWith('a', 'b', $colorName, 'svg'); $this->getHexColor()->shouldBeString(); } From aabb3c2c65cf8100f98b1b60ae863b402257d29c Mon Sep 17 00:00:00 2001 From: Andrea Giannantonio Date: Wed, 22 Jul 2020 15:44:16 +0200 Subject: [PATCH 12/20] feat(chnagelog): add changelog file --- CHANGELOG.md | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..83b119e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,101 @@ +# CHANGELOG + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + + +## [Unreleased] + +### Added +* add CircleCI for build and tests +* add changelog +* configure and run php-cs-fixer with new code style roles + +### Changed +* upgrade docker-compose for dev environment with php7.4 +* refactoring of code to work on php7.4 and drop unsupported deps +* refactoring library to full typed +* upgrade readme +* use class notation in tests + +### Deprecated +* this version works only with php version >= 7.4 +* rename SvgRender class to SvgPlasticRender to match the same naming pattern with other render classes + +### Removed +* travis configuration for the CI + +### Fixed +* fixup phpspec data provider +* fix dev autoloader +* remove var_dump from tests + +### Security + + +## [v1.4.1] - 2020-06-11 + +### Fixed +* fixed branch-alias in composer.json + + +## [v1.4.0] - 2020-06-04 + +### Changed +* Freeze docker-composer version to php7.1 + +### Fixed +* fixed security alert for symfony/dependency-injection package + + +## [v1.3.0] - 2019-01-03 + +### Added +* allow symfony 4 compatibility + +### Changed +* put test dependency under require-dev + + +## [v1.2.2] - 2016-03-29 + +### Changed +* extract SVG templates from renderer classes + +### Fixed +* small fixes + + +## [1.2.1] - 2016-03-16 + +### Changed +* clean code and add scrutinizer integration + + +## [v1.2.0] - 2016-03-16 + +### Added +* flat-square format + + +## [v1.1] - 2015-04-20 + +### Added +* flat version die to plastic one (added flat format) + + +## [v1.0] - 2015-01-13 +- stable release for poser + + +[unreleased]: https://github.com/badges/poser/compare/v1.4.1...HEAD +[v1.4.1]: https://github.com/badges/poser/tree/v1.4.1 +[v1.4.0]: https://github.com/badges/poser/tree/v1.4.0 +[v1.3.0]: https://github.com/badges/poser/tree/v1.3.0 +[v1.2.2]: https://github.com/badges/poser/tree/v1.2.2 +[1.2.1]: https://github.com/badges/poser/releases/tag/1.2.1 +[v1.2.0]: https://github.com/badges/poser/releases/tag/v1.2.0 +[v1.1]: https://github.com/badges/poser/releases/tag/v1.1 +[v1.0]: https://github.com/badges/poser/releases/tag/v1.0 From 604a080e3b2ecb433c40ae1f4326eca8f2cd0148 Mon Sep 17 00:00:00 2001 From: Alessandro Minoccheri Date: Thu, 23 Jul 2020 10:33:52 +0200 Subject: [PATCH 13/20] added first init of psalm --- bin/php-parse | 1 + bin/psalm | 1 + bin/psalm-language-server | 1 + bin/psalm-plugin | 1 + bin/psalm-refactor | 1 + bin/psalter | 1 + composer.json | 3 ++- psalm.xml | 15 +++++++++++++++ 8 files changed, 23 insertions(+), 1 deletion(-) create mode 120000 bin/php-parse create mode 120000 bin/psalm create mode 120000 bin/psalm-language-server create mode 120000 bin/psalm-plugin create mode 120000 bin/psalm-refactor create mode 120000 bin/psalter create mode 100644 psalm.xml diff --git a/bin/php-parse b/bin/php-parse new file mode 120000 index 0000000..726f634 --- /dev/null +++ b/bin/php-parse @@ -0,0 +1 @@ +../vendor/nikic/php-parser/bin/php-parse \ No newline at end of file diff --git a/bin/psalm b/bin/psalm new file mode 120000 index 0000000..406781e --- /dev/null +++ b/bin/psalm @@ -0,0 +1 @@ +../vendor/vimeo/psalm/psalm \ No newline at end of file diff --git a/bin/psalm-language-server b/bin/psalm-language-server new file mode 120000 index 0000000..8b84ab4 --- /dev/null +++ b/bin/psalm-language-server @@ -0,0 +1 @@ +../vendor/vimeo/psalm/psalm-language-server \ No newline at end of file diff --git a/bin/psalm-plugin b/bin/psalm-plugin new file mode 120000 index 0000000..6f35d7f --- /dev/null +++ b/bin/psalm-plugin @@ -0,0 +1 @@ +../vendor/vimeo/psalm/psalm-plugin \ No newline at end of file diff --git a/bin/psalm-refactor b/bin/psalm-refactor new file mode 120000 index 0000000..4c2b2a3 --- /dev/null +++ b/bin/psalm-refactor @@ -0,0 +1 @@ +../vendor/vimeo/psalm/psalm-refactor \ No newline at end of file diff --git a/bin/psalter b/bin/psalter new file mode 120000 index 0000000..f30a7fb --- /dev/null +++ b/bin/psalter @@ -0,0 +1 @@ +../vendor/vimeo/psalm/psalter \ No newline at end of file diff --git a/composer.json b/composer.json index fbbb284..814da26 100644 --- a/composer.json +++ b/composer.json @@ -42,7 +42,8 @@ "behat/behat": "^3.7", "friendsofphp/php-cs-fixer": "^2.16", "moave/phpspec-data-provider-extension": "dev-master", - "friends-of-phpspec/phpspec-code-coverage": "^4.3" + "friends-of-phpspec/phpspec-code-coverage": "^4.3", + "vimeo/psalm": "^3.12" }, "config": { "bin-dir": "bin" diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..f8edfd3 --- /dev/null +++ b/psalm.xml @@ -0,0 +1,15 @@ + + + + + + + + + From 222eb43ea0a55c1a9c16ec95d7d0eef9b146fd08 Mon Sep 17 00:00:00 2001 From: Alessandro Minoccheri Date: Thu, 23 Jul 2020 11:10:56 +0200 Subject: [PATCH 14/20] added spec and features dir to psalm and fix an error --- features/bootstrap/FeatureContext.php | 1 + psalm.xml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 763af55..0f2fc9d 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -9,6 +9,7 @@ class FeatureContext implements SnippetAcceptingContext { private string $binFolder; private string $output; + private int $return; /** * Initializes context. diff --git a/psalm.xml b/psalm.xml index f8edfd3..12fd1f2 100644 --- a/psalm.xml +++ b/psalm.xml @@ -8,6 +8,8 @@ > + + From b833da9f4152bcc1b943aa7625c124f67a82d550 Mon Sep 17 00:00:00 2001 From: Alessandro Minoccheri Date: Thu, 23 Jul 2020 14:25:49 +0200 Subject: [PATCH 15/20] added psalm to changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 83b119e..39dd3ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. * add CircleCI for build and tests * add changelog * configure and run php-cs-fixer with new code style roles +* add psalm ### Changed * upgrade docker-compose for dev environment with php7.4 From 127b0001e664f92cc649d0d71472dc26bcb80cf0 Mon Sep 17 00:00:00 2001 From: Andrea Giannantonio Date: Thu, 23 Jul 2020 17:29:55 +0200 Subject: [PATCH 16/20] Add github templates and sponsors --- .github/FUNDING.yml | 2 ++ .github/ISSUE_TEMPLATE/BC_Break.md | 34 ++++++++++++++++++++ .github/ISSUE_TEMPLATE/Bug.md | 34 ++++++++++++++++++++ .github/ISSUE_TEMPLATE/Feature_Request.md | 19 +++++++++++ .github/ISSUE_TEMPLATE/Support_Question.md | 22 +++++++++++++ .github/PULL_REQUEST_TEMPLATE/Improvement.md | 19 +++++++++++ .github/PULL_REQUEST_TEMPLATE/New_Feature.md | 24 ++++++++++++++ 7 files changed, 154 insertions(+) create mode 100644 .github/FUNDING.yml create mode 100644 .github/ISSUE_TEMPLATE/BC_Break.md create mode 100644 .github/ISSUE_TEMPLATE/Bug.md create mode 100644 .github/ISSUE_TEMPLATE/Feature_Request.md create mode 100644 .github/ISSUE_TEMPLATE/Support_Question.md create mode 100644 .github/PULL_REQUEST_TEMPLATE/Improvement.md create mode 100644 .github/PULL_REQUEST_TEMPLATE/New_Feature.md diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..7b3a741 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +custom: "https://paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=ETT4JRJARLTSC" +github: [JellyBellyDev, AlessandroMinoccheri] diff --git a/.github/ISSUE_TEMPLATE/BC_Break.md b/.github/ISSUE_TEMPLATE/BC_Break.md new file mode 100644 index 0000000..bd89906 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/BC_Break.md @@ -0,0 +1,34 @@ +--- +name: 💥 BC Break +about: Have you encountered an issue during upgrade? 💣 +--- + +### BC Break Report + + + +| Q | A +|------------ | ------ +| BC Break | yes +| Version | x.y.z + +#### Summary + + + +#### Previous behavior + + + +#### Current behavior + + + +#### How to reproduce + + + diff --git a/.github/ISSUE_TEMPLATE/Bug.md b/.github/ISSUE_TEMPLATE/Bug.md new file mode 100644 index 0000000..8f2b9cd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Bug.md @@ -0,0 +1,34 @@ +--- +name: 🐞 Bug Report +about: Something is broken? 🔨 +--- + +### Bug Report + + + +| Q | A +|---------------- | ------ +| BC Break | yes/no +| Library Version | x.y.z +| PHP version | x.y.z + +#### Summary + + + +#### Current behavior + + + +#### How to reproduce + + + +#### Expected behavior + + diff --git a/.github/ISSUE_TEMPLATE/Feature_Request.md b/.github/ISSUE_TEMPLATE/Feature_Request.md new file mode 100644 index 0000000..b30d4e6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Feature_Request.md @@ -0,0 +1,19 @@ +--- +name: 🎉 Feature Request +about: You have a neat idea that should be implemented? 🎩 +--- + +### Feature Request + + + +| Q | A +|------------ | ------ +| New Feature | yes +| RFC | yes/no +| BC Break | yes/no + +#### Summary + + + diff --git a/.github/ISSUE_TEMPLATE/Support_Question.md b/.github/ISSUE_TEMPLATE/Support_Question.md new file mode 100644 index 0000000..94207fb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Support_Question.md @@ -0,0 +1,22 @@ +--- +name: ❓ Support Question +about: Have a problem that you can't figure out? 🤔 +--- + + + +| Q | A +|---------------- | ------ +| Library version | x.y.z +| PHP version | x.y.z + + + + +### Support Question + + diff --git a/.github/PULL_REQUEST_TEMPLATE/Improvement.md b/.github/PULL_REQUEST_TEMPLATE/Improvement.md new file mode 100644 index 0000000..75371ba --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/Improvement.md @@ -0,0 +1,19 @@ +--- +name: ⚙ Improvement +about: You have some improvement to make badge-poser better? 🎁 +--- + +### Improvement + + + +| Q | A +|------------ | ------ +| New Feature | yes +| RFC | yes/no +| BC Break | yes/no +| Issue | Close #... + +#### Summary + + diff --git a/.github/PULL_REQUEST_TEMPLATE/New_Feature.md b/.github/PULL_REQUEST_TEMPLATE/New_Feature.md new file mode 100644 index 0000000..a096114 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/New_Feature.md @@ -0,0 +1,24 @@ +--- +name: 🎉 New Feature +about: You have implemented some neat idea that you want to make part of badge-poser? 🎩 +--- + + + +### New Feature + + + +| Q | A +|------------ | ------ +| New Feature | yes +| RFC | yes/no +| BC Break | yes/no +| Issue | Close #... + +#### Summary + + + From 75665a8fde9cbef1dbde0bafe682c68d8f11b49f Mon Sep 17 00:00:00 2001 From: Anton Komarev <1849174+antonkomarev@users.noreply.github.com> Date: Tue, 28 Jul 2020 13:52:54 +0300 Subject: [PATCH 17/20] [2.x] Extract badge style from file format (#46) * Extract badge style from file format * Make file extension optional * Add ability to get custom style from query string --- CHANGELOG.md | 2 + README.md | 8 +-- .../ui_command_creating_image_file.feature | 2 +- features/ui_command_echo_image.feature | 2 +- spec/PUGX/Poser/BadgeSpec.php | 12 ++--- spec/PUGX/Poser/PoserSpec.php | 52 +++++++++++++++++-- src/Badge.php | 29 ++++++++--- src/Image.php | 14 ++--- src/Poser.php | 31 ++++++----- src/Render/LocalSvgRenderer.php | 12 ++--- src/Render/RenderInterface.php | 4 +- src/Render/SvgFlatRender.php | 13 ++--- src/Render/SvgFlatSquareRender.php | 13 ++--- src/Render/SvgPlasticRender.php | 13 ++--- src/UI/Command.php | 21 ++++---- 15 files changed, 140 insertions(+), 88 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39dd3ac..c0121de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. * add CircleCI for build and tests * add changelog * configure and run php-cs-fixer with new code style roles +* add setting custom badge style from query string * add psalm ### Changed @@ -20,6 +21,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. * refactoring library to full typed * upgrade readme * use class notation in tests +* badge style separated from file format ### Deprecated * this version works only with php version >= 7.4 diff --git a/README.md b/README.md index 8cc2ec3..66c41a9 100644 --- a/README.md +++ b/README.md @@ -51,14 +51,16 @@ $poser = new Poser($render); echo $poser->generate('license', 'MIT', '428F7E', 'plastic'); // or -echo $poser->generateFromURI('license-MIT-428F7E.plastic'); +echo $poser->generateFromURI('license-MIT-428F7E.svg?style=plastic'); +// or +echo $poser->generateFromURI('license-MIT-428F7E?style=plastic'); // or $image = $poser->generate('license', 'MIT', '428F7E', 'plastic'); -echo $image->getFormat(); +echo $image->getStyle(); ``` -The allowed format are: `plastic`, `flat` and `flat-square`. +The allowed styles are: `plastic`, `flat` and `flat-square`. ## Encoding diff --git a/features/ui_command_creating_image_file.feature b/features/ui_command_creating_image_file.feature index e7a385e..8b70c08 100644 --- a/features/ui_command_creating_image_file.feature +++ b/features/ui_command_creating_image_file.feature @@ -5,7 +5,7 @@ Feature: Generation of an image I want to use the poser script Scenario: Create the image running a script with plastic format - When I run "poser license MIT blue -p /tmp/img.svg -f plastic" + When I run "poser license MIT blue -p /tmp/img.svg -s plastic" Then it should pass And the content of "/tmp/img.svg" should be equal to "bootstrap/fixtures/license-MIT-blue_plastic.svg" diff --git a/features/ui_command_echo_image.feature b/features/ui_command_echo_image.feature index 4a093aa..4434775 100644 --- a/features/ui_command_echo_image.feature +++ b/features/ui_command_echo_image.feature @@ -5,7 +5,7 @@ Feature: Generation of an image by echo-ing the content I want to use the poser script Scenario: Echo the image running a script with plastic format - When I run "poser license MIT blue -f plastic" + When I run "poser license MIT blue -s plastic" Then it should pass And the same output should be like the content of "bootstrap/fixtures/license-MIT-blue_plastic.svg" diff --git a/spec/PUGX/Poser/BadgeSpec.php b/spec/PUGX/Poser/BadgeSpec.php index 2bb936a..b0c4d28 100644 --- a/spec/PUGX/Poser/BadgeSpec.php +++ b/spec/PUGX/Poser/BadgeSpec.php @@ -10,13 +10,13 @@ class BadgeSpec extends ObjectBehavior { public function it_is_initializable(): void { - $this->beConstructedWith('a', 'b', '97CA00', 'svg'); + $this->beConstructedWith('a', 'b', '97CA00', 'flat'); $this->shouldHaveType(Badge::class); } public function it_should_be_constructed_by_fromURI_factory_method(): void { - $this->beConstructedWith('a', 'b', '97CA00', 'svg'); + $this->beConstructedWith('a', 'b', '97CA00', 'flat'); $assert = 'version-stable-97CA00.svg'; $it = Badge::fromURI($assert); @@ -27,7 +27,7 @@ public function it_should_be_constructed_by_fromURI_factory_method(): void public function it_should_be_constructed_by_fromURI_factory_method_escaping_correctly_underscores(): void { - $this->beConstructedWith('a', 'b', '97CA00', 'svg'); + $this->beConstructedWith('a', 'b', '97CA00', 'flat'); $input = 'I__m__liugg__io-b-97CA00.svg'; $assertInput = 'I_m_liugg_io-b-97CA00.svg'; $it = Badge::fromURI($input); @@ -39,7 +39,7 @@ public function it_should_be_constructed_by_fromURI_factory_method_escaping_corr public function it_should_be_constructed_by_fromURI_factory_method_escaping_correctly_with_single_underscore(): void { - $this->beConstructedWith('a', 'b', '97CA00', 'svg'); + $this->beConstructedWith('a', 'b', '97CA00', 'flat'); $input = 'I_m_liuggio-b-97CA00.svg'; $assertInput = 'I m liuggio-b-97CA00.svg'; $it = Badge::fromURI($input); @@ -51,7 +51,7 @@ public function it_should_be_constructed_by_fromURI_factory_method_escaping_corr public function it_should_be_constructed_by_fromURI_factory_method_escaping_correctly_with_dashes(): void { - $this->beConstructedWith('a', 'b', '97CA00', 'svg'); + $this->beConstructedWith('a', 'b', '97CA00', 'flat'); $input = 'I--m--liuggio-b-97CA00.svg'; $assertInput = 'I-m-liuggio-b-97CA00.svg'; $it = Badge::fromURI($input); @@ -66,7 +66,7 @@ public function it_should_be_constructed_by_fromURI_factory_method_escaping_corr */ public function it_should_validate_available_color_schemes($colorName, $expectedValue): void { - $this->beConstructedWith('a', 'b', $colorName, 'svg'); + $this->beConstructedWith('a', 'b', $colorName, 'flat'); $this->getHexColor()->shouldBeString(); } diff --git a/spec/PUGX/Poser/PoserSpec.php b/spec/PUGX/Poser/PoserSpec.php index d207797..d3bf7bb 100644 --- a/spec/PUGX/Poser/PoserSpec.php +++ b/spec/PUGX/Poser/PoserSpec.php @@ -5,13 +5,16 @@ use PhpSpec\ObjectBehavior; use PUGX\Poser\Poser; use PUGX\Poser\Render\SvgFlatRender; +use PUGX\Poser\Render\SvgFlatSquareRender; class PoserSpec extends ObjectBehavior { public function let(): void { - $render = new SvgFlatRender(); - $this->beConstructedWith([$render]); + $this->beConstructedWith([ + new SvgFlatRender(), + new SvgFlatSquareRender(), + ]); } public function it_is_initializable(): void @@ -24,9 +27,10 @@ public function it_should_be_able_to_generate_an_svg_image(): void $subject = 'stable'; $status = 'v2.0'; $color = '97CA00'; + $style = 'flat'; $format = 'svg'; - $this->generate($subject, $status, $color, $format)->shouldBeAValidSVGImageContaining($subject, $status); + $this->generate($subject, $status, $color, $style, $format)->shouldBeAValidSVGImageContaining($subject, $status); } public function it_should_be_able_to_generate_an_svg_image_from_URI(): void @@ -36,6 +40,48 @@ public function it_should_be_able_to_generate_an_svg_image_from_URI(): void $this->generateFromURI($subject)->shouldBeAValidSVGImageContaining('stable', 'v2.0'); } + public function it_should_be_able_to_generate_an_svg_image_from_URI_without_file_extension(): void + { + $subject = 'stable-v2.0-97CA00'; + + $this->generateFromURI($subject)->shouldBeAValidSVGImageContaining('stable', 'v2.0'); + } + + public function it_should_be_able_to_generate_an_svg_image_from_URI_with_style(): void + { + $subject = 'stable-v2.0-97CA00.svg?style=flat-square'; + + $this->generateFromURI($subject)->shouldBeAValidSVGImageContaining('stable', 'v2.0'); + } + + public function it_should_be_able_to_generate_an_svg_image_from_URI_with_empty_style(): void + { + $subject = 'stable-v2.0-97CA00.svg?style='; + + $this->generateFromURI($subject)->shouldBeAValidSVGImageContaining('stable', 'v2.0'); + } + + public function it_should_be_able_to_generate_an_svg_image_from_URI_with_empty_query(): void + { + $subject = 'stable-v2.0-97CA00.svg?'; + + $this->generateFromURI($subject)->shouldBeAValidSVGImageContaining('stable', 'v2.0'); + } + + public function it_should_be_able_to_generate_an_svg_image_from_URI_without_file_extension_with_style(): void + { + $subject = 'stable-v2.0-97CA00?style=flat-square'; + + $this->generateFromURI($subject)->shouldBeAValidSVGImageContaining('stable', 'v2.0'); + } + + public function it_should_throw_exception_on_generate_an_svg_image_with_bad_uri(): void + { + $subject = 'stable-v2.0-'; + + $this->shouldThrow(\InvalidArgumentException::class)->during('generateFromURI', [$subject]); + } + public function getMatchers(): array { return [ diff --git a/src/Badge.php b/src/Badge.php index e6aa7f7..bb3c4ae 100644 --- a/src/Badge.php +++ b/src/Badge.php @@ -4,6 +4,7 @@ class Badge { + public const DEFAULT_STYLE = 'flat'; public const DEFAULT_FORMAT = 'svg'; private static array $colorScheme = [ @@ -21,14 +22,16 @@ class Badge private string $subject; private string $status; private string $color; + private string $style; private string $format; - public function __construct(string $subject, string $status, string $color, string $format = self::DEFAULT_FORMAT) + public function __construct(string $subject, string $status, string $color, string $style = self::DEFAULT_STYLE, string $format = self::DEFAULT_FORMAT) { $this->subject = $this->escapeValue($subject); $this->status = $this->escapeValue($status); - $this->format = $this->escapeValue($format); $this->color = $this->getColorHex($color); + $this->style = $this->escapeValue($style); + $this->format = $this->escapeValue($format); if (!$this->isValidColorHex($this->color)) { throw new \InvalidArgumentException(\sprintf('Color not valid %s', $this->color)); @@ -51,19 +54,23 @@ public static function getColorNamesAvailable(): array */ public static function fromURI(string $URI): self { - $regex = '/^(([^-]|--)+)-(([^-]|--)+)-(([^-]|--)+)\.(svg|png|gif|jpg)$/'; + $parsedURI = \parse_url($URI); + $path = $parsedURI['path']; + \parse_str($parsedURI['query'] ?? '', $query); + + $regex = '/^(([^-]|--)+)-(([^-]|--)+)-(([^-.]|--)+)(\.(svg|png|gif|jpg))?$/'; $match = []; - if (1 !== \preg_match($regex, $URI, $match) && (7 !== \count($match))) { + if (1 !== \preg_match($regex, $path, $match) && (6 > \count($match))) { throw new \InvalidArgumentException('The URI given is not a valid URI' . $URI); } - $subject = $match[1]; $status = $match[3]; $color = $match[5]; - $format = $match[7]; + $style = isset($query['style']) && '' !== $query['style'] ? $query['style'] : self::DEFAULT_STYLE; + $format = $match[8] ?? self::DEFAULT_FORMAT; - return new self($subject, $status, $color, $format); + return new self($subject, $status, $color, $style, $format); } /** @@ -74,6 +81,14 @@ public function getHexColor(): string return '#' . $this->color; } + /** + * @return string the style of the image eg. `flat`. + */ + public function getStyle(): string + { + return $this->style; + } + /** * @return string the format of the image eg. `svg`. */ diff --git a/src/Image.php b/src/Image.php index c26148b..88e58e8 100644 --- a/src/Image.php +++ b/src/Image.php @@ -21,12 +21,12 @@ class Image { private string $content; - private string $format; + private string $style; - private function __construct(string $content, string $format) + private function __construct(string $content, string $style) { $this->content = $content; - $this->format = $format; + $this->style = $style; } /** @@ -40,13 +40,13 @@ public function __toString(): string /** * Factory method. */ - public static function createFromString(string $content, string $format): self + public static function createFromString(string $content, string $style): self { - return new self($content, $format); + return new self($content, $style); } - public function getFormat(): string + public function getStyle(): string { - return $this->format; + return $this->style; } } diff --git a/src/Poser.php b/src/Poser.php index 9cb8e25..78c6a57 100644 --- a/src/Poser.php +++ b/src/Poser.php @@ -21,23 +21,24 @@ public function __construct($renders) } foreach ($renders as $render) { - $this->addFormatRender($render); + $this->addStyleRender($render); } } /** - * Generate and Render a badge according to the format. + * Generate and Render a badge according to the style. * * @param $subject * @param $status * @param $color + * @param $style * @param $format */ - public function generate(string $subject, string $status, string $color, string $format): Image + public function generate(string $subject, string $status, string $color, string $style, string $format): Image { - $badge = new Badge($subject, $status, $color, $format); + $badge = new Badge($subject, $status, $color, $style, $format); - return $this->getRenderFor($badge->getFormat())->render($badge); + return $this->getRenderFor($badge->getStyle())->render($badge); } /** @@ -50,30 +51,28 @@ public function generateFromURI(string $string): Image { $badge = Badge::fromURI($string); - return $this->getRenderFor($badge->getFormat())->render($badge); + return $this->getRenderFor($badge->getStyle())->render($badge); } /** - * All the formats available. + * All the styles available. */ - public function validFormats(): array + public function validStyles(): array { return \array_keys($this->renders); } - private function addFormatRender(RenderInterface $render): void + private function addStyleRender(RenderInterface $render): void { - foreach ($render->supportedFormats() as $format) { - $this->renders[$format] = $render; - } + $this->renders[$render->getBadgeStyle()] = $render; } - private function getRenderFor(string $format): RenderInterface + private function getRenderFor(string $style): RenderInterface { - if (!isset($this->renders[$format])) { - throw new \InvalidArgumentException(\sprintf('No render founds for this format [%s]', $format)); + if (!isset($this->renders[$style])) { + throw new \InvalidArgumentException(\sprintf('No render founds for this style [%s]', $style)); } - return $this->renders[$format]; + return $this->renders[$style]; } } diff --git a/src/Render/LocalSvgRenderer.php b/src/Render/LocalSvgRenderer.php index ff3ec77..2cd45c2 100644 --- a/src/Render/LocalSvgRenderer.php +++ b/src/Render/LocalSvgRenderer.php @@ -49,7 +49,7 @@ public function render(Badge $badge): Image $template = $this->getTemplate($this->getTemplateName()); $parameters = $this->buildParameters($badge); - return $this->renderSvg($template, $parameters, $badge->getFormat()); + return $this->renderSvg($template, $parameters, $badge->getStyle()); } abstract protected function getTemplateName(): string; @@ -57,12 +57,12 @@ abstract protected function getTemplateName(): string; /** * @return string SVG content of the template */ - private function getTemplate(string $format): string + private function getTemplate(string $style): string { - $filepath = \sprintf('%s/%s.svg', $this->templatesDirectory, $format); + $filepath = \sprintf('%s/%s.svg', $this->templatesDirectory, $style); if (!\file_exists($filepath)) { - throw new \InvalidArgumentException(\sprintf('No template for format %s', $format)); + throw new \InvalidArgumentException(\sprintf('No template for style %s', $style)); } return \file_get_contents($filepath); @@ -73,7 +73,7 @@ private function stringWidth(string $text): float return $this->textSizeCalculator->calculateWidth($text); } - private function renderSvg(string $render, array $parameters, string $format): Image + private function renderSvg(string $render, array $parameters, string $style): Image { foreach ($parameters as $key => $variable) { $render = \str_replace(\sprintf('{{ %s }}', $key), $variable, $render); @@ -88,7 +88,7 @@ private function renderSvg(string $render, array $parameters, string $format): I throw new \RuntimeException('Generated xml is not a SVG'); } - return Image::createFromString($render, $format); + return Image::createFromString($render, $style); } private function buildParameters(Badge $badge): array diff --git a/src/Render/RenderInterface.php b/src/Render/RenderInterface.php index a0b5e20..3f5b422 100644 --- a/src/Render/RenderInterface.php +++ b/src/Render/RenderInterface.php @@ -22,7 +22,7 @@ interface RenderInterface public function render(Badge $badge): Image; /** - * @return array the list of the supported format eg array('svg') + * @return string the style of the badge image eg. `flat`. */ - public function supportedFormats(): array; + public function getBadgeStyle(): string; } diff --git a/src/Render/SvgFlatRender.php b/src/Render/SvgFlatRender.php index 3119138..b387566 100644 --- a/src/Render/SvgFlatRender.php +++ b/src/Render/SvgFlatRender.php @@ -12,24 +12,19 @@ namespace PUGX\Poser\Render; /** - * Class SvgFlatGenerator. + * Class SvgFlatRender. * * @author Giulio De Donato */ class SvgFlatRender extends LocalSvgRenderer { - /** - * A list of all supported formats. - * - * @return array|string[] - */ - public function supportedFormats(): array + public function getBadgeStyle(): string { - return ['flat', 'svg']; + return 'flat'; } protected function getTemplateName(): string { - return 'flat'; + return $this->getBadgeStyle(); } } diff --git a/src/Render/SvgFlatSquareRender.php b/src/Render/SvgFlatSquareRender.php index 7531bfb..979bb41 100644 --- a/src/Render/SvgFlatSquareRender.php +++ b/src/Render/SvgFlatSquareRender.php @@ -12,24 +12,19 @@ namespace PUGX\Poser\Render; /** - * Class SvgFlatGenerator. + * Class SvgFlatSquareRender. * * @author Giulio De Donato */ class SvgFlatSquareRender extends LocalSvgRenderer { - /** - * A list of all supported formats. - * - * @return array|string[] - */ - public function supportedFormats(): array + public function getBadgeStyle(): string { - return ['flat-square']; + return 'flat-square'; } protected function getTemplateName(): string { - return 'flat-square'; + return $this->getBadgeStyle(); } } diff --git a/src/Render/SvgPlasticRender.php b/src/Render/SvgPlasticRender.php index 5530c4f..69b7112 100644 --- a/src/Render/SvgPlasticRender.php +++ b/src/Render/SvgPlasticRender.php @@ -12,25 +12,20 @@ namespace PUGX\Poser\Render; /** - * Class SvgPlasticGenerator. + * Class SvgPlasticRender. * * @author Claudio D'Alicandro * @author Giulio De Donato */ class SvgPlasticRender extends LocalSvgRenderer { - /** - * A list of all supported formats. - * - * @return array|string[] - */ - public function supportedFormats(): array + public function getBadgeStyle(): string { - return ['plastic']; + return 'plastic'; } protected function getTemplateName(): string { - return 'plastic'; + return $this->getBadgeStyle(); } } diff --git a/src/UI/Command.php b/src/UI/Command.php index 4b6a5fa..0545285 100644 --- a/src/UI/Command.php +++ b/src/UI/Command.php @@ -25,8 +25,6 @@ class Command extends BaseCommand private Poser $poser; - protected string $format; - protected string $header; private function init(): void @@ -36,7 +34,6 @@ private function init(): void new SvgFlatRender(), new SvgFlatSquareRender(), ]); - $this->format = 'flat'; $this->header = self::HEADER; } @@ -62,11 +59,19 @@ protected function configure(): void InputArgument::OPTIONAL, 'The hexadecimal color eg. `97CA00` or the name [' . \implode(', ', Badge::getColorNamesAvailable()) . ']' ) + ->addOption( + 'style', + 's', + InputOption::VALUE_REQUIRED, + 'The style of the image eg. `flat`, styles available [' . \implode(', ', $this->poser->validStyles()) . ']', + Badge::DEFAULT_STYLE + ) ->addOption( 'format', 'f', InputOption::VALUE_REQUIRED, - 'The format of the image eg. `svg`, formats available [' . \implode(', ', $this->poser->validFormats()) . ']' + 'The format of the image eg. `svg`, formats available [' . \implode(', ', $this->poser->validStyles()) . ']', + Badge::DEFAULT_FORMAT ) ->addOption( 'path', @@ -84,13 +89,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int $subject = $input->getArgument('subject'); $status = $input->getArgument('status'); $color = $input->getArgument('color'); - - if ($input->getOption('format')) { - $this->format = (string) $input->getOption('format'); - } + $style = (string) $input->getOption('style'); + $format = (string) $input->getOption('format'); try { - $imageContent = $this->poser->generate($subject, $status, $color, $this->format); + $imageContent = $this->poser->generate($subject, $status, $color, $style, $format); if ($input->getOption('path')) { $this->storeImage($output, $input->getOption('path'), $imageContent); From d01e506ac00348b5f12f8d54311a9d7f5d138795 Mon Sep 17 00:00:00 2001 From: antonkomarev Date: Wed, 29 Jul 2020 00:30:07 +0300 Subject: [PATCH 18/20] Add missing colors from shields.io --- src/Badge.php | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/Badge.php b/src/Badge.php index bb3c4ae..6d18e55 100644 --- a/src/Badge.php +++ b/src/Badge.php @@ -8,15 +8,21 @@ class Badge public const DEFAULT_FORMAT = 'svg'; private static array $colorScheme = [ - 'brightgreen' => '44cc11', - 'green' => '97CA00', - 'yellow' => 'dfb317', - 'yellowgreen' => 'a4a61d', - 'orange' => 'fe7d37', - 'red' => 'e05d44', - 'blue' => '007ec6', - 'grey' => '555555', - 'lightgray' => '9f9f9f', + 'brightgreen' => '44cc11', + 'green' => '97CA00', + 'yellowgreen' => 'a4a61d', + 'yellow' => 'dfb317', + 'orange' => 'fe7d37', + 'red' => 'e05d44', + 'blue' => '007ec6', + 'lightgray' => '9f9f9f', + 'grey' => '555555', + 'blueviolet' => '8a2be2', + 'success' => '97CA00', + 'important' => 'fe7d37', + 'critical' => 'e05d44', + 'informational' => '007ec6', + 'inactive' => '9f9f9f', ]; private string $subject; From c4dfded249dd604e1b63f96658cad56363e33cf4 Mon Sep 17 00:00:00 2001 From: antonkomarev Date: Wed, 29 Jul 2020 00:36:29 +0300 Subject: [PATCH 19/20] Make all colors lowercase --- src/Badge.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Badge.php b/src/Badge.php index 6d18e55..07524c7 100644 --- a/src/Badge.php +++ b/src/Badge.php @@ -9,7 +9,7 @@ class Badge private static array $colorScheme = [ 'brightgreen' => '44cc11', - 'green' => '97CA00', + 'green' => '97ca00', 'yellowgreen' => 'a4a61d', 'yellow' => 'dfb317', 'orange' => 'fe7d37', @@ -18,7 +18,7 @@ class Badge 'lightgray' => '9f9f9f', 'grey' => '555555', 'blueviolet' => '8a2be2', - 'success' => '97CA00', + 'success' => '97ca00', 'important' => 'fe7d37', 'critical' => 'e05d44', 'informational' => '007ec6', From 0c5e6c50e496966e6298a8275a6bc192cd64676c Mon Sep 17 00:00:00 2001 From: antonkomarev Date: Wed, 29 Jul 2020 12:42:48 +0300 Subject: [PATCH 20/20] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0121de..24415ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. * configure and run php-cs-fixer with new code style roles * add setting custom badge style from query string * add psalm +* added all the colors from the shields.io site ### Changed * upgrade docker-compose for dev environment with php7.4