Skip to content

Commit

Permalink
Added report type --report=hgblame to show number of errors/warnings …
Browse files Browse the repository at this point in the history
…committed by authors in a Mercurial repository

git-svn-id: http://svn.php.net/repository/pear/packages/PHP_CodeSniffer/trunk@313191 c90b9560-bf6c-de11-be94-00142212c4b1
  • Loading branch information
gsherwood committed Jul 13, 2011
1 parent 9acc318 commit 7d0eafe
Show file tree
Hide file tree
Showing 7 changed files with 401 additions and 3 deletions.
3 changes: 2 additions & 1 deletion CodeSniffer/CLI.php
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,7 @@ public function processLongArgument($arg, $pos, $values)
'summary',
'svnblame',
'gitblame',
'hgblame',
);

if (in_array($report, $validReports) === false) {
Expand Down Expand Up @@ -713,7 +714,7 @@ public function printUsage()
echo ' <generator> The name of a doc generator to use'.PHP_EOL;
echo ' (forces doc generation instead of checking)'.PHP_EOL;
echo ' <report> Print either the "full", "xml", "checkstyle", "csv", "emacs"'.PHP_EOL;
echo ' "source", "summary", "svnblame" or "gitblame" report'.PHP_EOL;
echo ' "source", "summary", "svnblame", "gitblame" or "hgblame" report'.PHP_EOL;
echo ' (the "full" report is printed by default)'.PHP_EOL;
echo ' <reportfile> Write the report to the specified file path'.PHP_EOL;
echo ' <reportWidth> How many columns wide screen reports should be printed'.PHP_EOL;
Expand Down
134 changes: 134 additions & 0 deletions CodeSniffer/Reports/Hgblame.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
<?php
/**
* Mercurial report for PHP_CodeSniffer.
*
* PHP version 5
*
* @category PHP
* @package PHP_CodeSniffer
* @author Ben Selby <[email protected]>
* @copyright 2009 SQLI <www.sqli.com>
* @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
* @link http://pear.php.net/package/PHP_CodeSniffer
*/

/**
* Mercurial report for PHP_CodeSniffer.
*
* PHP version 5
*
* @category PHP
* @package PHP_CodeSniffer
* @author Ben Selby <[email protected]>
* @copyright 2009 SQLI <www.sqli.com>
* @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
* @version Release: @package_version@
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
class PHP_CodeSniffer_Reports_Hgblame extends PHP_CodeSniffer_Reports_VersionControl
{

/**
* The name of the report we want in the output
*
* @var string
*/
protected $reportName = 'MERCURIAL';


/**
* Extract the author from a blame line.
*
* @param string $line Line to parse.
*
* @return mixed string or false if impossible to recover.
*/
protected function getAuthor($line)
{
$blameParts = array();
$line = preg_replace('|\s+|', ' ', $line);

preg_match(
'|(.+[0-9]{2}:[0-9]{2}:[0-9]{2}\s[0-9]{4}\s.[0-9]{4}:)|',
$line,
$blameParts
);

if (isset($blameParts[0]) === false) {
return false;
}

$parts = explode(' ', $blameParts[0]);

if (count($parts) < 6) {
return false;
}

$parts = array_slice($parts, 0, (count($parts) - 6));

return trim(preg_replace('|<.+>|', '', implode($parts, ' ')));

}//end getAuthor()


/**
* Gets the blame output.
*
* @param string $filename File to blame.
*
* @return array
*/
protected function getBlameContent($filename)
{
$cwd = getcwd();

if (PHP_CODESNIFFER_VERBOSITY > 0) {
echo 'Getting MERCURIAL blame info for '.basename($filename).'... ';
}

$fileParts = explode('/', $filename);
$found = false;
$location = '';
while (empty($fileParts) === false) {
array_pop($fileParts);
$location = implode($fileParts, '/');
if (is_dir($location.'/.hg') === true) {
$found = true;
break;
}
}

if ($found === true) {
chdir($location);
} else {
echo 'ERROR: Could not locate .hg directory '.PHP_EOL.PHP_EOL;
exit(2);
}

$command = 'hg blame -u -d -v '.$filename;
$handle = popen($command, 'r');
if ($handle === false) {
echo 'ERROR: Could not execute "'.$command.'"'.PHP_EOL.PHP_EOL;
exit(2);
}

$rawContent = stream_get_contents($handle);
fclose($handle);

if (PHP_CODESNIFFER_VERBOSITY > 0) {
echo 'DONE'.PHP_EOL;
}

$blames = explode("\n", $rawContent);
chdir($cwd);

return $blames;

}//end getBlameContent()


}//end class

