[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/releeph/controller/product/ -> ReleephProductEditController.php (source)

   1  <?php
   2  
   3  final class ReleephProductEditController extends ReleephProductController {
   4  
   5    private $productID;
   6  
   7    public function willProcessRequest(array $data) {
   8      $this->productID = $data['projectID'];
   9    }
  10  
  11    public function processRequest() {
  12      $request = $this->getRequest();
  13      $viewer = $request->getUser();
  14  
  15      $product = id(new ReleephProductQuery())
  16        ->setViewer($viewer)
  17        ->withIDs(array($this->productID))
  18        ->needArcanistProjects(true)
  19        ->requireCapabilities(
  20          array(
  21            PhabricatorPolicyCapability::CAN_VIEW,
  22            PhabricatorPolicyCapability::CAN_EDIT,
  23          ))
  24        ->executeOne();
  25      if (!$product) {
  26        return new Aphront404Response();
  27      }
  28      $this->setProduct($product);
  29  
  30      $e_name = true;
  31      $e_trunk_branch = true;
  32      $e_branch_template = false;
  33      $errors = array();
  34  
  35      $product_name = $request->getStr('name', $product->getName());
  36  
  37      $trunk_branch = $request->getStr('trunkBranch', $product->getTrunkBranch());
  38      $branch_template = $request->getStr('branchTemplate');
  39      if ($branch_template === null) {
  40        $branch_template = $product->getDetail('branchTemplate');
  41      }
  42      $pick_failure_instructions = $request->getStr('pickFailureInstructions',
  43        $product->getDetail('pick_failure_instructions'));
  44      $test_paths = $request->getStr('testPaths');
  45      if ($test_paths !== null) {
  46        $test_paths = array_filter(explode("\n", $test_paths));
  47      } else {
  48        $test_paths = $product->getDetail('testPaths', array());
  49      }
  50  
  51      $arc_project_id = $product->getArcanistProjectID();
  52  
  53      if ($request->isFormPost()) {
  54        $pusher_phids = $request->getArr('pushers');
  55  
  56        if (!$product_name) {
  57          $e_name = pht('Required');
  58          $errors[] =
  59            pht('Your releeph product should have a simple descriptive name.');
  60        }
  61  
  62        if (!$trunk_branch) {
  63          $e_trunk_branch = pht('Required');
  64          $errors[] =
  65            pht('You must specify which branch you will be picking from.');
  66        }
  67  
  68        $other_releeph_products = id(new ReleephProject())
  69          ->loadAllWhere('id != %d', $product->getID());
  70        $other_releeph_product_names = mpull($other_releeph_products,
  71          'getName', 'getID');
  72  
  73        if (in_array($product_name, $other_releeph_product_names)) {
  74          $errors[] = pht('Releeph product name %s is already taken',
  75            $product_name);
  76        }
  77  
  78        foreach ($test_paths as $test_path) {
  79          $result = @preg_match($test_path, '');
  80          $is_a_valid_regexp = $result !== false;
  81          if (!$is_a_valid_regexp) {
  82            $errors[] = pht('Please provide a valid regular expression: '.
  83              '%s is not valid', $test_path);
  84          }
  85        }
  86  
  87        $product
  88          ->setTrunkBranch($trunk_branch)
  89          ->setDetail('pushers', $pusher_phids)
  90          ->setDetail('pick_failure_instructions', $pick_failure_instructions)
  91          ->setDetail('branchTemplate', $branch_template)
  92          ->setDetail('testPaths', $test_paths);
  93  
  94        $fake_commit_handle =
  95          ReleephBranchTemplate::getFakeCommitHandleFor($arc_project_id);
  96  
  97        if ($branch_template) {
  98          list($branch_name, $template_errors) = id(new ReleephBranchTemplate())
  99            ->setCommitHandle($fake_commit_handle)
 100            ->setReleephProjectName($product_name)
 101            ->interpolate($branch_template);
 102  
 103          if ($template_errors) {
 104            $e_branch_template = pht('Whoopsies!');
 105            foreach ($template_errors as $template_error) {
 106              $errors[] = "Template error: {$template_error}";
 107            }
 108          }
 109        }
 110  
 111        if (!$errors) {
 112          $product->save();
 113  
 114          return id(new AphrontRedirectResponse())->setURI($product->getURI());
 115        }
 116      }
 117  
 118      $pusher_phids = $request->getArr(
 119        'pushers',
 120        $product->getDetail('pushers', array()));
 121  
 122      $handles = id(new PhabricatorHandleQuery())
 123        ->setViewer($request->getUser())
 124        ->withPHIDs($pusher_phids)
 125        ->execute();
 126  
 127      $pusher_handles = array_select_keys($handles, $pusher_phids);
 128  
 129      $form = id(new AphrontFormView())
 130        ->setUser($request->getUser())
 131        ->appendChild(
 132          id(new AphrontFormTextControl())
 133            ->setLabel(pht('Name'))
 134            ->setName('name')
 135            ->setValue($product_name)
 136            ->setError($e_name)
 137            ->setCaption(pht('A name like "Thrift" but not "Thrift releases".')))
 138        ->appendChild(
 139          id(new AphrontFormStaticControl())
 140            ->setLabel(pht('Repository'))
 141            ->setValue(
 142              $product->getRepository()->getName()))
 143        ->appendChild(
 144          id(new AphrontFormStaticControl())
 145            ->setLabel(pht('Arc Project'))
 146            ->setValue(
 147              $product->getArcanistProject()->getName()))
 148        ->appendChild(
 149          id(new AphrontFormStaticControl())
 150            ->setLabel(pht('Releeph Project PHID'))
 151            ->setValue(
 152              $product->getPHID()))
 153        ->appendChild(
 154          id(new AphrontFormTextControl())
 155            ->setLabel(pht('Trunk'))
 156            ->setValue($trunk_branch)
 157            ->setName('trunkBranch')
 158            ->setError($e_trunk_branch))
 159        ->appendChild(
 160          id(new AphrontFormTextAreaControl())
 161            ->setLabel(pht('Pick Instructions'))
 162            ->setValue($pick_failure_instructions)
 163            ->setName('pickFailureInstructions')
 164            ->setCaption(
 165              pht('Instructions for pick failures, which will be used '.
 166              'in emails generated by failed picks')))
 167        ->appendChild(
 168          id(new AphrontFormTextAreaControl())
 169            ->setLabel(pht('Tests paths'))
 170            ->setValue(implode("\n", $test_paths))
 171            ->setName('testPaths')
 172            ->setCaption(
 173              pht('List of strings that all test files contain in their path '.
 174              'in this project. One string per line. '.
 175              'Examples: \'__tests__\', \'/javatests/\'...')));
 176  
 177      $branch_template_input = id(new AphrontFormTextControl())
 178        ->setName('branchTemplate')
 179        ->setValue($branch_template)
 180        ->setLabel('Branch Template')
 181        ->setError($e_branch_template)
 182        ->setCaption(
 183          pht("Leave this blank to use your installation's default."));
 184  
 185      $branch_template_preview = id(new ReleephBranchPreviewView())
 186        ->setLabel(pht('Preview'))
 187        ->addControl('template', $branch_template_input)
 188        ->addStatic('arcProjectID', $arc_project_id)
 189        ->addStatic('isSymbolic', false)
 190        ->addStatic('projectName', $product->getName());
 191  
 192      $form
 193        ->appendChild(
 194          id(new AphrontFormTokenizerControl())
 195            ->setLabel(pht('Pushers'))
 196            ->setName('pushers')
 197            ->setDatasource(new PhabricatorPeopleDatasource())
 198            ->setValue($pusher_handles))
 199        ->appendChild($branch_template_input)
 200        ->appendChild($branch_template_preview)
 201        ->appendRemarkupInstructions($this->getBranchHelpText());
 202  
 203      $form
 204        ->appendChild(
 205          id(new AphrontFormSubmitControl())
 206            ->addCancelButton('/releeph/product/')
 207            ->setValue(pht('Save')));
 208  
 209      $box = id(new PHUIObjectBoxView())
 210        ->setHeaderText(pht('Edit Releeph Product'))
 211        ->setFormErrors($errors)
 212        ->appendChild($form);
 213  
 214      $crumbs = $this->buildApplicationCrumbs();
 215      $crumbs->addTextCrumb(pht('Edit Product'));
 216  
 217      return $this->buildStandardPageResponse(
 218        array(
 219          $crumbs,
 220          $box,
 221        ),
 222        array(
 223          'title' => pht('Edit Releeph Product'),
 224          'device' => true,
 225        ));
 226    }
 227  
 228    private function getBranchHelpText() {
 229      return <<<EOTEXT
 230  
 231  ==== Interpolations ====
 232  
 233  | Code  | Meaning
 234  | ----- | -------
 235  | `%P`  | The name of your product, with spaces changed to "-".
 236  | `%p`  | Like %P, but all lowercase.
 237  | `%Y`  | The four digit year associated with the branch date.
 238  | `%m`  | The two digit month.
 239  | `%d`  | The two digit day.
 240  | `%v`  | The handle of the commit where the branch was cut ("rXYZa4b3c2d1").
 241  | `%V`  | The abbreviated commit id where the branch was cut ("a4b3c2d1").
 242  | `%..` | Any other sequence interpreted by `strftime()`.
 243  | `%%`  | A literal percent sign.
 244  
 245  
 246  ==== Tips for Branch Templates ====
 247  
 248  Use a directory to separate your release branches from other branches:
 249  
 250    lang=none
 251    releases/%Y-%M-%d-%v
 252    => releases/2012-30-16-rHERGE32cd512a52b7
 253  
 254  Include a second hierarchy if you share your repository with other products:
 255  
 256    lang=none
 257    releases/%P/%p-release-%Y%m%d-%V
 258    => releases/Tintin/tintin-release-20121116-32cd512a52b7
 259  
 260  Keep your branch names simple, avoiding strange punctuation, most of which is
 261  forbidden or escaped anyway:
 262  
 263    lang=none, counterexample
 264    releases//..clown-releases..//`date --iso=seconds`-$(sudo halt)
 265  
 266  Include the date early in your template, in an order which sorts properly:
 267  
 268    lang=none
 269    releases/%Y%m%d-%v
 270    => releases/20121116-rHERGE32cd512a52b7 (good!)
 271  
 272    releases/%V-%m.%d.%Y
 273    => releases/32cd512a52b7-11.16.2012 (awful!)
 274  
 275  
 276  EOTEXT;
 277    }
 278  
 279  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1