public function execute(PhutilArgumentParser $args)
 {
     $viewer = $this->getViewer();
     $names = $args->getArg('buildable');
     if (count($names) != 1) {
         throw new PhutilArgumentUsageException(pht('Specify exactly one buildable object, by object name.'));
     }
     $name = head($names);
     $buildable = id(new PhabricatorObjectQuery())->setViewer($viewer)->withNames($names)->executeOne();
     if (!$buildable) {
         throw new PhutilArgumentUsageException(pht('No such buildable "%s"!', $name));
     }
     if (!$buildable instanceof HarbormasterBuildableInterface) {
         throw new PhutilArgumentUsageException(pht('Object "%s" is not a buildable!', $name));
     }
     $plan_id = $args->getArg('plan');
     if (!$plan_id) {
         throw new PhutilArgumentUsageException(pht('Use --plan to specify a build plan to run.'));
     }
     $plan = id(new HarbormasterBuildPlanQuery())->setViewer($viewer)->withIDs(array($plan_id))->executeOne();
     if (!$plan) {
         throw new PhutilArgumentUsageException(pht('Build plan "%s" does not exist.', $plan_id));
     }
     $console = PhutilConsole::getConsole();
     $buildable = HarbormasterBuildable::initializeNewBuildable($viewer)->setIsManualBuildable(true)->setBuildablePHID($buildable->getHarbormasterBuildablePHID())->setContainerPHID($buildable->getHarbormasterContainerPHID())->save();
     $console->writeOut("%s\n", pht('Applying plan %s to new buildable %s...', $plan->getID(), 'B' . $buildable->getID()));
     $console->writeOut("\n    %s\n\n", PhabricatorEnv::getProductionURI('/B' . $buildable->getID()));
     PhabricatorWorker::setRunAllTasksInProcess(true);
     $buildable->applyPlan($plan);
     $console->writeOut("%s\n", pht('Done.'));
     return 0;
 }
 /**
  * Returns an existing buildable for the object's PHID or creates a
  * new buildable implicitly if needed.
  */
 public static function createOrLoadExisting(PhabricatorUser $actor, $buildable_object_phid, $container_object_phid)
 {
     $buildable = id(new HarbormasterBuildableQuery())->setViewer($actor)->withBuildablePHIDs(array($buildable_object_phid))->withManualBuildables(false)->setLimit(1)->executeOne();
     if ($buildable) {
         return $buildable;
     }
     $buildable = HarbormasterBuildable::initializeNewBuildable($actor)->setBuildablePHID($buildable_object_phid)->setContainerPHID($container_object_phid);
     $buildable->save();
     return $buildable;
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $this->getViewer();
     $this->requireApplicationCapability(HarbormasterManagePlansCapability::CAPABILITY);
     $plan_id = $request->getURIData('id');
     // NOTE: At least for now, this only requires the "Can Manage Plans"
     // capability, not the "Can Edit" capability. Possibly it should have
     // a more stringent requirement, though.
     $plan = id(new HarbormasterBuildPlanQuery())->setViewer($viewer)->withIDs(array($plan_id))->executeOne();
     if (!$plan) {
         return new Aphront404Response();
     }
     $cancel_uri = $this->getApplicationURI("plan/{$plan_id}/");
     if (!$plan->canRunManually()) {
         return $this->newDialog()->setTitle(pht('Can Not Run Plan'))->appendParagraph(pht('This plan can not be run manually.'))->addCancelButton($cancel_uri);
     }
     $e_name = true;
     $v_name = null;
     $errors = array();
     if ($request->isFormPost()) {
         $buildable = HarbormasterBuildable::initializeNewBuildable($viewer)->setIsManualBuildable(true);
         $v_name = $request->getStr('buildablePHID');
         if ($v_name) {
             $object = id(new PhabricatorObjectQuery())->setViewer($viewer)->withNames(array($v_name))->executeOne();
             if ($object instanceof HarbormasterBuildableInterface) {
                 $buildable->setBuildablePHID($object->getHarbormasterBuildablePHID())->setContainerPHID($object->getHarbormasterContainerPHID());
             } else {
                 $e_name = pht('Invalid');
                 $errors[] = pht('Enter the name of a revision or commit.');
             }
         } else {
             $e_name = pht('Required');
             $errors[] = pht('You must choose a revision or commit to build.');
         }
         if (!$errors) {
             $buildable->save();
             $buildable->applyPlan($plan);
             $buildable_uri = '/B' . $buildable->getID();
             return id(new AphrontRedirectResponse())->setURI($buildable_uri);
         }
     }
     if ($errors) {
         $errors = id(new PHUIInfoView())->setErrors($errors);
     }
     $title = pht('Run Build Plan Manually');
     $save_button = pht('Run Plan Manually');
     $form = id(new PHUIFormLayoutView())->setUser($viewer)->appendRemarkupInstructions(pht("Enter the name of a commit or revision to run this plan on (for " . "example, `rX123456` or `D123`).\n\n" . "For more detailed output, you can also run manual builds from " . "the command line:\n\n" . "  phabricator/ \$ ./bin/harbormaster build <object> --plan %s", $plan->getID()))->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Buildable Name'))->setName('buildablePHID')->setError($e_name)->setValue($v_name));
     return $this->newDialog()->setWidth(AphrontDialogView::WIDTH_FULL)->setTitle($title)->appendChild($form)->addCancelButton($cancel_uri)->addSubmitButton($save_button);
 }