1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* This file is part of the SVN-Buddy library. |
4
|
|
|
* For the full copyright and license information, please view |
5
|
|
|
* the LICENSE file that was distributed with this source code. |
6
|
|
|
* |
7
|
|
|
* @copyright Alexander Obuhovich <[email protected]> |
8
|
|
|
* @link https://github.com/console-helpers/svn-buddy |
9
|
|
|
*/ |
10
|
|
|
|
11
|
|
|
namespace ConsoleHelpers\SVNBuddy\Repository\RevisionLog\Plugin\RepositoryCollectorPlugin; |
12
|
|
|
|
13
|
|
|
|
14
|
|
|
use ConsoleHelpers\SVNBuddy\Repository\RevisionLog\Plugin\IOverwriteAwarePlugin; |
15
|
|
|
use ConsoleHelpers\SVNBuddy\Repository\RevisionLog\Plugin\TOverwriteAwarePlugin; |
16
|
|
|
use ConsoleHelpers\SVNBuddy\Repository\RevisionLog\RevisionLog; |
17
|
|
|
|
18
|
|
|
class MergesPlugin extends AbstractRepositoryCollectorPlugin implements IOverwriteAwarePlugin |
19
|
|
|
{ |
20
|
|
|
|
21
|
|
|
use TOverwriteAwarePlugin; |
22
|
|
|
|
23
|
|
|
const STATISTIC_MERGE_ADDED = 'merge_added'; |
24
|
|
|
|
25
|
|
|
const STATISTIC_MERGE_DELETED = 'merge_deleted'; |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* Returns plugin name. |
29
|
|
|
* |
30
|
|
|
* @return string |
31
|
|
|
*/ |
32
|
9 |
|
public function getName() |
33
|
|
|
{ |
34
|
9 |
|
return 'merges'; |
35
|
|
|
} |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* Returns revision query flags. |
39
|
|
|
* |
40
|
|
|
* @return array |
41
|
|
|
*/ |
42
|
1 |
|
public function getRevisionQueryFlags() |
43
|
|
|
{ |
44
|
1 |
|
return array(RevisionLog::FLAG_MERGE_HISTORY); |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* Defines parsing statistic types. |
49
|
|
|
* |
50
|
|
|
* @return array |
51
|
|
|
*/ |
52
|
19 |
|
public function defineStatisticTypes() |
53
|
|
|
{ |
54
|
19 |
|
return array( |
55
|
19 |
|
self::STATISTIC_MERGE_ADDED, self::STATISTIC_MERGE_DELETED, |
56
|
19 |
|
); |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* Does actual parsing. |
61
|
|
|
* |
62
|
|
|
* @param integer $revision Revision. |
63
|
|
|
* @param \SimpleXMLElement $log_entry Log Entry. |
64
|
|
|
* |
65
|
|
|
* @return void |
66
|
|
|
*/ |
67
|
4 |
|
protected function doParse($revision, \SimpleXMLElement $log_entry) |
68
|
|
|
{ |
69
|
4 |
|
$merged_revisions = array(); |
70
|
|
|
|
71
|
4 |
|
foreach ( $log_entry->logentry as $merged_log_entry ) { |
72
|
4 |
|
$merged_revisions[] = (int)$merged_log_entry['revision']; |
73
|
|
|
} |
74
|
|
|
|
75
|
4 |
|
$this->repositoryFiller->addMergeCommit($revision, $merged_revisions); |
76
|
4 |
|
$this->recordStatistic(self::STATISTIC_MERGE_ADDED, count($merged_revisions)); |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
/** |
80
|
|
|
* @inheritDoc |
81
|
|
|
*/ |
82
|
2 |
|
protected function remove($revision) |
83
|
|
|
{ |
84
|
2 |
|
$merged_revisions_count = $this->repositoryFiller->removeMergeCommit($revision); |
85
|
2 |
|
$this->recordStatistic(self::STATISTIC_MERGE_DELETED, $merged_revisions_count); |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
/** |
89
|
|
|
* Find revisions by collected data. |
90
|
|
|
* |
91
|
|
|
* @param array $criteria Criteria. |
92
|
|
|
* @param string|null $project_path Project path. |
93
|
|
|
* |
94
|
|
|
* @return array |
95
|
|
|
* @throws \InvalidArgumentException When one of given merge revision wasn't found. |
96
|
|
|
*/ |
97
|
7 |
|
public function find(array $criteria, $project_path) |
98
|
|
|
{ |
99
|
7 |
|
if ( !$criteria ) { |
|
|
|
|
100
|
1 |
|
return array(); |
101
|
|
|
} |
102
|
|
|
|
103
|
6 |
|
$first_criteria = reset($criteria); |
104
|
6 |
|
$project_id = $this->getProject($project_path); |
105
|
|
|
|
106
|
5 |
|
if ( $first_criteria === 'all_merges' ) { |
107
|
1 |
|
$sql = 'SELECT DISTINCT m.MergeRevision |
108
|
|
|
FROM Merges m |
109
|
|
|
JOIN CommitProjects cp ON cp.Revision = m.MergeRevision |
110
|
1 |
|
WHERE cp.ProjectId = :project_id'; |
111
|
|
|
|
112
|
1 |
|
return $this->database->fetchCol($sql, array('project_id' => $project_id)); |
113
|
|
|
} |
114
|
4 |
|
elseif ( $first_criteria === 'all_merged' ) { |
115
|
1 |
|
$sql = 'SELECT DISTINCT m.MergedRevision |
116
|
|
|
FROM Merges m |
117
|
|
|
JOIN CommitProjects cp ON cp.Revision = m.MergedRevision |
118
|
1 |
|
WHERE cp.ProjectId = :project_id'; |
119
|
|
|
|
120
|
1 |
|
return $this->database->fetchCol($sql, array('project_id' => $project_id)); |
121
|
|
|
} |
122
|
|
|
|
123
|
3 |
|
$merge_revisions = array(); |
124
|
3 |
|
$merged_revisions = array(); |
125
|
|
|
|
126
|
3 |
|
$sql = 'SELECT m.MergeRevision, m.MergedRevision |
127
|
|
|
FROM Merges m |
128
|
|
|
JOIN CommitProjects cp ON cp.Revision = m.MergeRevision |
129
|
3 |
|
WHERE cp.ProjectId = :project_id AND m.MergeRevision IN (:merge_revisions)'; |
130
|
3 |
|
$tmp_revisions = $this->database->fetchAll($sql, array( |
131
|
3 |
|
'project_id' => $project_id, |
132
|
3 |
|
'merge_revisions' => $criteria, |
133
|
3 |
|
)); |
134
|
|
|
|
135
|
3 |
|
foreach ( $tmp_revisions as $revision_data ) { |
136
|
2 |
|
$merge_revisions[$revision_data['MergeRevision']] = true; |
137
|
2 |
|
$merged_revisions[$revision_data['MergedRevision']] = true; |
138
|
|
|
} |
139
|
|
|
|
140
|
3 |
|
$unknown_merge_revisions = array_diff($criteria, array_keys($merge_revisions)); |
141
|
|
|
|
142
|
3 |
|
if ( $unknown_merge_revisions ) { |
|
|
|
|
143
|
3 |
|
throw new \InvalidArgumentException( |
144
|
3 |
|
'The merge revision(-s) "' . implode('", "', $unknown_merge_revisions) . '" not found.' |
145
|
3 |
|
); |
146
|
|
|
} |
147
|
|
|
|
148
|
2 |
|
$merged_revisions = array_keys($merged_revisions); |
149
|
2 |
|
sort($merged_revisions, SORT_NUMERIC); |
150
|
|
|
|
151
|
2 |
|
return $merged_revisions; |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
/** |
155
|
|
|
* Returns information about revisions. |
156
|
|
|
* |
157
|
|
|
* @param array $revisions Revisions. |
158
|
|
|
* |
159
|
|
|
* @return array |
160
|
|
|
*/ |
161
|
1 |
|
public function getRevisionsData(array $revisions) |
162
|
|
|
{ |
163
|
1 |
|
$results = array(); |
164
|
|
|
|
165
|
1 |
|
$sql = 'SELECT MergeRevision, MergedRevision |
166
|
|
|
FROM Merges |
167
|
1 |
|
WHERE MergedRevision IN (:merged_revisions)'; |
168
|
1 |
|
$revisions_data = $this->database->fetchAll($sql, array('merged_revisions' => $revisions)); |
169
|
|
|
|
170
|
1 |
|
foreach ( $revisions_data as $revision_data ) { |
171
|
1 |
|
$merge_revision = $revision_data['MergeRevision']; |
172
|
1 |
|
$merged_revision = $revision_data['MergedRevision']; |
173
|
|
|
|
174
|
1 |
|
if ( !isset($results[$merged_revision]) ) { |
175
|
1 |
|
$results[$merged_revision] = array(); |
176
|
|
|
} |
177
|
|
|
|
178
|
1 |
|
$results[$merged_revision][] = $merge_revision; |
179
|
|
|
} |
180
|
|
|
|
181
|
1 |
|
return $this->addMissingResults($revisions, $results); |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
} |
185
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.