From 426d9dbf28e1acec36bc8d294a98cfc598837d23 Mon Sep 17 00:00:00 2001 From: roquie Date: Mon, 11 Apr 2022 17:16:11 +0300 Subject: [PATCH] Upgrade package to supports PHP 8.1 --- README.md | 12 +++- composer.json | 14 +++-- phpstan.neon | 2 + src/Configuration.php | 80 ++++++++++-------------- src/ConfigurationAwareInterface.php | 2 +- src/ConfigurationAwareTrait.php | 4 +- src/ConfigurationInterface.php | 4 +- src/Console/DumpConfigCommand.php | 11 ++-- src/Exception/ConfigurationException.php | 20 +++--- tests/ConfigurationTest.php | 35 +++++------ 10 files changed, 94 insertions(+), 90 deletions(-) create mode 100644 phpstan.neon diff --git a/README.md b/README.md index 14d1737..c2b5dab 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,12 @@ and overrides the `defaults` stage. composer require spacetab-io/configuration ``` +#### Versions map + +* Package with version `4.*` requires PHP >= `8.1` +* Package with version `3.*` requires PHP >= `7.4` <= `8.0` +* Package with version `2.*` requires PHP < `7.4` + ## Usage By default, path to configuration directory and application stage @@ -90,7 +96,7 @@ That all. ## CLI utility Also, you can install simple small cli-utility to dump total results of merged config. -It possible with multiple ways: +It is possible with multiple ways: 1) Install to `/usr/local/bin` as global binary @@ -149,14 +155,14 @@ Help: ## Depends -* \>= PHP 7.4 (for prev version use `2.x` releases of library) +* \>= PHP 8.1 * Composer for install package ## License The MIT License -Copyright © 2020 spacetab.io, Inc. https://spacetab.io +Copyright © 2022 spacetab.io, Inc. https://spacetab.io 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/composer.json b/composer.json index df3a61b..9305422 100644 --- a/composer.json +++ b/composer.json @@ -16,17 +16,17 @@ } }, "require": { - "php": ">=7.4", + "php": ">=8.1", "symfony/yaml": "^4.2 || ^5.0 || ^6.0", "psr/log": "^1.1 || ^2.0 || ^3.0", "symfony/console": "^4.3 || ^5.0 || ^6.0", "spacetab-io/obelix": "^1.0" }, "require-dev": { - "phpunit/phpunit": "^9", - "symfony/var-dumper": "^4.2 || ^5.0", + "phpunit/phpunit": "^9 || ^10", + "symfony/var-dumper": "^4.2 || ^5.0 || ^6.0", "humbug/box": "^3.8", - "phpstan/phpstan": "^0.12", + "phpstan/phpstan": "^1.5.4", "spacetab-io/logger": "^2.0" }, "suggest": { @@ -37,5 +37,11 @@ "phpunit --coverage-text", "phpstan analyse src --level 6" ] + }, + "config": { + "sort-packages": true, + "allow-plugins": { + "ocramius/package-versions": true + } } } diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..a821b91 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,2 @@ +parameters: + checkMissingIterableValueType: false diff --git a/src/Configuration.php b/src/Configuration.php index bccf156..68cc3a4 100644 --- a/src/Configuration.php +++ b/src/Configuration.php @@ -15,7 +15,7 @@ /** * Class Configuration * - * @implements \ArrayAccess + * @implements ArrayAccess * @package Spacetab\Configuration */ final class Configuration implements ConfigurationInterface, ArrayAccess, LoggerAwareInterface @@ -59,14 +59,7 @@ final class Configuration implements ConfigurationInterface, ArrayAccess, Logger */ private Obelix\Dot $config; - /** - * @var string - */ private string $path; - - /** - * @var string - */ private string $stage; /** @@ -77,8 +70,8 @@ final class Configuration implements ConfigurationInterface, ArrayAccess, Logger */ public function __construct(?string $path = null, ?string $stage = null) { - $envPath = $this->getEnvVariable(self::CONFIG_PATH, self::DEFAULT_CONFIG_PATH); - $envStage = $this->getEnvVariable(self::STAGE, self::DEFAULT_STAGE); + $envPath = self::getEnvVariable(self::CONFIG_PATH, self::DEFAULT_CONFIG_PATH); + $envStage = self::getEnvVariable(self::STAGE, self::DEFAULT_STAGE); null === $path ? $this->setPath($envPath) : $this->setPath($path); null === $stage ? $this->setStage($envStage) : $this->setStage($stage); @@ -94,7 +87,7 @@ public function __construct(?string $path = null, ?string $stage = null) * Specially for lazy-based programmers like me. * * @param string|null $stage - * @throws \Spacetab\Configuration\Exception\ConfigurationException + * @throws ConfigurationException * * @return Configuration */ @@ -104,19 +97,19 @@ public static function auto(?string $stage = null): Configuration } /** - * Get's a value from config by dot notation - * E.g get('x.y', 'foo') => returns the value of $config['x']['y'] + * Gets a value from config by dot notation + * E.g. get('x.y', 'foo') => returns the value of $config['x']['y'] * And if not exist, return 'foo'. * * Supported dot-notation syntax with an asterisk. * You can read about it here: https://github.com/spacetab-io/obelix-php * * @param string $key - * @param mixed $default + * @param mixed|null $default * * @return mixed */ - public function get($key, $default = null) + public function get(string $key, mixed $default = null): mixed { return $this->config->get($key, $default)->getValue(); } @@ -124,7 +117,7 @@ public function get($key, $default = null) /** * Gets all the tree config. * - * @return array + * @return array */ public function all(): array { @@ -178,7 +171,7 @@ public function getStage(): string } /** - * Whether a offset exists + * Whether an offset exists * * @link https://php.net/manual/en/arrayaccess.offsetexists.php * @param mixed $offset

@@ -188,7 +181,7 @@ public function getStage(): string * * @return boolean true on success or false on failure. */ - public function offsetExists($offset): bool + public function offsetExists(mixed $offset): bool { return ! empty($this->get($offset)); } @@ -204,7 +197,7 @@ public function offsetExists($offset): bool * * @return mixed Can return all value types. */ - public function offsetGet($offset) + public function offsetGet(mixed $offset): mixed { return $this->get($offset); } @@ -220,11 +213,11 @@ public function offsetGet($offset) * The value to set. *

* @since 5.0.0 - * @throws \Spacetab\Configuration\Exception\ConfigurationException + * @throws ConfigurationException * * @return void */ - public function offsetSet($offset, $value) + public function offsetSet(mixed $offset, mixed $value): void { throw ConfigurationException::operationNotAllowed(); } @@ -237,11 +230,11 @@ public function offsetSet($offset, $value) * The offset to unset. *

* @since 5.0.0 - * @throws \Spacetab\Configuration\Exception\ConfigurationException + * @throws ConfigurationException * * @return void */ - public function offsetUnset($offset): void + public function offsetUnset(mixed $offset): void { throw ConfigurationException::operationNotAllowed(); } @@ -249,7 +242,7 @@ public function offsetUnset($offset): void /** * Initialize all the magic down here * - * @throws \Spacetab\Configuration\Exception\ConfigurationException + * @throws ConfigurationException */ public function load(): Configuration { @@ -288,9 +281,9 @@ public function dump(int $inline = 10, int $indent = 2): string * Parses configuration and makes a tree of it. * * @param string $stage - * @throws \Spacetab\Configuration\Exception\ConfigurationException + * @throws ConfigurationException * - * @return array + * @return array */ private function parseConfiguration(string $stage = self::DEFAULT_STAGE): array { @@ -346,38 +339,33 @@ private static function getEnvVariable(string $variable, string $default = ''): * * @param array ...$arrays * - * @return array|mixed + * @return array */ - private function arrayMergeRecursive(array ...$arrays) + private function arrayMergeRecursive(array ...$arrays): array { $base = array_shift($arrays); - if ( ! is_array($base)) { - $base = empty($base) ? [] : [$base]; - } foreach ($arrays as $append) { - if ( ! is_array($append)) { + if (!is_array($append)) { $append = [$append]; } foreach ($append as $key => $value) { - if ( ! array_key_exists($key, $base) && ! is_numeric($key)) { - $base[$key] = $append[$key]; + if (!array_key_exists($key, $base) && ! is_numeric($key)) { + $base[$key] = $value; continue; } if ((is_array($value) || (isset($base[$key]) && is_array($base[$key]))) && $this->isAssoc($value)) { $base[$key] = $this->arrayMergeRecursive( (array) $base[$key], - (array) $append[$key] + (array) $value ); - } else { - if (is_numeric($key)) { - if ( ! in_array($value, $base)) { - $base[] = $value; - } - } else { - $base[$key] = $value; + } else if (is_numeric($key)) { + if (!in_array($value, $base, true)) { + $base[] = $value; } + } else { + $base[$key] = $value; } } } @@ -388,7 +376,7 @@ private function arrayMergeRecursive(array ...$arrays) /** * Check if array is associative or sequential list. * - * @param array $array + * @param array $array * * @return bool */ @@ -398,19 +386,19 @@ private function isAssoc(array $array): bool return false; } - return array_keys($array) !== range(0, count($array) - 1); + return !array_is_list($array); } /** * Automatically find configuration in possible paths. * - * @throws \Spacetab\Configuration\Exception\ConfigurationException + * @throws ConfigurationException * * @return string */ private static function findDirectories(): string { - if ($value = trim((string) self::getEnvVariable(self::CONFIG_PATH))) { + if ($value = trim(self::getEnvVariable(self::CONFIG_PATH))) { // add env config path to top of possible locations. array_unshift(self::$possibleLocations, $value); } diff --git a/src/ConfigurationAwareInterface.php b/src/ConfigurationAwareInterface.php index 88e2ed4..34af8de 100644 --- a/src/ConfigurationAwareInterface.php +++ b/src/ConfigurationAwareInterface.php @@ -12,7 +12,7 @@ interface ConfigurationAwareInterface /** * Sets a configuration instance on the object. * - * @param \Spacetab\Configuration\ConfigurationInterface $configuration + * @param ConfigurationInterface $configuration * * @return void */ diff --git a/src/ConfigurationAwareTrait.php b/src/ConfigurationAwareTrait.php index 0c9bf84..9f2b43b 100644 --- a/src/ConfigurationAwareTrait.php +++ b/src/ConfigurationAwareTrait.php @@ -12,14 +12,14 @@ trait ConfigurationAwareTrait /** * The Configuration instance. * - * @var \Spacetab\Configuration\ConfigurationInterface + * @var ConfigurationInterface */ protected ConfigurationInterface $configuration; /** * Sets a configuration. * - * @param \Spacetab\Configuration\ConfigurationInterface $configuration + * @param ConfigurationInterface $configuration */ public function setConfiguration(ConfigurationInterface $configuration): void { diff --git a/src/ConfigurationInterface.php b/src/ConfigurationInterface.php index 6859183..8ba2802 100644 --- a/src/ConfigurationInterface.php +++ b/src/ConfigurationInterface.php @@ -23,12 +23,12 @@ interface ConfigurationInterface * @param mixed $default * @return mixed */ - public function get($key, $default = null); + public function get(string $key, mixed $default = null): mixed; /** * Gets all the tree config * - * @return array + * @return array */ public function all(): array; } diff --git a/src/Console/DumpConfigCommand.php b/src/Console/DumpConfigCommand.php index a844fa1..fd33374 100644 --- a/src/Console/DumpConfigCommand.php +++ b/src/Console/DumpConfigCommand.php @@ -5,6 +5,7 @@ namespace Spacetab\Configuration\Console; use Spacetab\Configuration\Configuration; +use Spacetab\Configuration\Exception\ConfigurationException; use Spacetab\Logger\Logger; use Psr\Log\LogLevel; use Symfony\Component\Console\Command\Command; @@ -15,6 +16,8 @@ class DumpConfigCommand extends Command { + protected static $defaultName = 'dump'; + protected static $defaultDescription = 'Dump loaded configuration'; protected function configure(): void { @@ -32,9 +35,9 @@ protected function configure(): void /** * Execute command, captain. * - * @param \Symfony\Component\Console\Input\InputInterface $input - * @param \Symfony\Component\Console\Output\OutputInterface $output - * @throws \Spacetab\Configuration\Exception\ConfigurationException + * @param InputInterface $input + * @param OutputInterface $output + * @throws ConfigurationException * * @return int */ @@ -58,6 +61,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int $output->writeln($string); - return 0; + return Command::SUCCESS; } } diff --git a/src/Exception/ConfigurationException.php b/src/Exception/ConfigurationException.php index 50f88c1..dc16045 100644 --- a/src/Exception/ConfigurationException.php +++ b/src/Exception/ConfigurationException.php @@ -8,7 +8,7 @@ class ConfigurationException extends Exception { - private const SPECIFICATION_URI = 'https://confluence.teamc.io/pages/viewpage.action?pageId=4227704'; + private const SPECIFICATION_URI = 'https://confluence.spacetab.io/pages/viewpage.action?pageId=4227704'; /** * ConfigurationException constructor. @@ -35,12 +35,12 @@ public static function operationNotAllowed(): self * * @return self */ - public static function filesNotFound(string $pattern, string $path, string $stage) + public static function filesNotFound(string $pattern, string $path, string $stage): self { - $one = "Files not found. Used glob pattern: {$pattern}."; - $two = "CONFIG_PATH={$path} and STAGE={$stage} is correct?"; + $one = "Files not found. Used glob pattern: $pattern."; + $two = "CONFIG_PATH=$path and STAGE=$stage is correct?"; - return new self("{$one}\n{$two}"); + return new self("$one\n$two"); } /** @@ -50,7 +50,7 @@ public static function filesNotFound(string $pattern, string $path, string $stag */ public static function pathNotFound(string $path): self { - return new self("Path [{$path}] not found."); + return new self("Path [$path] not found."); } /** @@ -62,10 +62,10 @@ public static function pathNotFound(string $path): self */ public static function fileNotEqualsCurrentStage(string $stage, string $top, string $filename): self { - $one = "Developer error! STAGE [{$stage}] is not equals top of file [{$top}]."; - $two = "Please, fix the file [{$filename}]."; + $one = "Developer error! STAGE [$stage] is not equals top of file [$top]."; + $two = "Please, fix the file [$filename]."; - return new self("{$one} {$two}"); + return new self("$one $two"); } /** @@ -77,7 +77,7 @@ public static function autoFindConfigurationDirFailed(array $possibleLocations): { return new self(sprintf( 'Configuration directory not found in known path\'s: %s', - join(',', $possibleLocations) + implode(', ', $possibleLocations) )); } } diff --git a/tests/ConfigurationTest.php b/tests/ConfigurationTest.php index 78371b1..b3402b9 100644 --- a/tests/ConfigurationTest.php +++ b/tests/ConfigurationTest.php @@ -1,5 +1,7 @@ [ @@ -42,7 +41,7 @@ public function getTrueMergedConfigurationForTestStage() ]; } - public function testConfigurationModuleFlowWithDefaultBehavior() + public function testConfigurationModuleFlowWithDefaultBehavior(): void { putenv('CONFIG_PATH=' . __DIR__ . '/configuration'); putenv('STAGE=test'); @@ -53,7 +52,7 @@ public function testConfigurationModuleFlowWithDefaultBehavior() $this->followAssertions($conf); } - public function testConfigurationModuleFlowWithPassingPathAndStage() + public function testConfigurationModuleFlowWithPassingPathAndStage(): void { $conf = new Configuration(__DIR__ . '/configuration', 'test'); $conf->load(); @@ -61,7 +60,7 @@ public function testConfigurationModuleFlowWithPassingPathAndStage() $this->followAssertions($conf); } - public function testDefaultPathAndValue() + public function testDefaultPathAndValue(): void { putenv('CONFIG_PATH='); putenv('STAGE='); @@ -79,9 +78,9 @@ public function testDefaultPathAndValue() } /** - * @param \Spacetab\Configuration\Configuration $conf + * @param Configuration $conf */ - private function followAssertions(Configuration $conf) + private function followAssertions(Configuration $conf): void { $array = $this->getTrueMergedConfigurationForTestStage(); @@ -92,7 +91,7 @@ private function followAssertions(Configuration $conf) $this->assertSame($array['hotelbook_params']['area_mapping'], $conf['hotelbook_params.area_mapping']); } - public function testHowConfigurationMergeArraysWithEmpty() + public function testHowConfigurationMergeArraysWithEmpty(): void { $config = [ 'content_security_policy' => [ @@ -112,7 +111,7 @@ public function testHowConfigurationMergeArraysWithEmpty() $this->assertSame($config, $conf->all()); } - public function testHowConfigurationMergeArrays() + public function testHowConfigurationMergeArrays(): void { $config = [ 'content_security_policy' => [ @@ -131,7 +130,7 @@ public function testHowConfigurationMergeArrays() $this->assertSame($config, $conf->all()); } - public function testHowConfigurationCanBeFoundDirectoryAutomatically() + public function testHowConfigurationCanBeFoundDirectoryAutomatically(): void { $this->xcopy(__DIR__ . '/configuration', './configuration'); @@ -144,7 +143,7 @@ public function testHowConfigurationCanBeFoundDirectoryAutomatically() $this->deleteDirectory('./configuration'); } - public function testHowConfigurationDumpYaml() + public function testHowConfigurationDumpYaml(): void { $conf = new Configuration(__DIR__ . '/configuration', 'test'); $conf->load(); @@ -153,7 +152,7 @@ public function testHowConfigurationDumpYaml() $this->assertSame($expected, $conf->dump()); } - public function testHowWorksUserMistakePrevention() + public function testHowWorksUserMistakePrevention(): void { $this->expectException(ConfigurationException::class); $this->expectExceptionMessageMatches('/Developer error\! STAGE .*/'); @@ -173,7 +172,7 @@ public function testHowWorksUserMistakePrevention() * @link http://aidanlister.com/2004/04/recursively-copying-directories-in-php/ * @author Aidan Lister */ - private function xcopy($source, $dest, $permissions = 0755) + private function xcopy(string $source, string $dest, int $permissions = 0755): bool { // Check for symlinks if (is_link($source)) { @@ -194,7 +193,7 @@ private function xcopy($source, $dest, $permissions = 0755) $dir = dir($source); while (false !== $entry = $dir->read()) { // Skip pointers - if ($entry == '.' || $entry == '..') { + if ($entry === '.' || $entry === '..') { continue; } @@ -213,7 +212,7 @@ private function xcopy($source, $dest, $permissions = 0755) * @param $dir * @return bool */ - private function deleteDirectory($dir) + private function deleteDirectory($dir): bool { if ( ! file_exists($dir)) { return true; @@ -224,7 +223,7 @@ private function deleteDirectory($dir) } foreach (scandir($dir) as $item) { - if ($item == '.' || $item == '..') { + if ($item === '.' || $item === '..') { continue; }