Completed
Push — master ( 851d6f...c63a9b )
by Christian
02:28
created

PhpCsFixer   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 130
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 94.12%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 10
c 1
b 0
f 0
lcom 1
cbo 9
dl 0
loc 130
ccs 32
cts 34
cp 0.9412
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A getName() 0 4 1
A isSupported() 0 12 2
A getCsFixer() 0 8 1
A resolveFixers() 0 14 1
B execute() 0 23 4
1
<?php
2
3
namespace uuf6429\ElderBrother\Action;
4
5
use Symfony\Component\Console\Input\InputInterface;
6
use Symfony\Component\Console\Output\OutputInterface;
7
use Symfony\Component\Finder\SplFileInfo as SfyFileInfo;
8
use Symfony\Component\Process\Process;
9
use uuf6429\ElderBrother\Change\FileList;
10
11
class PhpCsFixer extends ActionAbstract
12
{
13
    const NONE_LEVEL = 0;
14
    const PSR0_LEVEL = 1;
15
    const PSR1_LEVEL = 3;
16
    const PSR2_LEVEL = 7;
17
    const SYMFONY_LEVEL = 15;
18
    const CONTRIB_LEVEL = 32;
19
20
    /**
21
     * @var FileList
22
     */
23
    protected $files;
24
25
    /**
26
     * @var int|null
27
     */
28
    protected $level;
29
30
    /**
31
     * @var string[]|null
32
     */
33
    protected $fixers;
34
35
    /**
36
     * @var bool
37
     */
38
    protected $addAutomatically;
39
40
    /**
41
     * Runs all the provided files through PHP-CS-Fixer, fixing any code style issues.
42
     *
43
     * @param FileList      $files            The files to check
44
     * @param int|null      $level            (Optional, defaults to NONE_LEVEL) Fixer level to use
45
     * @param string[]|null $fixers           (Optional, defaults to null) Set the fixers to use
46
     * @param bool          $addAutomatically (Optional, default is true) Whether to add modified files to commit or not
47
     */
48 3
    public function __construct(FileList $files, $level = self::NONE_LEVEL, $fixers = null, $addAutomatically = true)
49
    {
50 3
        $this->files = $files;
51 3
        $this->level = $level;
52 3
        $this->fixers = $fixers;
53 3
        $this->addAutomatically = $addAutomatically;
54 3
    }
55
56
    /**
57
     * {@inheritdoc}
58
     */
59
    public function getName()
60
    {
61
        return 'PHP Code Style Fixer (PhpCsFixer)';
62
    }
63
64
    /**
65
     * {@inheritdoc}
66
     */
67
    public function isSupported()
68
    {
69
        if (!class_exists('\Symfony\CS\Fixer')) {
70
            $this->logger->warning(
71
                'PHP-CS-Fixer could not be loaded: class \Symfony\CS\Fixer not found.'
72
            );
73
74
            return false;
75
        }
76
77
        return true;
78
    }
79
80
    /**
81
     * {@inheritdoc}
82
     */
83 3
    public function execute(InputInterface $input, OutputInterface $output)
84
    {
85 3
        $fixer = $this->getCsFixer();
86 3
        $fixers = $this->resolveFixers($fixer, $this->level, $this->fixers);
0 ignored issues
show
Bug introduced by
It seems like $this->fixers can also be of type null; however, uuf6429\ElderBrother\Act...sFixer::resolveFixers() does only seem to accept array<integer,string>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
87 3
        $cache = new \Symfony\CS\FileCacheManager(false, getcwd(), $fixers);
88
89 3
        $progress = $this->createProgressBar($input, $output, $this->files->count());
90 3
        $progress->start();
91
92
        /** @var SfyFileInfo $file */
93 3
        foreach ($this->files->getSourceIterator() as $file) {
94 2
            $progress->setMessage('Processing ' . $file->getRelativePathname() . '...');
95
96 2
            if ($fixer->fixFile($file, $fixers, false, false, $cache) && $this->addAutomatically) {
97
                $process = new Process('git add ' . escapeshellarg($file->getRelativePathname()));
98
                $process->mustRun();
99
            }
100
101 2
            $progress->advance();
102
        }
103
104 3
        $progress->finish();
105 3
    }
106
107
    /**
108
     * @return \Symfony\CS\Fixer
109
     */
110 3
    private function getCsFixer()
111
    {
112 3
        $fixer = new \Symfony\CS\Fixer();
113 3
        $fixer->registerBuiltInFixers();
114 3
        $fixer->registerBuiltInConfigs();
115
116 3
        return $fixer;
117
    }
118
119
    /**
120
     * @param \Symfony\CS\Fixer $fixer
121
     * @param int               $level
122
     * @param string[]          $fixers
123
     *
124
     * @return \Symfony\CS\FixerInterface[]
125
     */
126 3
    private function resolveFixers($fixer, $level, $fixers)
127
    {
128 3
        $resolver = new \Symfony\CS\ConfigurationResolver();
129
        $resolver
130 3
            ->setAllFixers($fixer->getFixers())
131 3
            ->setConfig(
132 3
                \Symfony\CS\Config\Config::create()
133 3
                    ->level($level)
134 3
                    ->fixers($fixers)
135
            )
136 3
            ->resolve();
137
138 3
        return $resolver->getFixers();
139
    }
140
}
141