Skip to content

Commit 55c9482

Browse files
Add CHANGED_FILES placeholder
This placeholder only works for pre-push, post-rewrite, post-checkout and post-merge actions. If it is used in a pre-push hook and multiple refs are pushed the placeholder will contain all changed files for all refs.
1 parent 7e30555 commit 55c9482

File tree

2 files changed

+155
-0
lines changed

2 files changed

+155
-0
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
/**
4+
* This file is part of CaptainHook.
5+
*
6+
* (c) Sebastian Feldmann <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace CaptainHook\App\Runner\Action\Cli\Command\Placeholder;
13+
14+
use CaptainHook\App\Git;
15+
16+
/**
17+
* Changed Files Placeholder
18+
*
19+
* This placeholder only works for pre-push, post-rewrite, post-checkout and post-merge actions.
20+
* If it is used in a pre-push hook and multiple refs are pushed the placeholder will contain
21+
* all changed files for all refs.
22+
*
23+
* Usage examples:
24+
* - {$CHANGED_FILES|separated-by:,}
25+
* - {$CHANGED_FILES|in-dir:foo/bar}
26+
* - {$CHANGED_FILES|of-type:php}
27+
*
28+
* @package CaptainHook
29+
* @author Sebastian Feldmann <[email protected]>
30+
* @link https://github.com/captainhookphp/captainhook
31+
* @since Class available since Release 5.15.3
32+
*/
33+
class ChangedFiles extends CheckFiles
34+
{
35+
/**
36+
* @param array<string, string> $options
37+
* @return string
38+
*/
39+
public function replacement(array $options): string
40+
{
41+
$files = [];
42+
foreach (Git\Range\Detector::getRanges($this->io) as $range) {
43+
$filesInDiff = isset($options['of-type'])
44+
? $this->repository->getDiffOperator()->getChangedFilesOfType(
45+
$range->from()->id(),
46+
$range->to()->id(),
47+
$options['of-type']
48+
)
49+
: $this->repository->getDiffOperator()->getChangedFiles(
50+
$range->from()->id(),
51+
$range->to()->id()
52+
);
53+
54+
$files = array_merge($files, $filesInDiff);
55+
}
56+
$files = array_unique($files);
57+
$files = $this->filterByDirectory($files, $options);
58+
$files = $this->replaceInAll($files, $options);
59+
60+
return implode(($options['separated-by'] ?? ' '), $files);
61+
}
62+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
3+
/**
4+
* This file is part of CaptainHook.
5+
*
6+
* (c) Sebastian Feldmann <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace CaptainHook\App\Runner\Action\Cli\Command\Placeholder;
13+
14+
use CaptainHook\App\Console\IO\Mockery as IOMockery;
15+
use CaptainHook\App\Config\Mockery as ConfigMockery;
16+
use CaptainHook\App\Mockery as AppMockery;
17+
use PHPUnit\Framework\TestCase;
18+
19+
class ChangedFilesTest extends TestCase
20+
{
21+
use IOMockery;
22+
use AppMockery;
23+
use ConfigMockery;
24+
25+
/**
26+
* Tests ChangedFiles::replacement
27+
*/
28+
public function testCustomSeparator(): void
29+
{
30+
$io = $this->createIOMock();
31+
$config = $this->createConfigMock();
32+
$repo = $this->createRepositoryMock();
33+
$index = $this->createGitDiffOperator(['file1.php', 'file2.php', 'README.md']);
34+
$repo->expects($this->once())->method('getDiffOperator')->willReturn($index);
35+
36+
$placeholder = new ChangedFiles($io, $config, $repo);
37+
$command = $placeholder->replacement(['separated-by' => ', ']);
38+
39+
$this->assertEquals('file1.php, file2.php, README.md', $command);
40+
}
41+
42+
/**
43+
* Tests ChangedFiles::replacement
44+
*/
45+
public function testOfType(): void
46+
{
47+
$io = $this->createIOMock();
48+
$config = $this->createConfigMock();
49+
$repo = $this->createRepositoryMock();
50+
$index = $this->createGitDiffOperator(['file1.php', 'file2.php', 'README.md']);
51+
$repo->expects($this->once())->method('getDiffOperator')->willReturn($index);
52+
$index->expects($this->once())->method('getChangedFilesOfType')->willReturn(['file1.php', 'file2.php']);
53+
54+
$placeholder = new ChangedFiles($io, $config, $repo);
55+
$command = $placeholder->replacement(['of-type' => 'php']);
56+
57+
$this->assertEquals('file1.php file2.php', $command);
58+
}
59+
60+
/**
61+
* Tests ChangedFiles::replacement
62+
*/
63+
public function testFilterByDirectory(): void
64+
{
65+
$io = $this->createIOMock();
66+
$config = $this->createConfigMock();
67+
$repo = $this->createRepositoryMock();
68+
$index = $this->createGitDiffOperator(['foo/file1.php', 'foo/file2.php', 'README.md']);
69+
$repo->expects($this->once())->method('getDiffOperator')->willReturn($index);
70+
71+
$placeholder = new ChangedFiles($io, $config, $repo);
72+
$command = $placeholder->replacement(['in-dir' => 'foo/']);
73+
74+
$this->assertEquals('foo/file1.php foo/file2.php', $command);
75+
}
76+
77+
/**
78+
* Tests ChangedFiles::replacement
79+
*/
80+
public function testReplaceWith(): void
81+
{
82+
$io = $this->createIOMock();
83+
$config = $this->createConfigMock();
84+
$repo = $this->createRepositoryMock();
85+
$index = $this->createGitDiffOperator(['foo/file1.php', 'foo/file2.php', 'README.md']);
86+
$repo->expects($this->once())->method('getDiffOperator')->willReturn($index);
87+
88+
$placeholder = new ChangedFiles($io, $config, $repo);
89+
$command = $placeholder->replacement(['replace' => 'foo/', 'with' => 'bar/']);
90+
91+
$this->assertEquals('bar/file1.php bar/file2.php README.md', $command);
92+
}
93+
}

0 commit comments

Comments
 (0)