[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/releeph/view/branch/ -> ReleephBranchTemplate.php (source)

   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  }


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