Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/drydock/storage/DrydockRepositoryOperation.php
12256 views
1
<?php
2
3
/**
4
* Represents a request to perform a repository operation like a merge or
5
* cherry-pick.
6
*/
7
final class DrydockRepositoryOperation extends DrydockDAO
8
implements
9
PhabricatorPolicyInterface {
10
11
const STATE_WAIT = 'wait';
12
const STATE_WORK = 'work';
13
const STATE_DONE = 'done';
14
const STATE_FAIL = 'fail';
15
16
protected $authorPHID;
17
protected $objectPHID;
18
protected $repositoryPHID;
19
protected $repositoryTarget;
20
protected $operationType;
21
protected $operationState;
22
protected $properties = array();
23
protected $isDismissed;
24
25
private $repository = self::ATTACHABLE;
26
private $object = self::ATTACHABLE;
27
private $implementation = self::ATTACHABLE;
28
private $workingCopyLease = self::ATTACHABLE;
29
30
public static function initializeNewOperation(
31
DrydockRepositoryOperationType $op) {
32
33
return id(new DrydockRepositoryOperation())
34
->setOperationState(self::STATE_WAIT)
35
->setOperationType($op->getOperationConstant())
36
->setIsDismissed(0);
37
}
38
39
protected function getConfiguration() {
40
return array(
41
self::CONFIG_AUX_PHID => true,
42
self::CONFIG_SERIALIZATION => array(
43
'properties' => self::SERIALIZATION_JSON,
44
),
45
self::CONFIG_COLUMN_SCHEMA => array(
46
'repositoryTarget' => 'bytes',
47
'operationType' => 'text32',
48
'operationState' => 'text32',
49
'isDismissed' => 'bool',
50
),
51
self::CONFIG_KEY_SCHEMA => array(
52
'key_object' => array(
53
'columns' => array('objectPHID'),
54
),
55
'key_repository' => array(
56
'columns' => array('repositoryPHID', 'operationState'),
57
),
58
'key_state' => array(
59
'columns' => array('operationState'),
60
),
61
'key_author' => array(
62
'columns' => array('authorPHID', 'operationState'),
63
),
64
),
65
) + parent::getConfiguration();
66
}
67
68
public function generatePHID() {
69
return PhabricatorPHID::generateNewPHID(
70
DrydockRepositoryOperationPHIDType::TYPECONST);
71
}
72
73
public function attachRepository(PhabricatorRepository $repository) {
74
$this->repository = $repository;
75
return $this;
76
}
77
78
public function getRepository() {
79
return $this->assertAttached($this->repository);
80
}
81
82
public function attachObject($object) {
83
$this->object = $object;
84
return $this;
85
}
86
87
public function getObject() {
88
return $this->assertAttached($this->object);
89
}
90
91
public function attachImplementation(DrydockRepositoryOperationType $impl) {
92
$this->implementation = $impl;
93
return $this;
94
}
95
96
public function getImplementation() {
97
return $this->implementation;
98
}
99
100
public function getWorkingCopyLease() {
101
return $this->assertAttached($this->workingCopyLease);
102
}
103
104
public function attachWorkingCopyLease(DrydockLease $lease) {
105
$this->workingCopyLease = $lease;
106
return $this;
107
}
108
109
public function hasWorkingCopyLease() {
110
return ($this->workingCopyLease !== self::ATTACHABLE);
111
}
112
113
public function getProperty($key, $default = null) {
114
return idx($this->properties, $key, $default);
115
}
116
117
public function setProperty($key, $value) {
118
$this->properties[$key] = $value;
119
return $this;
120
}
121
122
public static function getOperationStateNameMap() {
123
return array(
124
self::STATE_WAIT => pht('Waiting'),
125
self::STATE_WORK => pht('Working'),
126
self::STATE_DONE => pht('Done'),
127
self::STATE_FAIL => pht('Failed'),
128
);
129
}
130
131
public static function getOperationStateIcon($state) {
132
$map = array(
133
self::STATE_WAIT => 'fa-clock-o',
134
self::STATE_WORK => 'fa-plane ph-spin blue',
135
self::STATE_DONE => 'fa-check green',
136
self::STATE_FAIL => 'fa-times red',
137
);
138
139
return idx($map, $state, null);
140
}
141
142
public static function getOperationStateName($state) {
143
$map = self::getOperationStateNameMap();
144
return idx($map, $state, pht('<Unknown: %s>', $state));
145
}
146
147
public function scheduleUpdate() {
148
PhabricatorWorker::scheduleTask(
149
'DrydockRepositoryOperationUpdateWorker',
150
array(
151
'operationPHID' => $this->getPHID(),
152
),
153
array(
154
'objectPHID' => $this->getPHID(),
155
'priority' => PhabricatorWorker::PRIORITY_ALERTS,
156
));
157
}
158
159
public function applyOperation(DrydockInterface $interface) {
160
$impl = $this->getImplementation();
161
$impl->setInterface($interface);
162
return $impl->applyOperation($this, $interface);
163
}
164
165
public function getOperationDescription(PhabricatorUser $viewer) {
166
return $this->getImplementation()->getOperationDescription(
167
$this,
168
$viewer);
169
}
170
171
public function getOperationCurrentStatus(PhabricatorUser $viewer) {
172
return $this->getImplementation()->getOperationCurrentStatus(
173
$this,
174
$viewer);
175
}
176
177
public function isUnderway() {
178
switch ($this->getOperationState()) {
179
case self::STATE_WAIT:
180
case self::STATE_WORK:
181
return true;
182
}
183
184
return false;
185
}
186
187
public function isDone() {
188
return ($this->getOperationState() === self::STATE_DONE);
189
}
190
191
public function getWorkingCopyMerges() {
192
return $this->getImplementation()->getWorkingCopyMerges(
193
$this);
194
}
195
196
public function setWorkingCopyLeasePHID($lease_phid) {
197
return $this->setProperty('exec.leasePHID', $lease_phid);
198
}
199
200
public function getWorkingCopyLeasePHID() {
201
return $this->getProperty('exec.leasePHID');
202
}
203
204
public function setCommandError(array $error) {
205
return $this->setProperty('exec.workingcopy.error', $error);
206
}
207
208
public function getCommandError() {
209
return $this->getProperty('exec.workingcopy.error');
210
}
211
212
public function logText($text) {
213
return $this->logEvent(
214
DrydockTextLogType::LOGCONST,
215
array(
216
'text' => $text,
217
));
218
}
219
220
public function logEvent($type, array $data = array()) {
221
$log = id(new DrydockLog())
222
->setEpoch(PhabricatorTime::getNow())
223
->setType($type)
224
->setData($data);
225
226
$log->setOperationPHID($this->getPHID());
227
228
if ($this->hasWorkingCopyLease()) {
229
$lease = $this->getWorkingCopyLease();
230
$log->setLeasePHID($lease->getPHID());
231
232
$resource_phid = $lease->getResourcePHID();
233
if ($resource_phid) {
234
$resource = $lease->getResource();
235
236
$log->setResourcePHID($resource->getPHID());
237
$log->setBlueprintPHID($resource->getBlueprintPHID());
238
}
239
}
240
241
return $log->save();
242
}
243
244
245
/* -( PhabricatorPolicyInterface )----------------------------------------- */
246
247
248
public function getCapabilities() {
249
return array(
250
PhabricatorPolicyCapability::CAN_VIEW,
251
PhabricatorPolicyCapability::CAN_EDIT,
252
);
253
}
254
255
public function getPolicy($capability) {
256
$need_capability = $this->getRequiredRepositoryCapability($capability);
257
258
return $this->getRepository()
259
->getPolicy($need_capability);
260
}
261
262
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
263
$need_capability = $this->getRequiredRepositoryCapability($capability);
264
265
return $this->getRepository()
266
->hasAutomaticCapability($need_capability, $viewer);
267
}
268
269
public function describeAutomaticCapability($capability) {
270
return pht(
271
'A repository operation inherits the policies of the repository it '.
272
'affects.');
273
}
274
275
private function getRequiredRepositoryCapability($capability) {
276
// To edit a RepositoryOperation, require that the user be able to push
277
// to the repository.
278
279
$map = array(
280
PhabricatorPolicyCapability::CAN_EDIT =>
281
DiffusionPushCapability::CAPABILITY,
282
);
283
284
return idx($map, $capability, $capability);
285
}
286
287
288
}
289
290