Completed
Push — develop ( 21139f...eaa140 )
by Tom
12s
created

CompareVersionsCommand::execute()   F

Complexity

Conditions 23
Paths 4161

Size

Total Lines 121
Code Lines 77

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 1 Features 1
Metric Value
c 6
b 1
f 1
dl 0
loc 121
rs 2
cc 23
eloc 77
nc 4161
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 N98\Magento\Command\AbstractMagentoCommand;
7
use N98\Util\Console\Helper\Table\Renderer\RendererFactory;
8
use Symfony\Component\Console\Input\InputInterface;
9
use Symfony\Component\Console\Input\InputOption;
10
use Symfony\Component\Console\Output\OutputInterface;
11
12
class CompareVersionsCommand extends AbstractMagentoCommand
13
{
14 View Code Duplication
    protected function configure()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
15
    {
16
        $this
17
            ->setName('sys:setup:compare-versions')
18
            ->addOption('ignore-data', null, InputOption::VALUE_NONE, 'Ignore data updates')
19
            ->addOption('log-junit', null, InputOption::VALUE_REQUIRED, 'Log output to a JUnit xml file.')
20
            ->addOption(
21
                'errors-only',
22
                null,
23
                InputOption::VALUE_NONE,
24
                'Only display Setup resources where Status equals Error.'
25
            )
26
            ->addOption(
27
                'format',
28
                null,
29
                InputOption::VALUE_OPTIONAL,
30
                'Output Format. One of [' . implode(',', RendererFactory::getFormats()) . ']'
31
            )
32
            ->setDescription('Compare module version with core_resource table.');
33
        $help = <<<HELP
34
Compares module version with saved setup version in `core_resource` table and displays version mismatch.
35
HELP;
36
        $this->setHelp($help);
37
    }
38
39
    /**
40
     * @param InputInterface  $input
41
     * @param OutputInterface $output
42
     *
43
     * @return int|null|void
44
     */
45
    protected function execute(InputInterface $input, OutputInterface $output)
46
    {
47
        $this->detectMagento($output);
48
        if (!$this->initMagento()) {
49
            return;
50
        }
51
52
        $time = microtime(true);
53
        $modules            = \Mage::getConfig()->getNode('modules');
54
        $resourceModel      = $this->_getResourceSingleton('core/resource', 'Mage_Core_Model_Resource_Resource');
55
        $setups             = \Mage::getConfig()->getNode('global/resources')->children();
56
        $ignoreDataUpdate   = $input->getOption('ignore-data');
57
58
        $headers = array('Setup', 'Module', 'DB', 'Data', 'Status');
59
        if ($ignoreDataUpdate) {
60
            unset($headers[array_search('Data', $headers)]);
61
        }
62
63
        $hasStatusErrors = false;
64
65
        $errorCounter = 0;
66
        $table = array();
67
        foreach ($setups as $setupName => $setup) {
68
            $moduleName    = (string) $setup->setup->module;
69
            $moduleVersion = (string) $modules->{$moduleName}->version;
70
            $dbVersion     = (string) $resourceModel->getDbVersion($setupName);
71
            if (!$ignoreDataUpdate) {
72
                $dataVersion = (string) $resourceModel->getDataVersion($setupName);
73
            }
74
            $ok = $dbVersion == $moduleVersion;
75
            if ($ok && !$ignoreDataUpdate) {
76
                $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...
77
            }
78
            if (!$ok) {
79
                $errorCounter++;
80
            }
81
82
            $row = array(
83
                'Setup'     => $setupName,
84
                'Module'    => $moduleVersion,
85
                'DB'        => $dbVersion,
86
            );
87
88
            if (!$ignoreDataUpdate) {
89
                $row['Data-Version'] = $dataVersion;
90
            }
91
            $row['Status'] = $ok ? 'OK' : 'Error';
92
93
            if (!$ok) {
94
                $hasStatusErrors = true;
95
            }
96
97
            $table[] = $row;
98
        }
99
100
        if ($input->getOption('errors-only')) {
101
            $table = array_filter($table, function ($row) {
102
                return ($row['Status'] === 'Error');
103
            });
104
        }
105
106
        //if there is no output format
107
        //highlight the status
108
        //and show error'd rows at bottom
109
        if (!$input->getOption('format')) {
110
            usort($table, function ($a, $b) {
111
                if ($a['Status'] !== 'OK' && $b['Status'] === 'OK') {
112
                    return 1;
113
                }
114
                if ($a['Status'] === 'OK' && $b['Status'] !== 'OK') {
115
                    return -1;
116
                }
117
                return strcmp($a['Setup'], $b['Setup']);
118
            });
119
120
            array_walk($table, function (&$row) {
121
                $status             = $row['Status'];
122
                $availableStatus    = array('OK' => 'info', 'Error' => 'error');
123
                $statusString       = sprintf(
124
                    '<%s>%s</%s>',
125
                    $availableStatus[$status],
126
                    $status,
127
                    $availableStatus[$status]
128
                );
129
                $row['Status'] = $statusString;
130
            });
131
        }
132
133
        if ($input->getOption('log-junit')) {
134
            $this->logJUnit($table, $input->getOption('log-junit'), microtime($time) - $time);
135
        } else {
136
            $this->getHelper('table')
137
                ->setHeaders($headers)
138
                ->renderByFormat($output, $table, $input->getOption('format'));
139
140
            //if no output format specified - output summary line
141
            if (!$input->getOption('format')) {
142
                if ($errorCounter > 0) {
143
                    $this->writeSection(
144
                        $output,
145
                        sprintf(
146
                            '%s error%s %s found!',
147
                            $errorCounter,
148
                            $errorCounter === 1 ? '' : 's',
149
                            $errorCounter === 1 ? 'was' : 'were'
150
                        ),
151
                        'error'
152
                    );
153
                } else {
154
                    $this->writeSection($output, 'No setup problems were found.', 'info');
155
                }
156
            }
157
        }
158
159
        if ($hasStatusErrors) {
160
            //Return a non-zero status to indicate there is an error in the setup scripts.
161
            return 1;
162
        } else {
163
            return 0;
164
        }
165
    }
166
167
    /**
168
     * @param array $data
169
     * @param string $filename
170
     * @param float $duration
171
     */
172
    protected function logJUnit(array $data, $filename, $duration)
173
    {
174
        $document = new JUnitXmlDocument();
175
        $suite = $document->addTestSuite();
176
        $suite->setName('n98-magerun: ' . $this->getName());
177
        $suite->setTimestamp(new \DateTime());
178
        $suite->setTime($duration);
179
180
        $testCase = $suite->addTestCase();
181
        $testCase->setName('Magento Setup Version Test');
182
        $testCase->setClassname('CompareVersionsCommand');
183
        if (count($data) > 0) {
184
            foreach ($data as $moduleSetup) {
185
                if (stristr($moduleSetup['Status'], 'error')) {
186
                    $testCase->addFailure(
187
                        sprintf(
188
                            'Setup Script Error: [Setup %s]',
189
                            $moduleSetup['Setup']
190
                        ),
191
                        'MagentoSetupScriptVersionException'
192
                    );
193
                }
194
            }
195
        }
196
197
        $document->save($filename);
198
    }
199
}
200