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;
 }
예제 #4
0
 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;
 }
예제 #10
0
 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'];
 }
예제 #11
0
 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;
     }
 }
예제 #19
0
 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;
     }
 }
예제 #20
0
 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;
 }
예제 #24
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 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;
 }
예제 #27
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;
 }
 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();
     }
 }