├── .gitignore ├── LICENSE ├── README.md ├── composer.json └── pretty /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | /composer.phar 3 | /composer.lock 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Matthieu Napoli 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![](https://hc4rcprbe1.execute-api.eu-west-1.amazonaws.com/dev?name=mnapoli/pretty)](https://prettyci.com/) 2 | 3 | **A single CLI command with sane defaults to simplify CodeSniffer and PHP-CS-Fixer.** 4 | 5 | --- 6 | 7 | [PHP CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) and [PHP-CS-Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer) are powerful but using them is not simple. It is not always obvious which tool a project uses and whether there is a configuration file to use or whether you need to provide options to the CLI command. 8 | 9 | Now it's easy, simply run: 10 | 11 | ``` 12 | pretty 13 | ``` 14 | 15 | *Pretty* will detect the configuration file that exist in the current directory and will run the correct tool. If no configuration file exist, *Pretty* will run PHP CodeSniffer with PSR-2 by default. 16 | 17 | If errors are found, simply run: 18 | 19 | ``` 20 | pretty fix 21 | ``` 22 | 23 | Again, *Pretty* will run the appropriate tool (`php-cs-fixer` or `phpcbf`) to fix as many errors as possible in your code. 24 | 25 | ## Installation 26 | 27 | If you have already [set up a global install of Composer](http://akrabat.com/php/global-installation-of-php-tools-with-composer/) just run: 28 | 29 | ``` 30 | composer global require mnapoli/pretty 31 | ``` 32 | 33 | *Pretty* comes with no dependencies so it should not bring any conflict in Composer. 34 | 35 | You can also install it as a local dependency of your project with `composer require --dev mnapoli/pretty`. In that case you can start the tool with `vendor/bin/pretty`. 36 | 37 | You will be able to update to new versions by running: 38 | 39 | ``` 40 | composer global update mnapoli/pretty 41 | ``` 42 | 43 | ## Usage 44 | 45 | Running an analysis is as simple as running: 46 | 47 | ``` 48 | pretty 49 | ``` 50 | 51 | This command will not change any code. To fix errors reported by this command, simply run: 52 | 53 | ``` 54 | pretty fix 55 | ``` 56 | 57 | In case you are running the analyses in CI you might want to run: 58 | 59 | ``` 60 | pretty ci 61 | ``` 62 | 63 | This will disable the caching option of PHP-CS-Fixer or CodeSniffer (because the cache will not be kept in CI). 64 | 65 | ## Hosted continuous integration 66 | 67 | If you are using `pretty` in your daily development workflow you may be interested in [PrettyCI.com](https://prettyci.com/), the SaaS version of `pretty`. 68 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mnapoli/pretty", 3 | "description": "Run all code formatting tools with one command: pretty", 4 | "keywords": ["pretty", "formatting", "psr-1", "psr-2", "code", "style", "coding", "standard"], 5 | "license": "MIT", 6 | "type": "project", 7 | "require": { 8 | "php": ">=7.0" 9 | }, 10 | "bin": [ 11 | "pretty" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /pretty: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | [ 13 | 'php-cs-fixer' => 'php-cs-fixer fix --dry-run --allow-risky=yes --diff', 14 | 'phpcs' => 'phpcs', 15 | 'default' => 'phpcs --standard=PSR2 --extensions=php --ignore="vendor/*" .', 16 | ], 17 | /** 18 | * The `fix` command will modify the files to try to fix the errors. 19 | */ 20 | 'fix' => [ 21 | 'php-cs-fixer' => 'php-cs-fixer fix --allow-risky=yes', 22 | 'phpcs' => 'phpcbf', 23 | 'default' => 'phpcbf --standard=PSR2 --extensions=php --ignore="vendor/*" .', 24 | ], 25 | /** 26 | * In CI we disable the cache. 27 | */ 28 | 'ci' => [ 29 | 'php-cs-fixer' => 'php-cs-fixer fix --dry-run --allow-risky=yes --diff --using-cache=no', 30 | 'phpcs' => 'phpcs --no-cache --no-colors', 31 | 'default' => 'phpcs --standard=PSR2 --extensions=php --ignore="vendor/*" --no-cache --no-colors .', 32 | ], 33 | ]; 34 | 35 | $task = isset($argv[1]) ? $argv[1] : 'default'; 36 | 37 | if ($task === 'help') { 38 | help(); 39 | exit(0); 40 | } 41 | if (!isset($commands[$task])) { 42 | echo "Unrecognized command '$task'\n"; 43 | help(); 44 | exit(1); 45 | } 46 | 47 | $commands = $commands[$task]; 48 | 49 | $command = ''; 50 | 51 | // Detect which tool to run 52 | if (file_exists('.phpcs.xml') || file_exists('phpcs.xml') || file_exists('.phpcs.xml.dist') || file_exists('phpcs.xml.dist')) { 53 | echo "PHP CodeSniffer configuration file found, running CodeSniffer with version\n"; 54 | $command = $commands['phpcs']; 55 | $program = explode(' ', $command, 2)[0]; 56 | assertPhpCodeSnifferIsInstalled($program); 57 | 58 | passthru($program." --version"); 59 | echo "\n"; 60 | } elseif (file_exists('.php_cs') || file_exists('.php_cs.dist')) { 61 | echo "PHP-CS-Fixer configuration file found, running PHP-CS-Fixer with version\n"; 62 | assertPhpCsFixerIsInstalled(); 63 | $command = $commands['php-cs-fixer']; 64 | 65 | passthru("php-cs-fixer --version"); 66 | echo "\n"; 67 | } else { 68 | echo "No configuration file found, running PHP CodeSniffer with PSR-2 with version\n"; 69 | $command = $commands['default']; 70 | $program = explode(' ', $command, 2)[0]; 71 | assertPhpCodeSnifferIsInstalled($program); 72 | 73 | passthru($program." --version"); 74 | echo "\n"; 75 | } 76 | 77 | // Run the analysis 78 | passthru($command, $exitCode); 79 | 80 | if ($exitCode !== 0) { 81 | echo "Errors were found, run 'pretty fix' to fix them.\n"; 82 | } 83 | 84 | exit($exitCode); 85 | 86 | function commandExists($command) 87 | { 88 | if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { 89 | $return = shell_exec('where ' . escapeshellarg($command)); 90 | } else { 91 | $return = shell_exec('which ' . escapeshellarg($command)); 92 | } 93 | return !empty($return); 94 | } 95 | 96 | function assertPhpCodeSnifferIsInstalled($command) 97 | { 98 | if (!commandExists($command)) { 99 | echo <<