diff --git a/.gitignore b/.gitignore index 187669e..4ac36bf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,11 @@ .idea/ +.vscode/ .DS_Store vendor/ +composer.lock +.phpunit.cache/ +.phpunit.result.cache +.phpcs-cache +.phpstan-cache/ +.psalm-cache/ +*.log diff --git a/README.md b/README.md index ecbde94..5b76aa0 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,22 @@ bin/magento setup:upgrade composer remove bradsearch/magento-extension ``` +## Development + +```bash +composer install # installs captainhook pre-commit + pre-push hooks +composer phpcbf # auto-fix Magento2 coding standard +composer phpcs # Magento2 coding standard check +composer phpstan # static analysis at level 6 +composer psalm # static analysis at error level 4 +composer test # phpunit unit tests +composer check # all of the above +``` + +Pre-commit hooks run `phpcbf` + `phpcs` + `phpstan` on staged PHP files. +Pre-push runs `psalm` + full test suite. CI (GitHub Actions) runs the same +checks across PHP 7.4 / 8.1 / 8.2 / 8.3 on every PR. + ## License Apache License 2.0 - see [LICENSE](LICENSE). diff --git a/captainhook.json b/captainhook.json new file mode 100644 index 0000000..e17c320 --- /dev/null +++ b/captainhook.json @@ -0,0 +1,67 @@ +{ + "config": { + "run-mode": "php" + }, + "pre-commit": { + "enabled": true, + "actions": [ + { + "action": "vendor/bin/phpcbf {$STAGED_FILES|of-type:php}", + "conditions": [ + { + "exec": "\\CaptainHook\\App\\Hook\\Condition\\FileStaged\\OfType", + "args": ["php"] + } + ] + }, + { + "action": "vendor/bin/phpcs {$STAGED_FILES|of-type:php}", + "conditions": [ + { + "exec": "\\CaptainHook\\App\\Hook\\Condition\\FileStaged\\OfType", + "args": ["php"] + } + ] + }, + { + "action": "vendor/bin/phpstan analyse {$STAGED_FILES|of-type:php}", + "conditions": [ + { + "exec": "\\CaptainHook\\App\\Hook\\Condition\\FileStaged\\OfType", + "args": ["php"] + } + ] + } + ] + }, + "commit-msg": { + "enabled": false, + "actions": [] + }, + "pre-push": { + "enabled": true, + "actions": [ + { "action": "composer psalm" } + ] + }, + "prepare-commit-msg": { + "enabled": false, + "actions": [] + }, + "post-commit": { + "enabled": false, + "actions": [] + }, + "post-merge": { + "enabled": false, + "actions": [] + }, + "post-checkout": { + "enabled": false, + "actions": [] + }, + "post-rewrite": { + "enabled": false, + "actions": [] + } +} diff --git a/composer.json b/composer.json index d472873..7750f20 100644 --- a/composer.json +++ b/composer.json @@ -28,6 +28,22 @@ "magento/module-catalog-graph-ql": "*", "magento/module-store-graph-ql": "*" }, + "require-dev": { + "squizlabs/php_codesniffer": "^3.7", + "magento/magento-coding-standard": "*", + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", + "phpstan/phpstan": "^1.10", + "vimeo/psalm": "^6.0 <6.5", + "phpunit/phpunit": "^9.6 || ^10.0", + "captainhook/captainhook": "^5.22", + "captainhook/plugin-composer": "^5.3" + }, + "repositories": { + "magento": { + "type": "composer", + "url": "https://repo.magento.com/" + } + }, "autoload": { "files": [ "Analytics/registration.php", @@ -41,5 +57,28 @@ "BradSearch\\ProductFeatures\\": "ProductFeatures/", "BradSearch\\SearchGraphQl\\": "SearchGraphQl/" } + }, + "scripts": { + "post-install-cmd": "@register-phpcs-paths", + "post-update-cmd": "@register-phpcs-paths", + "register-phpcs-paths": "phpcs --config-set installed_paths vendor/magento/magento-coding-standard,vendor/phpcsstandards/phpcsutils,vendor/magento/php-compatibility-fork", + "phpcs": "phpcs", + "phpcbf": "phpcbf", + "phpstan": "phpstan analyse --memory-limit=1G", + "psalm": "psalm", + "test": "phpunit", + "check": [ + "@phpcs", + "@phpstan", + "@psalm" + ] + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true, + "captainhook/plugin-composer": true, + "magento/composer-dependency-version-audit-plugin": true + }, + "sort-packages": true } } diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..7b71e4a --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,37 @@ + + + PHP_CodeSniffer ruleset for bradsearch/magento-extension. Extends Magento2. + + + + + + + Analytics + Autocomplete + ProductFeatures + SearchGraphQl + + */Test/* + */vendor/* + + + + + + + + SearchGraphQl/Plugin/CatalogGraphQl/Model/Resolver/Aggregations\.php + SearchGraphQl/Plugin/CatalogGraphQl/Model/Resolver/Products\.php + + + + + SearchGraphQl/Model/Data/*\.php + + diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..a28d855 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,25 @@ + + + + + ProductFeatures/Test/Unit + SearchGraphQl/Test/Unit + + + + + Analytics + Autocomplete + ProductFeatures + SearchGraphQl + + + */Test + */registration.php + + + diff --git a/psalm-baseline.xml b/psalm-baseline.xml new file mode 100644 index 0000000..6545a03 --- /dev/null +++ b/psalm-baseline.xml @@ -0,0 +1,195 @@ + + + + + + + + + + + + queue]]> + + + collectionFactory]]> + + + + + + + + + + + + + + + + '"']]> + + + + + + + + + groupCollection]]> + + + + + + + + + + + + + + + + + placeholderFactory]]> + + + + + + + + + + + + + + queue]]> + + + + + syncStateFactory]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + collectionFactory]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + operation !== null]]> + operation->name !== null]]> + operation)]]> + operation) && + $info->operation !== null]]> + operation) && + $info->operation !== null && + isset($info->operation->name) && + $info->operation->name !== null]]> + operation) && + $info->operation !== null && + isset($info->operation->name) && + $info->operation->name !== null && + isset($info->operation->name->value)]]> + + + + + + + + + + + operation !== null]]> + operation !== null]]> + operation->name !== null]]> + operation->name !== null]]> + operation)]]> + operation)]]> + operation) && + $info->operation !== null]]> + operation) && + $info->operation !== null]]> + operation) && + $info->operation !== null && + isset($info->operation->name) && + $info->operation->name !== null]]> + operation) && + $info->operation !== null && + isset($info->operation->name) && + $info->operation->name !== null]]> + operation) && + $info->operation !== null && + isset($info->operation->name) && + $info->operation->name !== null && + isset($info->operation->name->value)]]> + operation) && + $info->operation !== null && + isset($info->operation->name) && + $info->operation->name !== null && + isset($info->operation->name->value)]]> + + + diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..9bf80cb --- /dev/null +++ b/psalm.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +