/** * Execute the PhpCompatibility plugin */ protected function _execute() { $options = array('recursive' => true, 'report' => 'summary'); $min = 0; $minReadable = 0; $max = INF; $maxReadable = 'latest'; try { $phpci = new \PHP_CompatInfo($options); $phpci->parse($this->_extensionPath); $allResultsAtOnce = $phpci->toArray(); foreach ($phpci->toArray() as $file => $result) { if ($file == 'versions') { $currentMin = $this->_getVersionInt($result[0]); $currentMax = $this->_getVersionInt($result[1]); if (false == is_null($currentMin) && $min < $currentMin) { $min = $currentMin; $minReadable = $result[0]; } if (false == is_null($currentMax) && $currentMax < $max) { $max = $currentMax; $maxReadable = $result[1]; } } } } catch (\PHP_CompatInfo_Exception $e) { die('PHP_CompatInfo Exception : ' . $e->getMessage() . PHP_EOL); } if ($min <= $this->_getVersionInt($this->_settings->min) && $maxReadable == 'latest') { IssueHandler::addIssue(new Issue(array("extension" => $this->_extensionPath, "checkname" => $this->_pluginName, "type" => 'php_compatibility', "comment" => vsprintf('Extension is compatible to PHP from version %s up to latest versions', array($minReadable)), "failed" => false))); return; } IssueHandler::addIssue(new Issue(array("extension" => $this->_extensionPath, "checkname" => $this->_pluginName, "type" => 'php_compatibility', "comment" => vsprintf('Extension is compatible to PHP from version %s (instead of required %s) up to %s', array($minReadable, $this->_settings->min, $maxReadable)), "failed" => true))); }
/** * Execute the PerformanceCheck plugin */ protected function _execute() { $possiblePerformanceKillers = $this->_scanForPerformanceLeaks($this->_extensionPath); if (0 < sizeof($possiblePerformanceKillers)) { foreach ($possiblePerformanceKillers as $possiblePerformanceKiller) { Logger::setResultValue($this->_extensionPath, $this->_pluginName, $possiblePerformanceKiller, count($possiblePerformanceKillers)); IssueHandler::addIssue(new Issue(array("extension" => $this->_extensionPath, "checkname" => $this->_pluginName, "type" => 'performance_leak', "comment" => $possiblePerformanceKiller . ' (' . count($possiblePerformanceKillers) . 'times)', "failed" => true))); } } }
/** * Execute the MageCompatibility plugin */ protected function _execute() { try { $this->_connectTagDatabase(); $availableVersions = dibi::query('SELECT concat( m.edition, " ", m.version ) as Magento FROM magento m ORDER BY Magento')->fetchPairs(); $supportedVersions = array(); $extension = new Extension($this->_extensionPath); $methods = $extension->getUsedMagentoMethods(); $classes = $extension->getUsedMagentoClasses(); IssueHandler::addIssue(new Issue(array("extension" => $this->_extensionPath, "checkname" => $this->_pluginName, "type" => 'mage_compatibility', "comment" => sprintf('Extension uses %d classes and %d methods of Magento core', $classes->count(), $methods->count()), "failed" => true))); $incompatibleVersions = array(); foreach ($availableVersions as $version) { $incompatibleVersions[$version] = array('classes' => array(), 'methods' => array(), 'constants' => array()); } foreach ($classes as $class) { $class->setConfig($this->_settings); $supportedVersions = $class->getMagentoVersions(); if (is_array($supportedVersions)) { $tagIncompatibleVersions = array_diff($availableVersions, $supportedVersions); foreach ($tagIncompatibleVersions as $version) { $incompatibleVersions[$version]['classes'][] = $class->getName(); } } } foreach ($methods as $method) { $isExtensionMethod = false; $context = current($method->getContext()); $method->setConfig($this->_settings); $supportedVersions = $method->getMagentoVersions(); //echo $context['class'] . '->' . $method->getName() . ' '; if (false == is_array($supportedVersions)) { continue; } $tagIncompatibleVersions = array_diff($availableVersions, $supportedVersions); foreach ($tagIncompatibleVersions as $version) { $methodName = $method->getContext('class') . '->' . $method->getName() . '(' . implode(', ', $method->getParams()) . ')'; if ($extension->hasMethod($method->getName())) { $methodName .= ' [maybe part of the extension]'; continue; } $incompatibleVersions[$version]['methods'][] = $methodName; } } $compatibleVersions = array(); foreach ($incompatibleVersions as $version => $incompatibilities) { $message = ''; $incompatibleClasses = array_unique($incompatibilities['classes']); $incompatibleMethods = array_unique($incompatibilities['methods']); $incompatibleConstants = array_unique($incompatibilities['constants']); if (0 < count($incompatibleClasses)) { $message .= sprintf("<comment>The following classes are not compatible to Magento %s:</comment>\n * %s\n", $version, implode("\n * ", $incompatibleClasses)); } if (0 < count($incompatibleMethods)) { $message .= sprintf("<comment>The following methods are not compatible to Magento %s:</comment>\n * %s\n", $version, implode("\n * ", $incompatibleMethods)); } if (0 < count($incompatibleConstants)) { $message .= sprintf("<comment>The following constants are not compatible to Magento %s:</comment>\n * %s\n", $version, implode("\n * ", $incompatibleConstants)); } if (0 < strlen($message)) { IssueHandler::addIssue(new Issue(array("extension" => $this->_extensionPath, "checkname" => $this->_pluginName, "type" => 'mage_compatibility', "comment" => sprintf("<error>Extension is not compatible to Magento %s</error>\n%s", $version, $message), "failed" => true))); } else { $compatibleVersions[] = $version; } } IssueHandler::addIssue(new Issue(array("extension" => $this->_extensionPath, "checkname" => $this->_pluginName, "type" => 'mage_compatibility', "comment" => 'Checked Magento versions: ' . implode(', ', $availableVersions) . "\n" . '* Extension seems to support following Magento versions: ' . implode(', ', $compatibleVersions), "failed" => false))); foreach (array_keys($incompatibleVersions) as $key) { if (0 == count($incompatibleVersions[$key]['classes']) && 0 == count($incompatibleVersions[$key]['methods']) && 0 == count($incompatibleVersions[$key]['constants'])) { unset($incompatibleVersions[$key]); } } if ($this->_containsNoLatestVersion(array_keys($incompatibleVersions), 'CE')) { IssueHandler::addIssue(new Issue(array("extension" => $this->_extensionPath, "checkname" => $this->_pluginName, "type" => 'mage_compatibility', "comment" => sprintf('Extension supports Magento at least from CE version %s and EE version %s', $this->_settings->min->ce, $this->_settings->min->ee), "failed" => false))); return; } } catch (\Exception $e) { $this->setUnfinishedIssue(); $message = is_array($e->getMessage()) ? $e->getMessage() : array($e->getMessage()); Logger::error(implode(PHP_EOL, $message), array(), false); return; } }
/** * * calculates test coverage and find classes which are not covered by any test * * @param string $extensionPath */ protected function _evaluateTestCoverage($extensionPath) { $executable = realpath('vendor/bin/phpunit'); $phpUnitCoverageFile = $this->_magentoTarget . '/codecoverage' . (string) $this->_config->token . '.xml'; $phpUnitSwitches = array(sprintf("--coverage-clover %s", $phpUnitCoverageFile), sprintf("--filter %s", implode('|', $this->_moduleNames))); if (isset($this->_settings->phpUnitSwitches)) { $phpUnitSwitches = array_merge($phpUnitSwitches, $this->_settings->phpUnitSwitches->toArray()); } $switches = implode(' ', $phpUnitSwitches); $command = 'cd ' . $this->_magentoTarget . ' && ' . $executable . ' ' . $switches; $pdependSummaryFile = 'summary' . (string) $this->_config->token . '.xml'; $execString = sprintf('vendor/pdepend/pdepend/src/bin/pdepend --summary-xml="%s" "%s"', $pdependSummaryFile, $extensionPath); try { $this->_executeCommand($command); $this->_executeCommand($execString); } catch (\Exception $e) { $this->setUnfinishedIssue(); if (file_exists($pdependSummaryFile)) { unlink($pdependSummaryFile); } if (file_exists($phpUnitCoverageFile)) { unlink($phpUnitCoverageFile); } $this->_cleanTestEnvironment(); return; } if (!file_exists($phpUnitCoverageFile) || !file_exists($pdependSummaryFile)) { $this->setUnfinishedIssue(); $this->_cleanTestEnvironment(); return; } $phpUnitXpaths = array(); foreach ($this->_moduleNames as $modulePrefixString) { $phpUnitXpaths[] = "//class[starts-with(@name, '" . $modulePrefixString . "')]/../metrics"; } $codeCoverages = $this->_evaluateCodeCoverage($phpUnitCoverageFile, $phpUnitXpaths); $codeCoverageSettings = $this->_settings->phpUnitCodeCoverages->toArray(); foreach (array_keys($codeCoverageSettings) as $codeCoverageType) { if (array_key_exists($codeCoverageType, $codeCoverages)) { IssueHandler::addIssue(new Issue(array("extension" => $extensionPath, "checkname" => $this->_pluginName, "type" => $codeCoverageType, "comment" => $codeCoverages[$codeCoverageType], "failed" => true))); } } // compare phpunit test results with pdepend $phpUnitXpaths = array(); $pdependXpaths = array(); foreach ($this->_moduleNames as $modulePrefixString) { $phpUnitXpaths[] = "//class[starts-with(@name, '" . $modulePrefixString . "')]"; $pdependXpaths[] = "//class[starts-with(@name, '" . $modulePrefixString . "') and not(starts-with(@name, '" . $modulePrefixString . '_Test' . "'))]"; } $phpUnitClasses = $this->_getClasses($phpUnitCoverageFile, $phpUnitXpaths); $pdependClasses = $this->_getClasses($pdependSummaryFile, $pdependXpaths); $notCoveredClasses = array_diff($pdependClasses, $phpUnitClasses); if (0 < sizeof($notCoveredClasses)) { foreach ($notCoveredClasses as $notCoveredClass) { IssueHandler::addIssue(new Issue(array("extension" => $extensionPath, "checkname" => $this->_pluginName, "type" => 'notCovered', "comment" => '<comment>Following class is not covered by any test: ' . $notCoveredClass . ' </comment>', "failed" => false))); } } unlink($pdependSummaryFile); unlink($phpUnitCoverageFile); $this->_cleanTestEnvironment(); }