@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
fork

Configure Feed

Select the types of activity you want to include in your feed.

Allow "bin/drydock lease ..." to select particular blueprints with "--blueprint"

Summary: Ref T13676. See discussion in that task.

Test Plan: Tried nonsense blueprint identifiers, duplicate identifiers, incompatible identifiers, and valid identifiers. Got apparently sensible behavior in all cases.

Subscribers: PHID-OPKG-gm6ozazyms6q6i22gyam

Maniphest Tasks: T13676

Differential Revision: https://secure.phabricator.com/D21802

+175 -2
+78 -2
src/applications/drydock/management/DrydockManagementLeaseWorkflow.php
··· 32 32 'default' => 1, 33 33 'help' => pht('Lease a given number of identical resources.'), 34 34 ), 35 + array( 36 + 'name' => 'blueprint', 37 + 'param' => 'identifier', 38 + 'repeat' => true, 39 + 'help' => pht('Lease resources from a specific blueprint.'), 40 + ), 35 41 )); 36 42 } 37 43 ··· 79 85 $attributes = array(); 80 86 } 81 87 88 + $filter_identifiers = $args->getArg('blueprint'); 89 + if ($filter_identifiers) { 90 + $filter_blueprints = $this->getBlueprintFilterMap($filter_identifiers); 91 + } else { 92 + $filter_blueprints = array(); 93 + } 94 + 82 95 $blueprint_phids = null; 83 96 84 97 $leases = array(); ··· 94 107 } 95 108 96 109 if ($blueprint_phids === null) { 97 - $blueprint_phids = $this->newAllowedBlueprintPHIDs($lease); 110 + $blueprint_phids = $this->newAllowedBlueprintPHIDs( 111 + $lease, 112 + $filter_blueprints); 98 113 } 99 114 100 115 $lease->setAllowedBlueprintPHIDs($blueprint_phids); ··· 253 268 } 254 269 } 255 270 256 - private function newAllowedBlueprintPHIDs(DrydockLease $lease) { 271 + private function getBlueprintFilterMap(array $identifiers) { 272 + $viewer = $this->getViewer(); 273 + 274 + $query = id(new DrydockBlueprintQuery()) 275 + ->setViewer($viewer) 276 + ->withIdentifiers($identifiers); 277 + 278 + $blueprints = $query->execute(); 279 + $blueprints = mpull($blueprints, null, 'getPHID'); 280 + 281 + $map = $query->getIdentifierMap(); 282 + 283 + $seen = array(); 284 + foreach ($identifiers as $identifier) { 285 + if (!isset($map[$identifier])) { 286 + throw new PhutilArgumentUsageException( 287 + pht( 288 + 'Blueprint "%s" could not be loaded. Try a blueprint ID or '. 289 + 'PHID.', 290 + $identifier)); 291 + } 292 + 293 + $blueprint = $map[$identifier]; 294 + 295 + $blueprint_phid = $blueprint->getPHID(); 296 + if (isset($seen[$blueprint_phid])) { 297 + throw new PhutilArgumentUsageException( 298 + pht( 299 + 'Blueprint "%s" is specified more than once (as "%s" and "%s").', 300 + $blueprint->getBlueprintName(), 301 + $seen[$blueprint_phid], 302 + $identifier)); 303 + } 304 + 305 + $seen[$blueprint_phid] = true; 306 + } 307 + 308 + return mpull($map, null, 'getPHID'); 309 + } 310 + 311 + private function newAllowedBlueprintPHIDs( 312 + DrydockLease $lease, 313 + array $filter_blueprints) { 314 + assert_instances_of($filter_blueprints, 'DrydockBlueprint'); 315 + 257 316 $viewer = $this->getViewer(); 258 317 259 318 $impls = DrydockBlueprintImplementation::getAllForAllocatingLease($lease); ··· 281 340 } 282 341 283 342 $phids = mpull($blueprints, 'getPHID'); 343 + 344 + if ($filter_blueprints) { 345 + $allowed_map = array_fuse($phids); 346 + $filter_map = mpull($filter_blueprints, null, 'getPHID'); 347 + 348 + foreach ($filter_map as $filter_phid => $blueprint) { 349 + if (!isset($allowed_map[$filter_phid])) { 350 + throw new PhutilArgumentUsageException( 351 + pht( 352 + 'Specified blueprint "%s" is not capable of satisfying the '. 353 + 'configured lease.', 354 + $blueprint->getBlueprintName())); 355 + } 356 + } 357 + 358 + $phids = mpull($filter_blueprints, 'getPHID'); 359 + } 284 360 285 361 return $phids; 286 362 }
+97
src/applications/drydock/query/DrydockBlueprintQuery.php
··· 9 9 private $disabled; 10 10 private $authorizedPHIDs; 11 11 12 + private $identifiers; 13 + private $identifierIDs; 14 + private $identifierPHIDs; 15 + private $identifierMap; 16 + 12 17 public function withIDs(array $ids) { 13 18 $this->ids = $ids; 14 19 return $this; ··· 45 50 $ngrams); 46 51 } 47 52 53 + public function withIdentifiers(array $identifiers) { 54 + if (!$identifiers) { 55 + throw new Exception( 56 + pht( 57 + 'Can not issue a query with an empty identifier list.')); 58 + } 59 + 60 + $this->identifiers = $identifiers; 61 + 62 + $ids = array(); 63 + $phids = array(); 64 + 65 + foreach ($identifiers as $identifier) { 66 + if (ctype_digit($identifier)) { 67 + $ids[] = $identifier; 68 + } else { 69 + $phids[] = $identifier; 70 + } 71 + } 72 + 73 + $this->identifierIDs = $ids; 74 + $this->identifierPHIDs = $phids; 75 + 76 + return $this; 77 + } 78 + 79 + public function getIdentifierMap() { 80 + if ($this->identifierMap === null) { 81 + throw new Exception( 82 + pht( 83 + 'Execute a query with identifiers before getting the '. 84 + 'identifier map.')); 85 + } 86 + 87 + return $this->identifierMap; 88 + } 89 + 48 90 public function newResultObject() { 49 91 return new DrydockBlueprint(); 50 92 } ··· 57 99 return $this->loadStandardPage($this->newResultObject()); 58 100 } 59 101 102 + protected function willExecute() { 103 + if ($this->identifiers) { 104 + $this->identifierMap = array(); 105 + } else { 106 + $this->identifierMap = null; 107 + } 108 + } 109 + 60 110 protected function willFilterPage(array $blueprints) { 61 111 $impls = DrydockBlueprintImplementation::getAllBlueprintImplementations(); 62 112 foreach ($blueprints as $key => $blueprint) { ··· 70 120 $blueprint->attachImplementation($impl); 71 121 } 72 122 123 + if ($this->identifiers) { 124 + $id_map = mpull($blueprints, null, 'getID'); 125 + $phid_map = mpull($blueprints, null, 'getPHID'); 126 + 127 + $map = $this->identifierMap; 128 + 129 + foreach ($this->identifierIDs as $id) { 130 + if (isset($id_map[$id])) { 131 + $map[$id] = $id_map[$id]; 132 + } 133 + } 134 + 135 + foreach ($this->identifierPHIDs as $phid) { 136 + if (isset($phid_map[$phid])) { 137 + $map[$phid] = $phid_map[$phid]; 138 + } 139 + } 140 + 141 + // Just for consistency, reorder the map to match input order. 142 + $map = array_select_keys($map, $this->identifiers); 143 + 144 + $this->identifierMap = $map; 145 + } 146 + 73 147 return $blueprints; 74 148 } 75 149 ··· 109 183 $conn, 110 184 'blueprint.isDisabled = %d', 111 185 (int)$this->disabled); 186 + } 187 + 188 + if ($this->identifiers !== null) { 189 + $parts = array(); 190 + 191 + if ($this->identifierIDs) { 192 + $parts[] = qsprintf( 193 + $conn, 194 + 'blueprint.id IN (%Ld)', 195 + $this->identifierIDs); 196 + } 197 + 198 + if ($this->identifierPHIDs) { 199 + $parts[] = qsprintf( 200 + $conn, 201 + 'blueprint.phid IN (%Ls)', 202 + $this->identifierPHIDs); 203 + } 204 + 205 + $where[] = qsprintf( 206 + $conn, 207 + '%LO', 208 + $parts); 112 209 } 113 210 114 211 return $where;