[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/config/check/ -> PhabricatorSetupCheckBinaries.php (source)

   1  <?php
   2  
   3  final class PhabricatorSetupCheckBinaries extends PhabricatorSetupCheck {
   4  
   5  
   6    protected function executeChecks() {
   7  
   8      if (phutil_is_windows()) {
   9        $bin_name = 'where';
  10      } else {
  11        $bin_name = 'which';
  12      }
  13  
  14      if (!Filesystem::binaryExists($bin_name)) {
  15        $message = pht(
  16          "Without '%s', Phabricator can not test for the availability ".
  17          "of other binaries.",
  18          $bin_name);
  19        $this->raiseWarning($bin_name, $message);
  20  
  21        // We need to return here if we can't find the 'which' / 'where' binary
  22        // because the other tests won't be valid.
  23        return;
  24      }
  25  
  26      if (!Filesystem::binaryExists('diff')) {
  27        $message = pht(
  28          "Without 'diff', Phabricator will not be able to generate or render ".
  29          "diffs in multiple applications.");
  30        $this->raiseWarning('diff', $message);
  31      } else {
  32        $tmp_a = new TempFile();
  33        $tmp_b = new TempFile();
  34        $tmp_c = new TempFile();
  35  
  36        Filesystem::writeFile($tmp_a, 'A');
  37        Filesystem::writeFile($tmp_b, 'A');
  38        Filesystem::writeFile($tmp_c, 'B');
  39  
  40        list($err) = exec_manual('diff %s %s', $tmp_a, $tmp_b);
  41        if ($err) {
  42          $this->newIssue('bin.diff.same')
  43            ->setName(pht("Unexpected 'diff' Behavior"))
  44            ->setMessage(
  45              pht(
  46                "The 'diff' binary on this system has unexpected behavior: ".
  47                "it was expected to exit without an error code when passed ".
  48                "identical files, but exited with code %d.",
  49                $err));
  50        }
  51  
  52        list($err) = exec_manual('diff %s %s', $tmp_a, $tmp_c);
  53        if (!$err) {
  54          $this->newIssue('bin.diff.diff')
  55            ->setName(pht("Unexpected 'diff' Behavior"))
  56            ->setMessage(
  57              pht(
  58                "The 'diff' binary on this system has unexpected behavior: ".
  59                "it was expected to exit with a nonzero error code when passed ".
  60                "differing files, but did not."));
  61        }
  62      }
  63  
  64      $table = new PhabricatorRepository();
  65      $vcses = queryfx_all(
  66        $table->establishConnection('r'),
  67        'SELECT DISTINCT versionControlSystem FROM %T',
  68        $table->getTableName());
  69  
  70      foreach ($vcses as $vcs) {
  71        switch ($vcs['versionControlSystem']) {
  72          case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
  73            $binary = 'git';
  74            break;
  75          case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
  76            $binary = 'svn';
  77            break;
  78          case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
  79            $binary = 'hg';
  80            break;
  81          default:
  82            $binary = null;
  83            break;
  84        }
  85        if (!$binary) {
  86          continue;
  87        }
  88  
  89        if (!Filesystem::binaryExists($binary)) {
  90          $message = pht(
  91            'You have at least one repository configured which uses this '.
  92            'version control system. It will not work without the VCS binary.');
  93          $this->raiseWarning($binary, $message);
  94        }
  95  
  96        switch ($binary) {
  97          case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
  98            $minimum_version = null;
  99            $bad_versions = array();
 100            list($err, $stdout, $stderr) = exec_manual('git --version');
 101            $version = trim(substr($stdout, strlen('git version ')));
 102            break;
 103          case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
 104            $minimum_version = null;
 105            $bad_versions = array(
 106              '1.7.1' => pht('This version of Subversion has a bug where '.
 107                             '"svn diff -c N" does not work for files added '.
 108                             'in rN (Subverison issue #2873), fixed in 1.7.2.'),);
 109            list($err, $stdout, $stderr) = exec_manual('svn --version --quiet');
 110            $version = trim($stdout);
 111            break;
 112          case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
 113            $minimum_version = '1.9';
 114            $bad_versions = array(
 115              '2.1' => pht('This version of Mercurial returns a bad exit code '.
 116                           'after a successful pull.'),
 117              '2.2' => pht('This version of Mercurial has a significant memory '.
 118                           'leak, fixed in 2.2.1. Pushing fails with this '.
 119                           'version as well; see T3046#54922.'),);
 120            list($err, $stdout, $stderr) = exec_manual('hg --version --quiet');
 121            $version = rtrim(
 122              substr($stdout, strlen('Mercurial Distributed SCM (version ')),
 123              ")\n");
 124            break;
 125        }
 126  
 127        if ($minimum_version &&
 128          version_compare($version, $minimum_version, '<')) {
 129          $this->raiseMinimumVersionWarning(
 130            $binary,
 131            $minimum_version,
 132            $version);
 133        }
 134  
 135        foreach ($bad_versions as $bad_version => $details) {
 136          if ($bad_version === $version) {
 137            $this->raiseBadVersionWarning(
 138              $binary,
 139              $bad_version);
 140          }
 141        }
 142      }
 143  
 144    }
 145  
 146    private function raiseWarning($bin, $message) {
 147      if (phutil_is_windows()) {
 148        $preamble = pht(
 149          "The '%s' binary could not be found. Set the webserver's %s ".
 150          "environmental variable to include the directory where it resides, or ".
 151          "add that directory to '%s' in the Phabricator configuration.",
 152          $bin,
 153          'PATH',
 154          'environment.append-paths');
 155      } else {
 156        $preamble = pht(
 157          "The '%s' binary could not be found. Symlink it into '%s', or set the ".
 158          "webserver's %s environmental variable to include the directory where ".
 159          "it resides, or add that directory to '%s' in the Phabricator ".
 160          "configuration.",
 161          $bin,
 162          'phabricator/support/bin/',
 163          'PATH',
 164          'environment.append-paths');
 165      }
 166  
 167      $this->newIssue('bin.'.$bin)
 168        ->setShortName(pht("'%s' Missing", $bin))
 169        ->setName(pht("Missing '%s' Binary", $bin))
 170        ->setSummary(
 171          pht("The '%s' binary could not be located or executed.", $bin))
 172        ->setMessage($preamble.' '.$message)
 173        ->addPhabricatorConfig('environment.append-paths');
 174    }
 175  
 176    private function raiseMinimumVersionWarning(
 177      $binary,
 178      $minimum_version,
 179      $version) {
 180  
 181      switch ($binary) {
 182        case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
 183          break;
 184        case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
 185          break;
 186        case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
 187          $summary = pht(
 188            "The '%s' binary is version %s and Phabricator requires version ".
 189            "%s or higher.",
 190            $binary,
 191            $version,
 192            $minimum_version);
 193          $message = pht(
 194            "Please upgrade the '%s' binary to a more modern version.",
 195            $binary);
 196          $this->newIssue('bin.'.$binary)
 197            ->setShortName(pht("Unsupported '%s' Version", $binary))
 198            ->setName(pht("Unsupported '%s' Version", $binary))
 199            ->setSummary($summary)
 200            ->setMessage($summary.' '.$message);
 201          break;
 202        }
 203  
 204  
 205    }
 206  
 207    private function raiseBadVersionWarning($binary, $bad_version) {
 208  
 209      switch ($binary) {
 210        case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
 211          break;
 212        case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
 213        case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
 214          $summary = pht(
 215            "The '%s' binary is version %s which has bugs that break ".
 216            "Phabricator.",
 217            $binary,
 218            $bad_version);
 219          $message = pht(
 220            "Please upgrade the '%s' binary to a more modern version.",
 221            $binary);
 222          $this->newIssue('bin.'.$binary)
 223            ->setShortName(pht("Unsupported '%s' Version", $binary))
 224            ->setName(pht("Unsupported '%s' Version", $binary))
 225            ->setSummary($summary)
 226            ->setMessage($summary.' '.$message);
 227          break;
 228        }
 229  
 230  
 231    }
 232  
 233  }


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