protected final function updateCommitData($author, $message) { $commit = $this->commit; $data = id(new PhabricatorRepositoryCommitData())->loadOneWhere('commitID = %d', $commit->getID()); if (!$data) { $data = new PhabricatorRepositoryCommitData(); } $data->setCommitID($commit->getID()); $data->setAuthorName($author); $data->setCommitMessage($message); $repository = $this->repository; $detail_parser = $repository->getDetail('detail-parser', 'PhabricatorRepositoryDefaultCommitMessageDetailParser'); if ($detail_parser) { PhutilSymbolLoader::loadClass($detail_parser); $parser_obj = newv($detail_parser, array($commit, $data)); $parser_obj->parseCommitDetails(); } $data->save(); $conn_w = id(new DifferentialRevision())->establishConnection('w'); // NOTE: The `differential_commit` table has a unique ID on `commitPHID`, // preventing more than one revision from being associated with a commit. // Generally this is good and desirable, but with the advent of hash // tracking we may end up in a situation where we match several different // revisions. We just kind of ignore this and pick one, we might want to // revisit this and do something differently. (If we match several revisions // someone probably did something very silly, though.) $revision_id = $data->getCommitDetail('differential.revisionID'); if (!$revision_id) { $hashes = $this->getCommitHashes($this->repository, $this->commit); if ($hashes) { $query = new DifferentialRevisionQuery(); $query->withCommitHashes($hashes); $revisions = $query->execute(); if (!empty($revisions)) { $revision = $this->identifyBestRevision($revisions); $revision_id = $revision->getID(); } } } if ($revision_id) { $revision = id(new DifferentialRevision())->load($revision_id); if ($revision) { queryfx($conn_w, 'INSERT IGNORE INTO %T (revisionID, commitPHID) VALUES (%d, %s)', DifferentialRevision::TABLE_COMMIT, $revision->getID(), $commit->getPHID()); if ($revision->getStatus() != DifferentialRevisionStatus::COMMITTED) { $message = null; $committer = $data->getCommitDetail('authorPHID'); if (!$committer) { $committer = $revision->getAuthorPHID(); $message = 'Change committed by ' . $data->getAuthorName() . '.'; } $editor = new DifferentialCommentEditor($revision, $committer, DifferentialAction::ACTION_COMMIT); $editor->setMessage($message)->save(); } } } }
protected final function updateCommitData($author, $message, $committer = null) { $commit = $this->commit; $data = id(new PhabricatorRepositoryCommitData())->loadOneWhere('commitID = %d', $commit->getID()); if (!$data) { $data = new PhabricatorRepositoryCommitData(); } $data->setCommitID($commit->getID()); $data->setAuthorName($author); $data->setCommitMessage($message); if ($committer) { $data->setCommitDetail('committer', $committer); } $repository = $this->repository; $detail_parser = $repository->getDetail('detail-parser', 'PhabricatorRepositoryDefaultCommitMessageDetailParser'); if ($detail_parser) { $parser_obj = newv($detail_parser, array($commit, $data)); $parser_obj->parseCommitDetails(); } $author_phid = $this->lookupUser($commit, $data->getAuthorName(), $data->getCommitDetail('authorPHID')); $data->setCommitDetail('authorPHID', $author_phid); $committer_phid = $this->lookupUser($commit, $data->getCommitDetail('committer'), $data->getCommitDetail('committerPHID')); $data->setCommitDetail('committerPHID', $committer_phid); if ($author_phid != $commit->getAuthorPHID()) { $commit->setAuthorPHID($author_phid); $commit->save(); } $conn_w = id(new DifferentialRevision())->establishConnection('w'); // NOTE: The `differential_commit` table has a unique ID on `commitPHID`, // preventing more than one revision from being associated with a commit. // Generally this is good and desirable, but with the advent of hash // tracking we may end up in a situation where we match several different // revisions. We just kind of ignore this and pick one, we might want to // revisit this and do something differently. (If we match several revisions // someone probably did something very silly, though.) $revision_id = $data->getCommitDetail('differential.revisionID'); if (!$revision_id) { $hashes = $this->getCommitHashes($this->repository, $this->commit); if ($hashes) { $query = new DifferentialRevisionQuery(); $query->withCommitHashes($hashes); $revisions = $query->execute(); if (!empty($revisions)) { $revision = $this->identifyBestRevision($revisions); $revision_id = $revision->getID(); } } } if ($revision_id) { $revision = id(new DifferentialRevision())->load($revision_id); if ($revision) { queryfx($conn_w, 'INSERT IGNORE INTO %T (revisionID, commitPHID) VALUES (%d, %s)', DifferentialRevision::TABLE_COMMIT, $revision->getID(), $commit->getPHID()); $committer_phid = $data->getCommitDetail('committerPHID'); if ($committer_phid) { $handle = PhabricatorObjectHandleData::loadOneHandle($committer_phid); $committer_name = '@' . $handle->getName(); } else { $committer_name = $data->getCommitDetail('committer'); } $author_phid = $data->getCommitDetail('authorPHID'); if ($author_phid) { $handle = PhabricatorObjectHandleData::loadOneHandle($author_phid); $author_name = '@' . $handle->getName(); } else { $author_name = $data->getAuthorName(); } $commit_name = $repository->formatCommitName($commit->getCommitIdentifier()); $info = array(); $info[] = "authored by {$author_name}"; if ($committer_name && $committer_name != $author_name) { $info[] = "committed by {$committer_name}"; } $info = implode(', ', $info); $message = "Closed by commit {$commit_name} ({$info})."; $actor_phid = nonempty($committer_phid, $author_phid, $revision->getAuthorPHID()); $status_closed = ArcanistDifferentialRevisionStatus::CLOSED; $should_close = $revision->getStatus() != $status_closed && $repository->shouldAutocloseCommit($commit, $data); if ($should_close) { $diff = $this->attachToRevision($revision, $actor_phid); $revision->setDateCommitted($commit->getEpoch()); $editor = new DifferentialCommentEditor($revision, $actor_phid, DifferentialAction::ACTION_CLOSE); $editor->setIsDaemonWorkflow(true); $vs_diff = $this->loadChangedByCommit($diff); if ($vs_diff) { $data->setCommitDetail('vsDiff', $vs_diff->getID()); $changed_by_commit = PhabricatorEnv::getProductionURI('/D' . $revision->getID() . '?vs=' . $vs_diff->getID() . '&id=' . $diff->getID() . '#toc'); $editor->setChangedByCommit($changed_by_commit); } $editor->setMessage($message)->save(); } } } $data->save(); }
private function buildRevisionPanel() { $user = $this->getRequest()->getUser(); $user_phid = $user->getPHID(); $revision_query = new DifferentialRevisionQuery(); $revision_query->withStatus(DifferentialRevisionQuery::STATUS_OPEN); $revision_query->withResponsibleUsers(array($user_phid)); $revision_query->needRelationships(true); // NOTE: We need to unlimit this query to hit the responsible user // fast-path. $revision_query->setLimit(null); $revisions = $revision_query->execute(); list($active, $waiting) = DifferentialRevisionQuery::splitResponsible($revisions, $user_phid); if (!$active) { return $this->renderMiniPanel('No Waiting Revisions', 'No revisions are waiting on you.'); } $panel = new AphrontPanelView(); $panel->setHeader('Revisions Waiting on You'); $panel->setCaption('Revisions waiting for you for review or commit.'); $panel->addButton(phutil_render_tag('a', array('href' => '/differential/', 'class' => 'button grey'), "View Active Revisions »")); $revision_view = id(new DifferentialRevisionListView())->setHighlightAge(true)->setRevisions($active)->setFields(DifferentialRevisionListView::getDefaultFields())->setUser($user)->loadAssets(); $phids = array_merge(array($user_phid), $revision_view->getRequiredHandlePHIDs()); $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles(); $revision_view->setHandles($handles); $panel->appendChild($revision_view); return $panel; }
protected function execute(ConduitAPIRequest $request) { $authors = $request->getValue('authors'); $ccs = $request->getValue('ccs'); $reviewers = $request->getValue('reviewers'); $status = $request->getValue('status'); $order = $request->getValue('order'); $commit_hashes = $request->getValue('commitHashes'); $limit = $request->getValue('limit'); $offset = $request->getValue('offset'); $ids = $request->getValue('ids'); $phids = $request->getValue('phids'); $subscribers = $request->getValue('subscribers'); $responsible_users = $request->getValue('responsibleUsers'); $query = new DifferentialRevisionQuery(); if ($authors) { $query->withAuthors($authors); } if ($ccs) { $query->withCCs($ccs); } if ($reviewers) { $query->withReviewers($reviewers); } /* TODO: Implement. $paths = $request->getValue('paths'); if ($paths) { foreach ($paths as $path) { // (Lookup the repository IDs.) $query->withPath($repository_id, $path); } } */ if ($commit_hashes) { $hash_types = DifferentialRevisionHash::getTypes(); foreach ($commit_hashes as $info) { list($type, $hash) = $info; if (empty($type) || !in_array($type, $hash_types) || empty($hash)) { throw new ConduitException('ERR-INVALID-PARAMETER'); } } $query->withCommitHashes($commit_hashes); } if ($status) { $query->withStatus($status); } if ($order) { $query->setOrder($order); } if ($limit) { $query->setLimit($limit); } if ($offset) { $query->setOffset($offset); } if ($ids) { $query->withIDs($ids); } if ($phids) { $query->withPHIDs($phids); } if ($responsible_users) { $query->withResponsibleUsers($responsible_users); } if ($subscribers) { $query->withSubscribers($subscribers); } $query->needRelationships(true); $query->needCommitPHIDs(true); $query->needDiffIDs(true); $query->needActiveDiffs(true); $revisions = $query->execute(); $results = array(); foreach ($revisions as $revision) { $diff = $revision->getActiveDiff(); if (!$diff) { continue; } $id = $revision->getID(); $results[] = array('id' => $id, 'phid' => $revision->getPHID(), 'title' => $revision->getTitle(), 'uri' => PhabricatorEnv::getProductionURI('/D' . $id), 'dateCreated' => $revision->getDateCreated(), 'dateModified' => $revision->getDateModified(), 'authorPHID' => $revision->getAuthorPHID(), 'status' => $revision->getStatus(), 'statusName' => DifferentialRevisionStatus::getNameForRevisionStatus($revision->getStatus()), 'sourcePath' => $diff->getSourcePath(), 'summary' => $revision->getSummary(), 'testPlan' => $revision->getTestPlan(), 'lineCount' => $revision->getLineCount(), 'diffs' => $revision->getDiffIDs(), 'commits' => $revision->getCommitPHIDs(), 'reviewers' => array_values($revision->getReviewers()), 'ccs' => array_values($revision->getCCPHIDs())); } return $results; }
protected final function updateCommitData($author, $message, $committer = null) { $commit = $this->commit; $data = id(new PhabricatorRepositoryCommitData())->loadOneWhere('commitID = %d', $commit->getID()); if (!$data) { $data = new PhabricatorRepositoryCommitData(); } $data->setCommitID($commit->getID()); $data->setAuthorName($author); $data->setCommitMessage($message); if ($committer) { $data->setCommitDetail('committer', $committer); } $repository = $this->repository; $detail_parser = $repository->getDetail('detail-parser', 'PhabricatorRepositoryDefaultCommitMessageDetailParser'); if ($detail_parser) { $parser_obj = newv($detail_parser, array($commit, $data)); $parser_obj->parseCommitDetails(); } $author_phid = $this->lookupUser($commit, $data->getAuthorName(), $data->getCommitDetail('authorPHID')); $data->setCommitDetail('authorPHID', $author_phid); $committer_phid = $this->lookupUser($commit, $data->getCommitDetail('committer'), $data->getCommitDetail('committerPHID')); $data->setCommitDetail('committerPHID', $committer_phid); if ($author_phid != $commit->getAuthorPHID()) { $commit->setAuthorPHID($author_phid); $commit->save(); } $conn_w = id(new DifferentialRevision())->establishConnection('w'); // NOTE: The `differential_commit` table has a unique ID on `commitPHID`, // preventing more than one revision from being associated with a commit. // Generally this is good and desirable, but with the advent of hash // tracking we may end up in a situation where we match several different // revisions. We just kind of ignore this and pick one, we might want to // revisit this and do something differently. (If we match several revisions // someone probably did something very silly, though.) $revision = null; $should_autoclose = $repository->shouldAutocloseCommit($commit, $data); $revision_id = $data->getCommitDetail('differential.revisionID'); if (!$revision_id) { $hashes = $this->getCommitHashes($this->repository, $this->commit); if ($hashes) { $query = new DifferentialRevisionQuery(); $query->withCommitHashes($hashes); $revisions = $query->execute(); if (!empty($revisions)) { $revision = $this->identifyBestRevision($revisions); $revision_id = $revision->getID(); } } } if ($revision_id) { $lock = PhabricatorGlobalLock::newLock(get_class($this) . ':' . $revision_id); $lock->lock(5 * 60); $revision = id(new DifferentialRevision())->load($revision_id); if ($revision) { $revision->loadRelationships(); queryfx($conn_w, 'INSERT IGNORE INTO %T (revisionID, commitPHID) VALUES (%d, %s)', DifferentialRevision::TABLE_COMMIT, $revision->getID(), $commit->getPHID()); $status_closed = ArcanistDifferentialRevisionStatus::CLOSED; $should_close = $revision->getStatus() != $status_closed && $should_autoclose; if ($should_close) { $actor_phid = nonempty($committer_phid, $author_phid, $revision->getAuthorPHID()); $diff = $this->attachToRevision($revision, $actor_phid); $revision->setDateCommitted($commit->getEpoch()); $editor = new DifferentialCommentEditor($revision, $actor_phid, DifferentialAction::ACTION_CLOSE); $editor->setIsDaemonWorkflow(true); $vs_diff = $this->loadChangedByCommit($diff); if ($vs_diff) { $data->setCommitDetail('vsDiff', $vs_diff->getID()); $changed_by_commit = PhabricatorEnv::getProductionURI('/D' . $revision->getID() . '?vs=' . $vs_diff->getID() . '&id=' . $diff->getID() . '#toc'); $editor->setChangedByCommit($changed_by_commit); } $commit_name = $repository->formatCommitName($commit->getCommitIdentifier()); $committer_name = $this->loadUserName($committer_phid, $data->getCommitDetail('committer')); $author_name = $this->loadUserName($author_phid, $data->getAuthorName()); $info = array(); $info[] = "authored by {$author_name}"; if ($committer_name && $committer_name != $author_name) { $info[] = "committed by {$committer_name}"; } $info = implode(', ', $info); $editor->setMessage("Closed by commit {$commit_name} ({$info}).")->save(); } } $lock->unlock(); } if ($should_autoclose && $author_phid) { $user = id(new PhabricatorUser())->loadOneWhere('phid = %s', $author_phid); $call = new ConduitCall('differential.parsecommitmessage', array('corpus' => $message, 'partial' => true)); $call->setUser($user); $result = $call->execute(); $field_values = $result['fields']; $fields = DifferentialFieldSelector::newSelector()->getFieldSpecifications(); foreach ($fields as $key => $field) { if (!$field->shouldAppearOnCommitMessage()) { continue; } $field->setUser($user); $value = idx($field_values, $field->getCommitMessageKey()); $field->setValueFromParsedCommitMessage($value); if ($revision) { $field->setRevision($revision); } $field->didParseCommit($repository, $commit, $data); } } $data->save(); }
protected function execute(ConduitAPIRequest $request) { $authors = $request->getValue('authors'); $ccs = $request->getValue('ccs'); $reviewers = $request->getValue('reviewers'); $status = $request->getValue('status'); $order = $request->getValue('order'); $commit_hashes = $request->getValue('commitHashes'); $limit = $request->getValue('limit'); $offset = $request->getValue('offset'); $ids = $request->getValue('ids'); $phids = $request->getValue('phids'); $subscribers = $request->getValue('subscribers'); $responsible_users = $request->getValue('responsibleUsers'); $branches = $request->getValue('branches'); $arc_projects = $request->getValue('arcanistProjects'); $query = new DifferentialRevisionQuery(); if ($authors) { $query->withAuthors($authors); } if ($ccs) { $query->withCCs($ccs); } if ($reviewers) { $query->withReviewers($reviewers); } /* TODO: Implement. $paths = $request->getValue('paths'); if ($paths) { foreach ($paths as $path) { // (Lookup the repository IDs.) $query->withPath($repository_id, $path); } } */ if ($commit_hashes) { $hash_types = ArcanistDifferentialRevisionHash::getTypes(); foreach ($commit_hashes as $info) { list($type, $hash) = $info; if (empty($type) || !in_array($type, $hash_types) || empty($hash)) { throw new ConduitException('ERR-INVALID-PARAMETER'); } } $query->withCommitHashes($commit_hashes); } if ($status) { $query->withStatus($status); } if ($order) { $query->setOrder($order); } if ($limit) { $query->setLimit($limit); } if ($offset) { $query->setOffset($offset); } if ($ids) { $query->withIDs($ids); } if ($phids) { $query->withPHIDs($phids); } if ($responsible_users) { $query->withResponsibleUsers($responsible_users); } if ($subscribers) { $query->withSubscribers($subscribers); } if ($branches) { $query->withBranches($branches); } if ($arc_projects) { // This is sort of special-cased, but don't make arc do an extra round // trip. $projects = id(new PhabricatorRepositoryArcanistProject())->loadAllWhere('name in (%Ls)', $arc_projects); if (!$projects) { return array(); } $query->withArcanistProjectPHIDs(mpull($projects, 'getPHID')); } $query->needRelationships(true); $query->needCommitPHIDs(true); $query->needDiffIDs(true); $query->needActiveDiffs(true); $revisions = $query->execute(); $results = array(); foreach ($revisions as $revision) { $diff = $revision->getActiveDiff(); if (!$diff) { continue; } $id = $revision->getID(); $result = array('id' => $id, 'phid' => $revision->getPHID(), 'title' => $revision->getTitle(), 'uri' => PhabricatorEnv::getProductionURI('/D' . $id), 'dateCreated' => $revision->getDateCreated(), 'dateModified' => $revision->getDateModified(), 'authorPHID' => $revision->getAuthorPHID(), 'status' => $revision->getStatus(), 'statusName' => ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($revision->getStatus()), 'branch' => $diff->getBranch(), 'summary' => $revision->getSummary(), 'testPlan' => $revision->getTestPlan(), 'lineCount' => $revision->getLineCount(), 'diffs' => $revision->getDiffIDs(), 'commits' => $revision->getCommitPHIDs(), 'reviewers' => array_values($revision->getReviewers()), 'ccs' => array_values($revision->getCCPHIDs())); // TODO: This is a hacky way to put permissions on this field until we // have first-class support, see T838. if ($revision->getAuthorPHID() == $request->getUser()->getPHID()) { $result['sourcePath'] = $diff->getSourcePath(); } $results[] = $result; } return $results; }