[PHP, Symfony] Автоматическая проверка кода за 5 минут
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Данная инструкция показывает как автоматизировать проверку на code style в вашем php проекте.
Давайте посмотрим как будет выглядеть настройка в новом проекте.
Шаг 1 — Делаем инициализацию composer (у кого он уже настроен, пропускаем)
Для этого в корне вашего проекта запускаем команду. Если у вас не установлен composer, то можете обратиться к официальной документации getcomposer.org
composer init
Шаг 2 — Добавляем .gitignore
###> phpstorm ###
.idea
###< phpstorm ###
/vendor/
###> friendsofphp/php-cs-fixer ###
/.php_cs
/.php_cs.cache
###< friendsofphp/php-cs-fixer ###
Шаг 3 — Добавляем нужные библиотеки
composer require --dev friendsofphp/php-cs-fixer symfony/process symfony/console squizlabs/php_codesniffer
Шаг 4 — Добавляем обработчик хука
Сам обработчик можно написать на чем угодно, но так как статься про php то будем писать код на нем.
Создаем файлик в папочке hooks/pre-commit.php
SPL
#!/usr/bin/php
<?php
define('VENDOR_DIR', __DIR__.'/../../vendor');
require VENDOR_DIR.'/autoload.php';
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Application;
use Symfony\Component\Process\Process;
class CodeQualityTool extends Application
{
/**
* @var OutputInterface
*/
private $output;
/**
* @var InputInterface
*/
private $input;
const PHP_FILES_IN_SRC = '/^src\/(.*)(\.php)$/';
public function __construct()
{
parent::__construct('Ecombo Quality Tool', '1.0.0');
}
/**
* @param InputInterface $input
* @param OutputInterface $output
*
* @return void
* @throws \Exception
*/
public function doRun(InputInterface $input, OutputInterface $output)
{
$this->input = $input;
$this->output = $output;
$output->writeln('<fg=white;options=bold;bg=red>Code Quality Tool</fg=white;options=bold;bg=red>');
$output->writeln('<info>Fetching files</info>');
$files = $this->extractCommitedFiles();
$output->writeln('<info>Running PHPLint</info>');
if (! $this->phpLint($files)) {
throw new \Exception('There are some PHP syntax errors!');
}
$output->writeln('<info>Checking code style with PHPCS</info>');
if (! $this->codeStylePsr($files)) {
throw new \Exception(sprintf('There are PHPCS coding standards violations!'));
}
$output->writeln('<info>Well done!</info>');
}
/**
* @return array
*/
private function extractCommitedFiles()
{
$output = array();
$against = 'HEAD';
exec("git diff-index --cached --name-status $against | egrep '^(A|M)' | awk '{print $2;}'", $output);
return $output;
}
/**
* @param array $files
*
* @return bool
*
* @throws \Exception
*/
private function phpLint($files)
{
$needle = '/(\.php)|(\.inc)$/';
$succeed = true;
foreach ($files as $file) {
if (! preg_match($needle, $file)) {
continue;
}
$process = new Process(['php', '-l', $file]);
$process->run();
if (! $process->isSuccessful()) {
$this->output->writeln($file);
$this->output->writeln(sprintf('<error>%s</error>', trim($process->getErrorOutput())));
if ($succeed) {
$succeed = false;
}
}
}
return $succeed;
}
/**
* @param array $files
*
* @return bool
*/
private function codeStylePsr(array $files)
{
$succeed = true;
$needle = self::PHP_FILES_IN_SRC;
$standard = 'PSR2';
foreach ($files as $file) {
if (! preg_match($needle, $file)) {
continue;
}
$phpCsFixer = new Process([
'php',
VENDOR_DIR.'/bin/phpcs',
'-n',
'--standard='.$standard,
$file,
]);
$phpCsFixer->setWorkingDirectory(__DIR__.'/../../');
$phpCsFixer->run();
if (! $phpCsFixer->isSuccessful()) {
$this->output->writeln(sprintf('<error>%s</error>', trim($phpCsFixer->getOutput())));
if ($succeed) {
$succeed = false;
}
}
}
return $succeed;
}
}
$console = new CodeQualityTool();
$console->run();
В данном примере код будет проходить 3 проверки:
— проверка на синтаксические ошибки
— проверка на PSR2 через code sniffer
PSR2 можно заменить на любой другой который поддерживает code sniffer. Список поддерживаемых стандартов можно увидеть введя команду
vendor/bin/phpcs -i
Шаг 5 — Конфигурируем composer для реализации автозапуска проверки на pre-commit
Для того чтобы код проверки запускался на pre commit хук нам необходимо положить файлик с кодом, который сделали в 3 пункте положить в папку .git/hooks/pre-commit. Это можно сделать вручную но куда удобнее это дело автоматизировать. Для этого нам нужно написать обработчик, который будет копировать этот файлик и повешать его на событие которые вызывается после composer install. Для этого делаем следующее.
5.1 Создаем сам обработчик который будет копировать файлик pre-commit.php в папку хуков гита
Создаем файлик src/Composer/ScriptHandler.php
SPL
<?php
namespace App\Composer;
use Composer\Script\Event;
class ScriptHandler
{
/**
* @param Event $event
*
* @return bool
*/
public static function preHooks(Event $event)
{
$io = $event->getIO();
$gitHook = '.git/hooks/pre-commit';
if (file_exists($gitHook)) {
unlink($gitHook);
$io->write('<info>Pre-commit hook removed!</info>');
}
return true;
}
/**
* @param Event $event
*
* @return bool
*
* @throws \Exception
*/
public static function postHooks(Event $event)
{
/** @var array $extras */
$extras = $event->getComposer()->getPackage()->getExtra();
if (! array_key_exists('hooks', $extras)) {
throw new \InvalidArgumentException('The parameter handler needs to be configured through the extra.hooks setting.');
}
$configs = $extras['hooks'];
if (! array_key_exists('pre-commit', $configs)) {
throw new \InvalidArgumentException('The parameter handler needs to be configured through the extra.hooks.pre-commit setting.');
}
if (file_exists('.git/hooks')) {
/** @var \Composer\IO\IOInterface $io */
$io = $event->getIO();
$gitHook = '.git/hooks/pre-commit';
$docHook = $configs['pre-commit'];
copy($docHook, $gitHook);
chmod($gitHook, 0777);
$io->write('<info>Pre-commit hook created!</info>');
}
return true;
}
}
5.2 Настраиваем composer чтобы запускался обработчик
в composer.json добавляем следующую секцию
"scripts": {
"post-install-cmd": [
"App\\Composer\\ScriptHandler::postHooks"
],
"post-update-cmd": [
"App\\Composer\\ScriptHandler::postHooks"
],
"pre-update-cmd": "App\\Composer\\ScriptHandler::preHooks",
"pre-install-cmd": "App\\Composer\\ScriptHandler::preHooks"
},
"extra": {
"hooks": {
"pre-commit": "hooks/pre-commit.php"
}
}
pre-update-cmd, pre-install-cmd — перед install и update удаляется старый обработчик
post-install-cmd, post-update-cmd — после install и update будет устанавливаться обработчик на pre commit
В итоге файлкик composer.json примет следующий вид
composer.json
SPL
{
"name": "admin/test",
"authors": [
{
"name": "vitaly.gorbunov",
"email": "cezar62882@gmail.com"
}
],
"minimum-stability": "stable",
"require": {},
"autoload": {
"psr-4": {
"App\": "src/"
}
},
"scripts": {
"post-install-cmd": [
"App\\Composer\\ScriptHandler::postHooks"
],
"post-update-cmd": [
"App\\Composer\\ScriptHandler::postHooks"
],
"pre-update-cmd": "App\\Composer\\ScriptHandler::preHooks",
"pre-install-cmd": "App\\Composer\\ScriptHandler::preHooks"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.16",
"symfony/process": "^5.0",
"symfony/console": "^5.0",
"squizlabs/php_codesniffer": "^3.5"
},
"extra": {
"hooks": {
"pre-commit": "hooks/pre-commit.php"
}
}
}
Запускаем еще раз composer install чтобы файлик скопировался куда надо.
Все готово, теперь если вы попытаетесь закомитить код с кривым code style то git console вам об этом скажет.
В качестве примере давайте создадим в папке src файлик MyClass.php по следующим содержаением.
<?php
namespace App;
class MyClass
{
private $var1; private $var2;
public function __construct() {
}
public function test() {
}
}
Пытаемся закомитить и получаем ошибки проверки кода.
MBP-Admin:test admin$ git commit -am 'test'
Code Quality Tool
Fetching files
Running PHPLint
Checking code style with PHPCS
FILE: /Users/admin/projects/test/src/MyClass.php
----------------------------------------------------------------------
FOUND 5 ERRORS AFFECTING 5 LINES
----------------------------------------------------------------------
8 | ERROR | [x] Each PHP statement must be on a line by itself
10 | ERROR | [x] Opening brace should be on a new line
13 | ERROR | [x] Opening brace should be on a new line
15 | ERROR | [x] Function closing brace must go on the next line
| | following the body; found 1 blank lines before
| | brace
16 | ERROR | [x] Expected 1 newline at end of file; 0 found
----------------------------------------------------------------------
PHPCBF CAN FIX THE 5 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------
Time: 49ms; Memory: 6MB
In pre-commit line 53:
There are PHPCS coding standards violations!
Ура, всё работает.
===========
Источник:
habr.com
===========
Похожие новости:
- [PHP, Nginx, Laravel] Как переход со стека Nginx+FPM на Swoole увеличил производительность PHP API на 91%
- [Разработка веб-сайтов, PHP, Laravel] Laravel–Дайджест (8–21 марта 2021)
- [PHP, Проектирование и рефакторинг, Laravel] Еще немного про сервисный слой в PHP
- [PHP, Программирование] Как дойти до CQRS, если у тебя PHP
- [Высокая производительность, Разработка веб-сайтов, PHP, Программирование] Теория программирования: пакетные принципы и метрики
- [Разработка веб-сайтов, PHP, Laravel, Локализация продуктов] Разделение кода и текста: прототип
- [PHP, Программирование] Работа с заказом через админку OpenCart, взгляд изнутри
- [Разработка веб-сайтов, PHP, Программирование, Учебный процесс в IT, Карьера в IT-индустрии] Курсы PHP-программирования в Минске. Куда пойти учиться?
- [Ajax, PHP, JavaScript, CRM-системы] Обзор разработки дополнений для amoCRM, с использованием webHook и виджетов
- [Разработка веб-сайтов, PHP, Laravel] Laravel–Дайджест (22 февраля – 7 марта 2021)
Теги для поиска: #_php, #_symfony, #_instrumenty_dlja_vebrazrabotki (инструменты для веб-разработки), #_php, #_symfony
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 20:12
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Данная инструкция показывает как автоматизировать проверку на code style в вашем php проекте. Давайте посмотрим как будет выглядеть настройка в новом проекте. Шаг 1 — Делаем инициализацию composer (у кого он уже настроен, пропускаем) Для этого в корне вашего проекта запускаем команду. Если у вас не установлен composer, то можете обратиться к официальной документации getcomposer.org composer init
Шаг 2 — Добавляем .gitignore ###> phpstorm ###
.idea ###< phpstorm ### /vendor/ ###> friendsofphp/php-cs-fixer ### /.php_cs /.php_cs.cache ###< friendsofphp/php-cs-fixer ### Шаг 3 — Добавляем нужные библиотеки composer require --dev friendsofphp/php-cs-fixer symfony/process symfony/console squizlabs/php_codesniffer
Шаг 4 — Добавляем обработчик хука Сам обработчик можно написать на чем угодно, но так как статься про php то будем писать код на нем. Создаем файлик в папочке hooks/pre-commit.phpSPL#!/usr/bin/php
<?php define('VENDOR_DIR', __DIR__.'/../../vendor'); require VENDOR_DIR.'/autoload.php'; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Application; use Symfony\Component\Process\Process; class CodeQualityTool extends Application { /** * @var OutputInterface */ private $output; /** * @var InputInterface */ private $input; const PHP_FILES_IN_SRC = '/^src\/(.*)(\.php)$/'; public function __construct() { parent::__construct('Ecombo Quality Tool', '1.0.0'); } /** * @param InputInterface $input * @param OutputInterface $output * * @return void * @throws \Exception */ public function doRun(InputInterface $input, OutputInterface $output) { $this->input = $input; $this->output = $output; $output->writeln('<fg=white;options=bold;bg=red>Code Quality Tool</fg=white;options=bold;bg=red>'); $output->writeln('<info>Fetching files</info>'); $files = $this->extractCommitedFiles(); $output->writeln('<info>Running PHPLint</info>'); if (! $this->phpLint($files)) { throw new \Exception('There are some PHP syntax errors!'); } $output->writeln('<info>Checking code style with PHPCS</info>'); if (! $this->codeStylePsr($files)) { throw new \Exception(sprintf('There are PHPCS coding standards violations!')); } $output->writeln('<info>Well done!</info>'); } /** * @return array */ private function extractCommitedFiles() { $output = array(); $against = 'HEAD'; exec("git diff-index --cached --name-status $against | egrep '^(A|M)' | awk '{print $2;}'", $output); return $output; } /** * @param array $files * * @return bool * * @throws \Exception */ private function phpLint($files) { $needle = '/(\.php)|(\.inc)$/'; $succeed = true; foreach ($files as $file) { if (! preg_match($needle, $file)) { continue; } $process = new Process(['php', '-l', $file]); $process->run(); if (! $process->isSuccessful()) { $this->output->writeln($file); $this->output->writeln(sprintf('<error>%s</error>', trim($process->getErrorOutput()))); if ($succeed) { $succeed = false; } } } return $succeed; } /** * @param array $files * * @return bool */ private function codeStylePsr(array $files) { $succeed = true; $needle = self::PHP_FILES_IN_SRC; $standard = 'PSR2'; foreach ($files as $file) { if (! preg_match($needle, $file)) { continue; } $phpCsFixer = new Process([ 'php', VENDOR_DIR.'/bin/phpcs', '-n', '--standard='.$standard, $file, ]); $phpCsFixer->setWorkingDirectory(__DIR__.'/../../'); $phpCsFixer->run(); if (! $phpCsFixer->isSuccessful()) { $this->output->writeln(sprintf('<error>%s</error>', trim($phpCsFixer->getOutput()))); if ($succeed) { $succeed = false; } } } return $succeed; } } $console = new CodeQualityTool(); $console->run(); В данном примере код будет проходить 3 проверки: — проверка на синтаксические ошибки — проверка на PSR2 через code sniffer PSR2 можно заменить на любой другой который поддерживает code sniffer. Список поддерживаемых стандартов можно увидеть введя команду vendor/bin/phpcs -i
Шаг 5 — Конфигурируем composer для реализации автозапуска проверки на pre-commit Для того чтобы код проверки запускался на pre commit хук нам необходимо положить файлик с кодом, который сделали в 3 пункте положить в папку .git/hooks/pre-commit. Это можно сделать вручную но куда удобнее это дело автоматизировать. Для этого нам нужно написать обработчик, который будет копировать этот файлик и повешать его на событие которые вызывается после composer install. Для этого делаем следующее. 5.1 Создаем сам обработчик который будет копировать файлик pre-commit.php в папку хуков гита Создаем файлик src/Composer/ScriptHandler.phpSPL<?php
namespace App\Composer; use Composer\Script\Event; class ScriptHandler { /** * @param Event $event * * @return bool */ public static function preHooks(Event $event) { $io = $event->getIO(); $gitHook = '.git/hooks/pre-commit'; if (file_exists($gitHook)) { unlink($gitHook); $io->write('<info>Pre-commit hook removed!</info>'); } return true; } /** * @param Event $event * * @return bool * * @throws \Exception */ public static function postHooks(Event $event) { /** @var array $extras */ $extras = $event->getComposer()->getPackage()->getExtra(); if (! array_key_exists('hooks', $extras)) { throw new \InvalidArgumentException('The parameter handler needs to be configured through the extra.hooks setting.'); } $configs = $extras['hooks']; if (! array_key_exists('pre-commit', $configs)) { throw new \InvalidArgumentException('The parameter handler needs to be configured through the extra.hooks.pre-commit setting.'); } if (file_exists('.git/hooks')) { /** @var \Composer\IO\IOInterface $io */ $io = $event->getIO(); $gitHook = '.git/hooks/pre-commit'; $docHook = $configs['pre-commit']; copy($docHook, $gitHook); chmod($gitHook, 0777); $io->write('<info>Pre-commit hook created!</info>'); } return true; } } 5.2 Настраиваем composer чтобы запускался обработчик в composer.json добавляем следующую секцию "scripts": {
"post-install-cmd": [ "App\\Composer\\ScriptHandler::postHooks" ], "post-update-cmd": [ "App\\Composer\\ScriptHandler::postHooks" ], "pre-update-cmd": "App\\Composer\\ScriptHandler::preHooks", "pre-install-cmd": "App\\Composer\\ScriptHandler::preHooks" }, "extra": { "hooks": { "pre-commit": "hooks/pre-commit.php" } } pre-update-cmd, pre-install-cmd — перед install и update удаляется старый обработчик post-install-cmd, post-update-cmd — после install и update будет устанавливаться обработчик на pre commit В итоге файлкик composer.json примет следующий вид composer.jsonSPL{
"name": "admin/test", "authors": [ { "name": "vitaly.gorbunov", "email": "cezar62882@gmail.com" } ], "minimum-stability": "stable", "require": {}, "autoload": { "psr-4": { "App\": "src/" } }, "scripts": { "post-install-cmd": [ "App\\Composer\\ScriptHandler::postHooks" ], "post-update-cmd": [ "App\\Composer\\ScriptHandler::postHooks" ], "pre-update-cmd": "App\\Composer\\ScriptHandler::preHooks", "pre-install-cmd": "App\\Composer\\ScriptHandler::preHooks" }, "require-dev": { "friendsofphp/php-cs-fixer": "^2.16", "symfony/process": "^5.0", "symfony/console": "^5.0", "squizlabs/php_codesniffer": "^3.5" }, "extra": { "hooks": { "pre-commit": "hooks/pre-commit.php" } } } Запускаем еще раз composer install чтобы файлик скопировался куда надо. Все готово, теперь если вы попытаетесь закомитить код с кривым code style то git console вам об этом скажет. В качестве примере давайте создадим в папке src файлик MyClass.php по следующим содержаением. <?php
namespace App; class MyClass { private $var1; private $var2; public function __construct() { } public function test() { } } Пытаемся закомитить и получаем ошибки проверки кода. MBP-Admin:test admin$ git commit -am 'test'
Code Quality Tool Fetching files Running PHPLint Checking code style with PHPCS FILE: /Users/admin/projects/test/src/MyClass.php ---------------------------------------------------------------------- FOUND 5 ERRORS AFFECTING 5 LINES ---------------------------------------------------------------------- 8 | ERROR | [x] Each PHP statement must be on a line by itself 10 | ERROR | [x] Opening brace should be on a new line 13 | ERROR | [x] Opening brace should be on a new line 15 | ERROR | [x] Function closing brace must go on the next line | | following the body; found 1 blank lines before | | brace 16 | ERROR | [x] Expected 1 newline at end of file; 0 found ---------------------------------------------------------------------- PHPCBF CAN FIX THE 5 MARKED SNIFF VIOLATIONS AUTOMATICALLY ---------------------------------------------------------------------- Time: 49ms; Memory: 6MB In pre-commit line 53: There are PHPCS coding standards violations! Ура, всё работает. =========== Источник: habr.com =========== Похожие новости:
|
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 20:12
Часовой пояс: UTC + 5