<commit_before><?php

namespace Scrutinizer\Analyzer\Php;

use Scrutinizer\Analyzer\AnalyzerInterface;
use Scrutinizer\Config\ConfigBuilder;
use Scrutinizer\Model\Project;
use Scrutinizer\Util\XmlUtils;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;

/**
 * Gathers metrics using PHP PDepend.
 *
 * @doc-path tools/php/pdepend/
 * @display-name PHP PDepend
 */
class PDependAnalyzer implements AnalyzerInterface
{
    public function getName()
    {
        return 'php_pdepend';
    }

    /**
     * Builds the configuration structure of this analyzer.
     *
     * This is comparable to Symfony2's default builders except that the
     * ConfigBuilder does add a unified way to enable and disable analyzers,
     * and also provides a unified basic structure for all analyzers.
     *
     * You can read more about how to define your configuration at
     * http://symfony.com/doc/current/components/config/definition.html
     *
     * @param ConfigBuilder $builder
     *
     * @return void
     */
    public function buildConfig(ConfigBuilder $builder)
    {
        $builder
            ->info('Analyzes the size and structure of a PHP project.')
            ->disableDefaultFilter()
            ->globalConfig()
                ->scalarNode('command')->defaultValue('pdepend')->end()
                ->scalarNode('configuration_file')->defaultNull()->end()
                ->arrayNode('suffixes')
                    ->validate()->always(function(array $v) {
                        foreach ($v as $k => $suffix) {
                            if (preg_match('/\.([^.]+)$/', $suffix, $match)) {
                                $v[$k] = $match[1];
                            }
                        }

                        return array_unique($v);
                    })->end()
                    ->defaultValue(array('php'))
                    ->prototype('scalar')->end()
                ->end()
                ->arrayNode('excluded_dirs')
                    ->prototype('scalar')->end()
                    ->defaultValue(array('vendor'))
                ->end()
            ->end()
        ;
    }

    /**
     * Analyzes the given project.
     *
     * @param Project $project
     *
     * @return void
     */
    public function scrutinize(Project $project)
    {
        $outputFile = tempnam(sys_get_temp_dir(), 'pdepend-output');
        $command = $project->getGlobalConfig('command').' --summary-xml='.escapeshellarg($outputFile);

        if (null !== $configFile = $project->getGlobalConfig('configuration_file')) {
            $command .= ' --configuration='.escapeshellarg($configFile);
        }

        $suffixes = $project->getGlobalConfig('suffixes');
        if ( ! empty($suffixes)) {
            $command .= ' --suffix='.escapeshellarg(implode(',', $suffixes));
        }

        $excludedDirs = $project->getGlobalConfig('excluded_dirs');
        if ( ! empty($excludedDirs)) {
            $command .= ' --ignore='.escapeshellarg(implode(',', $excludedDirs));
        }

        $proc = new Process($command.' '.$project->getDir());
        $proc->setTimeout(300);
        $proc->run();

        $output = file_get_contents($outputFile);
        unlink($outputFile);
        if (0 !== $proc->run()) {
            throw new ProcessFailedException($proc);
        }

        /**
         *   <package name="Scrutinizer\PhpAnalyzer" cr="0.2484375" noc="3" nof="0" noi="1" nom="25" rcr="0.2775">
        <class name="Analyzer" ca="19" cbo="19" ce="19" cis="11" cloc="34" cr="0.15" csz="16" dit="0" eloc="104" impl="0" lloc="66" loc="189" ncloc="155" noam="0" nocc$
        <file name="/home/johannes/workspace/php-analyzer/src/Scrutinizer/PhpAnalyzer/Analyzer.php"/><commit_msg>increases timeout for PDepend<commit_after><?php

namespace Scrutinizer\Analyzer\Php;

use Scrutinizer\Analyzer\AnalyzerInterface;
use Scrutinizer\Config\ConfigBuilder;
use Scrutinizer\Model\Project;
use Scrutinizer\Util\XmlUtils;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;

/**
 * Gathers metrics using PHP PDepend.
 *
 * @doc-path tools/php/pdepend/
 * @display-name PHP PDepend
 */
class PDependAnalyzer implements AnalyzerInterface
{
    public function getName()
    {
        return 'php_pdepend';
    }

    /**
     * Builds the configuration structure of this analyzer.
     *
     * This is comparable to Symfony2's default builders except that the
     * ConfigBuilder does add a unified way to enable and disable analyzers,
     * and also provides a unified basic structure for all analyzers.
     *
     * You can read more about how to define your configuration at
     * http://symfony.com/doc/current/components/config/definition.html
     *
     * @param ConfigBuilder $builder
     *
     * @return void
     */
    public function buildConfig(ConfigBuilder $builder)
    {
        $builder
            ->info('Analyzes the size and structure of a PHP project.')
            ->disableDefaultFilter()
            ->globalConfig()
                ->scalarNode('command')->defaultValue('pdepend')->end()
                ->scalarNode('configuration_file')->defaultNull()->end()
                ->arrayNode('suffixes')
                    ->validate()->always(function(array $v) {
                        foreach ($v as $k => $suffix) {
                            if (preg_match('/\.([^.]+)$/', $suffix, $match)) {
                                $v[$k] = $match[1];
                            }
                        }

                        return array_unique($v);
                    })->end()
                    ->defaultValue(array('php'))
                    ->prototype('scalar')->end()
                ->end()
                ->arrayNode('excluded_dirs')
                    ->prototype('scalar')->end()
                    ->defaultValue(array('vendor'))
                ->end()
            ->end()
        ;
    }

    /**
     * Analyzes the given project.
     *
     * @param Project $project
     *
     * @return void
     */
    public function scrutinize(Project $project)
    {
        $outputFile = tempnam(sys_get_temp_dir(), 'pdepend-output');
        $command = $project->getGlobalConfig('command').' --summary-xml='.escapeshellarg($outputFile);

        if (null !== $configFile = $project->getGlobalConfig('configuration_file')) {
            $command .= ' --configuration='.escapeshellarg($configFile);
        }

        $suffixes = $project->getGlobalConfig('suffixes');
        if ( ! empty($suffixes)) {
            $command .= ' --suffix='.escapeshellarg(implode(',', $suffixes));
        }

        $excludedDirs = $project->getGlobalConfig('excluded_dirs');
        if ( ! empty($excludedDirs)) {
            $command .= ' --ignore='.escapeshellarg(implode(',', $excludedDirs));
        }

        $proc = new Process($command.' '.$project->getDir());
        $proc->setTimeout(900);
        $proc->run();

        $output = file_get_contents($outputFile);
        unlink($outputFile);
        if (0 !== $proc->run()) {
            throw new ProcessFailedException($proc);
        }

        /**
         *   <package name="Scrutinizer\PhpAnalyzer" cr="0.2484375" noc="3" nof="0" noi="1" nom="25" rcr="0.2775">
        <class name="Analyzer" ca="19" cbo="19" ce="19" cis="11" cloc="34" cr="0.15" csz="16" dit="0" eloc="104" impl="0" lloc="66" loc="189" ncloc="155" noam="0" nocc$
        <file name="/home/johannes/workspace/php-analyzer/src/Scrutinizer/PhpAnalyzer/Analyzer.php"/>
{'fraction_non_alphanumeric': 0.14866649062582518, 'fraction_numerical': 0.01399524689728017, 'mean_word_length': 2.1121610517666394, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 71, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6123551', 'n_tokens_mistral': 2289, 'n_tokens_neox': 2135, 'n_words': 428}