コード例 #1
0
 protected function checkBinaryConfiguration()
 {
     $binary = $this->getBinary();
     if (!Filesystem::binaryExists($binary)) {
         throw new ArcanistMissingLinterException(sprintf("%s\n%s", pht('Unable to locate binary "%s" to run linter %s. You may need ' . 'to install the binary, or adjust your linter configuration.', $binary, get_class($this)), pht('TO INSTALL: %s', $this->getInstallInstructions())));
     }
 }
コード例 #2
0
 protected function executeChecks()
 {
     if (phutil_is_windows()) {
         $bin_name = 'where';
     } else {
         $bin_name = 'which';
     }
     if (!Filesystem::binaryExists($bin_name)) {
         $message = pht("Without '%s', Phabricator can not test for the availability " . "of other binaries.", $bin_name);
         $this->raiseWarning($bin_name, $message);
         // We need to return here if we can't find the 'which' / 'where' binary
         // because the other tests won't be valid.
         return;
     }
     if (!Filesystem::binaryExists('diff')) {
         $message = pht("Without 'diff', Phabricator will not be able to generate or render " . "diffs in multiple applications.");
         $this->raiseWarning('diff', $message);
     } else {
         $tmp_a = new TempFile();
         $tmp_b = new TempFile();
         $tmp_c = new TempFile();
         Filesystem::writeFile($tmp_a, 'A');
         Filesystem::writeFile($tmp_b, 'A');
         Filesystem::writeFile($tmp_c, 'B');
         list($err) = exec_manual('diff %s %s', $tmp_a, $tmp_b);
         if ($err) {
             $this->newIssue('bin.diff.same')->setName(pht("Unexpected 'diff' Behavior"))->setMessage(pht("The 'diff' binary on this system has unexpected behavior: " . "it was expected to exit without an error code when passed " . "identical files, but exited with code %d.", $err));
         }
         list($err) = exec_manual('diff %s %s', $tmp_a, $tmp_c);
         if (!$err) {
             $this->newIssue('bin.diff.diff')->setName(pht("Unexpected 'diff' Behavior"))->setMessage(pht("The 'diff' binary on this system has unexpected behavior: " . "it was expected to exit with a nonzero error code when passed " . "differing files, but did not."));
         }
     }
     $table = new PhabricatorRepository();
     $vcses = queryfx_all($table->establishConnection('r'), 'SELECT DISTINCT versionControlSystem FROM %T', $table->getTableName());
     foreach ($vcses as $vcs) {
         switch ($vcs['versionControlSystem']) {
             case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
                 $binary = 'git';
                 break;
             case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
                 $binary = 'svn';
                 break;
             case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
                 $binary = 'hg';
                 break;
             default:
                 $binary = null;
                 break;
         }
         if (!$binary) {
             continue;
         }
         if (!Filesystem::binaryExists($binary)) {
             $message = pht('You have at least one repository configured which uses this ' . 'version control system. It will not work without the VCS binary.');
             $this->raiseWarning($binary, $message);
         }
     }
 }
コード例 #3
0
 public function testSvnStateParsing()
 {
     if (Filesystem::binaryExists('svn')) {
         $this->parseState('svn_basic.svn.tgz');
     } else {
         $this->assertSkipped(pht('Subversion is not installed'));
     }
 }
コード例 #4
0
 protected function executeChecks()
 {
     $imagemagick = PhabricatorEnv::getEnvConfig('files.enable-imagemagick');
     if ($imagemagick) {
         if (!Filesystem::binaryExists('convert')) {
             $message = pht("You have enabled Imagemagick in your config, but the '%s' " . "binary is not in the webserver's %s. Disable imagemagick " . "or make it available to the webserver.", 'convert', '$PATH');
             $this->newIssue('files.enable-imagemagick')->setName(pht("'%s' binary not found or Imagemagick is not installed.", 'convert'))->setMessage($message)->addRelatedPhabricatorConfig('files.enable-imagemagick')->addPhabricatorConfig('environment.append-paths');
         }
     }
 }
コード例 #5
0
 public function testBinaryExists()
 {
     // Test for the `which` binary on Linux, and the `where` binary on Windows,
     // because `which which` is cute.
     if (phutil_is_windows()) {
         $exists = 'where';
     } else {
         $exists = 'which';
     }
     $this->assertEqual(true, Filesystem::binaryExists($exists));
     // We don't expect to find this binary on any system.
     $this->assertEqual(false, Filesystem::binaryExists('halting-problem-decider'));
 }
コード例 #6
0
 public function getDefaultBinary()
 {
     $binary = 'go';
     if (Filesystem::binaryExists($binary)) {
         // Vet is only accessible through 'go vet' or 'go tool vet'
         // Let's manually try to find out if it's installed.
         list($err, $stdout, $stderr) = exec_manual('go tool vet');
         if ($err === 3) {
             throw new ArcanistMissingLinterException(sprintf("%s\n%s", pht('Unable to locate "go vet" to run linter %s. You may need ' . 'to install the binary, or adjust your linter configuration.', get_class($this)), pht('TO INSTALL: %s', $this->getInstallInstructions())));
         }
     }
     return $binary;
 }
コード例 #7
0
 /**
  * @phutil-external-symbol function jsShrink
  */
 public function transformResource($path, $data)
 {
     $type = self::getResourceType($path);
     switch ($type) {
         case 'css':
             $data = $this->replaceCSSPrintRules($path, $data);
             $data = $this->replaceCSSVariables($path, $data);
             $data = preg_replace_callback('@url\\s*\\((\\s*[\'"]?.*?)\\)@s', nonempty($this->translateURICallback, array($this, 'translateResourceURI')), $data);
             break;
     }
     if (!$this->minify) {
         return $data;
     }
     // Some resources won't survive minification (like Raphael.js), and are
     // marked so as not to be minified.
     if (strpos($data, '@' . 'do-not-minify') !== false) {
         return $data;
     }
     switch ($type) {
         case 'css':
             // Remove comments.
             $data = preg_replace('@/\\*.*?\\*/@s', '', $data);
             // Remove whitespace around symbols.
             $data = preg_replace('@\\s*([{}:;,])\\s*@', '\\1', $data);
             // Remove unnecessary semicolons.
             $data = preg_replace('@;}@', '}', $data);
             // Replace #rrggbb with #rgb when possible.
             $data = preg_replace('@#([a-f0-9])\\1([a-f0-9])\\2([a-f0-9])\\3@i', '#\\1\\2\\3', $data);
             $data = trim($data);
             break;
         case 'js':
             // If `jsxmin` is available, use it. jsxmin is the Javelin minifier and
             // produces the smallest output, but is complicated to build.
             if (Filesystem::binaryExists('jsxmin')) {
                 $future = new ExecFuture('jsxmin __DEV__:0');
                 $future->write($data);
                 list($err, $result) = $future->resolve();
                 if (!$err) {
                     $data = $result;
                     break;
                 }
             }
             // If `jsxmin` is not available, use `JsShrink`, which doesn't compress
             // quite as well but is always available.
             $root = dirname(phutil_get_library_root('phabricator'));
             require_once $root . '/externals/JsShrink/jsShrink.php';
             $data = jsShrink($data);
             break;
     }
     return $data;
 }
コード例 #8
0
 public function decryptSecret(PhutilOpaqueEnvelope $secret, PhutilOpaqueEnvelope $password)
 {
     $tmp = new TempFile();
     Filesystem::writeFile($tmp, $secret->openEnvelope());
     if (!Filesystem::binaryExists('ssh-keygen')) {
         throw new Exception(pht('Decrypting SSH keys requires the `ssh-keygen` binary, but it ' . 'is not available in PATH. Either make it available or strip the ' . 'password fromt his SSH key manually before uploading it.'));
     }
     list($err, $stdout, $stderr) = exec_manual('ssh-keygen -p -P %P -N %s -f %s', $password, '', (string) $tmp);
     if ($err) {
         return null;
     } else {
         return new PhutilOpaqueEnvelope(Filesystem::readFile($tmp));
     }
 }
コード例 #9
0
 public function getDefaultBinary()
 {
     if (Filesystem::binaryExists('pep8')) {
         return 'pep8';
     }
     $old_prefix = $this->getDeprecatedConfiguration('lint.pep8.prefix');
     $old_bin = $this->getDeprecatedConfiguration('lint.pep8.bin');
     if ($old_prefix || $old_bin) {
         $old_bin = nonempty($old_bin, 'pep8');
         return $old_prefix . '/' . $old_bin;
     }
     $arc_root = dirname(phutil_get_library_root('arcanist'));
     return $arc_root . '/externals/pep8/pep8.py';
 }
