public function handleRequest(AphrontRequest $request) { $response = $this->loadDiffusionContext(); if ($response) { return $response; } $viewer = $this->getViewer(); $drequest = $this->getDiffusionRequest(); $content = array(); $data = $this->callConduitWithDiffusionRequest('diffusion.diffquery', array('commit' => $drequest->getCommit(), 'path' => $drequest->getPath())); $drequest->updateSymbolicCommit($data['effectiveCommit']); $raw_changes = ArcanistDiffChange::newFromConduit($data['changes']); $diff = DifferentialDiff::newEphemeralFromRawChanges($raw_changes); $changesets = $diff->getChangesets(); $changeset = reset($changesets); if (!$changeset) { // TODO: Refine this. return new Aphront404Response(); } $repository = $drequest->getRepository(); $changesets = array(0 => $changeset); $changeset_view = new DifferentialChangesetListView(); $changeset_view->setTitle(pht('Change')); $changeset_view->setChangesets($changesets); $changeset_view->setVisibleChangesets($changesets); $changeset_view->setRenderingReferences(array(0 => $drequest->generateURI(array('action' => 'rendering-ref')))); $raw_params = array('action' => 'browse', 'params' => array('view' => 'raw')); $right_uri = $drequest->generateURI($raw_params); $raw_params['params']['before'] = $drequest->getStableCommit(); $left_uri = $drequest->generateURI($raw_params); $changeset_view->setRawFileURIs($left_uri, $right_uri); $changeset_view->setRenderURI($repository->getPathURI('diff/')); $changeset_view->setWhitespace(DifferentialChangesetParser::WHITESPACE_SHOW_ALL); $changeset_view->setUser($viewer); // TODO: This is pretty awkward, unify the CSS between Diffusion and // Differential better. require_celerity_resource('differential-core-view-css'); $content[] = $changeset_view->render(); $crumbs = $this->buildCrumbs(array('branch' => true, 'path' => true, 'view' => 'change')); $links = $this->renderPathLinks($drequest, $mode = 'browse'); $header = id(new PHUIHeaderView())->setHeader($links)->setUser($viewer)->setPolicyObject($drequest->getRepository()); $actions = $this->buildActionView($drequest); $properties = $this->buildPropertyView($drequest, $actions); $object_box = id(new PHUIObjectBoxView())->setHeader($header)->addPropertyList($properties); return $this->newPage()->setTitle(array(basename($drequest->getPath()), $repository->getDisplayName()))->setCrumbs($crumbs)->appendChild(array($object_box, $content)); }
public function buildPatch() { $diff = new DifferentialDiff(); $diff->attachChangesets($this->getChangesets()); $raw_changes = $diff->buildChangesList(); $changes = array(); foreach ($raw_changes as $changedict) { $changes[] = ArcanistDiffChange::newFromDictionary($changedict); } $viewer = $this->getViewer(); $loader = id(new PhabricatorFileBundleLoader())->setViewer($viewer); $bundle = ArcanistBundle::newFromChanges($changes); $bundle->setLoadFileDataCallback(array($loader, 'loadFileData')); $format = $this->getFormat(); switch ($format) { case 'git': return $bundle->toGitPatch(); break; case 'unified': default: return $bundle->toUnifiedDiff(); break; } }
/** * Note this code is somewhat similar to the buildPatch method in * @{class:DifferentialReviewRequestMail}. * * @return @{class:AphrontRedirectResponse} */ private function buildRawDiffResponse(DifferentialRevision $revision, array $changesets, array $vs_changesets, array $vs_map, PhabricatorRepository $repository = null) { assert_instances_of($changesets, 'DifferentialChangeset'); assert_instances_of($vs_changesets, 'DifferentialChangeset'); $viewer = $this->getRequest()->getUser(); id(new DifferentialHunkQuery())->setViewer($viewer)->withChangesets($changesets)->needAttachToChangesets(true)->execute(); $diff = new DifferentialDiff(); $diff->attachChangesets($changesets); $raw_changes = $diff->buildChangesList(); $changes = array(); foreach ($raw_changes as $changedict) { $changes[] = ArcanistDiffChange::newFromDictionary($changedict); } $loader = id(new PhabricatorFileBundleLoader())->setViewer($viewer); $bundle = ArcanistBundle::newFromChanges($changes); $bundle->setLoadFileDataCallback(array($loader, 'loadFileData')); $vcs = $repository ? $repository->getVersionControlSystem() : null; switch ($vcs) { case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: $raw_diff = $bundle->toGitPatch(); break; case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: default: $raw_diff = $bundle->toUnifiedDiff(); break; } $request_uri = $this->getRequest()->getRequestURI(); // this ends up being something like // D123.diff // or the verbose // D123.vs123.id123.whitespaceignore-all.diff // lame but nice to include these options $file_name = ltrim($request_uri->getPath(), '/') . '.'; foreach ($request_uri->getQueryParams() as $key => $value) { if ($key == 'download') { continue; } $file_name .= $key . $value . '.'; } $file_name .= 'diff'; $file = PhabricatorFile::buildFromFileDataOrHash($raw_diff, array('name' => $file_name, 'ttl' => 60 * 60 * 24, 'viewPolicy' => PhabricatorPolicies::POLICY_NOONE)); $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $file->attachToObject($revision->getPHID()); unset($unguarded); return $file->getRedirectResponse(); }
public static final function convertToArcanistChanges(array $changes) { assert_instances_of($changes, 'DiffusionPathChange'); $direct = array(); $result = array(); foreach ($changes as $path) { $change = new ArcanistDiffChange(); $change->setCurrentPath($path->getPath()); $direct[] = $path->getPath(); $change->setType($path->getChangeType()); $file_type = $path->getFileType(); if ($file_type == DifferentialChangeType::FILE_NORMAL) { $file_type = DifferentialChangeType::FILE_TEXT; } $change->setFileType($file_type); $change->setOldPath($path->getTargetPath()); foreach ($path->getAwayPaths() as $away_path) { $change->addAwayPath($away_path); } $result[$path->getPath()] = $change; } return array_select_keys($result, $direct); }
protected function getChange($path) { $repository_api = $this->getRepositoryAPI(); // TODO: Very gross $is_git = $repository_api instanceof ArcanistGitAPI; $is_hg = $repository_api instanceof ArcanistMercurialAPI; $is_svn = $repository_api instanceof ArcanistSubversionAPI; if ($is_svn) { // NOTE: In SVN, we don't currently support a "get all local changes" // operation, so special case it. if (empty($this->changeCache[$path])) { $diff = $repository_api->getRawDiffText($path); $parser = $this->newDiffParser(); $changes = $parser->parseDiff($diff); if (count($changes) != 1) { throw new Exception("Expected exactly one change."); } $this->changeCache[$path] = reset($changes); } } else { if ($is_git || $is_hg) { if (empty($this->changeCache)) { $changes = $repository_api->getAllLocalChanges(); foreach ($changes as $change) { $this->changeCache[$change->getCurrentPath()] = $change; } } } else { throw new Exception("Missing VCS support."); } } if (empty($this->changeCache[$path])) { if ($is_git) { // This can legitimately occur under git if you make a change, "git // commit" it, and then revert the change in the working copy and run // "arc lint". $change = new ArcanistDiffChange(); $change->setCurrentPath($path); return $change; } else { throw new Exception("Trying to get change for unchanged path '{$path}'!"); } } return $this->changeCache[$path]; }
protected function execute(ConduitAPIRequest $request) { $viewer = $request->getUser(); $change_data = $request->getValue('changes'); $changes = array(); foreach ($change_data as $dict) { $changes[] = ArcanistDiffChange::newFromDictionary($dict); } $diff = DifferentialDiff::newFromRawChanges($viewer, $changes); // TODO: Remove repository UUID eventually; for now continue writing // the UUID. Note that we'll overwrite it below if we identify a // repository, and `arc` no longer sends it. This stuff is retained for // backward compatibility. $repository_uuid = $request->getValue('repositoryUUID'); $repository_phid = $request->getValue('repositoryPHID'); if ($repository_phid) { $repository = id(new PhabricatorRepositoryQuery())->setViewer($viewer)->withPHIDs(array($repository_phid))->executeOne(); if ($repository) { $repository_phid = $repository->getPHID(); $repository_uuid = $repository->getUUID(); } } switch ($request->getValue('lintStatus')) { case 'skip': $lint_status = DifferentialLintStatus::LINT_SKIP; break; case 'okay': $lint_status = DifferentialLintStatus::LINT_OKAY; break; case 'warn': $lint_status = DifferentialLintStatus::LINT_WARN; break; case 'fail': $lint_status = DifferentialLintStatus::LINT_FAIL; break; case 'postponed': $lint_status = DifferentialLintStatus::LINT_POSTPONED; break; case 'none': default: $lint_status = DifferentialLintStatus::LINT_NONE; break; } switch ($request->getValue('unitStatus')) { case 'skip': $unit_status = DifferentialUnitStatus::UNIT_SKIP; break; case 'okay': $unit_status = DifferentialUnitStatus::UNIT_OKAY; break; case 'warn': $unit_status = DifferentialUnitStatus::UNIT_WARN; break; case 'fail': $unit_status = DifferentialUnitStatus::UNIT_FAIL; break; case 'postponed': $unit_status = DifferentialUnitStatus::UNIT_POSTPONED; break; case 'none': default: $unit_status = DifferentialUnitStatus::UNIT_NONE; break; } $diff_data_dict = array('sourcePath' => $request->getValue('sourcePath'), 'sourceMachine' => $request->getValue('sourceMachine'), 'branch' => $request->getValue('branch'), 'creationMethod' => $request->getValue('creationMethod'), 'authorPHID' => $viewer->getPHID(), 'bookmark' => $request->getValue('bookmark'), 'repositoryUUID' => $repository_uuid, 'repositoryPHID' => $repository_phid, 'sourceControlSystem' => $request->getValue('sourceControlSystem'), 'sourceControlPath' => $request->getValue('sourceControlPath'), 'sourceControlBaseRevision' => $request->getValue('sourceControlBaseRevision'), 'lintStatus' => $lint_status, 'unitStatus' => $unit_status); $xactions = array(id(new DifferentialTransaction())->setTransactionType(DifferentialDiffTransaction::TYPE_DIFF_CREATE)->setNewValue($diff_data_dict)); id(new DifferentialDiffEditor())->setActor($viewer)->setContentSourceFromConduitRequest($request)->setContinueOnNoEffect(true)->applyTransactions($diff, $xactions); $path = '/differential/diff/' . $diff->getID() . '/'; $uri = PhabricatorEnv::getURI($path); return array('diffid' => $diff->getID(), 'phid' => $diff->getPHID(), 'uri' => $uri); }
/** * Note this code is somewhat similar to the buildPatch method in * @{class:DifferentialReviewRequestMail}. * * @return @{class:AphrontRedirectResponse} */ private function buildRawDiffResponse(array $changesets, array $vs_changesets, array $vs_map, PhabricatorRepository $repository = null) { assert_instances_of($changesets, 'DifferentialChangeset'); assert_instances_of($vs_changesets, 'DifferentialChangeset'); $engine = new PhabricatorDifferenceEngine(); $generated_changesets = array(); foreach ($changesets as $changeset) { $changeset->attachHunks($changeset->loadHunks()); $right = $changeset->makeNewFile(); $choice = $changeset; $vs = idx($vs_map, $changeset->getID()); if ($vs == -1) { $left = $right; $right = $changeset->makeOldFile(); } else { if ($vs) { $choice = $vs_changeset = $vs_changesets[$vs]; $vs_changeset->attachHunks($vs_changeset->loadHunks()); $left = $vs_changeset->makeNewFile(); } else { $left = $changeset->makeOldFile(); } } $synthetic = $engine->generateChangesetFromFileContent($left, $right); if (!$synthetic->getAffectedLineCount()) { $filetype = $choice->getFileType(); if ($filetype == DifferentialChangeType::FILE_TEXT || $filetype == DifferentialChangeType::FILE_SYMLINK) { continue; } } $choice->attachHunks($synthetic->getHunks()); $generated_changesets[] = $choice; } $diff = new DifferentialDiff(); $diff->attachChangesets($generated_changesets); $diff_dict = $diff->getDiffDict(); $changes = array(); foreach ($diff_dict['changes'] as $changedict) { $changes[] = ArcanistDiffChange::newFromDictionary($changedict); } $bundle = ArcanistBundle::newFromChanges($changes); $bundle->setLoadFileDataCallback(array($this, 'loadFileByPHID')); $vcs = $repository ? $repository->getVersionControlSystem() : null; switch ($vcs) { case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: $raw_diff = $bundle->toGitPatch(); break; case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: default: $raw_diff = $bundle->toUnifiedDiff(); break; } $request_uri = $this->getRequest()->getRequestURI(); // this ends up being something like // D123.diff // or the verbose // D123.vs123.id123.whitespaceignore-all.diff // lame but nice to include these options $file_name = ltrim($request_uri->getPath(), '/') . '.'; foreach ($request_uri->getQueryParams() as $key => $value) { if ($key == 'download') { continue; } $file_name .= $key . $value . '.'; } $file_name .= 'diff'; $file = PhabricatorFile::buildFromFileDataOrHash($raw_diff, array('name' => $file_name)); return id(new AphrontRedirectResponse())->setURI($file->getBestURI()); }
protected function buildChange($path = null) { $change = null; if ($path !== null) { if (!empty($this->changes[$path])) { return $this->changes[$path]; } } if ($this->forcePath) { return $this->changes[$this->forcePath]; } $change = new ArcanistDiffChange(); if ($path !== null) { $change->setCurrentPath($path); $this->changes[$path] = $change; } else { $this->changes[] = $change; } return $change; }
private function buildBinaryChange(ArcanistDiffChange $change, $old_binary) { $eol = $this->getEOL('git'); // In Git, when we write out a binary file move or copy, we need the // original binary for the source and the current binary for the // destination. if ($old_binary) { if ($old_binary->getOriginalFileData() !== null) { $old_data = $old_binary->getOriginalFileData(); $old_phid = null; } else { $old_data = null; $old_phid = $old_binary->getMetadata('old:binary-phid'); } } else { $old_data = $change->getOriginalFileData(); $old_phid = $change->getMetadata('old:binary-phid'); } if ($old_data === null && $old_phid) { $name = basename($change->getOldPath()); $old_data = $this->getBlob($old_phid, $name); } $old_length = strlen($old_data); if ($old_data === null) { $old_data = ''; $old_sha1 = str_repeat('0', 40); } else { $old_sha1 = sha1("blob {$old_length}{$old_data}"); } $new_phid = $change->getMetadata('new:binary-phid'); $new_data = null; if ($change->getCurrentFileData() !== null) { $new_data = $change->getCurrentFileData(); } else { if ($new_phid) { $name = basename($change->getCurrentPath()); $new_data = $this->getBlob($new_phid, $name); } } $new_length = strlen($new_data); if ($new_data === null) { $new_data = ''; $new_sha1 = str_repeat('0', 40); } else { $new_sha1 = sha1("blob {$new_length}{$new_data}"); } $content = array(); $content[] = "index {$old_sha1}..{$new_sha1}" . $eol; $content[] = "GIT binary patch" . $eol; $content[] = "literal {$new_length}" . $eol; $content[] = $this->emitBinaryDiffBody($new_data) . $eol; $content[] = "literal {$old_length}" . $eol; $content[] = $this->emitBinaryDiffBody($old_data) . $eol; return implode('', $content); }
protected function buildAttachments() { $attachments = array(); if (PhabricatorEnv::getEnvConfig('metamta.differential.attach-patches')) { $revision = $this->getRevision(); $revision_id = $revision->getID(); $diffs = $revision->loadDiffs(); $diff_number = count($diffs); $diff = array_pop($diffs); $filename = "D{$revision_id}.{$diff_number}.patch"; $diff->attachChangesets($diff->loadChangesets()); // TODO: We could batch this to improve performance. foreach ($diff->getChangesets() as $changeset) { $changeset->attachHunks($changeset->loadHunks()); } $diff_dict = $diff->getDiffDict(); $changes = array(); foreach ($diff_dict['changes'] as $changedict) { $changes[] = ArcanistDiffChange::newFromDictionary($changedict); } $bundle = ArcanistBundle::newFromChanges($changes); $unified_diff = $bundle->toUnifiedDiff(); $attachments[] = new PhabricatorMetaMTAAttachment($unified_diff, $filename, 'text/x-patch; charset=utf-8'); } return $attachments; }
protected function execute(ConduitAPIRequest $request) { $change_data = $request->getValue('changes'); $changes = array(); foreach ($change_data as $dict) { $changes[] = ArcanistDiffChange::newFromDictionary($dict); } $diff = DifferentialDiff::newFromRawChanges($changes); $diff->setSourcePath($request->getValue('sourcePath')); $diff->setSourceMachine($request->getValue('sourceMachine')); $diff->setBranch($request->getValue('branch')); $diff->setCreationMethod($request->getValue('creationMethod')); $diff->setAuthorPHID($request->getValue('authorPHID')); $parent_id = $request->getValue('parentRevisionID'); if ($parent_id) { $parent_rev = id(new DifferentialRevision())->load($parent_id); if ($parent_rev) { if ($parent_rev->getStatus() != DifferentialRevisionStatus::COMMITTED) { $diff->setParentRevisionID($parent_id); } } } $system = $request->getValue('sourceControlSystem'); $diff->setSourceControlSystem($system); $diff->setSourceControlPath($request->getValue('sourceControlPath')); $diff->setSourceControlBaseRevision($request->getValue('sourceControlBaseRevision')); $project_name = $request->getValue('arcanistProject'); $project_phid = null; if ($project_name) { $arcanist_project = id(new PhabricatorRepositoryArcanistProject())->loadOneWhere('name = %s', $project_name); if (!$arcanist_project) { $arcanist_project = new PhabricatorRepositoryArcanistProject(); $arcanist_project->setName($project_name); $arcanist_project->save(); } $project_phid = $arcanist_project->getPHID(); } $diff->setArcanistProjectPHID($project_phid); $diff->setRepositoryUUID($request->getValue('repositoryUUID')); switch ($request->getValue('lintStatus')) { case 'skip': $diff->setLintStatus(DifferentialLintStatus::LINT_SKIP); break; case 'okay': $diff->setLintStatus(DifferentialLintStatus::LINT_OKAY); break; case 'warn': $diff->setLintStatus(DifferentialLintStatus::LINT_WARN); break; case 'fail': $diff->setLintStatus(DifferentialLintStatus::LINT_FAIL); break; case 'none': default: $diff->setLintStatus(DifferentialLintStatus::LINT_NONE); break; } switch ($request->getValue('unitStatus')) { case 'skip': $diff->setUnitStatus(DifferentialUnitStatus::UNIT_SKIP); break; case 'okay': $diff->setUnitStatus(DifferentialUnitStatus::UNIT_OKAY); break; case 'warn': $diff->setUnitStatus(DifferentialUnitStatus::UNIT_WARN); break; case 'fail': $diff->setUnitStatus(DifferentialUnitStatus::UNIT_FAIL); break; case 'postponed': $diff->setUnitStatus(DifferentialUnitStatus::UNIT_POSTPONED); break; case 'none': default: $diff->setUnitStatus(DifferentialUnitStatus::UNIT_NONE); break; } $diff->save(); $path = '/differential/diff/' . $diff->getID() . '/'; $uri = PhabricatorEnv::getURI($path); return array('diffid' => $diff->getID(), 'uri' => $uri); }
private function buildBinaryChange(ArcanistDiffChange $change) { $old_phid = $change->getMetadata('old:binary-phid', null); $new_phid = $change->getMetadata('new:binary-phid', null); $type = $change->getType(); if ($type == ArcanistDiffChangeType::TYPE_ADD) { $old_null = true; } else { $old_null = false; } if ($type == ArcanistDiffChangeType::TYPE_DELETE) { $new_null = true; } else { $new_null = false; } if ($old_null) { $old_data = ''; $old_length = 0; $old_sha1 = str_repeat('0', 40); } else { $old_data = $this->getBlob($old_phid); $old_length = strlen($old_data); $old_sha1 = sha1("blob {$old_length}{$old_data}"); } if ($new_null) { $new_data = ''; $new_length = 0; $new_sha1 = str_repeat('0', 40); } else { $new_data = $this->getBlob($new_phid); $new_length = strlen($new_data); $new_sha1 = sha1("blob {$new_length}{$new_data}"); } $content = array(); $content[] = "index {$old_sha1}..{$new_sha1}"; $content[] = "GIT binary patch"; $content[] = "literal {$new_length}"; $content[] = $this->emitBinaryDiffBody($new_data); $content[] = "literal {$old_length}"; $content[] = $this->emitBinaryDiffBody($old_data); return implode("\n", $content); }
protected function execute(ConduitAPIRequest $request) { $viewer = $request->getUser(); $change_data = $request->getValue('changes'); $changes = array(); foreach ($change_data as $dict) { $changes[] = ArcanistDiffChange::newFromDictionary($dict); } $diff = DifferentialDiff::newFromRawChanges($changes); $diff->setSourcePath($request->getValue('sourcePath')); $diff->setSourceMachine($request->getValue('sourceMachine')); $diff->setBranch($request->getValue('branch')); $diff->setCreationMethod($request->getValue('creationMethod')); $diff->setAuthorPHID($viewer->getPHID()); $diff->setBookmark($request->getValue('bookmark')); // TODO: Remove this eventually; for now continue writing the UUID. Note // that we'll overwrite it below if we identify a repository, and `arc` // no longer sends it. This stuff is retained for backward compatibility. $diff->setRepositoryUUID($request->getValue('repositoryUUID')); $repository_phid = $request->getValue('repositoryPHID'); if ($repository_phid) { $repository = id(new PhabricatorRepositoryQuery())->setViewer($viewer)->withPHIDs(array($repository_phid))->executeOne(); if ($repository) { $diff->setRepositoryPHID($repository->getPHID()); $diff->setRepositoryUUID($repository->getUUID()); } } $system = $request->getValue('sourceControlSystem'); $diff->setSourceControlSystem($system); $diff->setSourceControlPath($request->getValue('sourceControlPath')); $diff->setSourceControlBaseRevision($request->getValue('sourceControlBaseRevision')); $project_name = $request->getValue('arcanistProject'); $project_phid = null; if ($project_name) { $arcanist_project = id(new PhabricatorRepositoryArcanistProject())->loadOneWhere('name = %s', $project_name); if (!$arcanist_project) { $arcanist_project = new PhabricatorRepositoryArcanistProject(); $arcanist_project->setName($project_name); $arcanist_project->save(); } $project_phid = $arcanist_project->getPHID(); } $diff->setArcanistProjectPHID($project_phid); switch ($request->getValue('lintStatus')) { case 'skip': $diff->setLintStatus(DifferentialLintStatus::LINT_SKIP); break; case 'okay': $diff->setLintStatus(DifferentialLintStatus::LINT_OKAY); break; case 'warn': $diff->setLintStatus(DifferentialLintStatus::LINT_WARN); break; case 'fail': $diff->setLintStatus(DifferentialLintStatus::LINT_FAIL); break; case 'postponed': $diff->setLintStatus(DifferentialLintStatus::LINT_POSTPONED); break; case 'none': default: $diff->setLintStatus(DifferentialLintStatus::LINT_NONE); break; } switch ($request->getValue('unitStatus')) { case 'skip': $diff->setUnitStatus(DifferentialUnitStatus::UNIT_SKIP); break; case 'okay': $diff->setUnitStatus(DifferentialUnitStatus::UNIT_OKAY); break; case 'warn': $diff->setUnitStatus(DifferentialUnitStatus::UNIT_WARN); break; case 'fail': $diff->setUnitStatus(DifferentialUnitStatus::UNIT_FAIL); break; case 'postponed': $diff->setUnitStatus(DifferentialUnitStatus::UNIT_POSTPONED); break; case 'none': default: $diff->setUnitStatus(DifferentialUnitStatus::UNIT_NONE); break; } id(new DifferentialDiffEditor())->setActor($viewer)->setContentSource(PhabricatorContentSource::newFromConduitRequest($request))->saveDiff($diff); // If we didn't get an explicit `repositoryPHID` (which means the client is // old, or couldn't figure out which repository the working copy belongs // to), apply heuristics to try to figure it out. if (!$repository_phid) { $repository = id(new DifferentialRepositoryLookup())->setDiff($diff)->setViewer($viewer)->lookupRepository(); if ($repository) { $diff->setRepositoryPHID($repository->getPHID()); $diff->setRepositoryUUID($repository->getUUID()); $diff->save(); } } $path = '/differential/diff/' . $diff->getID() . '/'; $uri = PhabricatorEnv::getURI($path); return array('diffid' => $diff->getID(), 'uri' => $uri); }
public function handleRequest(AphrontRequest $request) { $response = $this->loadDiffusionContext(); if ($response) { return $response; } $viewer = $this->getViewer(); $drequest = $this->getDiffusionRequest(); if (!$request->isAjax()) { // This request came out of the dropdown menu, either "View Standalone" // or "View Raw File". $view = $request->getStr('view'); if ($view == 'r') { $uri = $drequest->generateURI(array('action' => 'browse', 'params' => array('view' => 'raw'))); } else { $uri = $drequest->generateURI(array('action' => 'change')); } return id(new AphrontRedirectResponse())->setURI($uri); } $data = $this->callConduitWithDiffusionRequest('diffusion.diffquery', array('commit' => $drequest->getCommit(), 'path' => $drequest->getPath())); $drequest->updateSymbolicCommit($data['effectiveCommit']); $raw_changes = ArcanistDiffChange::newFromConduit($data['changes']); $diff = DifferentialDiff::newEphemeralFromRawChanges($raw_changes); $changesets = $diff->getChangesets(); $changeset = reset($changesets); if (!$changeset) { return new Aphront404Response(); } $parser = new DifferentialChangesetParser(); $parser->setUser($viewer); $parser->setChangeset($changeset); $parser->setRenderingReference($drequest->generateURI(array('action' => 'rendering-ref'))); $parser->readParametersFromRequest($request); $coverage = $drequest->loadCoverage(); if ($coverage) { $parser->setCoverage($coverage); } $commit = $drequest->loadCommit(); $pquery = new DiffusionPathIDQuery(array($changeset->getFilename())); $ids = $pquery->loadPathIDs(); $path_id = $ids[$changeset->getFilename()]; $parser->setLeftSideCommentMapping($path_id, false); $parser->setRightSideCommentMapping($path_id, true); $parser->setCanMarkDone($commit->getAuthorPHID() && $viewer->getPHID() == $commit->getAuthorPHID()); $parser->setObjectOwnerPHID($commit->getAuthorPHID()); $parser->setWhitespaceMode(DifferentialChangesetParser::WHITESPACE_SHOW_ALL); $inlines = PhabricatorAuditInlineComment::loadDraftAndPublishedComments($viewer, $commit->getPHID(), $path_id); if ($inlines) { foreach ($inlines as $inline) { $parser->parseInlineComment($inline); } $phids = mpull($inlines, 'getAuthorPHID'); $handles = $this->loadViewerHandles($phids); $parser->setHandles($handles); } $engine = new PhabricatorMarkupEngine(); $engine->setViewer($viewer); foreach ($inlines as $inline) { $engine->addObject($inline, PhabricatorInlineCommentInterface::MARKUP_FIELD_BODY); } $engine->process(); $parser->setMarkupEngine($engine); $spec = $request->getStr('range'); list($range_s, $range_e, $mask) = DifferentialChangesetParser::parseRangeSpecification($spec); $parser->setRange($range_s, $range_e); $parser->setMask($mask); return id(new PhabricatorChangesetResponse())->setRenderedChangeset($parser->renderChangeset())->setUndoTemplates($parser->getRenderer()->renderUndoTemplates()); }
private function buildPatch() { $diff = new DifferentialDiff(); $diff->attachChangesets($this->getChangesets()); // TODO: We could batch this to improve performance. foreach ($diff->getChangesets() as $changeset) { $changeset->attachHunks($changeset->loadHunks()); } $diff_dict = $diff->getDiffDict(); $changes = array(); foreach ($diff_dict['changes'] as $changedict) { $changes[] = ArcanistDiffChange::newFromDictionary($changedict); } $bundle = ArcanistBundle::newFromChanges($changes); $bundle->setLoadFileDataCallback(array($this, 'loadFileByPHID')); $format = PhabricatorEnv::getEnvConfig('metamta.differential.patch-format'); switch ($format) { case 'git': return $bundle->toGitPatch(); break; case 'unified': default: return $bundle->toUnifiedDiff(); break; } }