From 5596c3e03d5db88dd29a1a77140c134d566a4901 Mon Sep 17 00:00:00 2001 From: Paul Mitchum Date: Mon, 13 Mar 2023 10:24:46 -0700 Subject: [PATCH] 13589 Target PHP 7.4, support PHP 8.1 (#14) --- .circleci/config.yml | 204 ++++++++++++++++++++--- .codeclimate.yml | 2 +- .editorconfig | 14 ++ .gitignore | 1 + composer.json | 39 +++-- phpcs.xml | 14 ++ phpunit.xml | 22 +-- rector.php | 26 +++ src/Mock/IdGenerator/Sequential.php | 2 +- src/Mock/Storage/JsonObjectMemory.php | 12 +- src/Mock/Storage/MemoryFactory.php | 2 +- test/Mock/IdGenerator/SequentialTest.php | 18 +- 12 files changed, 289 insertions(+), 67 deletions(-) create mode 100644 .editorconfig create mode 100644 phpcs.xml create mode 100644 rector.php diff --git a/.circleci/config.yml b/.circleci/config.yml index ee02796..baca078 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,26 +1,180 @@ -version: 2.0 +# PHPUnit Composer min/max test. +# TODO: Make our own orb out of this. + +version: 2.1 +orbs: + php: circleci/php@1.1.0 + +commands: + update-packages: + description: | + Update your composer packages with automated caching and best practices applied. + parameters: + app-dir: + default: ~/project + description: Path to the directory containing your composer.json file. Not needed if composer.json lives in the root. + type: string + cache-files-dir: + default: /home/circleci/.composer/cache/files + description: Absolute path to the file cache folder. This should be inline with "composer global config cache-files-dir --absolute". + type: string + cache-key: + default: composer.lock + description: If this file is updated a new cache bucket will be created. Recommended to use composer.lock. Use composer.json when composer.lock is absent. + type: string + cache-version: + default: v1 + description: Change the default cache version if you need to clear the cache for any reason. + type: string + install-flags: + default: --no-interaction --prefer-dist + description: | + By default, packages will be installed with "composer install --no-interaction --prefer-dist", use this to override the standard install flags. + type: string + vendor-dir: + default: vendor + description: Relative path to the vendor folder. Relative to "app-dir". This should be inline with "composer config vendor-dir". + type: string + with-cache: + default: true + description: Enable automatic caching of your dependencies for increased speed. + type: boolean + steps: + - when: + condition: << parameters.with-cache >> + steps: + - restore_cache: + keys: + - composer-deps-<>-{{ checksum "<>/<>" }} + - run: + command: | + if [ ! -f "composer.json" ] && [ ! -f "composer.lock" ]; then + echo + echo "---" + echo "Unable to find your composer.json and composer.lock files. Did you forget to set the app-dir parameter?" + echo "---" + echo + echo "Current directory: $(pwd)" + echo + echo + echo "List directory: " + echo + ls + exit 1 + fi + name: Verify composer.json and/or composer.lock exist + working_directory: <> + - run: + command: composer update <> + name: Updating Composer Packages + working_directory: <> + - when: + condition: << parameters.with-cache >> + steps: + - save_cache: + key: composer-deps-<>-{{ checksum "<>/<>" }} + paths: + - <>/<> + - <> + install-xdebug: + steps: + - run: + name: Install XDebug + command: sudo -E install-php-extensions xdebug && sudo -E docker-php-ext-enable xdebug + + install-cc-test-reporter: + # TODO: Parameterize location. + steps: + - run: + name: Install Codeclimate test reporter + command: | + curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter + chmod +x ./cc-test-reporter + + run-phpunit-tests: + description: | + Run PHPUnit tests. + parameters: + app-dir: + default: ~/project + description: Path to the directory containing your composer.json file. Not needed if composer.json lives in the root. + type: string + install-flags: + default: "" + description: Arguments to `composer update`. + type: string + test-command: + default: test + description: The name of the script within your composer.json which will run your tests. + type: string + report-to-codeclimate: + type: boolean + default: false + description: Report coverage info to Codeclimate. + steps: + - checkout + - update-packages: + app-dir: <> + cache-key: composer.json + install-flags: <> + - when: + condition: <> + steps: + - install-xdebug + - install-cc-test-reporter + - run: | + ./cc-test-reporter before-build + XDEBUG_MODE=coverage composer <> -- --coverage-clover clover.xml + ./cc-test-reporter after-build --coverage-input-type clover --exit-code $? + - when: + condition: + not: <> + steps: + - run: | + XDEBUG_MODE=off composer <> + jobs: - build: - environment: - CC_TEST_REPORTER_ID: d20339bfed51b1e242630efbe3f2745337794f7a856f610aad4d21897c5e0309 - docker: - - image: circleci/php:7-cli-node-browsers-legacy - working_directory: ~/repo - steps: - - checkout - - run: - name: Setup dependencies - command: | - sudo composer self-update - composer install -n --prefer-dist - - run: - name: Setup Code Climate test-reporter - command: | - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter - chmod +x ./cc-test-reporter - - run: - name: Run tests - command: | - ./cc-test-reporter before-build - vendor/bin/phpunit --testsuite all --coverage-clover clover.xml - ./cc-test-reporter after-build --coverage-input-type clover --exit-code $? + matrix-conditions: + environment: + CC_TEST_REPORTER_ID: d20339bfed51b1e242630efbe3f2745337794f7a856f610aad4d21897c5e0309 + description: Run tests for matrix + executor: + name: php/default + tag: << parameters.version >> + parameters: + version: + default: "7.4" + description: The `cimg/php` Docker image version tag. + type: string + install-flags: + default: "" + description: Arguments to `composer update`. + type: string + steps: + - when: + condition: + and: + - equal: [ "8.1", <> ] + - equal: [ "", <> ] + steps: + - run-phpunit-tests: + report-to-codeclimate: true + install-flags: << parameters.install-flags >> + - when: + condition: + not: + and: + - equal: [ "8.1", <> ] + - equal: [ "", <> ] + steps: + - run-phpunit-tests: + install-flags: << parameters.install-flags >> + +workflows: + all-tests: + jobs: + - matrix-conditions: + matrix: + parameters: + version: ["7.4", "8.0", "8.1"] + install-flags: ["", "--prefer-lowest"] diff --git a/.codeclimate.yml b/.codeclimate.yml index 8ec57d0..92ff118 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -1,4 +1,4 @@ -version: 2 +version: "2" plugins: phpcodesniffer: enabled: true diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..d9d308c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +# This is the top-most .editorconfig file; do not search in parent directories. +root = true + +# All files. +[*] +end_of_line = LF +indent_style = space +indent_size = 4 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[composer.{json,lock}] +indent_size = 4 diff --git a/.gitignore b/.gitignore index 4f38912..865ffaa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .idea +.phpunit.result.cache vendor composer.lock diff --git a/composer.json b/composer.json index 9b079e7..69ed766 100644 --- a/composer.json +++ b/composer.json @@ -1,21 +1,40 @@ { "name": "getdkan/contracts", "description": "A set of interfaces.", + "license": "GPL-3.0-only", "type": "library", + "authors": [ + { + "name": "fmizzell", + "email": "fmizzell@1312210.no-reply.drupal.org" + } + ], + "require": { + "php": ">=7.4 <9.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.6", + "rector/rector": "^0.15.17", + "squizlabs/php_codesniffer": "^3.7" + }, "autoload": { "psr-4": { - "Contracts\\": "src/", + "Contracts\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { "ContractsTest\\": "test/" } }, - "require-dev": { - "phpunit/phpunit": "~7.5.0" + "config": { + "sort-packages": true }, - "license": "GPL-3.0-only", - "authors": [ - { - "name": "fmizzell", - "email": "fmizzell@1312210.no-reply.drupal.org" - } - ] + "scripts": { + "phpcbf": "./vendor/bin/phpcbf", + "phpcs": "./vendor/bin/phpcs", + "rector": "./vendor/bin/rector process", + "rector-dry-run": "./vendor/bin/rector process --dry-run", + "test": "./vendor/bin/phpunit --testsuite all" + } } diff --git a/phpcs.xml b/phpcs.xml new file mode 100644 index 0000000..45200cd --- /dev/null +++ b/phpcs.xml @@ -0,0 +1,14 @@ + + + + + PHP CodeSniffer configuration for GetDKAN. + + src + test + rector.php + + + + + diff --git a/phpunit.xml b/phpunit.xml index b4d7c1e..8ffc757 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,18 +1,14 @@ - - + + + + + src + + - test + test - - - - src - - - diff --git a/rector.php b/rector.php new file mode 100644 index 0000000..81e3216 --- /dev/null +++ b/rector.php @@ -0,0 +1,26 @@ +paths([ + __DIR__ . '/src', + __DIR__ . '/test', + ]); + + $rectorConfig->sets([ + LevelSetList::UP_TO_PHP_74, + ]); + + $rectorConfig->skip([ + JsonThrowOnErrorRector::class, + ]); +}; diff --git a/src/Mock/IdGenerator/Sequential.php b/src/Mock/IdGenerator/Sequential.php index a142813..dd7a68c 100644 --- a/src/Mock/IdGenerator/Sequential.php +++ b/src/Mock/IdGenerator/Sequential.php @@ -6,7 +6,7 @@ class Sequential implements IdGeneratorInterface { - private $id = 0; + private int $id = 0; public function generate() { $this->id++; diff --git a/src/Mock/Storage/JsonObjectMemory.php b/src/Mock/Storage/JsonObjectMemory.php index 716f50f..11f6d59 100644 --- a/src/Mock/Storage/JsonObjectMemory.php +++ b/src/Mock/Storage/JsonObjectMemory.php @@ -13,15 +13,15 @@ class JsonObjectMemory extends Memory implements OffsetterInterface, LimiterInterface { - private $offset = 0; - private $limit = 0; + private int $offset = 0; + private int $limit = 0; - private $sorts = [ + private array $sorts = [ 'ascend' => [], 'descend' => [], ]; - private $conditions = []; + private array $conditions = []; public function retrieveAll(): array { @@ -85,9 +85,7 @@ private function applyFilters(array $results) foreach ($this->sorts as $type => $properties) { foreach ($properties as $property) { - usort($results, function ($a, $b) use ($property) { - return $this->compare($a, $b, $property); - }); + usort($results, fn($a, $b) => $this->compare($a, $b, $property)); if ($type == 'descend') { $results = array_reverse($results); diff --git a/src/Mock/Storage/MemoryFactory.php b/src/Mock/Storage/MemoryFactory.php index 823488d..65e3415 100644 --- a/src/Mock/Storage/MemoryFactory.php +++ b/src/Mock/Storage/MemoryFactory.php @@ -7,7 +7,7 @@ class MemoryFactory implements FactoryInterface { - private $stores; + private ?array $stores = null; public function getInstance(string $identifier, array $config = []) { diff --git a/test/Mock/IdGenerator/SequentialTest.php b/test/Mock/IdGenerator/SequentialTest.php index f1e743c..f037055 100644 --- a/test/Mock/IdGenerator/SequentialTest.php +++ b/test/Mock/IdGenerator/SequentialTest.php @@ -7,12 +7,12 @@ class SequentialTest extends TestCase { - public function test() { - $generator = new Sequential(); - $id1 = $generator->generate(); - $this->assertEquals(1, $id1); - $id2 = $generator->generate(); - $this->assertEquals(2, $id2); - } - -} \ No newline at end of file + public function test() + { + $generator = new Sequential(); + $id1 = $generator->generate(); + $this->assertEquals(1, $id1); + $id2 = $generator->generate(); + $this->assertEquals(2, $id2); + } +}