Completed
Pull Request — develop (#167)
by Robbie
04:07
created

CompareVersionsCommand::execute()   F

Complexity

Conditions 16
Paths 529

Size

Total Lines 93
Code Lines 59

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 1 Features 3
Metric Value
c 4
b 1
f 3
dl 0
loc 93
rs 2.8388
cc 16
eloc 59
nc 529
nop 2

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
namespace N98\Magento\Command\System\Setup;
4
5
use N98\JUnitXml\Document as JUnitXmlDocument;
6
use Symfony\Component\Console\Input\InputInterface;
7
use Symfony\Component\Console\Input\InputOption;
8
use Symfony\Component\Console\Output\OutputInterface;
9
use N98\Util\Console\Helper\Table\Renderer\RendererFactory;
10
11
class CompareVersionsCommand extends AbstractSetupCommand
12
{
13
    protected function configure()
14
    {
15
        $this
16
            ->setName('sys:setup:compare-versions')
17
            ->addOption('ignore-data', null, InputOption::VALUE_NONE, 'Ignore data updates')
18
            ->addOption('log-junit', null, InputOption::VALUE_REQUIRED, 'Log output to a JUnit xml file.')
19
            ->addOption(
20
                'format',
21
                null,
22
                InputOption::VALUE_OPTIONAL,
23
                'Output Format. One of [' . implode(',', RendererFactory::getFormats()) . ']'
24
            )
25
            ->setDescription('Compare module version with core_resource table.');
26
        $help = <<<HELP
27
Compares module version with saved setup version in `core_resource` table and displays version mismatch.
28
HELP;
29
        $this->setHelp($help);
30
    }
31
32
    /**
33
     * @param \Symfony\Component\Console\Input\InputInterface $input
34
     * @param \Symfony\Component\Console\Output\OutputInterface $output
35
     * @return int|null|void
36
     */
37
    protected function execute(InputInterface $input, OutputInterface $output)
38
    {
39
        $this->detectMagento($output, true);
40
41
        if (!$this->initMagento()) {
42
            return;
43
        }
44
45
        $time = microtime(true);
46
        $ignoreDataUpdate = $input->getOption('ignore-data');
47
48
        $headers = array('Setup', 'Module', 'DB', 'Data', 'Status');
49
        if ($ignoreDataUpdate) {
50
            unset($headers[array_search('Data', $headers)]);
51
        }
52
53
        $errorCounter = 0;
54
        $table = array();
55
        foreach ($this->getMagentoModuleList()->getAll() as $moduleName => $moduleInfo) {
56
57
            $moduleVersion = $moduleInfo['setup_version'];
58
            $dbVersion     = $this->getMagentoModuleResource()->getDbVersion($moduleName);
59
            if (!$ignoreDataUpdate) {
60
                $dataVersion = $this->getMagentoModuleResource()->getDataVersion($moduleName);
61
            }
62
63
            $ok = $dbVersion == $moduleVersion;
64
            if ($ok && !$ignoreDataUpdate) {
65
                $ok = $dataVersion == $moduleVersion;
0 ignored issues
show
Bug introduced by
The variable $dataVersion does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
66
            }
67
            if (!$ok) {
68
                $errorCounter++;
69
            }
70
71
            $row = array(
72
                'Module' => $moduleName,
73
                'DB'     => $dbVersion,
74
                'Data'   => $dataVersion,
75
            );
76
77
            if (!$ignoreDataUpdate) {
78
                $row['Data-Version'] = $dataVersion;
79
            }
80
            $row['Status'] = $ok ? 'OK' : 'Error';
81
            $table[] = $row;
82
        }
83
84
        // If there is no output format highlight the status and show error'd rows at bottom
85
        if (!$input->getOption('format')) {
86
87
            usort($table, function($a, $b) {
0 ignored issues
show
Unused Code introduced by
The parameter $b is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
88
                return $a['Status'] !== 'OK';
89
            });
90
91
            array_walk($table, function (&$row) {
92
                $status             = $row['Status'];
93
                $availableStatus    = array('OK' => 'info', 'Error' => 'error');
94
                $statusString       = sprintf(
95
                    '<%s>%s</%s>',
96
                    $availableStatus[$status],
97
                    $status,
98
                    $availableStatus[$status]
99
                );
100
                $row['Status'] = $statusString;
101
            });
102
        }
103
104
        if ($input->getOption('log-junit')) {
105
            $this->logJUnit($table, $input->getOption('log-junit'), microtime($time) - $time);
106
        } else {
107
            $this->getHelper('table')
108
                ->setHeaders($headers)
109
                ->renderByFormat($output, $table, $input->getOption('format'));
110
111
            //if no output format specified - output summary line
112
            if (!$input->getOption('format')) {
113
                if ($errorCounter > 0) {
114
                    $this->writeSection(
115
                        $output,
116
                        sprintf(
117
                            '%s error%s %s found!',
118
                            $errorCounter,
119
                            $errorCounter === 1 ? '' : 's',
120
                            $errorCounter === 1 ? 'was' : 'were'
121
                        ),
122
                        'error'
123
                    );
124
                } else {
125
                    $this->writeSection($output, 'No setup problems were found.', 'info');
126
                }
127
            }
128
        }
129
    }
130
131
    /**
132
     * @param array $data
133
     * @param string $filename
134
     * @param float $duration
135
     */
136
    protected function logJUnit(array $data, $filename, $duration)
137
    {
138
        $document = new JUnitXmlDocument();
139
        $suite = $document->addTestSuite();
140
        $suite->setName('n98-magerun2: ' . $this->getName());
141
        $suite->setTimestamp(new \DateTime());
142
        $suite->setTime($duration);
143
144
        $testCase = $suite->addTestCase();
145
        $testCase->setName('Magento Setup Version Test');
146
        $testCase->setClassname('CompareVersionsCommand');
147
        if (count($data) > 0) {
148
            foreach ($data as $moduleSetup) {
149
                if (stristr($moduleSetup['Status'], 'error')) {
150
                    $testCase->addFailure(
151
                        sprintf(
152
                            'Setup Script Error: [Setup %s]',
153
                            $moduleSetup['Setup']
154
                        ),
155
                        'MagentoSetupScriptVersionException'
156
                    );
157
                }
158
            }
159
        }
160
161
        $document->save($filename);
162
    }
163
}
164