Completed
Push — develop ( 390d3f...e8b3d3 )
by Paul
02:38
created

DirectoryParser::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 4
1
<?php
2
3
namespace PhpUnitGen\Parser;
4
5
use League\Flysystem\AdapterInterface;
6
use League\Flysystem\FilesystemInterface;
7
use PhpUnitGen\Configuration\ConsoleConfigInterface;
8
use PhpUnitGen\Exception\ParsingException;
9
use PhpUnitGen\Model\DirectoryModel;
10
use PhpUnitGen\Model\ModelInterface\DirectoryModelInterface;
11
use PhpUnitGen\Parser\ParserInterface\DirectoryParserInterface;
12
use PhpUnitGen\Parser\ParserInterface\PhpFileParserInterface;
13
use Respect\Validation\Validator;
14
use Symfony\Component\Console\Output\OutputInterface;
15
16
/**
17
 * Class DirectoryParser.
18
 *
19
 * @author     Paul Thébaud <[email protected]>.
20
 * @copyright  2017-2018 Paul Thébaud <[email protected]>.
21
 * @license    https://opensource.org/licenses/MIT The MIT license.
22
 * @link       https://github.com/paul-thebaud/phpunit-generator
23
 * @since      Class available since Release 2.0.0.
24
 */
25
class DirectoryParser implements DirectoryParserInterface
26
{
27
    /**
28
     * @var ConsoleConfigInterface $config The configuration to use.
29
     */
30
    private $config;
31
32
    /**
33
     * @var FilesystemInterface $fileSystem The file system to use.
34
     */
35
    private $fileSystem;
36
37
    /**
38
     * @var PhpFileParserInterface $phpFileParser The php file parser to use.
39
     */
40
    private $phpFileParser;
41
42
    /**
43
     * @var OutputInterface $output The output to display message.
44
     */
45
    private $output;
46
47
    /**
48
     * DirectoryParser constructor.
49
     *
50
     * @param ConsoleConfigInterface $config        A config instance.
51
     * @param FilesystemInterface    $fileSystem    A file system instance.
52
     * @param PhpFileParserInterface $phpFileParser A php file parser instance.
53
     * @param OutputInterface $output The output to display message.
54
     */
55
    public function __construct(
56
        ConsoleConfigInterface $config,
57
        FilesystemInterface $fileSystem,
58
        PhpFileParserInterface $phpFileParser,
59
        OutputInterface $output
60
    ) {
61
        $this->config        = $config;
62
        $this->fileSystem    = $fileSystem;
63
        $this->phpFileParser = $phpFileParser;
64
        $this->output = $output;
65
    }
66
67
    /**
68
     * {@inheritdoc}
69
     */
70
    public function parse(string $sourceDirectory, string $targetDirectory): DirectoryModelInterface
71
    {
72
        if (! $this->fileSystem->has($sourceDirectory) || ! $this->fileSystem->getMimetype($sourceDirectory) === 'directory') {
73
            throw new ParsingException(sprintf('The source directory "%s" does not exist.', $sourceDirectory));
74
        }
75
76
        $directoryModel = new DirectoryModel();
77
        $directoryModel->setSourceDirectory($sourceDirectory);
78
        $directoryModel->setTargetDirectory($targetDirectory);
79
80
        $directoryModel = $this->addPhpFiles($directoryModel);
81
82
        return $directoryModel;
83
    }
84
85
    /**
86
     * Get all php files from a directory (and sub-directories).
87
     *
88
     * @param DirectoryModelInterface $directoryModel The directory model to save php files in.
89
     *
90
     * @return DirectoryModelInterface The updated directory model.
91
     *
92
     * @throws ParsingException If the file is not readable.
93
     */
94
    private function addPhpFiles(DirectoryModelInterface $directoryModel): DirectoryModelInterface
95
    {
96
        foreach ($this->fileSystem->listContents($directoryModel->getSourceDirectory()) as $file) {
97
            try {
98
                if ($this->validateFile($file['type'], $file['path'])) {
99
                    $directoryModel->addPhpFile($this->phpFileParser->parse($this->fileSystem->read($file['path'])));
0 ignored issues
show
Bug introduced by
It seems like $this->fileSystem->read($file['path']) can also be of type false; however, parameter $code of PhpUnitGen\Parser\Parser...arserInterface::parse() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

99
                    $directoryModel->addPhpFile($this->phpFileParser->parse(/** @scrutinizer ignore-type */ $this->fileSystem->read($file['path'])));
Loading history...
100
                }
101
            } catch (ParsingException $exception) {
102
                if (! $this->config->hasIgnore()) {
103
                    throw new ParsingException($exception->getMessage());
104
                }
105
                $this->output->writeln(sprintf('<error>%s</error>', $exception->getMessage()));
106
            }
107
        }
108
109
        return $directoryModel;
110
    }
111
112
    /**
113
     * Get a file content if the file match requirements and if it is readable.
114
     *
115
     * @param string $type The file type.
116
     * @param string $path The file path.
117
     *
118
     * @return bool If the file is valid.
119
     *
120
     * @throws ParsingException If the file is not readable.
121
     */
122
    private function validateFile(string $type, string $path): bool
123
    {
124
        if (! $type === 'file'
125
            || Validator::regex($this->config->getIncludeRegex())->validate($path) !== true
126
            || Validator::regex($this->config->getExcludeRegex())->validate($path) !== false
127
        ) {
128
            return false;
129
        }
130
        if ($this->fileSystem->getVisibility($path) === AdapterInterface::VISIBILITY_PRIVATE) {
131
            throw new ParsingException(sprintf('The file "%s" is not readable.', $path));
132
        }
133
        return true;
134
    }
135
}