@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
at recaptime-dev/main 284 lines 7.9 kB view raw
1<?php 2 3final class HarbormasterBuildableViewController 4 extends HarbormasterController { 5 6 public function shouldAllowPublic() { 7 return true; 8 } 9 10 public function handleRequest(AphrontRequest $request) { 11 $viewer = $this->getViewer(); 12 13 $buildable = id(new HarbormasterBuildableQuery()) 14 ->setViewer($viewer) 15 ->withIDs(array($request->getURIData('id'))) 16 ->executeOne(); 17 if (!$buildable) { 18 return new Aphront404Response(); 19 } 20 21 $id = $buildable->getID(); 22 23 // Pull builds and build targets. 24 $builds = id(new HarbormasterBuildQuery()) 25 ->setViewer($viewer) 26 ->withBuildablePHIDs(array($buildable->getPHID())) 27 ->needBuildTargets(true) 28 ->execute(); 29 30 list($lint, $unit) = $this->renderLintAndUnit($buildable, $builds); 31 32 $buildable->attachBuilds($builds); 33 $object = $buildable->getBuildableObject(); 34 35 $build_list = $this->buildBuildList($buildable); 36 37 $title = pht('Buildable %d', $id); 38 39 $header = id(new PHUIHeaderView()) 40 ->setHeader($title) 41 ->setUser($viewer) 42 ->setPolicyObject($buildable) 43 ->setStatus( 44 $buildable->getStatusIcon(), 45 $buildable->getStatusColor(), 46 $buildable->getStatusDisplayName()) 47 ->setHeaderIcon('fa-recycle'); 48 49 $timeline = $this->buildTransactionTimeline( 50 $buildable, 51 new HarbormasterBuildableTransactionQuery()); 52 $timeline->setShouldTerminate(true); 53 54 $curtain = $this->buildCurtainView($buildable); 55 $properties = $this->buildPropertyList($buildable); 56 57 $crumbs = $this->buildApplicationCrumbs(); 58 $crumbs->addTextCrumb($buildable->getMonogram()); 59 $crumbs->setBorder(true); 60 61 $view = id(new PHUITwoColumnView()) 62 ->setHeader($header) 63 ->setCurtain($curtain) 64 ->setMainColumn(array( 65 $properties, 66 $lint, 67 $unit, 68 $build_list, 69 $timeline, 70 )); 71 72 return $this->newPage() 73 ->setTitle($title) 74 ->setCrumbs($crumbs) 75 ->appendChild($view); 76 77 } 78 79 private function buildCurtainView(HarbormasterBuildable $buildable) { 80 $viewer = $this->getViewer(); 81 $id = $buildable->getID(); 82 83 $curtain = $this->newCurtainView($buildable); 84 85 $can_edit = PhabricatorPolicyFilter::hasCapability( 86 $viewer, 87 $buildable, 88 PhabricatorPolicyCapability::CAN_EDIT); 89 90 $messages = array( 91 new HarbormasterBuildMessageRestartTransaction(), 92 new HarbormasterBuildMessagePauseTransaction(), 93 new HarbormasterBuildMessageResumeTransaction(), 94 new HarbormasterBuildMessageAbortTransaction(), 95 ); 96 97 foreach ($messages as $message) { 98 99 // Messages are enabled if they can be sent to at least one build. 100 $can_send = false; 101 foreach ($buildable->getBuilds() as $build) { 102 $can_send = $message->canSendMessage($viewer, $build); 103 if ($can_send) { 104 break; 105 } 106 } 107 108 $message_uri = urisprintf( 109 '/buildable/%d/%s/', 110 $id, 111 $message->getHarbormasterBuildMessageType()); 112 $message_uri = $this->getApplicationURI($message_uri); 113 114 $action = id(new PhabricatorActionView()) 115 ->setName($message->getHarbormasterBuildableMessageName()) 116 ->setIcon($message->getIcon()) 117 ->setHref($message_uri) 118 ->setDisabled(!$can_send || !$can_edit) 119 ->setWorkflow(true); 120 121 $curtain->addAction($action); 122 } 123 124 return $curtain; 125 } 126 127 private function buildPropertyList(HarbormasterBuildable $buildable) { 128 $viewer = $this->getViewer(); 129 130 $properties = id(new PHUIPropertyListView()) 131 ->setUser($viewer); 132 133 $container_phid = $buildable->getContainerPHID(); 134 $buildable_phid = $buildable->getBuildablePHID(); 135 136 if ($container_phid) { 137 $properties->addProperty( 138 pht('Container'), 139 $viewer->renderHandle($container_phid)); 140 } 141 142 $properties->addProperty( 143 pht('Buildable'), 144 $viewer->renderHandle($buildable_phid)); 145 146 $properties->addProperty( 147 pht('Origin'), 148 $buildable->getIsManualBuildable() 149 ? pht('Manual Buildable') 150 : pht('Automatic Buildable')); 151 152 return id(new PHUIObjectBoxView()) 153 ->setHeaderText(pht('Properties')) 154 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 155 ->appendChild($properties); 156 } 157 158 private function buildBuildList(HarbormasterBuildable $buildable) { 159 $viewer = $this->getRequest()->getUser(); 160 161 $build_list = id(new PHUIObjectItemListView()) 162 ->setUser($viewer); 163 foreach ($buildable->getBuilds() as $build) { 164 $view_uri = $this->getApplicationURI('/build/'.$build->getID().'/'); 165 166 $item = id(new PHUIObjectItemView()) 167 ->setObjectName(pht('Build %d', $build->getID())) 168 ->setHeader($build->getName()) 169 ->setHref($view_uri); 170 171 $status = $build->getBuildPendingStatusObject(); 172 173 $item->setStatusIcon( 174 $status->getIconIcon().' '.$status->getIconColor(), 175 $status->getName()); 176 177 $targets = $build->getBuildTargets(); 178 179 if ($targets) { 180 $target_list = new PHUIStatusListView(); 181 foreach ($targets as $target) { 182 $status = $target->getTargetStatus(); 183 $icon = HarbormasterBuildTarget::getBuildTargetStatusIcon($status); 184 $color = HarbormasterBuildTarget::getBuildTargetStatusColor($status); 185 $status_name = 186 HarbormasterBuildTarget::getBuildTargetStatusName($status); 187 188 $name = $target->getName(); 189 190 $target_list->addItem( 191 id(new PHUIStatusItemView()) 192 ->setIcon($icon, $color, $status_name) 193 ->setTarget(pht('Target %d', $target->getID())) 194 ->setNote($name)); 195 } 196 197 $target_box = id(new PHUIBoxView()) 198 ->addPadding(PHUI::PADDING_SMALL) 199 ->appendChild($target_list); 200 201 $item->appendChild($target_box); 202 } 203 204 $build_list->addItem($item); 205 } 206 207 $build_list->setFlush(true); 208 209 $box = id(new PHUIObjectBoxView()) 210 ->setHeaderText(pht('Builds')) 211 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 212 ->appendChild($build_list); 213 214 return $box; 215 } 216 217 private function renderLintAndUnit( 218 HarbormasterBuildable $buildable, 219 array $builds) { 220 221 $viewer = $this->getViewer(); 222 223 $targets = array(); 224 foreach ($builds as $build) { 225 foreach ($build->getBuildTargets() as $target) { 226 $targets[] = $target; 227 } 228 } 229 230 if (!$targets) { 231 return; 232 } 233 234 $target_phids = mpull($targets, 'getPHID'); 235 236 $lint_data = id(new HarbormasterBuildLintMessage())->loadAllWhere( 237 'buildTargetPHID IN (%Ls)', 238 $target_phids); 239 240 $unit_data = id(new HarbormasterBuildUnitMessageQuery()) 241 ->setViewer($viewer) 242 ->withBuildTargetPHIDs($target_phids) 243 ->execute(); 244 245 if ($lint_data) { 246 $lint_table = id(new HarbormasterLintPropertyView()) 247 ->setViewer($viewer) 248 ->setLimit(10) 249 ->setLintMessages($lint_data); 250 251 $lint_href = $this->getApplicationURI('lint/'.$buildable->getID().'/'); 252 253 $lint_header = id(new PHUIHeaderView()) 254 ->setHeader(pht('Lint Messages')) 255 ->addActionLink( 256 id(new PHUIButtonView()) 257 ->setTag('a') 258 ->setHref($lint_href) 259 ->setIcon('fa-list-ul') 260 ->setText('View All')); 261 262 $lint = id(new PHUIObjectBoxView()) 263 ->setHeader($lint_header) 264 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 265 ->setTable($lint_table); 266 } else { 267 $lint = null; 268 } 269 270 if ($unit_data) { 271 $unit = id(new HarbormasterUnitSummaryView()) 272 ->setViewer($viewer) 273 ->setBuildable($buildable) 274 ->setUnitMessages($unit_data) 275 ->setShowViewAll(true) 276 ->setLimit(5); 277 } else { 278 $unit = null; 279 } 280 281 return array($lint, $unit); 282 } 283 284}