コード例 #10
0
 /**
  * Get information about total and free memory on the system.
  *
  * Because "free memory" is a murky concept, the interpretation of the values
  * returned from this method will vary from system to system and the numbers
  * themselves may be only roughly accurate.
  *
  * @return map<string, wild> Dictionary of memory information.
  * @task memory
  */
 public static function getSystemMemoryInformation()
 {
     $meminfo_path = '/proc/meminfo';
     if (Filesystem::pathExists($meminfo_path)) {
         $meminfo_data = Filesystem::readFile($meminfo_path);
         return self::parseMemInfo($meminfo_data);
     } else {
         if (Filesystem::binaryExists('vm_stat')) {
             list($vm_stat_stdout) = execx('vm_stat');
             return self::parseVMStat($vm_stat_stdout);
         } else {
             throw new Exception(pht('Unable to access %s or `%s` on this system to ' . 'get system memory information.', '/proc/meminfo', 'vm_stat'));
         }
     }
 }
 public function markupContent($content, array $argv)
 {
     if (!Filesystem::binaryExists('dot')) {
         return $this->markupError(pht('Unable to locate the `%s` binary. Install Graphviz.', 'dot'));
     }
     $width = $this->parseDimension(idx($argv, 'width'));
     $future = id(new ExecFuture('dot -T%s', 'png'))->setTimeout(15)->write(trim($content));
     list($err, $stdout, $stderr) = $future->resolve();
     if ($err) {
         return $this->markupError(pht('Execution of `%s` failed (#%d), check your syntax: %s', 'dot', $err, $stderr));
     }
     $file = PhabricatorFile::buildFromFileDataOrHash($stdout, array('name' => 'graphviz.png'));
     if ($this->getEngine()->isTextMode()) {
         return '<' . $file->getBestURI() . '>';
     }
     return phutil_tag('img', array('src' => $file->getBestURI(), 'width' => nonempty($width, null)));
 }
 public function markupContent($content, array $argv)
 {
     if (!Filesystem::binaryExists('figlet')) {
         return $this->markupError(pht('Unable to locate the `%s` binary. Install figlet.', 'figlet'));
     }
     $font = idx($argv, 'font', 'standard');
     $safe_font = preg_replace('/[^0-9a-zA-Z-_.]/', '', $font);
     $future = id(new ExecFuture('figlet -f %s', $safe_font))->setTimeout(15)->write(trim($content, "\n"));
     list($err, $stdout, $stderr) = $future->resolve();
     if ($err) {
         return $this->markupError(pht('Execution of `%s` failed: %s', 'figlet', $stderr));
     }
     if ($this->getEngine()->isTextMode()) {
         return $stdout;
     }
     return phutil_tag('div', array('class' => 'PhabricatorMonospaced remarkup-figlet'), $stdout);
 }
コード例 #13
0
 /**
  * Builds XHPAST automatically.
  *
  * Attempts to build the XHPAST binary automatically.
  *
  * @return void
  */
 public static function build()
 {
     if (Filesystem::binaryExists('gmake')) {
         $command = 'gmake';
     } else {
         $command = 'make';
     }
     $root = phutil_get_library_root('phutil');
     $path = Filesystem::resolvePath($root . '/../support/xhpast');
     // Run the build.
     execx('%s -C %s %Ls', $command, $path, array('clean', 'all', 'install'));
     // Test the binary.
     if (!self::isAvailable()) {
         throw new Exception(pht('%s is broken.', 'xhpast'));
     }
     self::$version = null;
 }
コード例 #14
0
 public function execute(PhutilArgumentParser $args)
 {
     $console = PhutilConsole::getConsole();
     $root = dirname(__FILE__) . '/../../../..';
     if (!Filesystem::binaryExists('mxmlc')) {
         throw new PhutilArgumentUsageException(pht("The `mxmlc` binary was not found in PATH. This compiler binary " . "is required to rebuild the Aphlict client.\n\n" . "Adjust your PATH, or install the Flex SDK from:\n\n" . "    http://flex.apache.org\n\n" . "You may also be able to install it with `npm`:\n\n" . "    \$ npm install flex-sdk\n\n" . "(Note: you should only need to rebuild Aphlict if you are " . "developing Phabricator.)"));
     }
     $argv = array("-source-path={$root}/externals/vegas/src", '-static-link-runtime-shared-libraries=true', '-warnings=true', '-strict=true');
     if ($args->getArg('debug')) {
         $argv[] = '-debug=true';
     }
     list($err, $stdout, $stderr) = exec_manual('mxmlc %Ls -output=%s %s', $argv, $root . '/webroot/rsrc/swf/aphlict.swf', $root . '/support/aphlict/client/src/AphlictClient.as');
     if ($err) {
         $console->writeErr($stderr);
         return 1;
     }
     $console->writeOut("Done.\n");
     return 0;
 }