?>
3 changes: 3 additions & 0 deletions package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ http://pear.php.net/dtd/package-2.0.xsd">
<notes>
- All report file command line arguments now work with relative paths (request #17240)
- The extensions command line argument now supports multi-part file extensions (request #17227)
- Added report type --report=hgblame to show number of errors/warnings committed by authors in a Mercurial repository
-- Has the same functionality as the svnblame report
-- Thanks to Ben Selby for the patch
- Namespaces are now recognised as scope openers, although they do not require braces (request #18043)
- Added new ByteOrderMarkSniff to Generic standard (request #18194)
-- Throws an error is a byte order mark is found in any PHP file
Expand Down
2 changes: 2 additions & 0 deletions tests/Core/AllTests.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
require_once 'Reports/SourceTest.php';
require_once 'Reports/SvnblameTest.php';
require_once 'Reports/GitblameTest.php';
require_once 'Reports/HgblameTest.php';

if (is_file(dirname(__FILE__).'/../../CodeSniffer.php') === true) {
// We are not installed.
Expand Down Expand Up @@ -87,6 +88,7 @@ public static function suite()
$suite->addTestSuite('Core_Reports_SourceTest');
$suite->addTestSuite('Core_Reports_SvnblameTest');
$suite->addTestSuite('Core_Reports_GitblameTest');
$suite->addTestSuite('Core_Reports_HgblameTest');
return $suite;

}//end suite()
Expand Down
4 changes: 2 additions & 2 deletions tests/Core/ReportingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ public function testFactory()
{
$type = 'checkstyle';
$reportClass = $this->reporting->factory($type);
$this->assertType('PHP_CodeSniffer_Report', $reportClass);
$this->assertType('PHP_CodeSniffer_Reports_Checkstyle', $reportClass);
$this->assertInstanceOf('PHP_CodeSniffer_Report', $reportClass);
$this->assertInstanceOf('PHP_CodeSniffer_Reports_Checkstyle', $reportClass);

$this->setExpectedException('PHP_CodeSniffer_Exception');
$type = 'foo';
Expand Down
95 changes: 95 additions & 0 deletions tests/Core/Reports/HgblameTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php
/**
* Tests for the Hgblame report of PHP_CodeSniffer.
*
* PHP version 5
*
* @category PHP
* @package PHP_CodeSniffer
* @author Ben Selby <[email protected]>
* @copyright 2009 SQLI <www.sqli.com>
* @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
* @link http://pear.php.net/package/PHP_CodeSniffer
*/

require_once 'PHPUnit/Framework/TestCase.php';
require_once dirname(__FILE__).'/AbstractTestCase.php';
require_once dirname(__FILE__).'/Mock/Hgblame.php';

if (is_file(dirname(__FILE__).'/../../../CodeSniffer.php') === true) {
// We are not installed.
include_once dirname(__FILE__).'/../../../CodeSniffer/Reports/VersionControl.php';
} else {
include_once 'PHP/CodeSniffer/Reports/VersionControl.php';
}

/**
* Tests for the Hgblame report of PHP_CodeSniffer.
*
* @category PHP
* @package PHP_CodeSniffer
* @author Ben Selby <[email protected]>
* @copyright 2009 SQLI <www.sqli.com>
* @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
* @version Release: @package_version@
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
class Core_Reports_HgblameTest extends Core_Reports_AbstractTestCase
{


/**
* Test standard generation
*
* @return void
*/
public function testGenerate()
{
$fullReport = new PHP_CodeSniffer_Reports_Mock_Hgblame();
$generated = $this->getFixtureReport($fullReport);
$generatedLines = explode(PHP_EOL, $generated);
$this->assertGreaterThan(10, count($generatedLines));

}//end testGenerate()


/**
* Test author recovering from a hg blame line
*
* @param string $line The hg blame output
* @param string $expected The author name
*
* @dataProvider provideDataForGetHgAuthor
*
* @return void
*/
public function testGetHgAuthor($line, $expected)
{
$fullReport = new PHP_CodeSniffer_Reports_Mock_Hgblame();
$author = $fullReport->testGetHgAuthor($line);
$this->assertEquals($expected, $author);

}//end testGetHgAuthor()


/**
* Data provider for testGetHgAuthor
*
* @return array
*/
public static function provideDataForGetHgAuthor()
{
return array(
array('Ben Selby <[email protected]> Sun May 29 00:05:15 2011 +0300: /**', 'Ben Selby'),
array(' benmatselby@somewhere Sun May 29 00:05:15 2011 +0300: /**', 'benmatselby@somewhere'),
array('Ben Selby <[email protected]> Tue Apr 26 00:36:36 2011 +0300: * // Some random text with dates (e.g. 2011-05-01 12:30:00, Y-m-d H:i:s', 'Ben Selby'),
);

}//end provideDataForGetHgAuthor()


}//end class

?>
Loading

0 comments on commit 7d0eafe

Please sign in to comment.