Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
50.00% |
17 / 34 |
|
40.00% |
2 / 5 |
CRAP | |
0.00% |
0 / 1 |
Git | |
50.00% |
17 / 34 |
|
40.00% |
2 / 5 |
16.00 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getChangedFiles | |
100.00% |
16 / 16 |
|
100.00% |
1 / 1 |
3 | |||
checkout | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
getSha1 | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
findNonMergeCommit | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
6 |
1 | <?php |
2 | /** |
3 | * Copyright (C) 2018 Kunal Mehta <legoktm@debian.org> |
4 | * |
5 | * This program is free software: you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation, either version 3 of the License, or |
8 | * (at your option) any later version. |
9 | * |
10 | * This program is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * GNU General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU General Public License |
16 | * along with this program. If not, see <https://www.gnu.org/licenses/>. |
17 | */ |
18 | |
19 | namespace MediaWiki\Tool\PatchCoverage; |
20 | |
21 | use Symfony\Component\Process\Process; |
22 | |
23 | /** |
24 | * Wrapper around git |
25 | */ |
26 | class Git { |
27 | |
28 | /** |
29 | * @var string[] |
30 | */ |
31 | private static $status = [ |
32 | 'A' => 'added', |
33 | 'D' => 'deleted', |
34 | 'M' => 'modified', |
35 | 'R' => 'renamed', |
36 | ]; |
37 | |
38 | /** |
39 | * @var string |
40 | */ |
41 | private $path; |
42 | |
43 | /** |
44 | * @param string $path |
45 | */ |
46 | public function __construct( $path ) { |
47 | $this->path = $path; |
48 | } |
49 | |
50 | /** |
51 | * @param string $ref |
52 | * |
53 | * @return GitChanged |
54 | */ |
55 | public function getChangedFiles( $ref ) { |
56 | $process = new Process( |
57 | [ 'git', 'diff', '--name-status', $ref . '^', $ref ] |
58 | ); |
59 | $process->setWorkingDirectory( $this->path ); |
60 | $process->mustRun(); |
61 | $changed = new GitChanged(); |
62 | $lines = explode( "\n", trim( $process->getOutput() ) ); |
63 | foreach ( $lines as $line ) { |
64 | $status = self::$status[$line[0]]; |
65 | if ( $status === 'renamed' ) { |
66 | $matches = []; |
67 | preg_match( '/R\d{3}\s*(\S*)\s*(\S*)/', $line, $matches ); |
68 | $changed->renamed[$matches[1]] = $matches[2]; |
69 | } else { |
70 | $file = trim( substr( $line, 1 ) ); |
71 | $changed->{$status}[] = $file; |
72 | } |
73 | } |
74 | |
75 | return $changed; |
76 | } |
77 | |
78 | /** |
79 | * git checkout |
80 | * |
81 | * @param string $ref |
82 | */ |
83 | public function checkout( $ref ) { |
84 | $process = new Process( |
85 | [ 'git', 'checkout', $ref ] |
86 | ); |
87 | $process->mustRun(); |
88 | } |
89 | |
90 | /** |
91 | * Get a SHA1 for any ref |
92 | * |
93 | * @param string $ref |
94 | * |
95 | * @return string |
96 | */ |
97 | public function getSha1( $ref ) { |
98 | $process = new Process( |
99 | [ 'git', 'rev-parse', $ref ] |
100 | ); |
101 | $process->mustRun(); |
102 | return trim( $process->getOutput() ); |
103 | } |
104 | |
105 | /** |
106 | * If $ref is a merge commit, get its parent, |
107 | * otherwise return $ref |
108 | * |
109 | * @param string $ref |
110 | * |
111 | * @return string |
112 | */ |
113 | public function findNonMergeCommit( $ref ) { |
114 | $process = new Process( |
115 | [ 'git', 'log', '--format=%P', $ref, '-n1' ] |
116 | ); |
117 | $process->mustRun(); |
118 | $exploded = explode( ' ', trim( $process->getOutput() ) ); |
119 | if ( count( $exploded ) > 1 ) { |
120 | return end( $exploded ); |
121 | } else { |
122 | return $this->getSha1( $ref ); |
123 | } |
124 | } |
125 | } |