コード例 #15
0
 /**
  * Determines what executables and test paths to use. Between platforms this
  * also changes whether the test engine is run under .NET or Mono. It also
  * ensures that all of the required binaries are available for the tests to
  * run successfully.
  *
  * @return void
  */
 protected function loadEnvironment()
 {
     $this->projectRoot = $this->getWorkingCopy()->getProjectRoot();
     // Determine build engine.
     if (Filesystem::binaryExists('msbuild')) {
         $this->buildEngine = 'msbuild';
     } else {
         if (Filesystem::binaryExists('xbuild')) {
             $this->buildEngine = 'xbuild';
         } else {
             throw new Exception('Unable to find msbuild or xbuild in PATH!');
         }
     }
     // Determine runtime engine (.NET or Mono).
     if (phutil_is_windows()) {
         $this->runtimeEngine = '';
     } else {
         if (Filesystem::binaryExists('mono')) {
             $this->runtimeEngine = Filesystem::resolveBinary('mono');
         } else {
             throw new Exception('Unable to find Mono and you are not on Windows!');
         }
     }
     // Read the discovery rules.
     $this->discoveryRules = $this->getConfigurationManager()->getConfigFromAnySource('unit.csharp.discovery');
     if ($this->discoveryRules === null) {
         throw new Exception('You must configure discovery rules to map C# files ' . 'back to test projects (`unit.csharp.discovery` in .arcconfig).');
     }
     // Determine xUnit test runner path.
     if ($this->xunitHintPath === null) {
         $this->xunitHintPath = $this->getConfigurationManager()->getConfigFromAnySource('unit.csharp.xunit.binary');
     }
     $xunit = $this->projectRoot . DIRECTORY_SEPARATOR . $this->xunitHintPath;
     if (file_exists($xunit) && $this->xunitHintPath !== null) {
         $this->testEngine = Filesystem::resolvePath($xunit);
     } else {
         if (Filesystem::binaryExists('xunit.console.clr4.exe')) {
             $this->testEngine = 'xunit.console.clr4.exe';
         } else {
             throw new Exception("Unable to locate xUnit console runner. Configure " . "it with the `unit.csharp.xunit.binary' option in .arcconfig");
         }
     }
 }
コード例 #16
0
 /**
  * Determines what executables and lint paths to use. Between platforms
  * this also changes whether the lint engine is run under .NET or Mono. It
  * also ensures that all of the required binaries are available for the lint
  * to run successfully.
  *
  * @return void
  */
 private function loadEnvironment()
 {
     if ($this->loaded) {
         return;
     }
     // Determine runtime engine (.NET or Mono).
     if (phutil_is_windows()) {
         $this->runtimeEngine = '';
     } else {
         if (Filesystem::binaryExists('mono')) {
             $this->runtimeEngine = 'mono ';
         } else {
             throw new Exception(pht('Unable to find Mono and you are not on Windows!'));
         }
     }
     // Determine cslint path.
     $cslint = $this->cslintHintPath;
     if ($cslint !== null && file_exists($cslint)) {
         $this->cslintEngine = Filesystem::resolvePath($cslint);
     } else {
         if (Filesystem::binaryExists('cslint.exe')) {
             $this->cslintEngine = 'cslint.exe';
         } else {
             throw new Exception(pht('Unable to locate %s.', 'cslint'));
         }
     }
     // Determine cslint version.
     $ver_future = new ExecFuture('%C -v', $this->runtimeEngine . $this->cslintEngine);
     list($err, $stdout, $stderr) = $ver_future->resolve();
     if ($err !== 0) {
         throw new Exception(pht('You are running an old version of %s. Please ' . 'upgrade to version %s.', 'cslint', self::SUPPORTED_VERSION));
     }
     $ver = (int) $stdout;
     if ($ver < self::SUPPORTED_VERSION) {
         throw new Exception(pht('You are running an old version of %s. Please ' . 'upgrade to version %s.', 'cslint', self::SUPPORTED_VERSION));
     } else {
         if ($ver > self::SUPPORTED_VERSION) {
             throw new Exception(pht('Arcanist does not support this version of %s (it is newer). ' . 'You can try upgrading Arcanist with `%s`.', 'cslint', 'arc upgrade'));
         }
     }
     $this->loaded = true;
 }
