Test Failed
Branch fixes (39eb20)
by Fabian
08:05
created

ExceptionGeneratorCommand::execute()   B

Complexity

Conditions 10
Paths 48

Size

Total Lines 97
Code Lines 59

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 44
CRAP Score 10.001

Importance

Changes 0
Metric Value
eloc 59
dl 0
loc 97
ccs 44
cts 45
cp 0.9778
rs 7.0278
c 0
b 0
f 0
cc 10
nc 48
nop 2
crap 10.001

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Fabiang\ExceptionGenerator\Cli\Command;
6
7
use Fabiang\ExceptionGenerator\Cli\Console\Application;
8
use Fabiang\ExceptionGenerator\Generator\CreateException;
9
use Fabiang\ExceptionGenerator\Generator\RecursiveNamespaceResolver;
10
use Fabiang\ExceptionGenerator\Generator\RecursiveParentExceptionResolver;
11
use Fabiang\ExceptionGenerator\Generator\TemplateRenderer;
12
use Fabiang\ExceptionGenerator\Listener\CreateExceptionListener;
13
use Fabiang\ExceptionGenerator\TemplateResolver\TemplatePathMatcher;
14
use Fabiang\ExceptionGenerator\TemplateResolver\TemplateResolver;
15
use Symfony\Component\Console\Command\Command;
16
use Symfony\Component\Console\Helper\QuestionHelper;
17
use Symfony\Component\Console\Input\InputArgument;
18
use Symfony\Component\Console\Input\InputInterface;
19
use Symfony\Component\Console\Input\InputOption;
20
use Symfony\Component\Console\Output\OutputInterface;
21
use Symfony\Component\Console\Question\Question;
22
use Symfony\Component\EventDispatcher\EventDispatcher;
23
24
use function array_reverse;
25
use function getcwd;
26
use function is_array;
27
use function is_string;
28
use function realpath;
29
use function substr;
30
31
class ExceptionGeneratorCommand extends Command
32
{
33
    /**
34
     * {@inheritDoc}
35
     */
36
    protected function configure(): void
37
    {
38
        $this->setName('exception-generator')
39
            ->setDescription('Generates Exception Classes for php files in current dir.')
40
            ->addArgument(
41
                'path',
42
                InputArgument::OPTIONAL,
43
                'Basepath for generating exception class.'
44
            )
45
            ->addOption(
46
                'overwrite',
47
                'o',
48
                InputOption::VALUE_NONE,
49
                'Force overwriting existing exception classes.'
50
            )
51
            ->addOption(
52
                'template-path',
53
                't',
54
                InputOption::VALUE_REQUIRED,
55
                'Set path for templates you want to use.'
56
            )
57
            ->addOption(
58
                'no-parents',
59
                'p',
60
                InputOption::VALUE_NONE,
61
                'Disable searching for parent exceptions.'
62
            );
63
    }
64
65
    /**
66 2
     * {@inheritDoc}
67
     */
68 2
    protected function execute(InputInterface $input, OutputInterface $output): int
69 2
    {
70
        if ($input->getArgument('path')) {
71
            $path = $this->realpath($input->getArgument('path'));
72
        } else {
73
            $path = getcwd();
74
        }
75 2
76
        if (! is_string($path)) {
0 ignored issues
show
introduced by
The condition is_string($path) is always true.
Loading history...
77 2
            $path = '';
78 2
        }
79 2
80
        /** @var QuestionHelper $questionHelper */
81 2
        $questionHelper = $this->getHelper('question');
82 2
83
        $eventDispatcher = new EventDispatcher();
84 2
        $eventDispatcher->addSubscriber(new CreateExceptionListener($output, $input, $questionHelper));
85 2
        $namespaceResolver = new RecursiveNamespaceResolver($eventDispatcher);
86
87 2
        $namespace = $namespaceResolver->resolveNamespace($path);
88 2
89
        /** @var Application $application */
90 2
        $application = $this->getApplication();
91
92 2
        $templatePathMatcher = new TemplatePathMatcher($path, $application->getHome() ?? '');
93 2
94 2
        $templatePath     = $this->realpath($input->getOption('template-path')) ?: '';
95
        $templateResolver = new TemplateResolver($templatePath, $templatePathMatcher);
96 2
97 2
        $exceptionTemplate = $templateResolver->resolve('exception.phtml');
98 2
        $interfaceTemplate = $templateResolver->resolve('interface.phtml');
99
100 2
        $useParents = $input->getOption('no-parents') ? false : true;
101
102 2
        $output->writeln('Using path for templates: "' . $templatePath . '"', OutputInterface::VERBOSITY_VERY_VERBOSE);
103 1
        $output->writeln('Exception-Path: "' . $exceptionTemplate . '"', OutputInterface::VERBOSITY_VERY_VERBOSE);
104 1
        $output->writeln('Interface-Path: "' . $interfaceTemplate . '"', OutputInterface::VERBOSITY_VERY_VERBOSE);
105
106 1
        $templateRenderer = new TemplateRenderer();
107 1
        $templateRenderer->addPath('exception', $exceptionTemplate);
108 1
        $templateRenderer->addPath('interface', $interfaceTemplate);
109 1
110 1
        $parentExceptionNamespace = null;
111
112 1
        if (false !== $useParents) {
113 1
            $parentExceptionResolver = new RecursiveParentExceptionResolver($eventDispatcher);
114
            $parentExceptionDirs     = $parentExceptionResolver->resolveExceptionDirs($path);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $parentExceptionDirs is correct as $parentExceptionResolver...lveExceptionDirs($path) targeting Fabiang\ExceptionGenerat...:resolveExceptionDirs() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
115
116 1
            if (is_array($parentExceptionDirs)) {
0 ignored issues
show
introduced by
The condition is_array($parentExceptionDirs) is always false.
Loading history...
117 1
                $parentExceptionDirs = array_reverse($parentExceptionDirs);
118
                foreach ($parentExceptionDirs as $parentExceptionDir) {
119
                    $prevParentNamespace      = $parentExceptionNamespace;
120
                    $parentExceptionNamespace = $namespaceResolver->resolveNamespace($parentExceptionDir);
121 1
122
                    if ($parentExceptionNamespace !== null) {
123
                        $output->writeln(
124
                            'BaseExceptionPath: "' . $parentExceptionDir . '"',
125
                            OutputInterface::VERBOSITY_VERY_VERBOSE
126
                        );
127
                        $output->writeln(
128
                            'BaseExceptionNamespace: "' . $parentExceptionNamespace . '"',
129 1
                            OutputInterface::VERBOSITY_VERY_VERBOSE
130
                        );
131
132
                        $parentExceptionCreator = new CreateException(
133
                            $eventDispatcher,
134
                            $templateRenderer,
135
                            false
136
                        );
137
138
                        $parentExceptionCreator->create(
139 2
                            $parentExceptionNamespace,
140 2
                            $parentExceptionDir,
141
                            $prevParentNamespace
142 1
                        );
143
                    }
144
                }
145 2
            }
146 2
        }
147 2
148
        if ($parentExceptionNamespace === null) {
0 ignored issues
show
introduced by
The condition $parentExceptionNamespace === null is always true.
Loading history...
149 2
            $output->writeln('BaseExceptionPath: not found/used', OutputInterface::VERBOSITY_VERY_VERBOSE);
150
        }
151
152 2
        $namespaceQuestion = new Question("Is this the correct namespace: [$namespace]?", $namespace);
153
        $inputNamespace    = $questionHelper->ask($input, $output, $namespaceQuestion);
154
        $output->writeln('Namespace set to "' . $inputNamespace . '"');
155
156
        $exceptionCreator = new CreateException(
157 2
            $eventDispatcher,
158
            $templateRenderer,
159 2
            $input->getOption('overwrite')
160
        );
161
162
        $exceptionCreator->create($inputNamespace, $path . '/Exception', $parentExceptionNamespace);
163
164
        return 0;
165 2
    }
166
167 2
    /**
168
     * Realpath.
169
     */
170
    private function realpath(?string $path): string|false
171
    {
172 2
        if (null === $path) {
173 2
            return '';
174
        }
175
176
        // extra check for virtual file system since vfsstream can't handle realpath()
177
        if (substr($path, 0, 6) === 'vfs://') {
178
            return $path;
179
        }
180
181
        return realpath($path);
182
    }
183
}
184