Soullivaneuh /
php-cs-fixer-styleci-bridge
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | namespace SLLH\StyleCIBridge; |
||
| 4 | |||
| 5 | use Composer\Semver\Semver; |
||
| 6 | use SLLH\StyleCIBridge\Exception\LevelConfigException; |
||
| 7 | use SLLH\StyleCIBridge\StyleCI\Configuration; |
||
| 8 | use SLLH\StyleCIFixers\Fixers; |
||
| 9 | use Symfony\Component\Config\Definition\Processor; |
||
| 10 | use Symfony\Component\Console\Formatter\OutputFormatterStyle; |
||
| 11 | use Symfony\Component\Console\Output\ConsoleOutput; |
||
| 12 | use Symfony\Component\Console\Output\OutputInterface; |
||
| 13 | use Symfony\Component\DependencyInjection\Container; |
||
| 14 | use Symfony\Component\Finder\Finder; |
||
| 15 | use Symfony\Component\Yaml\Yaml; |
||
| 16 | use Symfony\CS\Config\Config; |
||
| 17 | use Symfony\CS\Finder\DefaultFinder; |
||
| 18 | use Symfony\CS\Fixer; |
||
| 19 | use Symfony\CS\Fixer\Contrib\HeaderCommentFixer; |
||
| 20 | use Symfony\CS\FixerFactory; |
||
| 21 | use Symfony\CS\FixerInterface; |
||
| 22 | |||
| 23 | /** |
||
| 24 | * @author Sullivan Senechal <[email protected]> |
||
| 25 | */ |
||
| 26 | final class ConfigBridge |
||
| 27 | { |
||
| 28 | const CS_FIXER_MIN_VERSION = '1.6.1'; |
||
| 29 | |||
| 30 | /** |
||
| 31 | * @var OutputInterface |
||
| 32 | */ |
||
| 33 | private $output; |
||
| 34 | |||
| 35 | /** |
||
| 36 | * @var FixerFactory |
||
| 37 | */ |
||
| 38 | private $fixerFactory = null; |
||
| 39 | |||
| 40 | /** |
||
| 41 | * @var string |
||
| 42 | */ |
||
| 43 | private $styleCIConfigDir; |
||
| 44 | |||
| 45 | /** |
||
| 46 | * @var array|null |
||
| 47 | */ |
||
| 48 | private $styleCIConfig = null; |
||
| 49 | |||
| 50 | /** |
||
| 51 | * @var string|array |
||
| 52 | */ |
||
| 53 | private $finderDirs; |
||
| 54 | |||
| 55 | /** |
||
| 56 | * @param string|null $styleCIConfigDir StyleCI config directory. Called script dir as default. |
||
| 57 | * @param string|array|null $finderDirs A directory path or an array of directories for Finder. Called script dir as default. |
||
| 58 | */ |
||
| 59 | public function __construct($styleCIConfigDir = null, $finderDirs = null) |
||
| 60 | { |
||
| 61 | if (!Semver::satisfies(Fixer::VERSION, sprintf('>=%s', self::CS_FIXER_MIN_VERSION))) { |
||
| 62 | throw new \RuntimeException(sprintf( |
||
| 63 | 'PHP-CS-Fixer v%s is not supported, please upgrade to v%s or higher.', |
||
| 64 | Fixer::VERSION, |
||
| 65 | self::CS_FIXER_MIN_VERSION |
||
| 66 | )); |
||
| 67 | } |
||
| 68 | |||
| 69 | // Guess config files path if not specified. |
||
| 70 | // getcwd function is not enough. See: https://github.com/Soullivaneuh/php-cs-fixer-styleci-bridge/issues/46 |
||
| 71 | if (null === $styleCIConfigDir || null === $finderDirs) { |
||
| 72 | $dbt = version_compare(PHP_VERSION, '5.4.0', '>=') ? debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2) : debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); |
||
| 73 | |||
| 74 | // Static call |
||
| 75 | if (isset($dbt[1]['class']) && 'SLLH\StyleCIBridge\ConfigBridge' === $dbt[1]['class'] && 'create' === $dbt[1]['function']) { |
||
| 76 | $configsPath = dirname($dbt[1]['file']); |
||
| 77 | } elseif (isset($dbt[0]['class']) && 'SLLH\StyleCIBridge\ConfigBridge' === $dbt[0]['class'] && '__construct' === $dbt[0]['function']) { // Manual instance |
||
| 78 | $configsPath = dirname($dbt[0]['file']); |
||
| 79 | } else { // If no case found, fallback to not reliable getcwd method. |
||
| 80 | $configsPath = getcwd(); |
||
| 81 | } |
||
| 82 | |||
| 83 | $this->styleCIConfigDir = $styleCIConfigDir ?: $configsPath; |
||
| 84 | $this->finderDirs = $finderDirs ?: $configsPath; |
||
| 85 | } |
||
| 86 | |||
| 87 | $this->output = new ConsoleOutput(); |
||
| 88 | $this->output->getFormatter()->setStyle('warning', new OutputFormatterStyle('black', 'yellow')); |
||
| 89 | // PHP-CS-Fixer 1.x BC |
||
| 90 | if (class_exists('Symfony\CS\FixerFactory')) { |
||
| 91 | $this->fixerFactory = FixerFactory::create(); |
||
| 92 | $this->fixerFactory->registerBuiltInFixers(); |
||
| 93 | } |
||
| 94 | |||
| 95 | $this->parseStyleCIConfig(); |
||
| 96 | } |
||
| 97 | |||
| 98 | /** |
||
| 99 | * @param string $styleCIConfigDir |
||
| 100 | * @param string|array $finderDirs A directory path or an array of directories for Finder |
||
| 101 | * |
||
| 102 | * @return Config |
||
| 103 | */ |
||
| 104 | public static function create($styleCIConfigDir = null, $finderDirs = null) |
||
| 105 | { |
||
| 106 | $bridge = new static($styleCIConfigDir, $finderDirs); |
||
| 107 | |||
| 108 | $config = Config::create(); |
||
| 109 | |||
| 110 | // PHP-CS-Fixer 1.x BC |
||
| 111 | if (method_exists($config, 'level')) { |
||
| 112 | $config->level(FixerInterface::NONE_LEVEL); |
||
| 113 | } |
||
| 114 | |||
| 115 | if (method_exists($config, 'setRules')) { |
||
| 116 | $config->setRules($bridge->getRules()); |
||
| 117 | } else { // PHP-CS-Fixer 1.x BC |
||
| 118 | $config->fixers($bridge->getFixers()); |
||
| 119 | } |
||
| 120 | |||
| 121 | // PHP-CS-Fixer 1.x BC |
||
| 122 | if (method_exists($config, 'setRiskyAllowed')) { |
||
| 123 | $config->setRiskyAllowed($bridge->getRisky()); |
||
|
0 ignored issues
–
show
|
|||
| 124 | } |
||
| 125 | |||
| 126 | return $config |
||
| 127 | ->finder($bridge->getFinder()) |
||
| 128 | ; |
||
| 129 | } |
||
| 130 | |||
| 131 | /** |
||
| 132 | * @return Finder |
||
| 133 | */ |
||
| 134 | public function getFinder() |
||
| 135 | { |
||
| 136 | $finder = DefaultFinder::create()->in($this->finderDirs); |
||
| 137 | if (isset($this->styleCIConfig['finder'])) { |
||
| 138 | $finderConfig = $this->styleCIConfig['finder']; |
||
| 139 | foreach ($finderConfig as $key => $values) { |
||
| 140 | $finderMethod = Container::camelize($key); |
||
| 141 | foreach ($values as $value) { |
||
| 142 | if (method_exists($finder, $finderMethod)) { |
||
| 143 | $finder->$finderMethod($value); |
||
| 144 | } else { |
||
| 145 | $this->output->writeln(sprintf( |
||
| 146 | '<warning>Can not apply "%s" finder option with PHP-CS-Fixer v%s. You fixer config may be erroneous. Consider upgrading to fix it.</warning>', |
||
| 147 | str_replace('_', '-', $key), |
||
| 148 | Fixer::VERSION |
||
| 149 | )); |
||
| 150 | } |
||
| 151 | } |
||
| 152 | } |
||
| 153 | } |
||
| 154 | |||
| 155 | return $finder; |
||
| 156 | } |
||
| 157 | |||
| 158 | /** |
||
| 159 | * @return int |
||
| 160 | * |
||
| 161 | * @deprecated since 1.1, to be removed in 2.0 |
||
| 162 | */ |
||
| 163 | public function getLevel() |
||
| 164 | { |
||
| 165 | @trigger_error('The '.__METHOD__.' method is deprecated since version 1.1 and will be removed in 2.0.', E_USER_DEPRECATED); |
||
| 166 | |||
| 167 | $preset = $this->styleCIConfig['preset']; |
||
| 168 | $validPresets = array( |
||
| 169 | 'psr1' => FixerInterface::PSR1_LEVEL, |
||
| 170 | 'psr2' => FixerInterface::PSR1_LEVEL, |
||
| 171 | 'symfony' => FixerInterface::SYMFONY_LEVEL, |
||
| 172 | ); |
||
| 173 | if (!in_array($preset, array_keys($validPresets))) { |
||
| 174 | throw new LevelConfigException(sprintf('Invalid preset "%s". Must be one of "%s".', $preset, implode('", "', array_keys($validPresets)))); |
||
| 175 | } |
||
| 176 | |||
| 177 | return $validPresets[$preset]; |
||
| 178 | } |
||
| 179 | |||
| 180 | /** |
||
| 181 | * @return string[] |
||
| 182 | */ |
||
| 183 | public function getFixers() |
||
| 184 | { |
||
| 185 | $presetFixers = $this->resolveAliases($this->getPresetFixers()); |
||
| 186 | $enabledFixers = $this->resolveAliases($this->styleCIConfig['enabled']); |
||
| 187 | $disabledFixers = $this->resolveAliases($this->styleCIConfig['disabled']); |
||
| 188 | |||
| 189 | $fixers = array_merge( |
||
| 190 | $enabledFixers, |
||
| 191 | array_map(function ($disabledFixer) { |
||
| 192 | return '-'.$disabledFixer; |
||
| 193 | }, $disabledFixers), |
||
| 194 | array_diff($presetFixers, $disabledFixers) // Remove disabled fixers from preset |
||
| 195 | ); |
||
| 196 | |||
| 197 | // PHP-CS-Fixer 1.x BC |
||
| 198 | if (method_exists('Symfony\CS\Fixer\Contrib\HeaderCommentFixer', 'getHeader') && HeaderCommentFixer::getHeader()) { |
||
| 199 | array_push($fixers, 'header_comment'); |
||
| 200 | } |
||
| 201 | |||
| 202 | return $fixers; |
||
| 203 | } |
||
| 204 | |||
| 205 | /** |
||
| 206 | * Returns fixers converted to rules for PHP-CS-Fixer 2.x. |
||
| 207 | * |
||
| 208 | * @return array |
||
| 209 | */ |
||
| 210 | public function getRules() |
||
| 211 | { |
||
| 212 | $fixers = $this->getFixers(); |
||
| 213 | |||
| 214 | $rules = array(); |
||
| 215 | foreach ($fixers as $fixer) { |
||
| 216 | if ('-' === $fixer[0]) { |
||
| 217 | $name = substr($fixer, 1); |
||
| 218 | $enabled = false; |
||
| 219 | } else { |
||
| 220 | $name = $fixer; |
||
| 221 | $enabled = true; |
||
| 222 | } |
||
| 223 | |||
| 224 | if ($this->isFixerAvailable($name)) { |
||
| 225 | $rules[$name] = $enabled; |
||
| 226 | } else { |
||
| 227 | $this->output->writeln(sprintf('<warning>Fixer "%s" does not exist, skipping.</warning>', $name)); |
||
| 228 | } |
||
| 229 | } |
||
| 230 | |||
| 231 | return $rules; |
||
| 232 | } |
||
| 233 | |||
| 234 | /** |
||
| 235 | * @return bool |
||
| 236 | */ |
||
| 237 | public function getRisky() |
||
|
0 ignored issues
–
show
function getRisky() does not seem to conform to the naming convention (^(?:is|has|should|may|supports)).
This check examines a number of code elements and verifies that they conform to the given naming conventions. You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods. Loading history...
|
|||
| 238 | { |
||
| 239 | return $this->styleCIConfig['risky']; |
||
| 240 | } |
||
| 241 | |||
| 242 | /** |
||
| 243 | * @return string[] |
||
| 244 | */ |
||
| 245 | private function getPresetFixers() |
||
| 246 | { |
||
| 247 | $preset = $this->styleCIConfig['preset']; |
||
| 248 | $validPresets = Fixers::getPresets(); |
||
| 249 | |||
| 250 | return $validPresets[$preset]; |
||
| 251 | } |
||
| 252 | |||
| 253 | /** |
||
| 254 | * Adds both aliases and real fixers if set. PHP-CS-Fixer would not take care if not existing. |
||
| 255 | * Better compatibility between PHP-CS-Fixer 1.x and 2.x. |
||
| 256 | * |
||
| 257 | * @param string[] $fixers |
||
| 258 | * |
||
| 259 | * @return string[] |
||
| 260 | */ |
||
| 261 | private function resolveAliases(array $fixers) |
||
| 262 | { |
||
| 263 | foreach (Fixers::$aliases as $alias => $name) { |
||
| 264 | View Code Duplication | if (in_array($alias, $fixers, true) && !in_array($name, $fixers, true) && $this->isFixerAvailable($name)) { |
|
| 265 | array_push($fixers, $name); |
||
| 266 | } |
||
| 267 | View Code Duplication | if (in_array($name, $fixers, true) && !in_array($alias, $fixers, true) && $this->isFixerAvailable($alias)) { |
|
| 268 | array_push($fixers, $alias); |
||
| 269 | } |
||
| 270 | } |
||
| 271 | |||
| 272 | return $fixers; |
||
| 273 | } |
||
| 274 | |||
| 275 | /** |
||
| 276 | * @param string $name |
||
| 277 | * |
||
| 278 | * @return bool |
||
| 279 | */ |
||
| 280 | private function isFixerAvailable($name) |
||
| 281 | { |
||
| 282 | // PHP-CS-Fixer 1.x BC |
||
| 283 | if (null === $this->fixerFactory) { |
||
| 284 | return true; |
||
| 285 | } |
||
| 286 | |||
| 287 | return $this->fixerFactory->hasRule($name); |
||
| 288 | } |
||
| 289 | |||
| 290 | private function parseStyleCIConfig() |
||
| 291 | { |
||
| 292 | if (null === $this->styleCIConfig) { |
||
| 293 | $config = Yaml::parse(file_get_contents(sprintf('%s/.styleci.yml', $this->styleCIConfigDir))); |
||
| 294 | $processor = new Processor(); |
||
| 295 | $this->styleCIConfig = $processor->processConfiguration(new Configuration(), array('styleci' => $config)); |
||
| 296 | } |
||
| 297 | } |
||
| 298 | } |
||
| 299 |
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.
This is most likely a typographical error or the method has been renamed.