コード例 #17
0
 public function run()
 {
     $console = PhutilConsole::getConsole();
     if (!Filesystem::binaryExists('git')) {
         throw new ArcanistUsageException(pht('Cannot display current version without having `%s` installed.', 'git'));
     }
     $roots = array('arcanist' => dirname(phutil_get_library_root('arcanist')), 'libphutil' => dirname(phutil_get_library_root('phutil')));
     foreach ($roots as $lib => $root) {
         $working_copy = ArcanistWorkingCopyIdentity::newFromPath($root);
         $configuration_manager = clone $this->getConfigurationManager();
         $configuration_manager->setWorkingCopyIdentity($working_copy);
         $repository = ArcanistRepositoryAPI::newAPIFromConfigurationManager($configuration_manager);
         if (!Filesystem::pathExists($repository->getMetadataPath())) {
             throw new ArcanistUsageException(pht('%s is not a git working copy.', $lib));
         }
         list($stdout) = $repository->execxLocal('log -1 --format=%s', '%H %ct');
         list($commit, $timestamp) = explode(' ', $stdout);
         $console->writeOut("%s %s (%s)\n", $lib, $commit, date('j M Y', (int) $timestamp));
     }
 }
コード例 #18
0
 protected function executeChecks()
 {
     $pygment = PhabricatorEnv::getEnvConfig('pygments.enabled');
     if ($pygment) {
         if (!Filesystem::binaryExists('pygmentize')) {
             $summary = pht('You enabled pygments but the %s script is not ' . 'actually available, your %s is probably broken.', 'pygmentize', '$PATH');
             $message = pht('The environmental variable %s does not contain %s. ' . 'You have enabled pygments, which requires ' . '%s to be available in your %s variable.', '$PATH', 'pygmentize', 'pygmentize', '$PATH');
             $this->newIssue('pygments.enabled')->setName(pht('%s Not Found', 'pygmentize'))->setSummary($summary)->setMessage($message)->addRelatedPhabricatorConfig('pygments.enabled')->addPhabricatorConfig('environment.append-paths');
         } else {
             list($err) = exec_manual('pygmentize -h');
             if ($err) {
                 $summary = pht('You have enabled pygments and the %s script is ' . 'available, but does not seem to work.', 'pygmentize');
                 $message = pht('Phabricator has %s available in %s, but the binary ' . 'exited with an error code when run as %s. Check that it is ' . 'installed correctly.', phutil_tag('tt', array(), 'pygmentize'), phutil_tag('tt', array(), '$PATH'), phutil_tag('tt', array(), 'pygmentize -h'));
                 $this->newIssue('pygments.failed')->setName(pht('%s Not Working', 'pygmentize'))->setSummary($summary)->setMessage($message)->addRelatedPhabricatorConfig('pygments.enabled')->addPhabricatorConfig('environment.append-paths');
             }
         }
     } else {
         $summary = pht('Pygments should be installed and enabled ' . 'to provide advanced syntax highlighting.');
         $message = pht('Phabricator can highlight a few languages by default, ' . 'but installing and enabling Pygments (a third-party highlighting ' . "tool) will add syntax highlighting for many more languages. \n\n" . 'For instructions on installing and enabling Pygments, see the ' . '%s configuration option.' . "\n\n" . 'If you do not want to install Pygments, you can ignore this issue.', phutil_tag('tt', array(), 'pygments.enabled'));
         $this->newIssue('pygments.noenabled')->setName(pht('Install Pygments to Improve Syntax Highlighting'))->setSummary($summary)->setMessage($message)->addRelatedPhabricatorConfig('pygments.enabled');
     }
 }
 public function markupContent($content, array $argv)
 {
     if (!Filesystem::binaryExists('cowsay')) {
         return $this->markupError(pht('Unable to locate the `%s` binary. Install cowsay.', 'cowsay'));
     }
     $bin = idx($argv, 'think') ? 'cowthink' : 'cowsay';
     $eyes = idx($argv, 'eyes', 'oo');
     $tongue = idx($argv, 'tongue', '  ');
     $cow = idx($argv, 'cow', 'default');
     // NOTE: Strip this aggressively to prevent nonsense like
     // `cow=/etc/passwd`. We could build a whiltelist with `cowsay -l`.
     $cow = preg_replace('/[^a-z.-]+/', '', $cow);
     $future = new ExecFuture('%s -e %s -T %s -f %s ', $bin, $eyes, $tongue, $cow);
     $future->setTimeout(15);
     $future->write($content);
     list($err, $stdout, $stderr) = $future->resolve();
     if ($err) {
         return $this->markupError(pht('Execution of `%s` failed: %s', 'cowsay', $stderr));
     }
     if ($this->getEngine()->isTextMode()) {
         return $stdout;
     }
     return phutil_tag('div', array('class' => 'PhabricatorMonospaced remarkup-cowsay'), $stdout);
 }
