Passed
Push — develop ( 45600c...ff69f6 )
by Paul
03:16
created

GenerateTestsCommand::execute()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 32
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 32
c 0
b 0
f 0
rs 8.439
cc 5
eloc 20
nc 3
nop 2
1
<?php
2
3
namespace PhpUnitGen\Console;
4
5
use League\Flysystem\FilesystemInterface;
6
use PhpUnitGen\Configuration\ConsoleConfigInterface;
7
use PhpUnitGen\Configuration\JsonConsoleConfig;
8
use PhpUnitGen\Configuration\YamlConsoleConfig;
9
use PhpUnitGen\Container\DependencyInjectorInterface;
10
use PhpUnitGen\Exception\InvalidConfigException;
11
use PhpUnitGen\Exception\ParsingException;
12
use PhpUnitGen\Parser\ParserInterface\DirectoryParserInterface;
13
use Psr\Container\ContainerInterface;
14
use Symfony\Component\Console\Command\Command;
15
use Symfony\Component\Console\Input\InputArgument;
16
use Symfony\Component\Console\Input\InputInterface;
17
use Symfony\Component\Console\Output\OutputInterface;
18
19
/**
20
 * Class GenerateTestsCommand.
21
 *
22
 * @author     Paul Thébaud <[email protected]>.
23
 * @copyright  2017-2018 Paul Thébaud <[email protected]>.
24
 * @license    https://opensource.org/licenses/MIT The MIT license.
25
 * @link       https://github.com/paul-thebaud/phpunit-generator
26
 * @since      Class available since Release 2.0.0.
27
 */
28
class GenerateTestsCommand extends Command
29
{
30
    /**
31
     * @var ContainerInterface $container A container to manage dependencies.
32
     */
33
    private $container;
34
35
    /**
36
     * @var DependencyInjectorInterface $dependencyInjector A tool to inject dependencies in container from config.
37
     */
38
    private $dependencyInjector;
39
40
    /**
41
     * @var FilesystemInterface $fileSystem A file system to find configuration file.
42
     */
43
    private $fileSystem;
44
45
    /**
46
     * @var DirectoryParserInterface $directoryParser A directory parser to parse each files in directory.
47
     */
48
    private $directoryParser;
49
50
    /**
51
     * GenerateTestsCommand constructor.
52
     *
53
     * @param ContainerInterface $container A container to manage dependencies.
54
     */
55
    public function __construct(ContainerInterface $container)
56
    {
57
        parent::__construct();
58
59
        $this->container          = $container;
60
        $this->dependencyInjector = $container->get(DependencyInjectorInterface::class);
61
        $this->fileSystem         = $container->get(FilesystemInterface::class);
62
    }
63
64
    /**
65
     * {@inheritdoc}
66
     */
67
    protected function configure()
68
    {
69
        $this->setName("generate")
70
            ->setDescription("Generate unit tests skeletons")
71
            ->setHelp("Use it to generate your unit tests skeletons")
72
            ->addArgument('config-path', InputArgument::REQUIRED, 'The config file path.');
73
    }
74
75
    /**
76
     * {@inheritdoc}
77
     */
78
    protected function execute(InputInterface $input, OutputInterface $output)
79
    {
80
        try {
81
            $config = $this->getConfiguration($input->getArgument('config-path'));
82
        } catch (InvalidConfigException $exception) {
83
            $output->writeln(
84
                sprintf("<error>Error during configuration parsing:\n\n%s</error>", $exception->getMessage())
85
            );
86
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
87
        }
88
89
        // Load the ConfigInterface dependency
90
        $this->container = $this->dependencyInjector->inject($config, $this->container);
91
92
        $this->directoryParser = $this->container->get(DirectoryParserInterface::class);
93
94
        $directoryModels = [];
95
        foreach ($config->getDirectories() as $sourceDirectory => $targetDirectory) {
96
            try {
97
                $directoryModels[] = $this->directoryParser->parse($sourceDirectory, $targetDirectory);
98
            } catch (ParsingException $exception) {
99
                $output->writeln(sprintf(
100
                    "<error>Parsing directory \"%s\" failed for the following reason:\n\n%s</error>",
101
                    $sourceDirectory,
102
                    $exception->getMessage()
103
                ));
104
                if (! $config->hasIgnore()) {
105
                    exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
106
                }
107
            }
108
109
            $output->writeln(sprintf('<info>Parsing directory "%s" completed.</info>', $sourceDirectory));
110
        }
111
    }
112
113
    /**
114
     * Build a configuration from a configuration file path.
115
     *
116
     * @param string $path The config file path.
117
     *
118
     * @return ConsoleConfigInterface The created configuration.
119
     *
120
     * @throws InvalidConfigException If an error occurs during process.
121
     */
122
    public function getConfiguration(string $path): ConsoleConfigInterface
123
    {
124
        if (! $this->fileSystem->has($path)) {
125
            throw new InvalidConfigException(sprintf('Config file "%s" does not exists.', $path));
126
        }
127
128
        switch (pathinfo($path, PATHINFO_EXTENSION)) {
129
            case 'yml':
130
                $configClass = YamlConsoleConfig::class;
131
                break;
132
            case 'json':
133
                $configClass = JsonConsoleConfig::class;
134
                break;
135
            default:
136
                throw new InvalidConfigException(
137
                    sprintf('Config file "%s" must have .json or .yml extension.', $path)
138
                );
139
        }
140
        return new $configClass($this->fileSystem->read($path));
141
    }
142
}
143