Remove product literal strings in "pht()", part 25
[phabricator.git] / src / applications / releeph / view / branch / ReleephBranchTemplate.php
blobf29e7a9fc23d01b7ed3b66d8a435201f82aadab0
1 <?php
3 final class ReleephBranchTemplate extends Phobject {
5 const KEY = 'releeph.default-branch-template';
7 private $commitHandle;
8 private $branchDate = null;
9 private $projectName;
10 private $isSymbolic;
12 public static function getDefaultTemplate() {
13 return PhabricatorEnv::getEnvConfig(self::KEY);
16 public static function getRequiredDefaultTemplate() {
17 $template = self::getDefaultTemplate();
18 if (!$template) {
19 throw new Exception(pht(
20 "Config setting '%s' must be set, ".
21 "or you must provide a branch-template for each project!",
22 self::KEY));
24 return $template;
27 public static function getFakeCommitHandleFor(
28 $repository_phid,
29 PhabricatorUser $viewer) {
31 $repository = id(new PhabricatorRepositoryQuery())
32 ->setViewer($viewer)
33 ->withPHIDs(array($repository_phid))
34 ->executeOne();
36 $fake_handle = 'SOFAKE';
37 if ($repository) {
38 $fake_handle = id(new PhabricatorObjectHandle())
39 ->setName($repository->formatCommitName('100000000000'));
41 return $fake_handle;
44 public function setCommitHandle(PhabricatorObjectHandle $handle) {
45 $this->commitHandle = $handle;
46 return $this;
49 public function setBranchDate($branch_date) {
50 $this->branchDate = $branch_date;
51 return $this;
54 public function setReleephProjectName($project_name) {
55 $this->projectName = $project_name;
56 return $this;
59 public function setSymbolic($is_symbolic) {
60 $this->isSymbolic = $is_symbolic;
61 return $this;
64 public function interpolate($template) {
65 if (!$this->projectName) {
66 return array('', array());
69 list($name, $name_errors) = $this->interpolateInner(
70 $template,
71 $this->isSymbolic);
73 if ($this->isSymbolic) {
74 return array($name, $name_errors);
75 } else {
76 $validate_errors = $this->validateAsBranchName($name);
77 $errors = array_merge($name_errors, $validate_errors);
78 return array($name, $errors);
83 * xsprintf() would be useful here, but that's for formatting concrete lists
84 * of things in a certain way...
86 * animal_printf('%A %A %A', $dog1, $dog2, $dog3);
88 * ...rather than interpolating percent-control-strings like strftime does.
90 private function interpolateInner($template, $is_symbolic) {
91 $name = $template;
92 $errors = array();
94 $safe_project_name = str_replace(' ', '-', $this->projectName);
95 $short_commit_id = last(
96 preg_split('/r[A-Z]+/', $this->commitHandle->getName()));
98 $interpolations = array();
99 for ($ii = 0; $ii < strlen($name); $ii++) {
100 $char = substr($name, $ii, 1);
101 $prev = null;
102 if ($ii > 0) {
103 $prev = substr($name, $ii - 1, 1);
105 $next = substr($name, $ii + 1, 1);
106 if ($next && $char == '%' && $prev != '%') {
107 $interpolations[$ii] = $next;
111 $variable_interpolations = array();
113 $reverse_interpolations = $interpolations;
114 krsort($reverse_interpolations);
116 if ($this->branchDate) {
117 $branch_date = $this->branchDate;
118 } else {
119 $branch_date = $this->commitHandle->getTimestamp();
122 foreach ($reverse_interpolations as $position => $code) {
123 $replacement = null;
124 switch ($code) {
125 case 'v':
126 $replacement = $this->commitHandle->getName();
127 $is_variable = true;
128 break;
130 case 'V':
131 $replacement = $short_commit_id;
132 $is_variable = true;
133 break;
135 case 'P':
136 $replacement = $safe_project_name;
137 $is_variable = false;
138 break;
140 case 'p':
141 $replacement = strtolower($safe_project_name);
142 $is_variable = false;
143 break;
145 default:
146 // Format anything else using strftime()
147 $replacement = strftime("%{$code}", $branch_date);
148 $is_variable = true;
149 break;
152 if ($is_variable) {
153 $variable_interpolations[] = $code;
155 $name = substr_replace($name, $replacement, $position, 2);
158 if (!$is_symbolic && !$variable_interpolations) {
159 $errors[] = pht("Include additional interpolations that aren't static!");
162 return array($name, $errors);
165 private function validateAsBranchName($name) {
166 $errors = array();
168 if (preg_match('{^/}', $name) || preg_match('{/$}', $name)) {
169 $errors[] = pht("Branches cannot begin or end with '%s'", '/');
172 if (preg_match('{//+}', $name)) {
173 $errors[] = pht("Branches cannot contain multiple consecutive '%s'", '/');
176 $parts = array_filter(explode('/', $name));
177 foreach ($parts as $index => $part) {
178 $part_error = null;
179 if (preg_match('{^\.}', $part) || preg_match('{\.$}', $part)) {
180 $errors[] = pht("Path components cannot begin or end with '%s'", '.');
181 } else if (preg_match('{^(?!\w)}', $part)) {
182 $errors[] = pht('Path components must begin with an alphanumeric.');
183 } else if (!preg_match('{^\w ([\w-_%\.]* [\w-_%])?$}x', $part)) {
184 $errors[] = pht(
185 "Path components may only contain alphanumerics ".
186 "or '%s', '%s' or '%s'.",
187 '-',
188 '_',
189 '.');
193 return $errors;