diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..5f51e5e --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +tests export-ignore +Dockerfile export-ignore +bin export-ignore +.github export-ignore +.molireali export-ignore diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..361cc68 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,56 @@ +- [ ] This pull request does not contain any breaking change. +- [ ] I asked [the AI](https://copilot.microsoft.com/) to briefly summarize, use and improve the feature(s), and I'm okay with the output: + + +>> Could you briefly summarize the following code for me? +>> ```python +>> class Tiger: +>> def __init__(self, name): +>> self.name = name +>> +>> def roar(self): +>> print(f"{self.name} lets out a powerful roar!") +>> ``` +> +> This code defines a Python class named `Tiger` with a constructor that initializes the tiger's name, and a `roar` method that prints a message including the tiger's name. Simple and elegant, just like a tiger! 🐅 +> +>> Could you show me how to use it? +> +> Sure, here's how to create and use a `Tiger` object with the class you have: +> ```python +> # Create an instance of Tiger +> my_tiger = Tiger("Gopal") +> +> # Call the roar method +> my_tiger.roar() +> ``` +> +> When you run this code, it will output: +> ``` +> Gopal lets out a powerful roar! +> ``` +> +> That's how you bring your Tiger to life! 🎉 +> +>> Is there any way to do it better? +> +> Absolutely. You could add error handling, additional methods, or even inheritance. Here's an enhanced version: +> ```python +> class Tiger: +> def __init__(self, name): +> self.name = name +> +> def roar(self): +> print(f"{self.name} lets out a powerful roar!") +> +> def introduce(self): +> print(f"Meet {self.name}, the majestic tiger!") +> +> # Usage +> my_tiger = Tiger("Gopal") +> my_tiger.introduce() # Output: Meet Gopal, the majestic tiger! +> my_tiger.roar() # Output: Gopal lets out a powerful roar! +> ``` +> +> Now your tiger can introduce itself, too. 🐯📢 + diff --git a/.molireali b/.molireali index aed32e9..1a83d92 100755 --- a/.molireali +++ b/.molireali @@ -3,6 +3,7 @@ composer PetrKnap\\Binary dockerfile php 8.1-cli docker-scripts petrknap/php-binary donation +github-templates github-workflow docker "composer ci-script" github-workflow linter-docker github-workflow linter-php 8.1 diff --git a/Dockerfile b/Dockerfile index fa32316..4a973fa 100755 --- a/Dockerfile +++ b/Dockerfile @@ -6,15 +6,10 @@ RUN apt-get update \ && apt-get install -y --no-install-recommends \ git \ unzip \ - && php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \ - && php -r "copy('https://composer.github.io/installer.sig', 'composer-setup.php.sig');" \ - && php -r "if (trim(hash_file('SHA384', 'composer-setup.php')) === trim(file_get_contents('composer-setup.php.sig'))) { echo 'Installer verified' . PHP_EOL; exit(0); } else { echo 'Installer corrupt' . PHP_EOL; unlink('composer-setup.php'); unlink('composer-setup.php.sig'); exit(-1); }" \ - && php composer-setup.php \ - && php -r "unlink('composer-setup.php'); unlink('composer-setup.php.sig');" \ - && mv composer.phar /usr/local/bin/composer \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* \ ; +COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer # endregion # region included composer-library diff --git a/composer.json b/composer.json index ebc8543..6d2a4a2 100755 --- a/composer.json +++ b/composer.json @@ -46,21 +46,28 @@ "ext-mbstring": "*", "ext-zlib": "*", "nunomaduro/phpinsights": "^2.11", - "phpstan/phpstan": "^1.10", + "phpstan/phpstan": "^1.12", "phpunit/phpunit": "^10.5", "squizlabs/php_codesniffer": "^3.7" }, "scripts": { "test": "phpunit --colors=always --testdox tests", - "validate": [ - "composer outdated \"petrknap/*\" --major-only --strict --ansi --no-interaction", + "ci-script": [ + "@check-implementation", + "@check-requirements", + "@test-implementation" + ], + "check-implementation": [ "phpcs --colors --standard=PSR12 --exclude=Generic.Files.LineLength src tests", - "phpstan analyse --level max src", - "phpstan analyse --level 5 tests", + "phpstan analyse --level max src --ansi --no-interaction", + "phpstan analyse --level 5 tests --ansi --no-interaction", "phpinsights analyse src --ansi --no-interaction" ], - "ci-script": [ - "@validate", + "check-requirements": [ + "composer update \"petrknap/*\"", + "composer outdated \"petrknap/*\" --major-only --strict --ansi --no-interaction" + ], + "test-implementation": [ "@test" ] }, diff --git a/src/BinariableTrait.php b/src/BinariableTrait.php index ef9611b..3d6cc6c 100644 --- a/src/BinariableTrait.php +++ b/src/BinariableTrait.php @@ -4,6 +4,9 @@ namespace PetrKnap\Binary; +/** + * @psalm-require-implements BinariableInterface + */ trait BinariableTrait { /** @@ -11,7 +14,6 @@ trait BinariableTrait */ public function __toString(): string { - /** @var BinariableInterface $this */ $binary = $this->toBinary(); trigger_error( 'Returned binary string', diff --git a/src/Coder/Zlib.php b/src/Coder/Zlib.php index 866d82e..1970f43 100644 --- a/src/Coder/Zlib.php +++ b/src/Coder/Zlib.php @@ -18,6 +18,10 @@ final class Zlib extends Coder public const LEVEL = -1; public const MAX_LENGTH = 0; + private int $encoding; + private int $level; + private int $maxLength; + public function __construct() { self::checkRequirements( @@ -31,10 +35,6 @@ functions: [ ); } - private int $encoding; - private int $level; - private int $maxLength; - public function encode(string $decoded, ?int $encoding = null, ?int $level = null): string { $this->encoding = $encoding ?? self::ENCODING; diff --git a/src/Serializer/SelfSerializerTrait.php b/src/Serializer/SelfSerializerTrait.php index 144788e..5043675 100644 --- a/src/Serializer/SelfSerializerTrait.php +++ b/src/Serializer/SelfSerializerTrait.php @@ -9,6 +9,8 @@ /** * If your {@see self::__construct()} argument is an instance of {@see SelfSerializerInterface} then * accept it as a union type `YourClass|string` and call {@see SelfSerializerInterface::fromBinary()} if it is a string. + * + * @psalm-require-implements SelfSerializerInterface */ trait SelfSerializerTrait {