コード例 #20
0
 private function verifyXcodebuildInstalled()
 {
     $binary = 'xcodebuild';
     if (!Filesystem::binaryExists($binary)) {
         throw new ArcanistMissingLinterException(sprintf("%s\n", pht('Unable to locate "%s" to run linter %s. You need to install Xcode.', $binary, get_class($this))));
     }
 }
コード例 #21
0
 public function setLinterConfigurationValue($key, $value)
 {
     switch ($key) {
         case 'interpreter':
             $working_copy = $this->getEngine()->getWorkingCopy();
             $root = $working_copy->getProjectRoot();
             foreach ((array) $value as $path) {
                 if (Filesystem::binaryExists($path)) {
                     $this->setInterpreter($path);
                     return;
                 }
                 $path = Filesystem::resolvePath($path, $root);
                 if (Filesystem::binaryExists($path)) {
                     $this->setInterpreter($path);
                     return;
                 }
             }
             throw new Exception(pht('None of the configured interpreters can be located.'));
         case 'bin':
             $is_script = $this->shouldUseInterpreter();
             $working_copy = $this->getEngine()->getWorkingCopy();
             $root = $working_copy->getProjectRoot();
             foreach ((array) $value as $path) {
                 if (!$is_script && Filesystem::binaryExists($path)) {
                     $this->setBinary($path);
                     return;
                 }
                 $path = Filesystem::resolvePath($path, $root);
                 if (!$is_script && Filesystem::binaryExists($path) || $is_script && Filesystem::pathExists($path)) {
                     $this->setBinary($path);
                     return;
                 }
             }
             throw new Exception(pht('None of the configured binaries can be located.'));
         case 'flags':
             if (!is_array($value)) {
                 phutil_deprecated('String support for flags.', 'You should use list<string> instead.');
                 $value = (array) $value;
             }
             $this->setFlags($value);
             return;
     }
     return parent::setLinterConfigurationValue($key, $value);
 }
コード例 #22
0
 protected function requireBinaryForTest($binary)
 {
     if (!Filesystem::binaryExists($binary)) {
         $this->assertSkipped(pht('No binary "%s" found on this system, skipping test.', $binary));
     }
 }
コード例 #23
0
 public function setLinterConfigurationValue($key, $value)
 {
     switch ($key) {
         case 'interpreter':
             $root = $this->getProjectRoot();
             foreach ((array) $value as $path) {
                 if (Filesystem::binaryExists($path)) {
                     $this->setInterpreter($path);
                     return;
                 }
                 $path = Filesystem::resolvePath($path, $root);
                 if (Filesystem::binaryExists($path)) {
                     $this->setInterpreter($path);
                     return;
                 }
             }
             throw new Exception(pht('None of the configured interpreters can be located.'));
         case 'bin':
             $is_script = $this->shouldUseInterpreter();
             $root = $this->getProjectRoot();
             foreach ((array) $value as $path) {
                 if (!$is_script && Filesystem::binaryExists($path)) {
                     $this->setBinary($path);
                     return;
                 }
                 $path = Filesystem::resolvePath($path, $root);
                 if (!$is_script && Filesystem::binaryExists($path) || $is_script && Filesystem::pathExists($path)) {
                     $this->setBinary($path);
                     return;
                 }
             }
             throw new Exception(pht('None of the configured binaries can be located.'));
         case 'flags':
             $this->setFlags($value);
             return;
         case 'version':
             $this->setVersionRequirement($value);
             return;
     }
     return parent::setLinterConfigurationValue($key, $value);
 }
