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()))); } }
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); } } }
public function testSvnStateParsing() { if (Filesystem::binaryExists('svn')) { $this->parseState('svn_basic.svn.tgz'); } else { $this->assertSkipped(pht('Subversion is not installed')); } }
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'); } } }
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')); }
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; }
/** * @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; }
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)); } }
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'; }
/** * 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); }
/** * 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; }
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; }
/** * 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"); } } }
/** * 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; }
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)); } }
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); }
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)))); } }
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); }
protected function requireBinaryForTest($binary) { if (!Filesystem::binaryExists($binary)) { $this->assertSkipped(pht('No binary "%s" found on this system, skipping test.', $binary)); } }
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); }
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); } } } } }
/** * @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; } }
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')); }
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')); }
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')); } }
/** * 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.'); }
/** * 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); } } }