[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 final class ReleephBranchTemplate { 4 5 const KEY = 'releeph.default-branch-template'; 6 7 public static function getDefaultTemplate() { 8 return PhabricatorEnv::getEnvConfig(self::KEY); 9 } 10 11 public static function getRequiredDefaultTemplate() { 12 $template = self::getDefaultTemplate(); 13 if (!$template) { 14 throw new Exception(sprintf( 15 "Config setting '%s' must be set, ". 16 "or you must provide a branch-template for each project!", 17 self::KEY)); 18 } 19 return $template; 20 } 21 22 public static function getFakeCommitHandleFor($arc_project_id) { 23 $arc_project = id(new PhabricatorRepositoryArcanistProject()) 24 ->load($arc_project_id); 25 if (!$arc_project) { 26 throw new Exception( 27 "No Arc project found with id '{$arc_project_id}'!"); 28 } 29 30 $repository = $arc_project->loadRepository(); 31 return id(new PhabricatorObjectHandle()) 32 ->setName($repository->formatCommitName('100000000000')); 33 } 34 35 private $commitHandle; 36 private $branchDate = null; 37 private $projectName; 38 private $isSymbolic; 39 40 public function setCommitHandle(PhabricatorObjectHandle $handle) { 41 $this->commitHandle = $handle; 42 return $this; 43 } 44 45 public function setBranchDate($branch_date) { 46 $this->branchDate = $branch_date; 47 return $this; 48 } 49 50 public function setReleephProjectName($project_name) { 51 $this->projectName = $project_name; 52 return $this; 53 } 54 55 public function setSymbolic($is_symbolic) { 56 $this->isSymbolic = $is_symbolic; 57 return $this; 58 } 59 60 public function interpolate($template) { 61 if (!$this->projectName) { 62 return array('', array()); 63 } 64 65 list($name, $name_errors) = $this->interpolateInner( 66 $template, 67 $this->isSymbolic); 68 69 if ($this->isSymbolic) { 70 return array($name, $name_errors); 71 } else { 72 $validate_errors = $this->validateAsBranchName($name); 73 $errors = array_merge($name_errors, $validate_errors); 74 return array($name, $errors); 75 } 76 } 77 78 /* 79 * xsprintf() would be useful here, but that's for formatting concrete lists 80 * of things in a certain way... 81 * 82 * animal_printf('%A %A %A', $dog1, $dog2, $dog3); 83 * 84 * ...rather than interpolating percent-control-strings like strftime does. 85 */ 86 private function interpolateInner($template, $is_symbolic) { 87 $name = $template; 88 $errors = array(); 89 90 $safe_project_name = str_replace(' ', '-', $this->projectName); 91 $short_commit_id = last( 92 preg_split('/r[A-Z]+/', $this->commitHandle->getName())); 93 94 $interpolations = array(); 95 for ($ii = 0; $ii < strlen($name); $ii++) { 96 $char = substr($name, $ii, 1); 97 $prev = null; 98 if ($ii > 0) { 99 $prev = substr($name, $ii - 1, 1); 100 } 101 $next = substr($name, $ii + 1, 1); 102 if ($next && $char == '%' && $prev != '%') { 103 $interpolations[$ii] = $next; 104 } 105 } 106 107 $variable_interpolations = array(); 108 109 $reverse_interpolations = $interpolations; 110 krsort($reverse_interpolations); 111 112 if ($this->branchDate) { 113 $branch_date = $this->branchDate; 114 } else { 115 $branch_date = $this->commitHandle->getTimestamp(); 116 } 117 118 foreach ($reverse_interpolations as $position => $code) { 119 $replacement = null; 120 switch ($code) { 121 case 'v': 122 $replacement = $this->commitHandle->getName(); 123 $is_variable = true; 124 break; 125 126 case 'V': 127 $replacement = $short_commit_id; 128 $is_variable = true; 129 break; 130 131 case 'P': 132 $replacement = $safe_project_name; 133 $is_variable = false; 134 break; 135 136 case 'p': 137 $replacement = strtolower($safe_project_name); 138 $is_variable = false; 139 break; 140 141 default: 142 // Format anything else using strftime() 143 $replacement = strftime("%{$code}", $branch_date); 144 $is_variable = true; 145 break; 146 } 147 148 if ($is_variable) { 149 $variable_interpolations[] = $code; 150 } 151 $name = substr_replace($name, $replacement, $position, 2); 152 } 153 154 if (!$is_symbolic && !$variable_interpolations) { 155 $errors[] = "Include additional interpolations that aren't static!"; 156 } 157 158 return array($name, $errors); 159 } 160 161 private function validateAsBranchName($name) { 162 $errors = array(); 163 164 if (preg_match('{^/}', $name) || preg_match('{/$}', $name)) { 165 $errors[] = "Branches cannot begin or end with '/'"; 166 } 167 168 if (preg_match('{//+}', $name)) { 169 $errors[] = "Branches cannot contain multiple consective '/'"; 170 } 171 172 $parts = array_filter(explode('/', $name)); 173 foreach ($parts as $index => $part) { 174 $part_error = null; 175 if (preg_match('{^\.}', $part) || preg_match('{\.$}', $part)) { 176 $errors[] = "Path components cannot begin or end with '.'"; 177 } else if (preg_match('{^(?!\w)}', $part)) { 178 $errors[] = 'Path components must begin with an alphanumeric'; 179 } else if (!preg_match('{^\w ([\w-_%\.]* [\w-_%])?$}x', $part)) { 180 $errors[] = 181 "Path components may only contain alphanumerics ". 182 "or '-', '_', or '.'"; 183 } 184 } 185 186 return $errors; 187 } 188 }
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 |