[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |