├── .devcontainer ├── Dockerfile ├── devcontainer.json └── docker-compose.yml ├── .gitignore ├── LICENSE ├── README.md ├── composer.json ├── config └── fixer.php ├── phpunit.xml ├── src ├── Console │ └── FixCommand.php ├── FixerServiceProvider.php └── Services │ ├── Fixer.php │ └── Fixer │ └── Concerns │ ├── HasConfigurationResolver.php │ ├── HasErrorsManager.php │ ├── HasEventDispatcher.php │ ├── HasFinder.php │ ├── HasFixEvent.php │ ├── HasProgressOutput.php │ ├── HasRunner.php │ └── HasStopWatch.php └── tests └── .gitkeep /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | # Update the VARIANT arg in docker-compose.yml to pick a PHP version: 7, 7.4, 7.3 2 | ARG VARIANT=8 3 | FROM mcr.microsoft.com/vscode/devcontainers/php:0-${VARIANT} 4 | 5 | # Install MariaDB client 6 | RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ 7 | && apt-get install -y mariadb-client \ 8 | && apt-get clean -y && rm -rf /var/lib/apt/lists/* 9 | 10 | # Update args in docker-compose.yaml to set the UID/GID of the "vscode" user. 11 | ARG USER_UID=1000 12 | ARG USER_GID=$USER_UID 13 | RUN if [ "$USER_GID" != "1000" ] || [ "$USER_UID" != "1000" ]; then groupmod --gid $USER_GID vscode && usermod --uid $USER_UID --gid $USER_GID vscode; fi 14 | 15 | RUN pecl install -o -f redis \ 16 | && rm -rf /tmp/pear \ 17 | && docker-php-ext-enable redis 18 | 19 | # Install php-mysql driver 20 | RUN docker-php-ext-install mysqli pdo pdo_mysql 21 | 22 | # [Optional] Install a version of Node.js using nvm for front end dev 23 | ARG INSTALL_NODE="true" 24 | ARG NODE_VERSION="lts/*" 25 | RUN if [ "${INSTALL_NODE}" = "true" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi 26 | RUN rm -rf /usr/local/etc/php/conf.d/xdebug.ini 27 | # [Optional] Uncomment this section to install additional OS packages. 28 | # RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ 29 | # && apt-get -y install --no-install-recommends 30 | 31 | # [Optional] Uncomment this line to install global node packages. 32 | # RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g " 2>&1 33 | 34 | WORKDIR /workspace 35 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: 2 | // https://github.com/microsoft/vscode-dev-containers/tree/v0.166.1/containers/php-mariadb 3 | // Update the VARIANT arg in docker-compose.yml to pick a PHP version: 7, 7.3, 7.4 4 | { 5 | "name": "metrics-app", 6 | "dockerComposeFile": "docker-compose.yml", 7 | "service": "app", 8 | "workspaceFolder": "/workspace", 9 | 10 | // Set *default* container specific settings.json values on container create. 11 | "settings": { 12 | "terminal.integrated.shell.linux": "/bin/bash" 13 | }, 14 | 15 | // Add the IDs of extensions you want installed when the container is created. 16 | "extensions": [ 17 | "eamodio.gitlens", 18 | "mikestead.dotenv", 19 | "felixfbecker.php-debug", 20 | "marabesi.php-import-checker", 21 | "fterrag.vscode-php-cs-fixer", 22 | "marsl.vscode-php-refactoring", 23 | "coenraads.bracket-pair-colorizer-2", 24 | "bmewburn.vscode-intelephense-client" 25 | ], 26 | 27 | // For use with PHP or Apache (e.g.php -S localhost:8080 or apache2ctl start) 28 | "forwardPorts": [8080, 3306], 29 | 30 | // Use 'postCreateCommand' to run commands after the container is created. 31 | // "postCreateCommand": "sudo chmod a+x \"$(pwd)\" && sudo rm -rf /var/www/html && sudo ln -s \"$(pwd)\" /var/www/html" 32 | 33 | // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. 34 | "remoteUser": "vscode" 35 | } 36 | -------------------------------------------------------------------------------- /.devcontainer/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | app: 5 | build: 6 | context: . 7 | dockerfile: Dockerfile 8 | args: 9 | # [Choice] PHP version: 7, 7.4, 7.3 10 | VARIANT: "8" 11 | # [Option] Install Node.js 12 | INSTALL_NODE: "true" 13 | NODE_VERSION: "lts/*" 14 | # On Linux, you may need to update USER_UID and USER_GID below if not your local UID is not 1000. 15 | USER_UID: 1000 16 | USER_GID: 1000 17 | 18 | volumes: 19 | - ..:/workspace:cached 20 | 21 | # Overrides default command so things don't shut down after the process ends. 22 | command: sleep infinity 23 | 24 | # Uncomment the next line to use a non-root user for all processes. 25 | # user: vscode -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | .DS_Store 3 | .idea 4 | composer.lock 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Signature Tech Studio, Inc 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Deprecated 2 | 3 | **This package is deprecated. We encourage you to look at [Laravel Pint](https://laravel.com/docs/pint) instead.** 4 | 5 | # Laravel PHP CS Fixer 6 | 7 | The PHP CS Fixer is maintained on GitHub at https://github.com/FriendsOfPHP/PHP-CS-Fixer 8 | bug reports and ideas about new features are welcome there. 9 | 10 | > The PHP Coding Standards Fixer (PHP CS Fixer) tool fixes your code to follow standards; 11 | whether you want to follow PHP coding standards as defined in the PSR-1, PSR-2, etc., 12 | or other community driven ones like the Symfony one. 13 | You can **also** define your (teams) style through configuration. 14 | 15 | This package makes it easier than ever to use PHP CS Fixer to maintain your laravel code by providing access to it via 16 | tools that you are already familiar with. An artisan command to fix the code, and manage the configuration the way you 17 | do all the other laravel packages you use. 18 | 19 | # Features of this package 20 | * Run PHP-CS-Fixer commands via Laravel Artisan CLI. 21 | * Laravel Code Style Configuration Used by Default. 22 | * No need to learn a new tool. 23 | 24 | ## Versions and compatibility 25 | > **Note:** This documentation was written for Laravel 5.5. 26 | * PHP Version: "^7.1.3 || ^8.0" 27 | * Laravel/Lumen: "^5.4|^6.0|^7.0|^8.0" 28 | * PHP-CS-Fixer: "^3.0.0" 29 | 30 | ## Installation 31 | 32 | ``` 33 | composer require stechstudio/laravel-php-cs-fixer 34 | ``` 35 | 36 | ## Configuration 37 | The default rule configuration is in the [fixer.php](https://github.com/stechstudio/Laravel-PHP-CS-Fixer/blob/master/config/fixer.php) and is intended to match the rules used by Laravel Shift. 38 | 39 | if you want to modify this yourself, just use artisan `php artisan vendor:publish --provider="STS\Fixer\FixerServiceProvider"` 40 | and it will put the default configuration in 'config/fixer.php'. Check the 41 | [PHP-CS-Fixer/README](https://github.com/FriendsOfPHP/PHP-CS-Fixer#usage) for valid rules. 42 | 43 | ## Usage 44 | #### Fix Your Code 45 | Fix your code with Laravel Coding Standards. 46 | 47 | Syntax: 48 | ``` 49 | $ php artisan fixer:fix [options] 50 | ``` 51 | 52 | Example: 53 | ``` 54 | Usage: 55 | fixer:fix [options] [--] [...] 56 | 57 | Arguments: 58 | path The path. Can be a list of space separated paths 59 | 60 | Options: 61 | --path-mode=PATH-MODE Specify path mode (can be override or intersection). [default: "override"] 62 | --allow-risky=ALLOW-RISKY Are risky fixers allowed (can be yes or no). 63 | --config=CONFIG The path to a .php-cs-fixer.php file. 64 | --dry-run Only shows which files would have been modified. 65 | --rules=RULES The rules. 66 | --using-cache=USING-CACHE Does cache should be used (can be yes or no). 67 | --cache-file=CACHE-FILE The path to the cache file. 68 | --diff Also produce diff for each file. 69 | --format=FORMAT To output results in other formats. 70 | --stop-on-violation Stop execution on first violation. 71 | --show-progress=SHOW-PROGRESS Type of progress indicator (none, dots). 72 | -h, --help Display help for the given command. When no command is given display help for the list command 73 | -q, --quiet Do not output any message 74 | -V, --version Display this application version 75 | --ansi Force ANSI output 76 | --no-ansi Disable ANSI output 77 | -n, --no-interaction Do not ask any interactive question 78 | --env[=ENV] The environment the command should run under 79 | -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug 80 | 81 | ``` 82 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "stechstudio/laravel-php-cs-fixer", 3 | "description": "Easily format your Laravel Code with this Configuration file and accompanying artisan command.", 4 | "type": "library", 5 | "license": "MIT", 6 | "keywords": [ 7 | "php-cs-fixer", 8 | "develop", 9 | "artisan", 10 | "lumen", 11 | "laravel", 12 | "coding", 13 | "standards", 14 | "fixer" 15 | ], 16 | "autoload": { 17 | "classmap": [], 18 | "psr-4": { 19 | "STS\\Fixer\\": "src" 20 | }, 21 | "files": [] 22 | }, 23 | "authors": [ 24 | { 25 | "name": "Bubba Hines", 26 | "email": "rob@stechstudio.com" 27 | } 28 | ], 29 | "require": { 30 | "php": "^7.1.3 || ^8.0", 31 | "illuminate/support": "^5.4|^6.0|^7.0|^8.0|^9.0", 32 | "friendsofphp/php-cs-fixer": "^3.0.0" 33 | }, 34 | "require-dev": { 35 | "illuminate/console": "^5.4|^6.0|^7.0|^8.0|^9.0", 36 | "orchestra/testbench": "^7.0" 37 | }, 38 | "extra": { 39 | "laravel": { 40 | "providers": [ 41 | "STS\\Fixer\\FixerServiceProvider" 42 | ] 43 | } 44 | }, 45 | "scripts": { 46 | "post-autoload-dump": [ 47 | "@php ./vendor/bin/testbench package:discover --ansi" 48 | ] 49 | }, 50 | "minimum-stability": "stable" 51 | } 52 | -------------------------------------------------------------------------------- /config/fixer.php: -------------------------------------------------------------------------------- 1 | 'Laravel Fixer', 6 | 7 | /** By default, we will ignore any and all dot files. */ 8 | 'ignore_dot_files' => true, 9 | 10 | /** By default, we will ignore all the source control metadata */ 11 | 'ignore_vcs' => true, 12 | 13 | /** The list of directories you want to fix. These are the default laravel directories. */ 14 | 'find_directories' => [ 15 | base_path('/app'), 16 | base_path('/config'), 17 | database_path(), 18 | resource_path(), 19 | base_path('/routes'), 20 | base_path('/tests') 21 | 22 | ], 23 | 24 | /** We will fix all files in those directories that match a pattern in this list. */ 25 | 'file_name_pattern_whitelist' => [ 26 | '*.php', 27 | ], 28 | 29 | /** However, we will not fix files that match patterns in this list. */ 30 | 'file_name_pattern_blacklist' => [ 31 | '*.blade.php', 32 | ], 33 | 34 | /** 35 | * These are all the rules. 36 | * Find them all at https://github.com/FriendsOfPHP/PHP-CS-Fixer/blob/v3.0.0/doc/rules/index.rst 37 | */ 38 | 'rules' => [ 39 | /** PHP arrays should be declared using the configured syntax. */ 40 | 'array_syntax' => ['syntax' => 'short'], 41 | 42 | /** Binary operators should be surrounded by space as configured. */ 43 | 'binary_operator_spaces' => [ 44 | 'default' => 'single_space', 45 | 'operators' => ['=>' => null] 46 | ], 47 | 48 | /** There MUST be one blank line after the namespace declaration. */ 49 | 'blank_line_after_namespace' => true, 50 | 51 | /** Ensure there is no code on the same line as the PHP open tag and it is followed by a blank line. */ 52 | 'blank_line_after_opening_tag' => true, 53 | 54 | /** An empty line feed must precede any configured statement. */ 55 | 'blank_line_before_statement' => [ 56 | 'statements' => ['return'] 57 | ], 58 | 59 | /** The body of each structure MUST be enclosed by braces. Braces should be properly placed. Body of braces should be properly indented. */ 60 | 'braces' => true, 61 | 62 | /** A single space or none should be between cast and variable. */ 63 | 'cast_spaces' => true, 64 | 65 | /** Class, trait and interface elements must be separated with one or none blank line. */ 66 | 'class_attributes_separation' => [ 67 | 'elements' => ['method' => 'one'], 68 | ], 69 | 70 | /** Whitespace around the keywords of a class, trait or interfaces definition should be one space. */ 71 | 'class_definition' => true, 72 | 73 | /** Concatenation should be spaced according configuration. */ 74 | 'concat_space' => [ 75 | 'spacing' => 'none' 76 | ], 77 | 78 | /** Equal sign in declare statement should be surrounded by spaces or not following configuration. */ 79 | 'declare_equal_normalize' => true, 80 | 81 | /** The keyword elseif should be used instead of else if so that all control keywords look like single words. */ 82 | 'elseif' => true, 83 | 84 | /** PHP code MUST use only UTF-8 without BOM (remove BOM). */ 85 | 'encoding' => true, 86 | 87 | /** PHP code must use the long true, 89 | 90 | /** Transforms imported FQCN parameters and return types in function arguments to short version. */ 91 | 'fully_qualified_strict_types' => true, 92 | 93 | /** Spaces should be properly placed in a function declaration. */ 94 | 'function_declaration' => true, 95 | 96 | /** nsure single space between function's argument and its typehint. */ 97 | 'function_typehint_space' => true, 98 | 99 | /** Convert heredoc to nowdoc where possible. */ 100 | 'heredoc_to_nowdoc' => true, 101 | 102 | /** Include/Require and file path should be divided with a single space. File path should not be placed under brackets. */ 103 | 'include' => true, 104 | 105 | /** Pre- or post-increment and decrement operators should be used if possible. */ 106 | 'increment_style' => ['style' => 'post'], 107 | 108 | /** Code MUST use configured indentation type. */ 109 | 'indentation_type' => true, 110 | 111 | /** Ensure there is no code on the same line as the PHP open tag. */ 112 | 'linebreak_after_opening_tag' => true, 113 | 114 | /** All PHP files must use same line ending. */ 115 | 'line_ending' => true, 116 | 117 | /** Cast should be written in lower case. */ 118 | 'lowercase_cast' => true, 119 | 120 | /** The PHP constants true, false, and null MUST be written using the correct casing. */ 121 | 'constant_case' => true, 122 | 123 | /** PHP keywords MUST be in lower case. */ 124 | 'lowercase_keywords' => true, 125 | 126 | /** Class static references self, static and parent MUST be in lower case. */ 127 | 'lowercase_static_reference' => true, 128 | 129 | /** Magic method definitions and calls must be using the correct casing. */ 130 | 'magic_method_casing' => true, 131 | 132 | /** Magic constants should be referred to using the correct casing */ 133 | 'magic_constant_casing' => true, 134 | 135 | /** 136 | * In method arguments and method call, there MUST NOT be a space before each comma and 137 | * there MUST be one space after each comma. Argument lists MAY be split across multiple 138 | * lines, where each subsequent line is indented once. When doing so, the first item in the 139 | * list MUST be on the next line, and there MUST be only one argument per line. 140 | */ 141 | 'method_argument_space' => true, 142 | 143 | /** Function defined by PHP should be called using the correct casing. */ 144 | 'native_function_casing' => true, 145 | 146 | /** (risky) Master functions shall be used instead of aliases. */ 147 | 'no_alias_functions' => true, 148 | 149 | /** Removes extra blank lines and/or blank lines following configuration. */ 150 | 'no_extra_blank_lines' => [ 151 | 'tokens' => [ 152 | 'extra', 153 | 'throw', 154 | 'use', 155 | 'use_trait', 156 | ] 157 | ], 158 | /** There should be no empty lines after class opening brace. */ 159 | 'no_blank_lines_after_class_opening' => true, 160 | 'no_blank_lines_after_phpdoc' => true, 161 | 'no_closing_tag' => true, 162 | 'no_empty_phpdoc' => true, 163 | 'no_empty_statement' => true, 164 | 'no_leading_import_slash' => true, 165 | 'no_leading_namespace_whitespace' => true, 166 | 'no_mixed_echo_print' => [ 167 | 'use' => 'echo' 168 | ], 169 | 'no_multiline_whitespace_around_double_arrow' => true, 170 | 'multiline_whitespace_before_semicolons' => [ 171 | 'strategy' => 'no_multi_line' 172 | ], 173 | 'no_short_bool_cast' => true, 174 | 'no_singleline_whitespace_before_semicolons' => true, 175 | 'no_spaces_after_function_name' => true, 176 | 'no_spaces_around_offset' => true, 177 | 'no_spaces_inside_parenthesis' => true, 178 | 'no_trailing_comma_in_list_call' => true, 179 | 'no_trailing_comma_in_singleline_array' => true, 180 | 'no_trailing_whitespace' => true, 181 | 'no_trailing_whitespace_in_comment' => true, 182 | 'no_unneeded_control_parentheses' => true, 183 | 'no_unused_imports' => true, 184 | 185 | /* (risky) In function arguments there must not be arguments with default values before non-default ones. */ 186 | 'no_unreachable_default_argument_value' => true, 187 | 188 | 'no_useless_return' => true, 189 | 'no_whitespace_before_comma_in_array' => true, 190 | 'no_whitespace_in_blank_line' => true, 191 | 'normalize_index_brace' => true, 192 | 'not_operator_with_successor_space' => true, 193 | 'object_operator_without_whitespace' => true, 194 | 'ordered_imports' => ['sort_algorithm' => 'alpha'], 195 | 'phpdoc_indent' => true, 196 | 'phpdoc_inline_tag_normalizer' => true, 197 | 'phpdoc_no_access' => true, 198 | 'phpdoc_no_package' => true, 199 | 'phpdoc_no_useless_inheritdoc' => true, 200 | 'phpdoc_scalar' => true, 201 | 'phpdoc_single_line_var_spacing' => true, 202 | 'phpdoc_summary' => true, 203 | 'phpdoc_to_comment' => true, 204 | 'phpdoc_trim' => true, 205 | 'phpdoc_types' => true, 206 | 'phpdoc_var_without_name' => true, 207 | 208 | /* (risky) Classes must be in a path that matches their namespace, be at least one namespace deep and the class name should match the file name. */ 209 | 'psr_autoloading' => true, 210 | 211 | /* (risky) Inside class or interface element self should be preferred to the class name itself. */ 212 | 'self_accessor' => true, 213 | 214 | 'short_scalar_cast' => true, 215 | 'simplified_null_return' => false, // disabled by Shift 216 | 'single_blank_line_at_eof' => true, 217 | 'single_blank_line_before_namespace' => true, 218 | 'single_class_element_per_statement' => true, 219 | 'single_import_per_statement' => true, 220 | 'single_line_after_imports' => true, 221 | 'single_line_comment_style' => [ 222 | 'comment_types' => ['hash'] 223 | ], 224 | 'single_quote' => true, 225 | 'space_after_semicolon' => true, 226 | 'standardize_not_equals' => true, 227 | 'switch_case_semicolon_to_colon' => true, 228 | 'switch_case_space' => true, 229 | 'ternary_operator_spaces' => true, 230 | 'trailing_comma_in_multiline' => ['elements' => ['arrays']], 231 | 'trim_array_spaces' => true, 232 | 'unary_operator_spaces' => true, 233 | 'visibility_required' => [ 234 | 'elements' => ['method', 'property'] 235 | ], 236 | 'whitespace_after_comma_in_array' => true, 237 | ], 238 | ]; 239 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | ./tests/ 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/Console/FixCommand.php: -------------------------------------------------------------------------------- 1 | 7 | * Dariusz Rumiński 8 | * 9 | * This source file is subject to the MIT license that is bundled 10 | * with this source code in the file LICENSE. 11 | * 12 | * It is replicated and modified here due to them having made it a `final` class. 13 | */ 14 | 15 | 16 | namespace STS\Fixer\Console; 17 | 18 | use Illuminate\Console\Command; 19 | 20 | use PhpCsFixer\ConfigurationException\InvalidConfigurationException; 21 | use PhpCsFixer\Console\Command\FixCommand as CommandFixCommand; 22 | use PhpCsFixer\ToolInfo; 23 | use STS\Fixer\Services\Fixer; 24 | use Symfony\Component\Console\Output\OutputInterface; 25 | use Symfony\Component\Console\Style\SymfonyStyle; 26 | 27 | class FixCommand extends Command 28 | { 29 | /** 30 | * The console command name. 31 | * 32 | * @var string 33 | */ 34 | protected $name = 'fixer:fix'; 35 | 36 | /** 37 | * 38 | * @var string 39 | */ 40 | protected $longVersion; 41 | 42 | /** 43 | * 44 | * @var Fixer 45 | */ 46 | protected $fixerService; 47 | 48 | 49 | public function __construct() 50 | { 51 | parent::__construct(); 52 | $fixerCommand = new CommandFixCommand(new ToolInfo()); 53 | $this->setDefinition($fixerCommand->getDefinition()); 54 | $this->setHelp($fixerCommand->getHelp()); 55 | $this->setDescription($fixerCommand->getDescription()); 56 | $this->fixerApplication = new \PhpCsFixer\Console\Application(); 57 | $this->longVersion = $this->fixerApplication->getLongVersion(); 58 | } 59 | 60 | 61 | 62 | public function handle() 63 | { 64 | try { 65 | $this->verbocityAndValidation(); 66 | } catch (InvalidConfigurationException $exception) { 67 | $this->error($exception->getMessage()); 68 | return 1; 69 | } 70 | 71 | $this->writePreamble(); 72 | 73 | $this->fixerService->fixFiles(); 74 | $this->fixerService->printLegend(); 75 | $this->fixerService->report($this->verbosity, $this->output); 76 | return $this->fixerService->exitStatus(); 77 | } 78 | 79 | protected function verbocityAndValidation() 80 | { 81 | $this->setVerbosity($this->output->getVerbosity()); 82 | if (null !== $this->option('config') && null !== $this->option('rules')) { 83 | throw new InvalidConfigurationException('Passing both `--config` and `--rules` options is not allowed.'); 84 | } 85 | } 86 | 87 | protected function getFixerService(): Fixer 88 | { 89 | if ($this->fixerService === null) { 90 | $this->fixerService = new Fixer($this->output, $this->composeCliInput()); 91 | } 92 | 93 | return $this->fixerService; 94 | } 95 | protected function writePreamble() 96 | { 97 | if (OutputInterface::VERBOSITY_VERBOSE <= $this->verbosity) { 98 | $this->info($this->longVersion); 99 | $this->writeln($this->getFixerService()->getPhpRuntimeMessage()); 100 | } 101 | 102 | $this->writeln($this->getFixerService()->getLoadedConfigMessage()); 103 | 104 | if ($this->getFixerService()->isUsingCache() && $this->getFixerService()->cacheFileExists()) { 105 | $this->writeln($this->getFixerService()->getCacheFileMessage()); 106 | } 107 | } 108 | 109 | protected function composeCliInput() 110 | { 111 | return [ 112 | 'allow-risky' => $this->option('allow-risky') ?? 'yes', 113 | 'config' => $this->option('config'), 114 | 'dry-run' => $this->option('dry-run'), 115 | 'rules' => $this->option('rules'), 116 | 'path' => $this->argument('path'), 117 | 'path-mode' => $this->option('path-mode'), 118 | 'using-cache' => $this->option('using-cache'), 119 | 'cache-file' => $this->option('cache-file'), 120 | 'format' => $this->option('format'), 121 | 'diff' => $this->option('diff'), 122 | 'stop-on-violation' => $this->option('stop-on-violation'), 123 | 'verbosity' => $this->verbosity, 124 | 'show-progress' => $this->option('show-progress'), 125 | ]; 126 | } 127 | protected function writeln($messages, int $type = SymfonyStyle::OUTPUT_NORMAL) 128 | { 129 | $this->output->writeln($messages, $type); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/FixerServiceProvider.php: -------------------------------------------------------------------------------- 1 | publish(); 29 | $this->addCommands(); 30 | } 31 | 32 | public function register() 33 | { 34 | $this->config(); 35 | } 36 | 37 | /** 38 | * Add any package commands if we are running in the console. 39 | * 40 | * @return void 41 | */ 42 | protected function addCommands() 43 | { 44 | if ($this->app->runningInConsole()) { 45 | $this->commands([ 46 | FixCommand::class 47 | ]); 48 | } 49 | } 50 | 51 | /** 52 | * Handles configuation for Luman or Laravel 53 | * 54 | * @return void 55 | */ 56 | protected function config() 57 | { 58 | if (is_a($this->app, 'Laravel\Lumen\Application')) { 59 | $this->app->configure('fixer'); 60 | } 61 | $this->mergeConfigFrom($this->configPath, 'fixer'); 62 | Config::set('laravel_cs_sha1_checksum', '3f504802e3b3d9dd5eeb08ce34c2073d77fc59c6'); 63 | } 64 | 65 | /** 66 | * Handles publishing the configuation class for Luman or Laravel 67 | * 68 | * @return void 69 | * @throws BindingResolutionException 70 | */ 71 | protected function publish() 72 | { 73 | // helps deal with Lumen vs Laravel differences 74 | if (function_exists('config_path')) { 75 | $publishPath = config_path('fixer.php'); 76 | } else { 77 | $publishPath = base_path('config/fixer.php'); 78 | } 79 | 80 | $this->publishes([$this->configPath => $publishPath], 'config'); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/Services/Fixer.php: -------------------------------------------------------------------------------- 1 | output = $output; 32 | $this->cliInput = $cliInput; 33 | $this->setResolver($cliInput, $config, $cwd, $toolInfo); 34 | $this->setEventDispatcher(); 35 | $this->setFinder(); 36 | $this->setProgressOutput(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Services/Fixer/Concerns/HasConfigurationResolver.php: -------------------------------------------------------------------------------- 1 | setRules($options['rules'] ?: config('fixer.rules')); 23 | $cwd = $cwd ?: getcwd(); 24 | $toolInfo = $toolInfo ?: new ToolInfo(); 25 | $this->configResolver = new ConfigurationResolver($config, $options, $cwd, $toolInfo); 26 | } 27 | 28 | public function getLoadedConfigMessage() 29 | { 30 | return sprintf( 31 | 'Loaded config %s from %s.', 32 | $this->configResolver->getConfig()->getName(), 33 | $this->configResolver->getConfigFile() ?? 'Laravel Fixer Configuration.' 34 | ); 35 | } 36 | 37 | public function getPhpRuntimeMessage() 38 | { 39 | $configFile = $this->configResolver->getConfig()->getPhpExecutable(); 40 | return sprintf('Runtime: PHP %s', PHP_VERSION); 41 | } 42 | 43 | public function isUsingCache() 44 | { 45 | return $this->configResolver->getUsingCache(); 46 | } 47 | 48 | public function cacheFileExists() 49 | { 50 | return is_file($this->configResolver->getCacheFile()); 51 | } 52 | 53 | public function getCacheFileMessage() 54 | { 55 | return sprintf('Using cache file "%s".', $this->configResolver->getCacheFile()); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Services/Fixer/Concerns/HasErrorsManager.php: -------------------------------------------------------------------------------- 1 | errorsManager = $errorsManager ?? new ErrorsManager(); 27 | } 28 | 29 | public function getErrorsManager() 30 | { 31 | if ($this->errorsManager === null) { 32 | $this->setErrorsManager(); 33 | } 34 | 35 | return $this->errorsManager; 36 | } 37 | 38 | public function getErrorOutput(?OutputInterface $output = null) 39 | { 40 | if ($this->errorOutput === null) { 41 | $this->errorOutput = new ErrorOutput($output); 42 | } 43 | return $this->errorOutput; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Services/Fixer/Concerns/HasEventDispatcher.php: -------------------------------------------------------------------------------- 1 | eventDispatcher = $eventDispatcher ?? new EventDispatcher(); 21 | } 22 | 23 | public function getEventDispatcher() 24 | { 25 | if ($this->eventDispatcher === null) { 26 | $this->setEventDispatcher(); 27 | } 28 | return $this->eventDispatcher; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Services/Fixer/Concerns/HasFinder.php: -------------------------------------------------------------------------------- 1 | finder = Finder::create() 19 | ->in(config('fixer.find_directories')) 20 | ->name(config('fixer.file_name_pattern_whitelist')) 21 | ->notName(config('fixer.file_name_pattern_blacklist')) 22 | ->ignoreDotFiles(config('fixer.ignore_dot_files')) 23 | ->ignoreVCS(config('fixer.ignore_vcs')); 24 | } 25 | 26 | public function getFinder() 27 | { 28 | if ($this->finder === null) { 29 | $this->setFinder(); 30 | } 31 | 32 | return $this->finder; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Services/Fixer/Concerns/HasFixEvent.php: -------------------------------------------------------------------------------- 1 | filesModified, 21 | \count($this->getFinder()), 22 | $this->getStopWatch()->getEvent('fixFiles')->getDuration(), 23 | $this->getStopWatch()->getEvent('fixFiles')->getMemory(), 24 | OutputInterface::VERBOSITY_VERBOSE <= $verbosity, 25 | $this->configResolver->isDryRun(), 26 | $output->isDecorated() 27 | ); 28 | 29 | 30 | $output->isDecorated() 31 | ? $output->write($this->configResolver->getReporter()->generate($reportSummary)) 32 | : $output->write($this->configResolver->getReporter()->generate($reportSummary), false, OutputInterface::OUTPUT_RAW);; 33 | 34 | if (\count($this->getErrorsManager()->getInvalidErrors()) > 0) { 35 | $this->getErrorOutput($output)->listErrors('linting before fixing', $this->getErrorsManager()->getInvalidErrors()); 36 | } 37 | 38 | if (\count($this->getErrorsManager()->getExceptionErrors()) > 0) { 39 | $this->getErrorOutput($output)->listErrors('fixing', $this->getErrorsManager()->getExceptionErrors()); 40 | } 41 | 42 | if (\count($this->getErrorsManager()->getLintErrors()) > 0) { 43 | $this->getErrorOutput($output)->listErrors('linting after fixing', $this->getErrorsManager()->getLintErrors()); 44 | } 45 | } 46 | 47 | public function exitStatus() 48 | { 49 | $exitStatusCalculator = new FixCommandExitStatusCalculator(); 50 | 51 | return $exitStatusCalculator->calculate( 52 | $this->configResolver->isDryRun(), 53 | \count($this->filesModified) > 0, 54 | \count($this->getErrorsManager()->getInvalidErrors()) > 0, 55 | \count($this->getErrorsManager()->getExceptionErrors()) > 0, 56 | \count($this->getErrorsManager()->getLintErrors()) > 0 57 | ); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Services/Fixer/Concerns/HasProgressOutput.php: -------------------------------------------------------------------------------- 1 | progressOutput = new NullOutput(); 34 | 35 | if ('none' !== $this->configResolver->getProgress()) { 36 | $this->progressOutput = new ProcessOutput( 37 | $this->output, 38 | $this->eventDispatcher, 39 | (new Terminal())->getWidth(), 40 | $this->finder->count() 41 | ); 42 | } 43 | } 44 | 45 | public function getProgressOutput() 46 | { 47 | return $this->getProgressOutput(); 48 | } 49 | 50 | public function printLegend() 51 | { 52 | $this->progressOutput->printLegend(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Services/Fixer/Concerns/HasRunner.php: -------------------------------------------------------------------------------- 1 | runner = new Runner( 30 | $this->getFinder(), 31 | $this->configResolver->getFixers(), 32 | $this->configResolver->getDiffer(), 33 | 'none' !== $this->configResolver->getProgress() ? $this->getEventDispatcher() : null, 34 | $this->getErrorsManager(), 35 | $this->configResolver->getLinter(), 36 | $this->configResolver->isDryRun(), 37 | $this->configResolver->getCacheManager(), 38 | $this->configResolver->getDirectory(), 39 | $this->configResolver->shouldStopOnViolation() 40 | ); 41 | } 42 | 43 | public function getRunner() 44 | { 45 | if ($this->runner === null) { 46 | $this->setRunner(); 47 | } 48 | return $this->runner; 49 | } 50 | 51 | public function fixFiles() 52 | { 53 | $this->getStopWatch()->start('fixFiles'); 54 | $this->filesModified = $this->getRunner()->fix(); 55 | $this->getStopWatch()->stop('fixFiles'); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Services/Fixer/Concerns/HasStopWatch.php: -------------------------------------------------------------------------------- 1 | stopWatch = new Stopwatch(); 19 | } 20 | 21 | public function getStopWatch() 22 | { 23 | if ($this->stopWatch === null) { 24 | $this->setStopWatch(); 25 | } 26 | 27 | return $this->stopWatch; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stechstudio/Laravel-PHP-CS-Fixer/c677319f848ef32a3cc19099a77531d29f056e32/tests/.gitkeep --------------------------------------------------------------------------------