forked from phacility/phabricator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPhabricatorRepositoryPushLog.php
240 lines (208 loc) · 7.08 KB
/
PhabricatorRepositoryPushLog.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
<?php
/**
* Records a push to a hosted repository. This allows us to store metadata
* about who pushed commits, when, and from where. We can also record the
* history of branches and tags, which is not normally persisted outside of
* the reflog.
*
* This log is written by commit hooks installed into hosted repositories.
* See @{class:DiffusionCommitHookEngine}.
*/
final class PhabricatorRepositoryPushLog
extends PhabricatorRepositoryDAO
implements PhabricatorPolicyInterface {
const REFTYPE_BRANCH = 'branch';
const REFTYPE_TAG = 'tag';
const REFTYPE_BOOKMARK = 'bookmark';
const REFTYPE_COMMIT = 'commit';
const REFTYPE_REF = 'ref';
const CHANGEFLAG_ADD = 1;
const CHANGEFLAG_DELETE = 2;
const CHANGEFLAG_APPEND = 4;
const CHANGEFLAG_REWRITE = 8;
const CHANGEFLAG_DANGEROUS = 16;
const CHANGEFLAG_ENORMOUS = 32;
const CHANGEFLAG_OVERSIZED = 64;
const CHANGEFLAG_TOUCHES = 128;
const REJECT_ACCEPT = 0;
const REJECT_DANGEROUS = 1;
const REJECT_HERALD = 2;
const REJECT_EXTERNAL = 3;
const REJECT_BROKEN = 4;
const REJECT_ENORMOUS = 5;
const REJECT_OVERSIZED = 6;
const REJECT_TOUCHES = 7;
protected $repositoryPHID;
protected $epoch;
protected $pusherPHID;
protected $pushEventPHID;
protected $devicePHID;
protected $refType;
protected $refNameHash;
protected $refNameRaw;
protected $refNameEncoding;
protected $refOld;
protected $refNew;
protected $mergeBase;
protected $changeFlags;
private $dangerousChangeDescription = self::ATTACHABLE;
private $pushEvent = self::ATTACHABLE;
private $repository = self::ATTACHABLE;
public static function initializeNewLog(PhabricatorUser $viewer) {
return id(new PhabricatorRepositoryPushLog())
->setPusherPHID($viewer->getPHID());
}
public static function getFlagDisplayNames() {
return array(
self::CHANGEFLAG_ADD => pht('Create'),
self::CHANGEFLAG_DELETE => pht('Delete'),
self::CHANGEFLAG_APPEND => pht('Append'),
self::CHANGEFLAG_REWRITE => pht('Rewrite'),
self::CHANGEFLAG_DANGEROUS => pht('Dangerous'),
self::CHANGEFLAG_ENORMOUS => pht('Enormous'),
self::CHANGEFLAG_OVERSIZED => pht('Oversized'),
self::CHANGEFLAG_TOUCHES => pht('Touches Too Many Paths'),
);
}
public static function getRejectCodeDisplayNames() {
return array(
self::REJECT_ACCEPT => pht('Accepted'),
self::REJECT_DANGEROUS => pht('Rejected: Dangerous'),
self::REJECT_HERALD => pht('Rejected: Herald'),
self::REJECT_EXTERNAL => pht('Rejected: External Hook'),
self::REJECT_BROKEN => pht('Rejected: Broken'),
self::REJECT_ENORMOUS => pht('Rejected: Enormous'),
self::REJECT_OVERSIZED => pht('Rejected: Oversized File'),
self::REJECT_TOUCHES => pht('Rejected: Touches Too Many Paths'),
);
}
public static function getHeraldChangeFlagConditionOptions() {
return array(
self::CHANGEFLAG_ADD =>
pht('change creates ref'),
self::CHANGEFLAG_DELETE =>
pht('change deletes ref'),
self::CHANGEFLAG_REWRITE =>
pht('change rewrites ref'),
self::CHANGEFLAG_DANGEROUS =>
pht('dangerous change'),
);
}
protected function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_TIMESTAMPS => false,
self::CONFIG_BINARY => array(
'refNameRaw' => true,
),
self::CONFIG_COLUMN_SCHEMA => array(
'refType' => 'text12',
'refNameHash' => 'bytes12?',
'refNameRaw' => 'bytes?',
'refNameEncoding' => 'text16?',
'refOld' => 'text40?',
'refNew' => 'text40',
'mergeBase' => 'text40?',
'changeFlags' => 'uint32',
'devicePHID' => 'phid?',
),
self::CONFIG_KEY_SCHEMA => array(
'key_repository' => array(
'columns' => array('repositoryPHID'),
),
'key_ref' => array(
'columns' => array('repositoryPHID', 'refNew'),
),
'key_name' => array(
'columns' => array('repositoryPHID', 'refNameHash'),
),
'key_event' => array(
'columns' => array('pushEventPHID'),
),
'key_pusher' => array(
'columns' => array('pusherPHID'),
),
'key_epoch' => array(
'columns' => array('epoch'),
),
),
) + parent::getConfiguration();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
PhabricatorRepositoryPushLogPHIDType::TYPECONST);
}
public function attachPushEvent(PhabricatorRepositoryPushEvent $push_event) {
$this->pushEvent = $push_event;
return $this;
}
public function getPushEvent() {
return $this->assertAttached($this->pushEvent);
}
public function getRefName() {
return $this->getUTF8StringFromStorage(
$this->getRefNameRaw(),
$this->getRefNameEncoding());
}
public function setRefName($ref_raw) {
$this->setRefNameRaw($ref_raw);
$this->setRefNameHash(PhabricatorHash::digestForIndex($ref_raw));
$this->setRefNameEncoding($this->detectEncodingForStorage($ref_raw));
return $this;
}
public function getRefOldShort() {
if ($this->getRepository()->isSVN()) {
return $this->getRefOld();
}
return substr($this->getRefOld(), 0, 12);
}
public function getRefNewShort() {
if ($this->getRepository()->isSVN()) {
return $this->getRefNew();
}
return substr($this->getRefNew(), 0, 12);
}
public function hasChangeFlags($mask) {
return ($this->changeFlags & $mask);
}
public function attachDangerousChangeDescription($description) {
$this->dangerousChangeDescription = $description;
return $this;
}
public function getDangerousChangeDescription() {
return $this->assertAttached($this->dangerousChangeDescription);
}
public function attachRepository(PhabricatorRepository $repository) {
// NOTE: Some gymnastics around this because of object construction order
// in the hook engine. Particularly, web build the logs before we build
// their push event.
$this->repository = $repository;
return $this;
}
public function getRepository() {
if ($this->repository == self::ATTACHABLE) {
return $this->getPushEvent()->getRepository();
}
return $this->assertAttached($this->repository);
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
);
}
public function getPolicy($capability) {
// NOTE: We're passing through the repository rather than the push event
// mostly because we need to do policy checks in Herald before we create
// the event. The two approaches are equivalent in practice.
return $this->getRepository()->getPolicy($capability);
}
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
return $this->getRepository()->hasAutomaticCapability($capability, $viewer);
}
public function describeAutomaticCapability($capability) {
return pht(
"A repository's push logs are visible to users who can see the ".
"repository.");
}
}