Completed
Pull Request — develop (#166)
by Robbie
04:29
created

CompareVersionsCommand::inject()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 1
Metric Value
dl 0
loc 7
rs 9.4286
c 2
b 1
f 1
cc 1
eloc 5
nc 1
nop 2
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
        $time = microtime(true);
40
        $ignoreDataUpdate = $input->getOption('ignore-data');
41
42
        $headers = array('Setup', 'Module', 'DB', 'Data', 'Status');
43
        if ($ignoreDataUpdate) {
44
            unset($headers[array_search('Data', $headers)]);
45
        }
46
47
        $errorCounter = 0;
48
        $table = array();
49
        foreach ($this->getModuleList()->getAll() as $moduleName => $moduleInfo) {
50
51
            $moduleVersion = $moduleInfo['setup_version'];
52
            $dbVersion     = $this->getResource()->getDbVersion($moduleName);
53
            if (!$ignoreDataUpdate) {
54
                $dataVersion = $this->getResource()->getDataVersion($moduleName);
55
            }
56
57
            $ok = $dbVersion == $moduleVersion;
58
            if ($ok && !$ignoreDataUpdate) {
59
                $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...
60
            }
61
            if (!$ok) {
62
                $errorCounter++;
63
            }
64
65
            $row = array(
66
                'Module' => $moduleName,
67
                'DB'     => $dbVersion,
68
                'Data'   => $dataVersion,
69
            );
70
71
            if (!$ignoreDataUpdate) {
72
                $row['Data-Version'] = $dataVersion;
73
            }
74
            $row['Status'] = $ok ? 'OK' : 'Error';
75
            $table[] = $row;
76
        }
77
78
        // If there is no output format highlight the status and show error'd rows at bottom
79
        if (!$input->getOption('format')) {
80
81
            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...
82
                return $a['Status'] !== 'OK';
83
            });
84
85
            array_walk($table, function (&$row) {
86
                $status             = $row['Status'];
87
                $availableStatus    = array('OK' => 'info', 'Error' => 'error');
88
                $statusString       = sprintf(
89
                    '<%s>%s</%s>',
90
                    $availableStatus[$status],
91
                    $status,
92
                    $availableStatus[$status]
93
                );
94
                $row['Status'] = $statusString;
95
            });
96
        }
97
98
        if ($input->getOption('log-junit')) {
99
            $this->logJUnit($table, $input->getOption('log-junit'), microtime($time) - $time);
100
        } else {
101
            $this->getHelper('table')
102
                ->setHeaders($headers)
103
                ->renderByFormat($output, $table, $input->getOption('format'));
104
105
            //if no output format specified - output summary line
106
            if (!$input->getOption('format')) {
107
                if ($errorCounter > 0) {
108
                    $this->writeSection(
109
                        $output,
110
                        sprintf(
111
                            '%s error%s %s found!',
112
                            $errorCounter,
113
                            $errorCounter === 1 ? '' : 's',
114
                            $errorCounter === 1 ? 'was' : 'were'
115
                        ),
116
                        'error'
117
                    );
118
                } else {
119
                    $this->writeSection($output, 'No setup problems were found.', 'info');
120
                }
121
            }
122
        }
123
    }
124
125
    /**
126
     * @param array $data
127
     * @param string $filename
128
     * @param float $duration
129
     */
130
    protected function logJUnit(array $data, $filename, $duration)
131
    {
132
        $document = new JUnitXmlDocument();
133
        $suite = $document->addTestSuite();
134
        $suite->setName('n98-magerun2: ' . $this->getName());
135
        $suite->setTimestamp(new \DateTime());
136
        $suite->setTime($duration);
137
138
        $testCase = $suite->addTestCase();
139
        $testCase->setName('Magento Setup Version Test');
140
        $testCase->setClassname('CompareVersionsCommand');
141
        if (count($data) > 0) {
142
            foreach ($data as $moduleSetup) {
143
                if (stristr($moduleSetup['Status'], 'error')) {
144
                    $testCase->addFailure(
145
                        sprintf(
146
                            'Setup Script Error: [Setup %s]',
147
                            $moduleSetup['Setup']
148
                        ),
149
                        'MagentoSetupScriptVersionException'
150
                    );
151
                }
152
            }
153
        }
154
155
        $document->save($filename);
156
    }
157
}
158