-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: create composer script for phpcbf
Add instructions in the README.md file
- Loading branch information
1 parent
5b2e005
commit 9b1cf4b
Showing
4 changed files
with
215 additions
and
1 deletion.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,83 @@ | ||
# PHP Code Sniffer Helpers | ||
|
||
[![License](https://img.shields.io/github/license/nelson6e65/php_nml.svg)](LICENSE) | ||
[![License](https://img.shields.io/github/license/nelson6e65/php-code-sniffer-helpers.svg)](LICENSE) | ||
[![time tracker](https://wakatime.com/badge/github/nelson6e65/php-code-sniffer-helpers.svg)](https://wakatime.com/badge/github/nelson6e65/php-code-sniffer-helpers) | ||
|
||
Helpers for PHP Code Sniffer. | ||
|
||
## Installation | ||
|
||
```sh | ||
composer require --dev nelson6e65/code-sniffer-helpers | ||
``` | ||
|
||
## Features | ||
|
||
### Composer scripts | ||
|
||
#### `phpcbf` for lint-staged | ||
|
||
A wrapper to fix your staged code (or argumented files/folders) using the **PHP Code Sniffer** auto-fixer. | ||
|
||
There is a bug that does not allows you to use it directly as autofixer (https://github.com/squizlabs/PHP_CodeSniffer/issues/1818). There is [a workarround for using it as a composer script](https://github.com/squizlabs/PHP_CodeSniffer/issues/1818#issuecomment-735620637), but does not works for using it in a [lint-staged](https://github.com/okonet/lint-staged) pre-commit hook. | ||
|
||
This helper is designed to be run with lint-staged, but you can also use it directly in your composer script. | ||
|
||
##### Setup with lint-staged | ||
|
||
Add the script to your composer.json: | ||
|
||
```json | ||
{ | ||
"scripts": { | ||
"cs:fix-filtered": ["NelsonMartell\\PhpCodeSniffer\\ComposerScripts::phpcbf"] | ||
} | ||
} | ||
``` | ||
|
||
> I used `"cs:fix-filtered"` name, but you can use any script name you like. | ||
Configure your Husky + lint-staged in your package.json | ||
|
||
```json | ||
{ | ||
"husky": { | ||
"hooks": { | ||
"pre-commit": "lint-staged" | ||
} | ||
}, | ||
"lint-staged": { | ||
"*.php": "composer cs:fix-filtered" | ||
} | ||
} | ||
``` | ||
|
||
> Example for Husky 4. Adapt it if you use Husky 5. | ||
##### Usage | ||
|
||
You can also run it directly with composer by using `composer cs:fix-filtered {PATHS}`. Example: | ||
|
||
```sh | ||
composer cs:fix-filtered src/ tests/ config/my-config-file.php | ||
``` | ||
|
||
> Note: Non exixtent files/directories are ignored. | ||
##### Output | ||
|
||
The output is inspired on [pretty-quick](https://github.com/azz/pretty-quick) output: | ||
|
||
```sh | ||
composer cs:fix-filtered config/ src/Example.php src/non-existent-file.php | ||
``` | ||
|
||
![output1](.github/screenshots/output1.png) | ||
|
||
## License | ||
|
||
[![License](https://img.shields.io/github/license/nelson6e65/php-code-sniffer-helpers.svg)](LICENSE) | ||
|
||
Copyright (c) 2021 Nelson Martell | ||
|
||
Read the [`LICENSE` file](LICENSE) for details. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace NelsonMartell\PhpCodeSniffer; | ||
|
||
use Composer\IO\IOInterface; | ||
use Composer\Script\Event; | ||
|
||
/** | ||
* Composer scripts helpers. | ||
*/ | ||
class ComposerScripts | ||
{ | ||
/** | ||
* @var string|null | ||
*/ | ||
protected static $binDir; | ||
|
||
/** | ||
* @var string|null | ||
*/ | ||
protected static $vendorDir; | ||
|
||
protected static function getBinDir(Event $event) | ||
{ | ||
if (!static::$binDir) { | ||
static::$binDir = realpath($event->getComposer()->getConfig()->get('bin-dir')); | ||
} | ||
|
||
return static::$binDir; | ||
} | ||
|
||
protected static function getVendorDir(Event $event) | ||
{ | ||
if (!static::$vendorDir) { | ||
static::$vendorDir = realpath($event->getComposer()->getConfig()->get('vendor-dir')); | ||
} | ||
|
||
return static::$vendorDir; | ||
} | ||
|
||
protected static function bootstrap(Event $event) | ||
{ | ||
require_once static::getVendorDir($event) . '/autoload.php'; | ||
} | ||
|
||
/** | ||
* Custom PHP Code Sniffer Fixer to be run with lint-staged pre-commit hook. | ||
*/ | ||
public static function phpcbf(Event $event): void | ||
{ | ||
$start_time = microtime(true); | ||
|
||
static::bootstrap($event); | ||
|
||
$rootDir = realpath(getcwd()); | ||
|
||
$cmd = str_replace($rootDir . DIRECTORY_SEPARATOR, '', realpath(static::getBinDir($event) . '/phpcbf')); | ||
|
||
$files = $event->getArguments(); | ||
$count = count($files); | ||
|
||
$ignoredPaths = []; | ||
|
||
if ($count > 0) { | ||
$event->getIO()->write("Fixing PHP Coding Standard of ${count} paths."); | ||
|
||
foreach ($files as $i => $file) { | ||
$realPath = realpath($file); | ||
|
||
if (!$realPath) { | ||
$ignoredPaths[] = $file; | ||
continue; | ||
} | ||
|
||
// if ($realPath === realpath(__FILE__)) { | ||
// // Do not self-fix this file when lint-staged | ||
// continue; | ||
// } | ||
|
||
$relativePath = str_replace( | ||
[$rootDir . DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR], | ||
['', '/'], | ||
$realPath | ||
); | ||
|
||
$type = strlen($relativePath) < 4 || stripos($relativePath, '.php', -4) === false ? 'directory' : 'file'; | ||
|
||
$event->getIO()->write("Improving <info>${relativePath}</info> ${type}..."); | ||
|
||
$output = []; | ||
$return = 0; | ||
|
||
// NOTE: workarround: need to run 2 times due to a bug that exits 1 instead of 0 when a file gets fixed | ||
// https://github.com/squizlabs/PHP_CodeSniffer/issues/1818#issuecomment-735620637 | ||
exec("${cmd} \"${realPath}\" || ${cmd} \"${realPath}\" -q", $output, $return); | ||
|
||
$event->getIO()->write($output, true, IOInterface::VERBOSE); | ||
|
||
if ($return !== 0) { | ||
$event->getIO()->error("Error! Unable to autofix the ${relativePath} file!"); | ||
$event->getIO()->write( | ||
'<comment>Run <options=bold>`phpcs`</> manually to check the conflicting files</comment>' | ||
); | ||
exit(1); | ||
} | ||
} | ||
} | ||
|
||
$event->getIO()->write('<info>Everything is awesome!</info>'); | ||
|
||
$end_time = microtime(true); | ||
$execution_time = round($end_time - $start_time, 2); | ||
|
||
$event->getIO()->write("Done in ${execution_time}s"); | ||
|
||
if (count($ignoredPaths)) { | ||
$ignoredPaths = array_map(function ($item) { | ||
return ' - ' . $item; | ||
}, $ignoredPaths); | ||
|
||
$event->getIO()->write('<comment>Note: Some paths were not found:</comment>'); | ||
$event->getIO()->write($ignoredPaths); | ||
} | ||
} | ||
} |