protected function executeQuery() { $drequest = $this->getRequest(); $repository = $drequest->getRepository(); if (!$drequest->getRawCommit()) { $effective_commit = $this->getEffectiveCommit(); if (!$effective_commit) { return null; } // TODO: This side effect is kind of skethcy. $drequest->setCommit($effective_commit); } else { $effective_commit = $drequest->getCommit(); } $options = array('-M', '-C', '--no-ext-diff', '--no-color', '--src-prefix=a/', '--dst-prefix=b/', '-U65535'); $options = implode(' ', $options); list($raw_diff) = execx("(cd %s && git diff {$options} %s^ %s -- %s)", $repository->getDetail('local-path'), $effective_commit, $effective_commit, $drequest->getPath()); $parser = new ArcanistDiffParser(); $parser->setDetectBinaryFiles(true); $changes = $parser->parseDiff($raw_diff); $diff = DifferentialDiff::newFromRawChanges($changes); $changesets = $diff->getChangesets(); $changeset = reset($changesets); $this->renderingReference = $drequest->getBranchURIComponent($drequest->getBranch()) . $drequest->getPath() . ';' . $drequest->getCommit(); return $changeset; }
public final function run() { $repository = $this->loadRepository(); $expected_type = $this->getSupportedRepositoryType(); $repo_type = $repository->getVersionControlSystem(); if ($repo_type != $expected_type) { $repo_type_name = PhabricatorRepositoryType::getNameForRepositoryType($repo_type); $expected_type_name = PhabricatorRepositoryType::getNameForRepositoryType($expected_type); $repo_name = $repository->getName() . ' (' . $repository->getCallsign() . ')'; throw new Exception("This daemon pulls '{$expected_type_name}' repositories, but the " . "repository '{$repo_name}' is a '{$repo_type_name}' repository."); } $tracked = $repository->isTracked(); if (!$tracked) { throw new Exception("Tracking is not enabled for this repository."); } $local_path = $repository->getDetail('local-path'); if (!$local_path) { throw new Exception("No local path is available for this repository."); } while (true) { if (!Filesystem::pathExists($local_path)) { execx('mkdir -p %s', dirname($local_path)); $this->executeCreate($repository, $local_path); } else { $this->executeUpdate($repository, $local_path); } $this->sleep($repository->getDetail('pull-frequency', 15)); } }
protected function executeQuery() { $drequest = $this->getRequest(); $repository = $drequest->getRepository(); $path = $drequest->getPath(); $commit = $drequest->getCommit(); $remote_uri = $repository->getDetail('remote-uri'); try { list($corpus) = execx('svn --non-interactive %s %s%s@%s', $this->getNeedsBlame() ? 'blame' : 'cat', $remote_uri, $path, $commit); } catch (CommandException $ex) { $stderr = $ex->getStdErr(); if (preg_match('/path not found$/', trim($stderr))) { // TODO: Improve user experience for this. One way to end up here // is to have the parser behind and look at a file which was recently // nuked; Diffusion will think it still exists and try to grab content // at HEAD. throw new Exception("Failed to retrieve file content from Subversion. The file may " . "have been recently deleted, or the Diffusion cache may be out of " . "date."); } else { throw $ex; } } $file_content = new DiffusionFileContent(); $file_content->setCorpus($corpus); return $file_content; }
function testTwoDeep() { $dir = PhutilDirectoryFixture::newEmptyFixture(); $root = realpath($dir->getPath()); $watch = $this->watch($root); $this->assertFileList($root, array()); $this->assertEqual(true, mkdir("{$root}/foo")); $this->assertEqual(true, mkdir("{$root}/foo/bar")); // Guarantee that 111's mtime is greater than its directory's sleep(1); $this->assertEqual(3, file_put_contents("{$root}/foo/bar/111", "111")); $this->watchmanCommand('log', 'debug', 'XXX: created 111'); $this->assertFileList($root, array("foo", "foo/bar", "foo/bar/111")); $query = $this->watchmanCommand('find', $root, 'foo/bar/111'); $wfile = $query['files'][0]; clearstatcache(); $sfile = stat("{$root}/foo/bar/111"); $query = $this->watchmanCommand('find', $root, 'foo/bar'); $wdir = $query['files'][0]; clearstatcache(); $sdir = stat("{$root}/foo/bar"); $this->watchmanCommand('log', 'debug', 'XXX: perform assertions'); $compare_fields = array('size', 'mode', 'uid', 'gid', 'ino', 'dev', 'nlink', 'mtime', 'ctime'); foreach ($compare_fields as $field) { $this->assertEqual($sfile[$field], $wfile[$field], "file: {$field} {$sfile[$field]} vs watchman {$wfile[$field]}"); $this->assertEqual($sdir[$field], $wdir[$field], "dir: {$field} {$sdir[$field]} vs watchman {$wdir[$field]}"); } $this->watchmanCommand('log', 'debug', 'XXX: remove it all'); execx('rm -rf %s', "{$root}/foo/bar"); $this->assertFileList($root, array("foo")); }
public function getPublicKey(PhabricatorUser $viewer, PassphraseCredential $credential) { $key = PassphraseSSHKey::loadFromPHID($credential->getPHID(), $viewer); $file = $key->getKeyfileEnvelope(); list($stdout) = execx('ssh-keygen -y -f %P', $file); return $stdout; }
public function testPasswords() { // Normal "%s" doesn't do anything special. $command = csprintf('echo %s', 'hunter2trustno1'); $this->assertTrue(strpos($command, 'hunter2trustno1') !== false); // "%P" takes a PhutilOpaqueEnvelope. $caught = null; try { csprintf('echo %P', 'hunter2trustno1'); } catch (Exception $ex) { $caught = $ex; } $this->assertTrue($caught instanceof Exception); // "%P" masks the provided value. $command = csprintf('echo %P', new PhutilOpaqueEnvelope('hunter2trustno1')); $this->assertFalse(strpos($command, 'hunter2trustno1')); // Executing the command works as expected. list($out) = execx('%C', $command); $this->assertTrue(strpos($out, 'hunter2trustno1') !== false); // Escaping should be robust even when used to escape commands which take // other commands. if (!phutil_is_windows()) { list($out) = execx('sh -c %s', csprintf('sh -c %s', csprintf('sh -c %s', csprintf('echo %P', new PhutilOpaqueEnvelope('!@#$%^&*()'))))); $this->assertTrue(strpos($out, '!@#$%^&*()') !== false); } }
public function run() { while (true) { execx('true'); $this->stillWorking(); } }
public function run() { $repository = $this->loadRepository(); if ($repository->getVersionControlSystem() != 'git') { throw new Exception("Not a git repository!"); } $tracked = $repository->getDetail('tracking-enabled'); if (!$tracked) { throw new Exception("Tracking is not enabled for this repository."); } $local_path = $repository->getDetail('local-path'); $remote_uri = $repository->getDetail('remote-uri'); if (!$local_path) { throw new Exception("No local path is available for this repository."); } while (true) { if (!Filesystem::pathExists($local_path)) { if (!$remote_uri) { throw new Exception("No remote URI is available."); } execx('mkdir -p %s', dirname($local_path)); execx('git clone %s %s', $remote_uri, rtrim($local_path, '/')); } else { execx('(cd %s && git fetch --all)', $local_path); } $this->sleep($repository->getDetail('pull-frequency', 15)); } }
protected function executeQuery() { $drequest = $this->getRequest(); $repository = $drequest->getRepository(); $path = $drequest->getPath(); $commit = $drequest->getCommit(); $local_path = $repository->getDetail('local-path'); if ($path == '') { // Fast path to improve the performance of the repository view; we know // the root is always a tree at any commit and always exists. $stdout = 'tree'; } else { try { list($stdout) = execx("(cd %s && git cat-file -t %s:%s)", $local_path, $commit, $path); } catch (CommandException $e) { $stderr = $e->getStdErr(); if (preg_match('/^fatal: Not a valid object name/', $stderr)) { // Grab two logs, since the first one is when the object was deleted. list($stdout) = execx('(cd %s && git log -n2 --format="%%H" %s -- %s)', $local_path, $commit, $path); $stdout = trim($stdout); if ($stdout) { $commits = explode("\n", $stdout); $this->reason = self::REASON_IS_DELETED; $this->deletedAtCommit = idx($commits, 0); $this->existedAtCommit = idx($commits, 1); return array(); } $this->reason = self::REASON_IS_NONEXISTENT; return array(); } else { throw $e; } } } if (trim($stdout) == 'blob') { $this->reason = self::REASON_IS_FILE; return array(); } if ($this->shouldOnlyTestValidity()) { return true; } list($stdout) = execx("(cd %s && git ls-tree -l %s:%s)", $local_path, $commit, $path); $results = array(); foreach (explode("\n", rtrim($stdout)) as $line) { list($mode, $type, $hash, $size, $name) = preg_split('/\\s+/', $line); if ($type == 'tree') { $file_type = DifferentialChangeType::FILE_DIRECTORY; } else { $file_type = DifferentialChangeType::FILE_NORMAL; } $result = new DiffusionRepositoryPath(); $result->setPath($name); $result->setHash($hash); $result->setFileType($file_type); $result->setFileSize($size); $results[] = $result; } return $results; }
protected function getVersion() { $cmd = csprintf('%s version', $this->getBinary()); list($stdout) = execx('%C', $cmd); $matches = array(); preg_match('/^go version go(?P<version>[0-9\\.]+).*/', $stdout, $matches); return $matches['version']; }
public function getVersion() { list($stdout, $stderr) = execx('%C --version', $this->getExecutableCommand()); $matches = null; if (preg_match('@HLint v(.*),@', $stdout, $matches)) { return $matches[1]; } return null; }
public function destroy() { PhabricatorLiskDAO::popStorageNamespace(); // NOTE: We need to close all connections before destroying the databases. // If we do not, the "DROP DATABASE ..." statements may hang, waiting for // our connections to close. PhabricatorLiskDAO::closeAllConnections(); execx('php %s destroy --force --namespace %s', $this->getStorageBinPath(), $this->name); }
public function saveToArchive($path) { $tmp = new TempFile(); execx('tar -C %s -czvvf %s .', $this->getPath(), $tmp); $ok = rename($tmp, Filesystem::resolvePath($path)); if (!$ok) { throw new FilesystemException($path, 'Failed to overwrite file.'); } return $this; }
public static function generateKeypair() { self::assertCanGenerateKeypair(); $tempfile = new TempFile(); $keyfile = dirname($tempfile) . DIRECTORY_SEPARATOR . 'keytext'; execx('ssh-keygen -t rsa -N %s -f %s', '', $keyfile); $public_key = Filesystem::readFile($keyfile . '.pub'); $private_key = Filesystem::readFile($keyfile); return array($public_key, $private_key); }
public function getVersion() { list($stdout) = execx('%C --version', $this->getExecutableCommand()); $matches = array(); if (preg_match('/^(?P<version>\\d+\\.\\d+\\.\\d+)$/', $stdout, $matches)) { return $matches['version']; } else { return false; } }
public function testEscapingIsRobust() { if (phutil_is_windows()) { $this->assertSkipped(pht("This test doesn't work on Windows.")); } // Escaping should be robust even when used to escape commands which take // other commands. list($out) = execx('sh -c %s', csprintf('sh -c %s', csprintf('sh -c %s', csprintf('echo %P', new PhutilOpaqueEnvelope('!@#$%^&*()'))))); $this->assertTrue(strpos($out, '!@#$%^&*()') !== false); }
public function getVersion() { list($stdout) = execx('%C --version', $this->getExecutableCommand()); $matches = array(); $regex = '/^PHP_CodeSniffer version (?P<version>\\d+\\.\\d+\\.\\d+)\\b/'; if (preg_match($regex, $stdout, $matches)) { return $matches['version']; } else { return false; } }
public function getVersion() { list($stdout) = execx('%C --version', $this->getExecutableCommand()); $matches = array(); $regex = '/^clang-format version (?P<version>\\S+)/'; if (preg_match($regex, $stdout, $matches)) { return $matches['version']; } else { return false; } }
public function getVersion() { list($stdout) = execx('%C version', $this->getExecutableCommand()); $pattern = '/^go version go(?P<version>\\d+\\.\\d+\\.\\d+).*$/'; $matches = array(); if (preg_match($pattern, $stdout, $matches)) { return $matches['version']; } else { return false; } }
public function getVersion() { // NOTE: `jshint --version` emits version information on stderr, not stdout. list($stdout, $stderr) = execx('%C --version', $this->getExecutableCommand()); $matches = array(); $regex = '/^jshint v(?P<version>\\d+\\.\\d+\\.\\d+)$/'; if (preg_match($regex, $stderr, $matches)) { return $matches['version']; } else { return false; } }
protected function executeQuery() { $drequest = $this->getRequest(); $repository = $drequest->getRepository(); list($hash) = execx("(cd %s && git log -n1 --format=%%H %s -- %s)", $repository->getDetail('local-path'), $drequest->getCommit(), $drequest->getPath()); $hash = trim($hash); $commit_data = null; $commit = id(new PhabricatorRepositoryCommit())->loadOneWhere('repositoryID = %d AND commitIdentifier = %s', $repository->getID(), $hash); if ($commit) { $commit_data = id(new PhabricatorRepositoryCommitData())->loadOneWhere('commitID = %d', $commit->getID()); } return array($commit, $commit_data); }
protected function executeQuery() { $drequest = $this->getRequest(); $repository = $drequest->getRepository(); $path = $drequest->getPath(); $commit_hash = $drequest->getCommit(); $local_path = $repository->getDetail('local-path'); list($stdout) = execx('(cd %s && git log ' . '--skip=%d ' . '-n %d ' . '--abbrev=40 ' . '--pretty=format:%%H ' . '%s -- %s)', $local_path, $this->getOffset(), $this->getLimit(), $commit_hash, $path); $hashes = explode("\n", $stdout); $hashes = array_filter($hashes); $commits = array(); $commit_data = array(); $path_changes = array(); $conn_r = $repository->establishConnection('r'); if ($hashes) { $commits = id(new PhabricatorRepositoryCommit())->loadAllWhere('repositoryID = %d AND commitIdentifier IN (%Ls)', $repository->getID(), $hashes); $commits = mpull($commits, null, 'getCommitIdentifier'); if ($commits) { $commit_data = id(new PhabricatorRepositoryCommitData())->loadAllWhere('commitID in (%Ld)', mpull($commits, 'getID')); $commit_data = mpull($commit_data, null, 'getCommitID'); } if ($commits) { $path_normal = '/' . trim($path, '/'); $paths = queryfx_all($conn_r, 'SELECT id, path FROM %T WHERE path IN (%Ls)', PhabricatorRepository::TABLE_PATH, array($path_normal)); $paths = ipull($paths, 'id', 'path'); $path_id = idx($paths, $path_normal); $path_changes = queryfx_all($conn_r, 'SELECT * FROM %T WHERE commitID IN (%Ld) AND pathID = %d', PhabricatorRepository::TABLE_PATHCHANGE, mpull($commits, 'getID'), $path_id); $path_changes = ipull($path_changes, null, 'commitID'); } } $history = array(); foreach ($hashes as $hash) { $item = new DiffusionPathChange(); $item->setCommitIdentifier($hash); $commit = idx($commits, $hash); if ($commit) { $item->setCommit($commit); $data = idx($commit_data, $commit->getID()); if ($data) { $item->setCommitData($data); } $change = idx($path_changes, $commit->getID()); if ($change) { $item->setChangeType($change['changeType']); $item->setFileType($change['fileType']); } } $history[] = $item; } return $history; }
protected function executeQuery() { $drequest = $this->getRequest(); $repository = $drequest->getRepository(); $local_path = $repository->getDetail('local-path'); list($stdout) = execx('(cd %s && git branch -r --verbose --no-abbrev)', $local_path); $branches = array(); foreach (self::parseGitRemoteBranchOutput($stdout) as $name => $head) { $branch = new DiffusionBranchInformation(); $branch->setName($name); $branch->setHeadCommitIdentifier($head); $branches[] = $branch; } return $branches; }
/** * 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 run() { $working_copy = $this->getWorkingCopy(); if (!$working_copy->getProjectID()) { throw new ArcanistUsageException("You have installed a git pre-receive hook in a remote without an " . ".arcconfig."); } // Git repositories have special rules in pre-receive hooks. We need to // construct the API against the .git directory instead of the project // root or commands don't work properly. $repository_api = ArcanistGitAPI::newHookAPI($_SERVER['PWD']); $root = $working_copy->getProjectRoot(); $parser = new ArcanistDiffParser(); $mark_revisions = array(); $stdin = file_get_contents('php://stdin'); $commits = array_filter(explode("\n", $stdin)); foreach ($commits as $commit) { list($old_ref, $new_ref, $refname) = explode(' ', $commit); list($log) = execx('(cd %s && git log -n1 %s)', $repository_api->getPath(), $new_ref); $message_log = reset($parser->parseDiff($log)); $message = ArcanistDifferentialCommitMessage::newFromRawCorpus($message_log->getMetadata('message')); $revision_id = $message->getRevisionID(); if ($revision_id) { $mark_revisions[] = $revision_id; } // TODO: Do commit message junk. $info = $repository_api->getPreReceiveHookStatus($old_ref, $new_ref); $paths = ipull($info, 'mask'); $frefs = ipull($info, 'ref'); $data = array(); foreach ($paths as $path => $mask) { list($stdout) = execx('(cd %s && git cat-file blob %s)', $repository_api->getPath(), $frefs[$path]); $data[$path] = $stdout; } // TODO: Do commit content junk. $commit_name = $new_ref; if ($revision_id) { $commit_name = 'D' . $revision_id . ' (' . $commit_name . ')'; } echo "[arc pre-receive] {$commit_name} OK...\n"; } $conduit = $this->getConduit(); $futures = array(); foreach ($mark_revisions as $revision_id) { $futures[] = $conduit->callMethod('differential.close', array('revisionID' => $revision_id)); } Futures($futures)->resolveAll(); return 0; }
protected function executeQuery() { $drequest = $this->getRequest(); $repository = $drequest->getRepository(); $path = $drequest->getPath(); $commit = $drequest->getCommit(); $local_path = $repository->getDetail('local-path'); if ($this->getNeedsBlame()) { list($corpus) = execx('(cd %s && git --no-pager blame -c -l --date=short %s -- %s)', $local_path, $commit, $path); } else { list($corpus) = execx('(cd %s && git cat-file blob %s:%s)', $local_path, $commit, $path); } $file_content = new DiffusionFileContent(); $file_content->setCorpus($corpus); return $file_content; }
/** * 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; }
protected function discoverCommits() { $repository = $this->getRepository(); $vcs = $repository->getVersionControlSystem(); if ($vcs != PhabricatorRepositoryType::REPOSITORY_TYPE_SVN) { throw new Exception("Repository is not a svn repository."); } $uri = $this->getBaseSVNLogURI(); list($xml) = execx('svn log --xml --non-interactive --quiet --limit 1 %s@HEAD', $uri); $results = $this->parseSVNLogXML($xml); $commit = key($results); $epoch = reset($results); if ($this->isKnownCommit($commit)) { return false; } $this->discoverCommit($commit, $epoch); return true; }
private function applyMemeToFile(PhabricatorFile $file, $upper_text, $lower_text) { $data = $file->loadFileData(); $img_type = $file->getMimeType(); $imagemagick = PhabricatorEnv::getEnvConfig('files.enable-imagemagick'); if ($img_type != 'image/gif' || $imagemagick == false) { return $this->applyMemeTo($data, $upper_text, $lower_text, $img_type); } $data = $file->loadFileData(); $input = new TempFile(); Filesystem::writeFile($input, $data); list($out) = execx('convert %s info:', $input); $split = phutil_split_lines($out); if (count($split) > 1) { return $this->applyMemeWithImagemagick($input, $upper_text, $lower_text, count($split), $img_type); } else { return $this->applyMemeTo($data, $upper_text, $lower_text, $img_type); } }
public function parseCommit(PhabricatorRepository $repository, PhabricatorRepositoryCommit $commit) { $local_path = $repository->getDetail('local-path'); // NOTE: %B was introduced somewhat recently in git's history, so pull // commit message information with %s and %b instead. list($info) = execx('(cd %s && git log -n 1 --pretty=format:%%an%%x00%%s%%n%%n%%b %s)', $local_path, $commit->getCommitIdentifier()); list($author, $message) = explode("", $info); // Make sure these are valid UTF-8. $author = phutil_utf8ize($author); $message = phutil_utf8ize($message); $message = trim($message); $this->updateCommitData($author, $message); if ($this->shouldQueueFollowupTasks()) { $task = new PhabricatorWorkerTask(); $task->setTaskClass('PhabricatorRepositoryGitCommitChangeParserWorker'); $task->setData(array('commitID' => $commit->getID())); $task->save(); } }