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;
 }
 protected function executeQueryFromFuture(Future $future)
 {
     list($corpus) = $future->resolvex();
     $file_content = new DiffusionFileContent();
     $file_content->setCorpus($corpus);
     return $file_content;
 }
 public final function loadFileContentFromFuture(Future $future)
 {
     if ($this->timeout) {
         $future->setTimeout($this->timeout);
     }
     if ($this->getByteLimit()) {
         $future->setStdoutSizeLimit($this->getByteLimit());
     }
     try {
         $file_content = $this->executeQueryFromFuture($future);
     } catch (CommandException $ex) {
         if (!$future->getWasKilledByTimeout()) {
             throw $ex;
         }
         $message = pht('<Attempt to load this file was terminated after %s second(s).>', $this->timeout);
         $file_content = new DiffusionFileContent();
         $file_content->setCorpus($message);
     }
     $this->fileContent = $file_content;
     $repository = $this->getRequest()->getRepository();
     $try_encoding = $repository->getDetail('encoding');
     if ($try_encoding) {
         $this->fileContent->setCorpus(phutil_utf8_convert($this->fileContent->getCorpus(), 'UTF-8', $try_encoding));
     }
     return $this->fileContent;
 }
 protected function executeQuery()
 {
     $drequest = $this->getRequest();
     $repository = $drequest->getRepository();
     $path = $drequest->getPath();
     $commit = $drequest->getCommit();
     list($corpus) = $repository->execxLocalCommand('cat --rev %s -- %s', $commit, $path);
     $file_content = new DiffusionFileContent();
     $file_content->setCorpus($corpus);
     return $file_content;
 }
 protected function executeQuery()
 {
     $drequest = $this->getRequest();
     $repository = $drequest->getRepository();
     $path = $drequest->getPath();
     $commit = $drequest->getCommit();
     if ($this->getNeedsBlame()) {
         list($corpus) = $repository->execxLocalCommand('--no-pager blame -c -l --date=short %s -- %s', $commit, $path);
     } else {
         list($corpus) = $repository->execxLocalCommand('cat-file blob %s:%s', $commit, $path);
     }
     $file_content = new DiffusionFileContent();
     $file_content->setCorpus($corpus);
     return $file_content;
 }
 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;
 }
 protected function executeQuery()
 {
     $drequest = $this->getRequest();
     $repository = $drequest->getRepository();
     $path = $drequest->getPath();
     $commit = $drequest->getCommit();
     if ($this->getNeedsBlame()) {
         // NOTE: We're using "--number" instead of "--changeset" because there is
         // no way to get "--changeset" to show us the full commit hashes.
         list($corpus) = $repository->execxLocalCommand('annotate --user --number --rev %s -- %s', $commit, $path);
     } else {
         list($corpus) = $repository->execxLocalCommand('cat --rev %s -- %s', $commit, $path);
     }
     $file_content = new DiffusionFileContent();
     $file_content->setCorpus($corpus);
     return $file_content;
 }
 protected function executeQueryFromFuture(Future $future)
 {
     try {
         list($corpus) = $future->resolvex();
     } 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(pht('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;
 }
 protected function getResult(ConduitAPIRequest $request)
 {
     $drequest = $this->getDiffusionRequest();
     $path_dicts = $request->getValue('paths', array());
     $paths = array();
     foreach ($path_dicts as $dict) {
         $paths[] = DiffusionRepositoryPath::newFromDictionary($dict);
     }
     $best = -1;
     $readme = '';
     $best_render_type = 'plain';
     foreach ($paths as $result_path) {
         $file_type = $result_path->getFileType();
         if ($file_type != ArcanistDiffChangeType::FILE_NORMAL && $file_type != ArcanistDiffChangeType::FILE_TEXT) {
             // Skip directories, etc.
             continue;
         }
         $path = strtolower($result_path->getPath());
         if ($path === 'readme') {
             $path .= '.remarkup';
         }
         if (strncmp($path, 'readme.', 7) !== 0) {
             continue;
         }
         $priority = 0;
         switch (substr($path, 7)) {
             case 'remarkup':
                 $priority = 100;
                 $render_type = 'remarkup';
                 break;
             case 'rainbow':
                 $priority = 90;
                 $render_type = 'rainbow';
                 break;
             case 'md':
                 $priority = 50;
                 $render_type = 'remarkup';
                 break;
             case 'txt':
                 $priority = 10;
                 $render_type = 'plain';
                 break;
             default:
                 $priority = 0;
                 $render_type = 'plain';
                 break;
         }
         if ($priority > $best) {
             $best = $priority;
             $readme = $result_path;
             $best_render_type = $render_type;
         }
     }
     if (!$readme) {
         return '';
     }
     $readme_request = DiffusionRequest::newFromDictionary(array('user' => $request->getUser(), 'repository' => $drequest->getRepository(), 'commit' => $drequest->getStableCommit(), 'path' => $readme->getFullPath()));
     $file_content = DiffusionFileContent::newFromConduit(DiffusionQuery::callConduitWithDiffusionRequest($request->getUser(), $readme_request, 'diffusion.filecontentquery', array('commit' => $drequest->getStableCommit(), 'path' => $readme->getFullPath(), 'needsBlame' => false)));
     $readme_content = $file_content->getCorpus();
     switch ($best_render_type) {
         case 'plain':
             $readme_content = phutil_escape_html_newlines($readme_content);
             $class = null;
             break;
         case 'rainbow':
             $highlighter = new PhutilRainbowSyntaxHighlighter();
             $readme_content = $highlighter->getHighlightFuture($readme_content)->resolve();
             $readme_content = phutil_escape_html_newlines($readme_content);
             require_celerity_resource('syntax-highlighting-css');
             $class = 'remarkup-code';
             break;
         case 'remarkup':
             // TODO: This is sketchy, but make sure we hit the markup cache.
             $markup_object = id(new PhabricatorMarkupOneOff())->setEngineRuleset('diffusion-readme')->setContent($readme_content);
             $markup_field = 'default';
             $readme_content = id(new PhabricatorMarkupEngine())->setViewer($request->getUser())->addObject($markup_object, $markup_field)->process()->getOutput($markup_object, $markup_field);
             $engine = $markup_object->newMarkupEngine($markup_field);
             $toc = PhutilRemarkupHeaderBlockRule::renderTableOfContents($engine);
             if ($toc) {
                 $toc = phutil_tag_div('phabricator-remarkup-toc', array(phutil_tag_div('phabricator-remarkup-toc-header', pht('Table of Contents')), $toc));
                 $readme_content = array($toc, $readme_content);
             }
             $class = 'phabricator-remarkup';
             break;
     }
     $readme_content = phutil_tag('div', array('class' => $class), $readme_content);
     return $readme_content;
 }
 private function buildCorpus($show_blame, $show_color, DiffusionFileContent $file_content, $needs_blame, DiffusionRequest $drequest, $path, $data)
 {
     if (!$show_color) {
         $style = 'border: none; width: 100%; height: 80em; font-family: monospace';
         if (!$show_blame) {
             $corpus = phutil_tag('textarea', array('style' => $style), $file_content->getCorpus());
         } else {
             $text_list = $file_content->getTextList();
             $rev_list = $file_content->getRevList();
             $blame_dict = $file_content->getBlameDict();
             $rows = array();
             foreach ($text_list as $k => $line) {
                 $rev = $rev_list[$k];
                 $author = $blame_dict[$rev]['author'];
                 $rows[] = sprintf('%-10s %-20s %s', substr($rev, 0, 7), $author, $line);
             }
             $corpus = phutil_tag('textarea', array('style' => $style), implode("\n", $rows));
         }
     } else {
         require_celerity_resource('syntax-highlighting-css');
         $text_list = $file_content->getTextList();
         $rev_list = $file_content->getRevList();
         $blame_dict = $file_content->getBlameDict();
         $text_list = implode("\n", $text_list);
         $text_list = PhabricatorSyntaxHighlighter::highlightWithFilename($path, $text_list);
         $text_list = explode("\n", $text_list);
         $rows = $this->buildDisplayRows($text_list, $rev_list, $blame_dict, $needs_blame, $drequest, $show_blame, $show_color);
         $corpus_table = javelin_tag('table', array('class' => 'diffusion-source remarkup-code PhabricatorMonospaced', 'sigil' => 'phabricator-source'), $rows);
         if ($this->getRequest()->isAjax()) {
             return $corpus_table;
         }
         $id = celerity_generate_unique_node_id();
         $repo = $drequest->getRepository();
         $symbol_repos = nonempty($repo->getSymbolSources(), array());
         $symbol_repos[] = $repo;
         $lang = last(explode('.', $drequest->getPath()));
         $repo_languages = $repo->getSymbolLanguages();
         $repo_languages = nonempty($repo_languages, array());
         $repo_languages = array_fill_keys($repo_languages, true);
         $needs_symbols = true;
         if ($repo_languages && $symbol_repos) {
             $have_symbols = id(new DiffusionSymbolQuery())->existsSymbolsInRepository($repo->getPHID());
             if (!$have_symbols) {
                 $needs_symbols = false;
             }
         }
         if ($needs_symbols && $repo_languages) {
             $needs_symbols = isset($repo_languages[$lang]);
         }
         if ($needs_symbols) {
             Javelin::initBehavior('repository-crossreference', array('container' => $id, 'lang' => $lang, 'repositories' => $symbol_repos));
         }
         $corpus = phutil_tag('div', array('id' => $id), $corpus_table);
         Javelin::initBehavior('load-blame', array('id' => $id));
     }
     $edit = $this->renderEditButton();
     $file = $this->renderFileButton();
     $header = id(new PHUIHeaderView())->setHeader(pht('File Contents'))->addActionLink($edit)->addActionLink($file);
     $corpus = id(new PHUIObjectBoxView())->setHeader($header)->appendChild($corpus);
     return $corpus;
 }
 private function buildCorpus($show_blame, $show_color, DiffusionFileContent $file_content, $needs_blame, DiffusionRequest $drequest, $path, $data)
 {
     $viewer = $this->getViewer();
     $blame_timeout = 15;
     $blame_failed = false;
     $file_corpus = $file_content->getCorpus();
     $highlight_limit = DifferentialChangesetParser::HIGHLIGHT_BYTE_LIMIT;
     $blame_limit = DifferentialChangesetParser::HIGHLIGHT_BYTE_LIMIT;
     $can_highlight = strlen($file_corpus) <= $highlight_limit;
     $can_blame = strlen($file_corpus) <= $blame_limit;
     if ($needs_blame && $can_blame) {
         $blame = $this->loadBlame($path, $drequest->getCommit(), $blame_timeout);
         list($blame_list, $blame_commits) = $blame;
         if ($blame_list === null) {
             $blame_failed = true;
             $blame_list = array();
         }
     } else {
         $blame_list = array();
         $blame_commits = array();
     }
     if (!$show_color) {
         $corpus = $this->renderPlaintextCorpus($file_corpus, $blame_list, $blame_commits, $show_blame);
     } else {
         if ($can_highlight) {
             require_celerity_resource('syntax-highlighting-css');
             $highlighted = PhabricatorSyntaxHighlighter::highlightWithFilename($path, $file_corpus);
             $lines = phutil_split_lines($highlighted);
         } else {
             $lines = phutil_split_lines($file_corpus);
         }
         $rows = $this->buildDisplayRows($lines, $blame_list, $blame_commits, $show_blame, $show_color);
         $corpus_table = javelin_tag('table', array('class' => 'diffusion-source remarkup-code PhabricatorMonospaced', 'sigil' => 'phabricator-source'), $rows);
         if ($this->getRequest()->isAjax()) {
             return $corpus_table;
         }
         $id = celerity_generate_unique_node_id();
         $repo = $drequest->getRepository();
         $symbol_repos = nonempty($repo->getSymbolSources(), array());
         $symbol_repos[] = $repo->getPHID();
         $lang = last(explode('.', $drequest->getPath()));
         $repo_languages = $repo->getSymbolLanguages();
         $repo_languages = nonempty($repo_languages, array());
         $repo_languages = array_fill_keys($repo_languages, true);
         $needs_symbols = true;
         if ($repo_languages && $symbol_repos) {
             $have_symbols = id(new DiffusionSymbolQuery())->existsSymbolsInRepository($repo->getPHID());
             if (!$have_symbols) {
                 $needs_symbols = false;
             }
         }
         if ($needs_symbols && $repo_languages) {
             $needs_symbols = isset($repo_languages[$lang]);
         }
         if ($needs_symbols) {
             Javelin::initBehavior('repository-crossreference', array('container' => $id, 'lang' => $lang, 'repositories' => $symbol_repos));
         }
         $corpus = phutil_tag('div', array('id' => $id), $corpus_table);
         Javelin::initBehavior('load-blame', array('id' => $id));
     }
     $edit = $this->renderEditButton();
     $file = $this->renderFileButton();
     $header = id(new PHUIHeaderView())->setHeader(pht('File Contents'))->addActionLink($edit)->addActionLink($file);
     $corpus = id(new PHUIObjectBoxView())->setHeader($header)->appendChild($corpus)->setCollapsed(true);
     $messages = array();
     if (!$can_highlight) {
         $messages[] = pht('This file is larger than %s, so syntax highlighting is disabled ' . 'by default.', phutil_format_bytes($highlight_limit));
     }
     if ($show_blame && !$can_blame) {
         $messages[] = pht('This file is larger than %s, so blame is disabled.', phutil_format_bytes($blame_limit));
     }
     if ($blame_failed) {
         $messages[] = pht('Failed to load blame information for this file in %s second(s).', new PhutilNumber($blame_timeout));
     }
     if ($messages) {
         $corpus->setInfoView(id(new PHUIInfoView())->setSeverity(PHUIInfoView::SEVERITY_WARNING)->setErrors($messages));
     }
     return $corpus;
 }