@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3final class HarbormasterBuildArtifact
4 extends HarbormasterDAO
5 implements
6 PhabricatorPolicyInterface,
7 PhabricatorDestructibleInterface,
8 PhabricatorConduitResultInterface {
9
10 protected $buildTargetPHID;
11 protected $artifactType;
12 protected $artifactIndex;
13 protected $artifactKey;
14 protected $artifactData = array();
15 protected $isReleased = 0;
16
17 private $buildTarget = self::ATTACHABLE;
18 private $artifactImplementation;
19
20 public static function initializeNewBuildArtifact(
21 HarbormasterBuildTarget $build_target) {
22
23 return id(new HarbormasterBuildArtifact())
24 ->attachBuildTarget($build_target)
25 ->setBuildTargetPHID($build_target->getPHID());
26 }
27
28 protected function getConfiguration() {
29 return array(
30 self::CONFIG_AUX_PHID => true,
31 self::CONFIG_SERIALIZATION => array(
32 'artifactData' => self::SERIALIZATION_JSON,
33 ),
34 self::CONFIG_COLUMN_SCHEMA => array(
35 'artifactType' => 'text32',
36 'artifactIndex' => 'bytes12',
37 'artifactKey' => 'text255',
38 'isReleased' => 'bool',
39 ),
40 self::CONFIG_KEY_SCHEMA => array(
41 'key_artifact' => array(
42 'columns' => array('artifactType', 'artifactIndex'),
43 'unique' => true,
44 ),
45 'key_garbagecollect' => array(
46 'columns' => array('artifactType', 'dateCreated'),
47 ),
48 'key_target' => array(
49 'columns' => array('buildTargetPHID', 'artifactType'),
50 ),
51 'key_index' => array(
52 'columns' => array('artifactIndex'),
53 ),
54 ),
55 ) + parent::getConfiguration();
56 }
57
58 public function getPHIDType() {
59 return HarbormasterBuildArtifactPHIDType::TYPECONST;
60 }
61
62 public function attachBuildTarget(HarbormasterBuildTarget $build_target) {
63 $this->buildTarget = $build_target;
64 return $this;
65 }
66
67 public function getBuildTarget() {
68 return $this->assertAttached($this->buildTarget);
69 }
70
71 public function setArtifactKey($key) {
72 $target = $this->getBuildTarget();
73 $this->artifactIndex = self::getArtifactIndex($target, $key);
74 $this->artifactKey = $key;
75 return $this;
76 }
77
78 public static function getArtifactIndex(
79 HarbormasterBuildTarget $target,
80 $artifact_key) {
81
82 $build = $target->getBuild();
83
84 $parts = array(
85 $build->getPHID(),
86 $target->getBuildGeneration(),
87 $artifact_key,
88 );
89 $parts = implode("\0", $parts);
90
91 return PhabricatorHash::digestForIndex($parts);
92 }
93
94 public function releaseArtifact() {
95 if ($this->getIsReleased()) {
96 return $this;
97 }
98
99 $impl = $this->getArtifactImplementation();
100 if ($impl) {
101 $impl->releaseArtifact(PhabricatorUser::getOmnipotentUser());
102 }
103
104 return $this
105 ->setIsReleased(1)
106 ->save();
107 }
108
109 public function getArtifactImplementation() {
110 if ($this->artifactImplementation === null) {
111 $type = $this->getArtifactType();
112 $impl = HarbormasterArtifact::getArtifactType($type);
113 if (!$impl) {
114 return null;
115 }
116
117 $impl = clone $impl;
118 $impl->setBuildArtifact($this);
119 $this->artifactImplementation = $impl;
120 }
121
122 return $this->artifactImplementation;
123 }
124
125
126 public function getProperty($key, $default = null) {
127 return idx($this->artifactData, $key, $default);
128 }
129
130
131/* -( PhabricatorPolicyInterface )----------------------------------------- */
132
133
134 public function getCapabilities() {
135 return array(
136 PhabricatorPolicyCapability::CAN_VIEW,
137 );
138 }
139
140 public function getPolicy($capability) {
141 return $this->getBuildTarget()->getPolicy($capability);
142 }
143
144 public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
145 return $this->getBuildTarget()->hasAutomaticCapability(
146 $capability,
147 $viewer);
148 }
149
150 public function describeAutomaticCapability($capability) {
151 return pht(
152 'Users must be able to see a build target to see its artifacts.');
153 }
154
155
156/* -( PhabricatorDestructibleInterface )----------------------------------- */
157
158
159 public function destroyObjectPermanently(
160 PhabricatorDestructionEngine $engine) {
161
162 $viewer = $this->getViewer();
163
164 $this->openTransaction();
165 $this->releaseArtifact();
166 $this->delete();
167 $this->saveTransaction();
168 }
169
170
171/* -( PhabricatorConduitResultInterface )---------------------------------- */
172
173 public function getFieldSpecificationsForConduit() {
174 return array(
175 id(new PhabricatorConduitSearchFieldSpecification())
176 ->setKey('buildTargetPHID')
177 ->setType('phid')
178 ->setDescription(pht('The build target this artifact is attached to.')),
179 id(new PhabricatorConduitSearchFieldSpecification())
180 ->setKey('artifactType')
181 ->setType('string')
182 ->setDescription(pht('The artifact type.')),
183 id(new PhabricatorConduitSearchFieldSpecification())
184 ->setKey('artifactKey')
185 ->setType('string')
186 ->setDescription(pht('The artifact key.')),
187 id(new PhabricatorConduitSearchFieldSpecification())
188 ->setKey('isReleased')
189 ->setType('bool')
190 ->setDescription(pht('True if this artifact has been released.')),
191 );
192 }
193
194 public function getFieldValuesForConduit() {
195 return array(
196 'buildTargetPHID' => $this->getBuildTargetPHID(),
197 'artifactType' => $this->getArtifactType(),
198 'artifactKey' => $this->getArtifactKey(),
199 'isReleased' => (bool)$this->getIsReleased(),
200 );
201 }
202
203 public function getConduitSearchAttachments() {
204 return array();
205 }
206}