CompareVersionsCommand::logJUnit()   A
last analyzed

Complexity

Conditions 4
Paths 2

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

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