Skip to content

Commit

Permalink
Task PHPMDTask and PhpCodeSnifferTask enables writing of last-modifie…
Browse files Browse the repository at this point in the history
…d times to cachefile, to speed up processing of files that rarely change.
  • Loading branch information
ruifil authored and rui committed Nov 24, 2015
1 parent 09b2ef5 commit 18a00b0
Show file tree
Hide file tree
Showing 7 changed files with 430 additions and 117 deletions.
89 changes: 74 additions & 15 deletions classes/phing/tasks/ext/PhpCodeSnifferTask.php
Expand Up @@ -31,7 +31,18 @@
class PhpCodeSnifferTask extends Task
{

/**
* A php source code filename or directory
*
* @var PhingFile
*/
protected $file; // the source file (from xml attribute)

/**
* All fileset objects assigned to this task
*
* @var FileSet[]
*/
protected $filesets = array(); // all fileset objects assigned to this task

// parameters for php code sniffer
Expand Down Expand Up @@ -73,6 +84,12 @@ class PhpCodeSnifferTask extends Task
private $skipversioncheck = false;
private $propertyName = null;

/**
* Cache data storage
* @var DataStore
*/
protected $cache;

/**
* Load the necessary environment for running PHP_CodeSniffer.
*
Expand Down Expand Up @@ -361,6 +378,49 @@ public function getPropertyName()
return $this->propertyName;
}

/**
* Whether to store last-modified times in cache
*
* @param PhingFile $file
*/
public function setCacheFile(PhingFile $file)
{
$this->cache = new DataStore($file);
}

/**
* Return the list of files to parse
*
* @return string[] list of absolute files to parse
*/
protected function getFilesToParse()
{
$filesToParse = array();

if ($this->file instanceof PhingFile) {
$filesToParse[] = $this->file->getPath();
} else {
// append any files in filesets
foreach ($this->filesets as $fs) {
$dir = $fs->getDir($this->project)->getAbsolutePath();
foreach ($fs->getDirectoryScanner($this->project)->getIncludedFiles() as $filename) {
$fileAbsolutePath = $dir . DIRECTORY_SEPARATOR . $filename;
if ($this->cache) {
$lastMTime = $this->cache->get($fileAbsolutePath);
$currentMTime = filemtime($fileAbsolutePath);
if ($lastMTime >= $currentMTime) {
continue;
} else {
$this->cache->put($fileAbsolutePath, $currentMTime);
}
}
$filesToParse[] = $fileAbsolutePath;
}
}
}
return $filesToParse;
}

/**
* Executes PHP code sniffer against PhingFile or a FileSet
*/
Expand Down Expand Up @@ -405,21 +465,7 @@ public function main()
$this->formatters[] = $fmt;
}

$fileList = array();

if (!isset($this->file)) {
$project = $this->getProject();
foreach ($this->filesets as $fs) {
$ds = $fs->getDirectoryScanner($project);
$files = $ds->getIncludedFiles();
$dir = $fs->getDir($this->project)->getAbsolutePath();
foreach ($files as $file) {
$fileList[] = $dir . DIRECTORY_SEPARATOR . $file;
}
}
} else {
$fileList[] = $this->file->getPath();
}
$fileList = $this->getFilesToParse();

$cwd = getcwd();

Expand Down Expand Up @@ -489,10 +535,23 @@ public function main()
$_SERVER['argc']++;
}

if ($this->cache) {
require_once 'phing/tasks/ext/phpcs/Reports_PhingRemoveFromCache.php';
PHP_CodeSniffer_Reports_PhingRemoveFromCache::setCache($this->cache);
// add a fake report to remove from cache
$_SERVER['argv'][] = '--report-phingRemoveFromCache=';
$_SERVER['argc']++;
}

$codeSniffer->process($fileList, $this->standards, $this->sniffs, $this->noSubdirectories);
$_SERVER['argv'] = array();
$_SERVER['argc'] = 0;

if ($this->cache) {
PHP_CodeSniffer_Reports_PhingRemoveFromCache::setCache(null);
$this->cache->commit();
}

$this->printErrorReport($codeSniffer);

// generate the documentation
Expand Down
98 changes: 98 additions & 0 deletions classes/phing/tasks/ext/phpcs/Reports_PhingRemoveFromCache.php
@@ -0,0 +1,98 @@
<?php
/**
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/

/**
* Remove from cache files where contains errors
*
* @category PHP
* @package PHP_CodeSniffer
* @author Rui Filipe Da Cunha Alves <ruifil@ruifil.com>
*/
class PHP_CodeSniffer_Reports_PhingRemoveFromCache implements PHP_CodeSniffer_Report
{
/**
* Cache data storage
* @var DataStore
*/
protected static $cache;

/**
* Set cache object
*
* @param DataStore $cache
*/
public static function setCache($cache)
{
self::$cache = $cache;
}

/**
* Remove file from cache if contains errors
*
* @param array $report Prepared report data.
* @param PHP_CodeSniffer_File $phpcsFile The file being reported on.
* @param boolean $showSources Show sources?
* @param int $width Maximum allowed line width.
*
* @return boolean
*/
public function generateFileReport(
$report,
PHP_CodeSniffer_File $phpcsFile,
$showSources = false,
$width = 80
) {
if (!self::$cache || ($report['errors'] === 0 && $report['warnings'] === 0)) {
// Nothing to do
return false;
}

self::$cache->remove($report['filename']);
return false;
}


/**
* Do nothing
*
* @param string $cachedData Any partial report data that was returned from
* generateFileReport during the run.
* @param int $totalFiles Total number of files processed during the run.
* @param int $totalErrors Total number of errors found during the run.
* @param int $totalWarnings Total number of warnings found during the run.
* @param int $totalFixable Total number of problems that can be fixed.
* @param boolean $showSources Show sources?
* @param int $width Maximum allowed line width.
* @param boolean $toScreen Is the report being printed to screen?
*
* @return void
*/
public function generate(
$cachedData,
$totalFiles,
$totalErrors,
$totalWarnings,
$totalFixable,
$showSources = false,
$width = 80,
$toScreen = true
) {
// Do nothing
}
}
64 changes: 64 additions & 0 deletions classes/phing/tasks/ext/phpmd/PHPMDRendererRemoveFromCache.php
@@ -0,0 +1,64 @@
<?php
/**
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/

require_once 'phing/util/DataStore.php';

use PHPMD\AbstractRenderer;
use PHPMD\Report;

/**
* This class will remove files with violations from cache
*
* @category PHP
* @package PHPMD
* @author Rui Filipe Da Cunha Alves <ruifil@ruifil.com>
*/
class PHPMDRendererRemoveFromCache extends AbstractRenderer
{
/**
* Cache data storage
* @var DataStore
*/
protected $cache;

/**
* Constructor
*
* @param DataStore $cache
*/
public function __construct($cache)
{
$this->cache = $cache;
}

/**
* This method will be called when the engine has finished the source
* analysis phase. To remove file with violations from cache.
*
* @param Report $report
* @return void
*/
public function renderReport(Report $report)
{
foreach ($report->getRuleViolations() as $violation) {
$fileName = $violation->getFileName();
$this->cache->remove($fileName, null);
}
}
}

0 comments on commit 18a00b0

Please sign in to comment.