diff --git a/src/Diff/FilterUtil.php b/src/Diff/FilterUtil.php new file mode 100644 index 0000000..019371e --- /dev/null +++ b/src/Diff/FilterUtil.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianFeldmann\Git\Diff; + +/** + * Filter utility class + * + * + * @author Sebastian Feldmann + * @link https://github.com/sebastianfeldmann/git + * @since Class available since Release 3.9.0 + */ +abstract class FilterUtil +{ + /** + * Remove all invalid filter options + * + * @param array $filter + * @return array + */ + public static function sanitize(array $filter): array + { + return array_filter($filter, fn($e) => in_array($e, ['A', 'C', 'D', 'M', 'R', 'T', 'U', 'X', 'B', '*']) ); + } +} + + + diff --git a/src/Operator/Index.php b/src/Operator/Index.php index aa6a0a4..b8c9cad 100644 --- a/src/Operator/Index.php +++ b/src/Operator/Index.php @@ -17,6 +17,7 @@ use SebastianFeldmann\Git\Command\DiffIndex\GetStagedFiles\FilterByStatus; use SebastianFeldmann\Git\Command\RevParse\GetCommitHash; use SebastianFeldmann\Git\Command\Rm\RemoveFiles; +use SebastianFeldmann\Git\Diff\FilterUtil; /** * Index Operator @@ -77,12 +78,39 @@ public function hasStagedFilesOfType(string $suffix): bool * * @param string $suffix * @param array $diffFilter - * @return array + * @return array */ public function getStagedFilesOfType(string $suffix, array $diffFilter = []): array { - $filter = empty($diffFilter) ? $this->defaultDiffFilter : $diffFilter; - return $this->retrieveStagedFilesByType($suffix, $filter); + $suffix = strtolower($suffix); + $sanitized = FilterUtil::sanitize($diffFilter); + $filter = empty($sanitized) ? $this->defaultDiffFilter : $sanitized; + $filesByType = $this->retrieveStagedFilesByType($filter); + + return $filesByType[$suffix] ?? []; + } + + /** + * Return list of changed files of a given types + * + * @param array $suffixes + * @param array $diffFilter + * @return array + */ + public function getStagedFilesOfTypes(array $suffixes, array $diffFilter = []): array + { + $suffixes = array_map('strtolower', $suffixes); + $sanitized = FilterUtil::sanitize($diffFilter); + $filter = empty($sanitized) ? $this->defaultDiffFilter : $sanitized; + $filesByType = $this->retrieveStagedFilesByType($filter); + + $files = []; + foreach ($suffixes as $suffix) { + if (!empty($filesByType[$suffix])) { + $files = array_merge($files, $filesByType[$suffix]); + } + } + return $files; } /** @@ -245,14 +273,12 @@ private function retrieveFromCache(array $diffFilter): array /** * Sort files by file suffix * - * @param string $suffix * @param array $diffFilter - * @return array + * @return array> */ - private function retrieveStagedFilesByType(string $suffix, array $diffFilter): array + private function retrieveStagedFilesByType(array $diffFilter): array { - $suffix = strtolower($suffix); - $key = implode($diffFilter); + $key = implode($diffFilter); if (!isset($this->types[$key])) { $this->types[$key] = []; @@ -261,7 +287,7 @@ private function retrieveStagedFilesByType(string $suffix, array $diffFilter): a $this->types[$key][$ext][] = $file; } } - return isset($this->types[$key][$suffix]) ? $this->types[$key][$suffix] : []; + return $this->types[$key]; } /** diff --git a/tests/git/Diff/FilterUtilTest.php b/tests/git/Diff/FilterUtilTest.php new file mode 100644 index 0000000..0bf281c --- /dev/null +++ b/tests/git/Diff/FilterUtilTest.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianFeldmann\Git\Diff; + +use PHPUnit\Framework\TestCase; + +class FilterUtilTest extends TestCase +{ + /** + * Tests FilterUtil::sanitize + */ + public function testSanitize(): void + { + $sanitized = FilterUtil::sanitize(['A', 'C', 'Z']); + + $this->assertFalse(in_array('Z', $sanitized)); + $this->assertTrue(in_array('A', $sanitized)); + $this->assertTrue(in_array('C', $sanitized)); + } + + /** + * Tests FilterUtil::sanitize + */ + public function testSanitizeEmpty(): void + { + $sanitized = FilterUtil::sanitize(['Q', 'L', 'Z']); + + $this->assertEmpty($sanitized); + } +} diff --git a/tests/git/Operator/IndexTest.php b/tests/git/Operator/IndexTest.php index eb2246f..fba9359 100644 --- a/tests/git/Operator/IndexTest.php +++ b/tests/git/Operator/IndexTest.php @@ -103,6 +103,35 @@ public function testGetStagedFilesOfType() $this->assertCount(2, $files); } + /** + * Tests StagedFiles::getStagedFilesOfType + */ + public function testGetStagedFilesOfTypes() + { + $out = [ + '/foo/bar.txt', + '/fiz/baz.txt', + '/foo/bar.php', + '/fiz/baz.php', + '/foo/bar.tpl', + '/fiz/baz.tpl', + ]; + + $repo = $this->getRepoMock(); + $runner = $this->getRunnerMock(); + $cmd = new CommandResult('git ...', 0); + $result = new RunnerResult($cmd, $out); + + $repo->method('getRoot')->willReturn((string) realpath(__FILE__ . '/../../..')); + $runner->method('run')->willReturn($result); + + $operator = new Index($runner, $repo); + $files = $operator->getStagedFilesOfTypes(['php', 'tpl']); + + $this->assertIsArray($files); + $this->assertCount(4, $files); + } + /** * Tests StagedFiles::getStagedFilesOfType */