PrePush   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 93
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 28
c 1
b 0
f 0
dl 0
loc 93
rs 10
ccs 30
cts 30
cp 1
wmc 12

5 Methods

Rating   Name   Duplication   Size   Complexity  
A getRanges() 0 4 1
A getChangedFiles() 0 15 4
A useReflogFallback() 0 3 1
A collectChangedFiles() 0 21 5
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/captainhook-git/captainhook
26
 * @since   Class available since Release 5.20.0
27
 */
28
class PrePush extends Detector
29
{
30
    /**
31
     * Reflog fallback switch
32
     *
33
     * @var bool
34
     */
35
    private bool $reflogFallback = false;
36
37
    /**
38
     * Activate the reflog fallback file detection
39
     *
40
     * @param bool $bool
41
     * @return void
42
     */
43 2
    public function useReflogFallback(bool $bool): void
44
    {
45 2
        $this->reflogFallback = $bool;
46
    }
47
48
    /**
49
     * Return list of changed files
50
     *
51
     * @param  array<string> $filter
52
     * @return array<string>
53
     */
54 8
    public function getChangedFiles(array $filter = []): array
55
    {
56 8
        $ranges = $this->getRanges();
57 8
        if (empty($ranges)) {
58 1
            return [];
59
        }
60 7
        $files = $this->collectChangedFiles($ranges, $filter);
61 7
        if (count($files) > 0 || !$this->reflogFallback) {
62 6
            return $files;
63
        }
64
        // by now we should have found something, but if the "branch: created" entry is gone from the reflog,
65
        // try to find as many commits belonging to this branch as possible
66 1
        $branch    = $ranges[0]->to()->branch();
67 1
        $revisions = $this->repository->getLogOperator()->getBranchRevsFromRefLog($branch);
68 1
        return $this->repository->getLogOperator()->getChangedFilesInRevisions($revisions);
69
    }
70
71
    /**
72
     * Create ranges from stdIn
73
     *
74
     * @return array<\CaptainHook\App\Git\Range\PrePush>
75
     */
76 8
    private function getRanges(): array
77
    {
78 8
        $detector = new RangeDetector();
79 8
        return $detector->getRanges($this->io);
80
    }
81
82
    /**
83
     * Collect all changed files from all ranges
84
     *
85
     * @param  array<\CaptainHook\App\Git\Range\PrePush> $ranges
86
     * @param  array<string> $filter
87
     * @return array<string>
88
     */
89 7
    private function collectChangedFiles(array $ranges, array $filter): array
90
    {
91 7
        $files = [];
92 7
        foreach ($ranges as $range) {
93 7
            if ($this->isKnownBranch($range)) {
94 4
                $oldHash = $range->from()->id();
95 4
                $newHash = $range->to()->id();
96
            } else {
97 3
                if (!$this->reflogFallback) {
98 1
                    continue;
99
                }
100
                // remote branch does not exist
101
                // try to find the branch starting point with the reflog
102 2
                $oldHash = $this->repository->getLogOperator()->getBranchRevFromRefLog($range->to()->branch());
103 2
                $newHash = 'HEAD';
104
            }
105 6
            if (!empty($oldHash)) {
106 5
                $files[] = $this->repository->getDiffOperator()->getChangedFiles($oldHash, $newHash, $filter);
107
            }
108
        }
109 7
        return array_unique(array_merge(...$files));
110
    }
111
112
    /**
113
     * If the remote branch is known the diff can  be easily determined
114
     *
115
     * @param  \CaptainHook\App\Git\Range\PrePush $range
116
     * @return bool
117
     */
118 7
    private function isKnownBranch(Range $range): bool
119
    {
120 7
        return !$range->from()->isZeroRev();
121
    }
122
}
123