Passed
Push — main ( 604bfc...f70419 )
by Sebastian
04:51
created

PrePush   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 75
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 26
c 1
b 0
f 0
dl 0
loc 75
rs 10
ccs 29
cts 29
cp 1
wmc 9

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getRanges() 0 4 1
A collectChangedFiles() 0 21 4
A getChangedFiles() 0 15 3
A isKnownBranch() 0 3 1
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\Git\ChangedFiles\Detector;
13
14
use CaptainHook\App\Console\IO;
15
use CaptainHook\App\Git\ChangedFiles\Detector;
16
use CaptainHook\App\Git\Range\Detector\PrePush as RangeDetector;
17
use CaptainHook\App\Git\Range\PrePush as Range;
18
use SebastianFeldmann\Git\Repository;
19
20
/**
21
 * Class PrePush
22
 *
23
 * @package CaptainHook
24
 * @author  Sebastian Feldmann <[email protected]>
25
 * @link    https://github.com/captainhookphp/captainhook
26
 * @since   Class available since Release 5.20.0
27
 */
28
class PrePush extends Detector
29
{
30
    /**
31
     * Return list of changed files
32
     *
33
     * @param  array<string> $filter
34
     * @return array<string>
35
     */
36 7
    public function getChangedFiles(array $filter = []): array
37
    {
38 7
        $ranges = $this->getRanges();
39 7
        if (empty($ranges)) {
40 1
            return [];
41
        }
42 6
        $files = $this->collectChangedFiles($ranges, $filter);
43 6
        if (count($files) > 0) {
44 3
            return $files;
45
        }
46
        // by now we should have found something but if the "branch: created" entry is gone from the reflog
47
        // try to find as many commits belonging to this branch as possible
48 3
        $branch    = $ranges[0]->to()->branch();
49 3
        $revisions = $this->repository->getLogOperator()->getBranchRevsFromRefLog($branch);
50 3
        return $this->repository->getLogOperator()->getChangedFilesInRevisions($revisions);
51
    }
52
53
    /**
54
     * Create ranges from stdIn
55
     *
56
     * @return array<\CaptainHook\App\Git\Range\PrePush>
57
     */
58 7
    private function getRanges(): array
59
    {
60 7
        $detector = new RangeDetector();
61 7
        return $detector->getRanges($this->io);
62
    }
63
64
    /**
65
     * Collect all changed files from all ranges
66
     *
67
     * @param  array<\CaptainHook\App\Git\Range\PrePush> $ranges
68
     * @param  array<string> $filter
69
     * @return array<string>
70
     */
71 6
    private function collectChangedFiles(array $ranges, array $filter): array
72
    {
73 6
        $files = [];
74 6
        foreach ($ranges as $range) {
75 6
            if ($this->isKnownBranch($range)) {
76 3
                $oldHash = $range->from()->id();
77 3
                $newHash = $range->to()->id();
78
            } else {
79
                // remote branch does not exist
80
                // try to find the branch starting point with the reflog
81 3
                $oldHash = $this->repository->getLogOperator()->getBranchRevFromRefLog($range->to()->branch());
82 3
                $newHash = 'HEAD';
83
            }
84 6
            if (!empty($oldHash)) {
85 4
                $files = array_merge(
86 4
                    $files,
87 4
                    $this->repository->getDiffOperator()->getChangedFiles($oldHash, $newHash, $filter)
88 4
                );
89
            }
90
        }
91 6
        return array_unique($files);
92
    }
93
94
    /**
95
     * If the remote branch is known the diff can  be easily determined
96
     *
97
     * @param  \CaptainHook\App\Git\Range\PrePush $range
98
     * @return bool
99
     */
100 6
    private function isKnownBranch(Range $range): bool
101
    {
102 6
        return !$range->from()->isZeroRev();
103
    }
104
}
105