コード例 #24
0
 protected function executeChecks()
 {
     if (phutil_is_windows()) {
         $bin_name = 'where';
     } else {
         $bin_name = 'which';
     }
     if (!Filesystem::binaryExists($bin_name)) {
         $message = pht("Without '%s', Phabricator can not test for the availability " . "of other binaries.", $bin_name);
         $this->raiseWarning($bin_name, $message);
         // We need to return here if we can't find the 'which' / 'where' binary
         // because the other tests won't be valid.
         return;
     }
     if (!Filesystem::binaryExists('diff')) {
         $message = pht("Without '%s', Phabricator will not be able to generate or render " . "diffs in multiple applications.", 'diff');
         $this->raiseWarning('diff', $message);
     } else {
         $tmp_a = new TempFile();
         $tmp_b = new TempFile();
         $tmp_c = new TempFile();
         Filesystem::writeFile($tmp_a, 'A');
         Filesystem::writeFile($tmp_b, 'A');
         Filesystem::writeFile($tmp_c, 'B');
         list($err) = exec_manual('diff %s %s', $tmp_a, $tmp_b);
         if ($err) {
             $this->newIssue('bin.diff.same')->setName(pht("Unexpected '%s' Behavior", 'diff'))->setMessage(pht("The '%s' binary on this system has unexpected behavior: " . "it was expected to exit without an error code when passed " . "identical files, but exited with code %d.", 'diff', $err));
         }
         list($err) = exec_manual('diff %s %s', $tmp_a, $tmp_c);
         if (!$err) {
             $this->newIssue('bin.diff.diff')->setName(pht("Unexpected 'diff' Behavior"))->setMessage(pht("The '%s' binary on this system has unexpected behavior: " . "it was expected to exit with a nonzero error code when passed " . "differing files, but did not.", 'diff'));
         }
     }
     $table = new PhabricatorRepository();
     $vcses = queryfx_all($table->establishConnection('r'), 'SELECT DISTINCT versionControlSystem FROM %T', $table->getTableName());
     foreach ($vcses as $vcs) {
         switch ($vcs['versionControlSystem']) {
             case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
                 $binary = 'git';
                 break;
             case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
                 $binary = 'svn';
                 break;
             case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
                 $binary = 'hg';
                 break;
             default:
                 $binary = null;
                 break;
         }
         if (!$binary) {
             continue;
         }
         if (!Filesystem::binaryExists($binary)) {
             $message = pht('You have at least one repository configured which uses this ' . 'version control system. It will not work without the VCS binary.');
             $this->raiseWarning($binary, $message);
             continue;
         }
         $version = null;
         switch ($vcs['versionControlSystem']) {
             case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
                 $minimum_version = null;
                 $bad_versions = array();
                 list($err, $stdout, $stderr) = exec_manual('git --version');
                 $version = trim(substr($stdout, strlen('git version ')));
                 break;
             case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
                 $minimum_version = '1.5';
                 $bad_versions = array('1.7.1' => pht('This version of Subversion has a bug where `%s` does not work ' . 'for files added in rN (Subversion issue #2873), fixed in 1.7.2.', 'svn diff -c N'));
                 list($err, $stdout, $stderr) = exec_manual('svn --version --quiet');
                 $version = trim($stdout);
                 break;
             case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
                 $minimum_version = '1.9';
                 $bad_versions = array('2.1' => pht('This version of Mercurial returns a bad exit code ' . 'after a successful pull.'), '2.2' => pht('This version of Mercurial has a significant memory leak, fixed ' . 'in 2.2.1. Pushing fails with this version as well; see %s.', 'T3046#54922'));
                 $version = PhabricatorRepositoryVersion::getMercurialVersion();
                 break;
         }
         if ($version === null) {
             $this->raiseUnknownVersionWarning($binary);
         } else {
             if ($minimum_version && version_compare($version, $minimum_version, '<')) {
                 $this->raiseMinimumVersionWarning($binary, $minimum_version, $version);
             }
             foreach ($bad_versions as $bad_version => $details) {
                 if ($bad_version === $version) {
                     $this->raiseBadVersionWarning($binary, $bad_version);
                 }
             }
         }
     }
 }
