phpcq / repository

The base repository containing tool specifications
0 stars 1 forks source link

Recognize phpcs configuration from CodeSniffer.conf #4

Closed dmolineus closed 4 years ago

dmolineus commented 4 years ago

The PHP_CodeSniffer has a configuration file where it stores some project made configurations, e.g. the installed coding standard paths. Tools like dealerdirect/phpcodesniffer-composer-installer detects all installed coding standards and adjust the PHP_CodeSniffer when a composer update is done.

I'd like to support the given configuration file. There are two solutions which we might implement:

  1. Symlinking the vendor/squizlabs/php_codesniffer/CodeSniffer.conf to vendor/phpcq/CodeSniffer.conf. It would be recognized by the phar. We might need a PostUpdatePluginInterface then where a tool execute such logic. Our future composer plugin should trigger the post update of phpcq also to keep up to date with composer updates.
  2. Parse an existing vendor/squizlabs/php_codesniffer/CodeSniffer.conf file and set configurations as runtime setting. A prooph of concept would be following bootstrap file:
    
    <?php

use Phpcq\PluginApi\Version10\BuildConfigInterface; use Phpcq\PluginApi\Version10\ConfigurationOptionsBuilderInterface; use Phpcq\PluginApi\Version10\ConfigurationPluginInterface;

return new class implements ConfigurationPluginInterface { public function getName() : string { return 'phpcs'; }

public function describeOptions(ConfigurationOptionsBuilderInterface $configOptionsBuilder) : void
{
    $configOptionsBuilder
        ->describeArrayOption('directories', 'The source directories to be analyzed with phpcs.')
        ->describeStringOption('standard', 'The default coding standard style')
        ->describeArrayOption('excluded', 'The excluded files and folders.', [])
        ->describeStringOption('config-file', 'Path where CodeSniffer.conf file is located', 'vendor/squizlabs/php_codesniffer/CodeSniffer.conf')
    ;

    $configOptionsBuilder->describeStringOption(
        'custom_flags',
        'Any custom flags to pass to phpcs. For valid flags refer to the cphpcs documentation.',
        );
}

public function processConfig(array $config, BuildConfigInterface $buildConfig) : iterable
{
    foreach ($config['directories'] as $directory => $directoryConfig) {
        yield $buildConfig
            ->getTaskFactory()
            ->buildRunPhar('phpcs', $this->buildArguments($directory, $directoryConfig ?: $config, $buildConfig))
            ->withWorkingDirectory($buildConfig->getProjectConfiguration()->getProjectRootPath())
            ->build();
    }
}

private function buildArguments(string $directory, array $config, BuildConfigInterface $buildConfig) : array
{
    $arguments = [];

    if (isset($config['standard'])) {
        $arguments[] = '--standard=' . $config['standard'];
    }

    if (isset($config['excluded'])) {
        $arguments[] = '--exclude=' . implode(',', $config['excluded']);
    }

    if (isset($config['custom_flags'])) {
        $arguments[] = $config['custom_flags'];
    }

    $configFile = $config['config-file'] ?? 'vendor/squizlabs/php_codesniffer/CodeSniffer.conf';
    if ($configFile !== null) {
        $configFile = $buildConfig->getProjectConfiguration()->getProjectRootPath() . '/' . $configFile;
        foreach ($this->yieldRuntimeConfig($configFile) as $key => $value) {
            $arguments[] = '--runtime-set';
            $arguments[] = $key;
            $arguments[] = $value;
        }
    }

    $arguments[] = $directory;

    return $arguments;
}

private function yieldRuntimeConfig(string $configFile) : \Generator
{
    if (!file_exists($configFile)) {
        return;
    }

    include $configFile;

    if (!isset($phpCodeSnifferConfig)) {
        return;
    }

    foreach ($phpCodeSnifferConfig as $key => $value) {
        // Only set plain values
        if (is_array($value) || is_object($value)) {
            continue;
        }

        yield $key => $value;
    }
}

};



Wdyt @discordier @baumannsven?
dmolineus commented 4 years ago

e78267cbc6cb8854570431ec302e42834effbc75 provides basic support for custom code styles. It uses the runtime-set directive. For now configuring each standard path explicitly is required but that should be enough for now.