public function testNoHangOnExecFutureDestructionWithRunningChild() { $start = microtime(true); $future = new ExecFuture('sleep 30'); $future->start(); unset($future); $end = microtime(true); // If ExecFuture::__destruct() hangs until the child closes, we won't make // it here in time. $this->assertTrue($end - $start < 5); }
public function willLintPaths(array $paths) { $working_copy = $this->getEngine()->getWorkingCopy(); $root = $working_copy->getProjectRoot(); $chunks = array_chunk($paths, 8); foreach ($chunks as $chunk) { $f = new ExecFuture("python %C --root=include --filter=-build/include_order " . "--verbose=2 %Ls", $root . '/thirdparty/cpplint.py', $chunk); $f->start(); $this->futures[] = $f; } }
public function invoke() { parent::invoke(); $future = new \ExecFuture("composer --no-ansi update"); $future->start(); try { do { list($out) = $future->read(); echo $out; } while (!$future->isReady()); } catch (\Exception $e) { list($err) = $future->read(); throw new \Exception($err); } }
private function buildLockFuture($flags, $file) { $root = dirname(phutil_get_library_root('phutil')); $bin = $root . '/scripts/utils/lock.php'; // NOTE: Use `exec` so this passes on Ubuntu, where the default `dash` shell // will eat any kills we send during the tests. $future = new ExecFuture('exec php %s %C %s', $bin, $flags, $file); $future->start(); return $future; }
public function run() { $this->console = PhutilConsole::getConsole(); $this->runRepositoryAPISetup(); if ($this->getArgument('no-diff')) { $this->removeScratchFile('diff-result.json'); $data = $this->runLintUnit(); $this->writeScratchJSONFile('diff-result.json', $data); return 0; } $this->runDiffSetupBasics(); $background = $this->getArgument('background', true); if ($this->isRawDiffSource() || phutil_is_windows()) { $background = false; } if ($background) { $argv = $this->getPassedArguments(); if (!PhutilConsoleFormatter::getDisableANSI()) { array_unshift($argv, '--ansi'); } $script = phutil_get_library_root('arcanist') . '/../scripts/arcanist.php'; if ($argv) { $lint_unit = new ExecFuture('php %s --recon diff --no-diff %Ls', $script, $argv); } else { $lint_unit = new ExecFuture('php %s --recon diff --no-diff', $script); } $lint_unit->write('', true); $lint_unit->start(); } $commit_message = $this->buildCommitMessage(); $this->dispatchEvent(ArcanistEventType::TYPE_DIFF_DIDBUILDMESSAGE, array('message' => $commit_message)); if (!$this->shouldOnlyCreateDiff()) { $revision = $this->buildRevisionFromCommitMessage($commit_message); } if ($background) { $server = new PhutilConsoleServer(); $server->addExecFutureClient($lint_unit); $server->setHandler(array($this, 'handleServerMessage')); $server->run(); list($err) = $lint_unit->resolve(); $data = $this->readScratchJSONFile('diff-result.json'); if ($err || !$data) { throw new Exception('Unable to read results from background linting and unit testing. ' . 'You can try running arc diff again with --background 0'); } } else { $server = $this->console->getServer(); $server->setHandler(array($this, 'handleServerMessage')); $data = $this->runLintUnit(); } $lint_result = $data['lintResult']; $this->unresolvedLint = $data['unresolvedLint']; $this->postponedLinters = $data['postponedLinters']; $unit_result = $data['unitResult']; $this->testResults = $data['testResults']; if ($this->getArgument('nolint')) { $this->excuses['lint'] = $this->getSkipExcuse('Provide explanation for skipping lint or press Enter to abort:', 'lint-excuses'); } if ($this->getArgument('nounit')) { $this->excuses['unit'] = $this->getSkipExcuse('Provide explanation for skipping unit tests or press Enter to abort:', 'unit-excuses'); } $changes = $this->generateChanges(); if (!$changes) { throw new ArcanistUsageException("There are no changes to generate a diff from!"); } $diff_spec = array('changes' => mpull($changes, 'toDictionary'), 'lintStatus' => $this->getLintStatus($lint_result), 'unitStatus' => $this->getUnitStatus($unit_result)) + $this->buildDiffSpecification(); $conduit = $this->getConduit(); $diff_info = $conduit->callMethodSynchronous('differential.creatediff', $diff_spec); $this->diffID = $diff_info['diffid']; $event = $this->dispatchEvent(ArcanistEventType::TYPE_DIFF_WASCREATED, array('diffID' => $diff_info['diffid'], 'lintResult' => $lint_result, 'unitResult' => $unit_result)); $this->updateLintDiffProperty(); $this->updateUnitDiffProperty(); $this->updateLocalDiffProperty(); $this->resolveDiffPropertyUpdates(); $output_json = $this->getArgument('json'); if ($this->shouldOnlyCreateDiff()) { if (!$output_json) { echo phutil_console_format("Created a new Differential diff:\n" . " **Diff URI:** __%s__\n\n", $diff_info['uri']); } else { $human = ob_get_clean(); echo json_encode(array('diffURI' => $diff_info['uri'], 'diffID' => $this->getDiffID(), 'human' => $human)) . "\n"; ob_start(); } } else { $revision['diffid'] = $this->getDiffID(); if ($commit_message->getRevisionID()) { $result = $conduit->callMethodSynchronous('differential.updaterevision', $revision); foreach (array('edit-messages.json', 'update-messages.json') as $file) { $messages = $this->readScratchJSONFile($file); unset($messages[$revision['id']]); $this->writeScratchJSONFile($file, $messages); } echo "Updated an existing Differential revision:\n"; } else { $revision = $this->dispatchWillCreateRevisionEvent($revision); $result = $conduit->callMethodSynchronous('differential.createrevision', $revision); $revised_message = $conduit->callMethodSynchronous('differential.getcommitmessage', array('revision_id' => $result['revisionid'])); if ($this->shouldAmend()) { $repository_api = $this->getRepositoryAPI(); if ($repository_api->supportsAmend()) { echo "Updating commit message...\n"; $repository_api->amendCommit($revised_message); } else { echo "Commit message was not amended. Amending commit message is " . "only supported in git and hg (version 2.2 or newer)"; } } echo "Created a new Differential revision:\n"; } $uri = $result['uri']; echo phutil_console_format(" **Revision URI:** __%s__\n\n", $uri); if ($this->getArgument('plan-changes')) { $conduit->callMethodSynchronous('differential.createcomment', array('revision_id' => $result['revisionid'], 'action' => 'rethink')); echo "Planned changes to the revision.\n"; } } echo "Included changes:\n"; foreach ($changes as $change) { echo ' ' . $change->renderTextSummary() . "\n"; } if ($output_json) { ob_get_clean(); } $this->removeScratchFile('create-message'); return 0; }
private function buildLockFuture($flags, $file) { $root = dirname(phutil_get_library_root('phutil')); $bin = $root . '/scripts/utils/lock.php'; $future = new ExecFuture('%s %C %s', $bin, $flags, $file); $future->start(); return $future; }