diff --git a/.gitignore b/.gitignore index 9383c15d..85621708 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ Vagrantfile provision.sh .vagrant Makefile +/nbproject diff --git a/build/metrics.phar b/build/metrics.phar index d2d8a372..698a5a4d 100755 Binary files a/build/metrics.phar and b/build/metrics.phar differ diff --git a/src/Hal/Application/Command/RunMetricsCommand.php b/src/Hal/Application/Command/RunMetricsCommand.php index 6ca24b4a..380bc6bc 100644 --- a/src/Hal/Application/Command/RunMetricsCommand.php +++ b/src/Hal/Application/Command/RunMetricsCommand.php @@ -42,28 +42,31 @@ protected function configure() ->setName('metrics') ->setDescription('Run analysis') ->addArgument( - 'path', InputArgument::REQUIRED, 'Path to explore' + 'path', InputArgument::REQUIRED, 'Path to explore' ) ->addOption( - 'report-html',null, InputOption::VALUE_REQUIRED, 'Path to save report in HTML format. Example: /tmp/report.html' + 'report-html',null, InputOption::VALUE_REQUIRED, 'Path to save report in HTML format. Example: /tmp/report.html' ) ->addOption( - 'report-xml', null, InputOption::VALUE_REQUIRED, 'Path to save summary report in XML format. Example: /tmp/report.xml' + 'report-xml', null, InputOption::VALUE_REQUIRED, 'Path to save summary report in XML format. Example: /tmp/report.xml' ) ->addOption( 'violations-xml', null, InputOption::VALUE_REQUIRED, 'Path to save violations in XML format. Example: /tmp/report.xml' ) ->addOption( - 'report-csv', null, InputOption::VALUE_REQUIRED, 'Path to save summary report in CSV format. Example: /tmp/report.csv' + 'report-csv', null, InputOption::VALUE_REQUIRED, 'Path to save summary report in CSV format. Example: /tmp/report.csv' ) ->addOption( - 'level', null, InputOption::VALUE_REQUIRED, 'Depth of summary report', 0 + 'level', null, InputOption::VALUE_REQUIRED, 'Depth of summary report', 0 ) ->addOption( - 'extensions', null, InputOption::VALUE_REQUIRED, 'Regex of extensions to include', 'php' + 'extensions', null, InputOption::VALUE_REQUIRED, 'Regex of extensions to include', 'php' ) ->addOption( - 'without-oop', null, InputOption::VALUE_NONE, 'If provided, tool will not extract any informations about OOP model (faster)' + 'excludedDirs', null, InputOption::VALUE_REQUIRED, 'Regex of subdirectories to exclude', 'Tests|Features' + ) + ->addOption( + 'without-oop', null, InputOption::VALUE_NONE, 'If provided, tool will not extract any informations about OOP model (faster)' ) ; } @@ -80,7 +83,10 @@ protected function execute(InputInterface $input, OutputInterface $output) $level = $input->getOption('level'); // files - $finder = new Finder($input->getOption('extensions')); + $finder = new Finder( + $input->getOption('extensions'), + $input->getOption('excludedDirs') + ); // rules $rules = new \Hal\Application\Rule\RuleSet(); diff --git a/src/Hal/Component/File/Finder.php b/src/Hal/Component/File/Finder.php index babd2413..9cce921a 100644 --- a/src/Hal/Component/File/Finder.php +++ b/src/Hal/Component/File/Finder.php @@ -9,6 +9,10 @@ namespace Hal\Component\File; +use RecursiveDirectoryIterator; +use RecursiveIteratorIterator; +use RegexIterator; + /** * File finder * @@ -18,18 +22,27 @@ class Finder { /** - * Extensions to match + * Extensions to match (regex) * * @var string */ private $extensions; /** - * @param string $extensions regex + * Subdirectories to exclude (regex) + * + * @var string + */ + private $excludedDirs; + + /** + * @param string $extensions regex of file extensions to include + * @param string $excludedDirs regex of directories to exclude */ - function __construct($extensions = 'php') + function __construct($extensions = 'php', $excludedDirs = '') { $this->extensions = (string) $extensions; + $this->excludedDirs = (string) $excludedDirs; } /** @@ -38,14 +51,27 @@ function __construct($extensions = 'php') * @param string $path * @return array */ - public function find($path) { + public function find($path) + { $files = array(); if(is_dir($path)) { $path = rtrim($path, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR; - $directory = new \RecursiveDirectoryIterator($path); - $iterator = new \RecursiveIteratorIterator($directory); - $regex = new \RegexIterator($iterator, '/^.+\.('. $this->extensions .')$/i', \RecursiveRegexIterator::GET_MATCH); - foreach($regex as $file) { + $directory = new RecursiveDirectoryIterator($path); + $iterator = new RecursiveIteratorIterator($directory); + + $filterRegex = sprintf( + '`^%s%s$`', + !empty($this->excludedDirs) ? '((?!'.$this->excludedDirs.').)+' : '.+', + '\.(' . $this->extensions . ')' + ); + + $filteredIterator = new RegexIterator( + $iterator, + $filterRegex, + \RecursiveRegexIterator::GET_MATCH + ); + + foreach($filteredIterator as $file) { $files[] = $file[0]; } } elseif(is_file($path)) { @@ -53,4 +79,4 @@ public function find($path) { } return $files; } -} \ No newline at end of file +} diff --git a/tests/Hal/Component/File/FinderTest.php b/tests/Hal/Component/File/FinderTest.php index fa8c3148..eeb6f4e5 100644 --- a/tests/Hal/Component/File/FinderTest.php +++ b/tests/Hal/Component/File/FinderTest.php @@ -10,17 +10,30 @@ class FinderTest extends \PHPUnit_Framework_TestCase { private $toExplore; - public function setup() { + protected function setup() { $this->toExplore = sys_get_temp_dir().'/metrics-tmp-finder'; if(!file_exists($this->toExplore)) { mkdir($this->toExplore); + mkdir($this->toExplore . '/toExclude'); file_put_contents($this->toExplore.'/tmp.php', "toExplore.'/tmp2.php', "toExplore.'/tmp3.php', "toExplore.'/tmp4.txt', "toExplore.'/toExclude/tmp.php', "toExplore.'/tmp.php'); + unlink($this->toExplore.'/tmp2.php'); + unlink($this->toExplore.'/tmp3.php'); + unlink($this->toExplore.'/tmp4.txt'); + unlink($this->toExplore.'/toExclude/tmp.php'); + rmdir($this->toExplore.'/toExclude'); + rmdir($this->toExplore); + } + public function testICanFindFilesByExtension() { $finder = new Finder('txt'); $results = $finder->find($this->toExplore); @@ -36,6 +49,13 @@ public function testICanGiveFilepathInsteadOfDirectory() { public function testIFindPhpFilesByDefault() { $finder = new Finder(); $results = $finder->find($this->toExplore); + $this->assertEquals(4, sizeof($results)); + } + + public function testIDontFindFilesFromExcludedDirs() + { + $finder = new Finder('php', 'toExclude'); + $results = $finder->find($this->toExplore); $this->assertEquals(3, sizeof($results)); } -} \ No newline at end of file +}