コード例 #25
0
 /**
  * @task exec
  */
 public function find()
 {
     $files = array();
     if (!is_dir($this->root) || !is_readable($this->root)) {
         throw new Exception("Invalid FileFinder root directory specified ('{$this->root}'). " . "Root directory must be a directory, be readable, and be specified " . "with an absolute path.");
     }
     if ($this->forceMode == "shell") {
         $php_mode = false;
     } else {
         if ($this->forceMode == "php") {
             $php_mode = true;
         } else {
             $php_mode = phutil_is_windows() || !Filesystem::binaryExists('find');
         }
     }
     if ($php_mode) {
         $files = $this->getFiles("");
     } else {
         $args = array();
         $command = array();
         $command[] = 'find';
         if ($this->followSymlinks) {
             $command[] = '-L';
         }
         $command[] = '.';
         if ($this->exclude) {
             $command[] = $this->generateList('path', $this->exclude) . ' -prune';
             $command[] = '-o';
         }
         if ($this->type) {
             $command[] = '-type %s';
             $args[] = $this->type;
         }
         if ($this->suffix) {
             $command[] = $this->generateList('name', $this->suffix);
         }
         if ($this->paths) {
             $command[] = $this->generateList('path', $this->paths);
         }
         $command[] = '-print0';
         array_unshift($args, implode(' ', $command));
         list($stdout) = newv('ExecFuture', $args)->setCWD($this->root)->resolvex();
         $stdout = trim($stdout);
         if (!strlen($stdout)) {
             return array();
         }
         $files = explode("", $stdout);
         // On OSX/BSD, find prepends a './' to each file.
         for ($i = 0; $i < count($files); $i++) {
             if (substr($files[$i], 0, 2) == './') {
                 $files[$i] = substr($files[$i], 2);
             }
         }
     }
     if (!$this->generateChecksums) {
         return $files;
     } else {
         $map = array();
         foreach ($files as $line) {
             $fullpath = $this->root . '/' . ltrim($line, '/');
             if (is_dir($fullpath)) {
                 $map[$line] = null;
             } else {
                 $map[$line] = md5_file($fullpath);
             }
         }
         return $map;
     }
 }
コード例 #26
0
 private function getBrowserCommand()
 {
     $config = $this->getConfigFromAnySource('browser');
     if ($config) {
         return $config;
     }
     if (phutil_is_windows()) {
         return 'start';
     }
     $candidates = array('sensible-browser', 'xdg-open', 'open');
     // NOTE: The "open" command works well on OS X, but on many Linuxes "open"
     // exists and is not a browser. For now, we're just looking for other
     // commands first, but we might want to be smarter about selecting "open"
     // only on OS X.
     foreach ($candidates as $cmd) {
         if (Filesystem::binaryExists($cmd)) {
             return $cmd;
         }
     }
     throw new ArcanistUsageException(pht("Unable to find a browser command to run. Set '%s' in your " . "Arcanist config to specify a command to use.", 'browser'));
 }
コード例 #27
0
 private function getNodeBinary()
 {
     if (Filesystem::binaryExists('nodejs')) {
         return 'nodejs';
     }
     if (Filesystem::binaryExists('node')) {
         return 'node';
     }
     throw new PhutilArgumentUsageException(pht('No `%s` or `%s` binary was found in %s. You must install ' . 'Node.js to start the Aphlict server.', 'nodejs', 'node', '$PATH'));
 }
コード例 #28
0
 private function checkRubocopInstallation()
 {
     if (!Filesystem::binaryExists('rubocop')) {
         throw new ArcanistUsageException(pht('Rubocop is not installed, please run `gen install rubocop` or add it to your Bundler Gemfile'));
     }
 }
コード例 #29
0
 /**
  * Get the name of the editor program to use. The value of the environmental
  * variable $EDITOR will be used if available; otherwise, the `editor` binary
  * if present; otherwise the best editor will be selected.
  *
  * @return string  Command-line editing program.
  *
  * @task config
  */
 public function getEditor()
 {
     if ($this->preferred) {
         return $this->preferred;
     }
     $editor = getenv('EDITOR');
     if ($editor) {
         return $editor;
     }
     // Look for `editor` in PATH, some systems provide an editor which is
     // linked to something sensible.
     if (Filesystem::binaryExists('editor')) {
         return 'editor';
     }
     if ($this->fallback) {
         return $this->fallback;
     }
     if (Filesystem::binaryExists('nano')) {
         return 'nano';
     }
     throw new Exception('Unable to launch an interactive text editor. Set the EDITOR ' . 'environment variable to an appropriate editor.');
 }
コード例 #30
0
 /**
  * Tries to find and update phpunit configuration file based on
  * `phpunit_config` option in `.arcconfig`.
  */
 private function prepareConfigFile()
 {
     $project_root = $this->projectRoot . DIRECTORY_SEPARATOR;
     $config = $this->getConfigurationManager()->getConfigFromAnySource('phpunit_config');
     if ($config) {
         if (Filesystem::pathExists($project_root . $config)) {
             $this->configFile = $project_root . $config;
         } else {
             throw new Exception(pht('PHPUnit configuration file was not found in %s', $project_root . $config));
         }
     }
     $bin = $this->getConfigurationManager()->getConfigFromAnySource('unit.phpunit.binary');
     if ($bin) {
         if (Filesystem::binaryExists($bin)) {
             $this->phpunitBinary = $bin;
         } else {
             $this->phpunitBinary = Filesystem::resolvePath($bin, $project_root);
         }
     }
 }