Passed
Push — master ( b730fe...05c3b6 )
by Malte
02:06
created

Task::getUnusedPhpFiles()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 41
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 41
rs 8.439
cc 5
eloc 30
nc 4
nop 5
1
<?php
2
3
namespace AppBundle\ShowUnusedPhpFiles;
4
5
use Helper\FileSystem;
6
use Helper\NullStyle;
7
use Symfony\Component\Console\Style\OutputStyle;
8
use Symfony\Component\Finder\Finder;
9
10
/**
11
 * Get all PHP files in a given directory, minus the used and temporary files, and offers the rest for deletion.
12
 */
13
final class Task
14
{
15
    /**
16
     * @param string $userProvidedPathToUsedFiles
17
     * @param string|null $pathToInspect
18
     * @param string|null $userProvidedPathToOutput
19
     * @param string|null $userProvidedPathToBlacklist
20
     * @param OutputStyle|null $ioStyle
21
     * @throws \InvalidArgumentException
22
     */
23
    public function getUnusedPhpFiles($userProvidedPathToUsedFiles, $pathToInspect, $userProvidedPathToOutput, $userProvidedPathToBlacklist, OutputStyle $ioStyle = null)
24
    {
25
        $ioStyle = $ioStyle ?: new NullStyle();
26
        $ioStyle->text('Started.');
27
28
        $usedFiles = FileSystem::readFileIntoArray($userProvidedPathToUsedFiles);
29
        if (count($usedFiles) === 0) {
30
            throw new \InvalidArgumentException('Empty list for used files');
31
        }
32
        $ioStyle->text('Found ' . count($usedFiles) . ' used files.');
33
34
        if ($pathToInspect === null) {
35
            $pathToInspect = $this->guessPathToInspect($usedFiles);
36
            $ioStyle->text('Determined ' . $pathToInspect . ' as root for inspection (see --help to set it manually).');
37
        }
38
39
        $foundFilesInfos = iterator_to_array((new Finder())->in($pathToInspect)->files()->name('*.php')->getIterator());
40
        $blacklistingRegExps = FileSystem::getBlacklistingRegExps($userProvidedPathToBlacklist);
41
        $foundFiles = FileSystem::filterFilesIn($foundFilesInfos, $blacklistingRegExps);
42
43
        $message = 'Found ' . count($foundFiles) . ' PHP files';
44
        $numberOfBlacklistingRegExps = count($blacklistingRegExps);
45
        if ($numberOfBlacklistingRegExps > 0) {
46
            $message .= ' not matched by the ' . $numberOfBlacklistingRegExps . ' blacklisting regular expressions';
47
        }
48
        $ioStyle->text($message . ' in ' . $pathToInspect . '.');
49
50
        $unusedPhpFiles = array_diff($foundFiles, $usedFiles);
51
        sort($unusedPhpFiles);
52
53
        $pathToOutput = FileSystem::getPathToOutput($userProvidedPathToOutput, $userProvidedPathToUsedFiles);
54
        FileSystem::writeArrayToFile($unusedPhpFiles, $pathToOutput);
55
        $ioStyle->success([
56
            'Finished writing list of ' . count($unusedPhpFiles) . ' potentially unused PHP files. Please inspect the '
57
                . 'output file ' . $pathToOutput,
58
            'For files you want to keep (even if they are not used according to the code coverage of your tests), you '
59
                . 'can maintain a blacklist. With it, you can exclude these files from the output of further runs of '
60
                . 'this command. See --help or the readme for details.',
61
            'Once you are sure you can restore the rest of the files (ideally from your version control system), try '
62
                . 'deleting them, e.g. with "xargs rm < ' . $pathToOutput . '" and rerun your tests to see if that '
63
                . 'broke anything.',
64
        ]);
65
    }
66
67
    /**
68
     * @param string[] $usedFiles
69
     * @return string
70
     */
71
    private function guessPathToInspect(array $usedFiles)
72
    {
73
        return (new CommonPathDeterminator())->determineCommonPath($usedFiles);
74
    }
75
}
76