protected function execute(ConduitAPIRequest $request) { $diff = null; $revision_id = $request->getValue('revision_id'); $revision = id(new DifferentialRevision())->load($revision_id); if (!$revision) { throw new ConduitException('ERR_BAD_REVISION'); } $revision->loadRelationships(); $reviewer_phids = array_values($revision->getReviewers()); $diffs = $revision->loadDiffs(); $diff_dicts = array(); foreach ($diffs as $diff) { $diff->attachChangesets($diff->loadChangesets()); // TODO: We could batch this to improve performance. foreach ($diff->getChangesets() as $changeset) { $changeset->attachHunks($changeset->loadHunks()); } $diff_dicts[] = $diff->getDiffDict(); } $commit_dicts = array(); $commit_phids = $revision->loadCommitPHIDs(); $handles = id(new PhabricatorObjectHandleData($commit_phids))->loadHandles(); foreach ($commit_phids as $commit_phid) { $commit_dicts[] = array('fullname' => $handles[$commit_phid]->getFullName(), 'dateCommitted' => $handles[$commit_phid]->getTimestamp()); } $auxiliary_fields = $this->loadAuxiliaryFields($revision); $dict = array('id' => $revision->getID(), 'phid' => $revision->getPHID(), 'authorPHID' => $revision->getAuthorPHID(), 'uri' => PhabricatorEnv::getURI('/D' . $revision->getID()), 'title' => $revision->getTitle(), 'status' => $revision->getStatus(), 'statusName' => ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($revision->getStatus()), 'summary' => $revision->getSummary(), 'testPlan' => $revision->getTestPlan(), 'lineCount' => $revision->getLineCount(), 'reviewerPHIDs' => $reviewer_phids, 'diffs' => $diff_dicts, 'commits' => $commit_dicts, 'auxiliary' => $auxiliary_fields); return $dict; }
public static function renderFullDescription($status) { $color = self::getRevisionStatusColor($status); $status_name = ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($status); $img = id(new PHUIIconView())->setIconFont(self::getRevisionStatusIcon($status)); $tag = phutil_tag('span', array('class' => 'phui-header-status phui-header-' . $color), array($img, $status_name)); return $tag; }
protected function execute(ConduitAPIRequest $request) { $query = $request->getValue('query'); $guids = $request->getValue('guids'); $results = array(); if (!$guids) { return $results; } $revisions = id(new DifferentialRevisionListData($query, (array) $guids))->loadRevisions(); foreach ($revisions as $revision) { $diff = $revision->loadActiveDiff(); if (!$diff) { continue; } $id = $revision->getID(); $results[] = array('id' => $id, 'phid' => $revision->getPHID(), 'name' => $revision->getTitle(), 'uri' => PhabricatorEnv::getProductionURI('/D' . $id), 'dateCreated' => $revision->getDateCreated(), 'authorPHID' => $revision->getAuthorPHID(), 'statusName' => ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($revision->getStatus()), 'sourcePath' => $diff->getSourcePath()); } return $results; }
protected function execute(ConduitAPIRequest $request) { $diff = null; $revision_id = $request->getValue('revision_id'); $revision = id(new DifferentialRevisionQuery())->withIDs(array($revision_id))->setViewer($request->getUser())->needRelationships(true)->needReviewerStatus(true)->executeOne(); if (!$revision) { throw new ConduitException('ERR_BAD_REVISION'); } $reviewer_phids = array_values($revision->getReviewers()); $diffs = id(new DifferentialDiffQuery())->setViewer($request->getUser())->withRevisionIDs(array($revision_id))->needChangesets(true)->needArcanistProjects(true)->execute(); $diff_dicts = mpull($diffs, 'getDiffDict'); $commit_dicts = array(); $commit_phids = $revision->loadCommitPHIDs(); $handles = id(new PhabricatorHandleQuery())->setViewer($request->getUser())->withPHIDs($commit_phids)->execute(); foreach ($commit_phids as $commit_phid) { $commit_dicts[] = array('fullname' => $handles[$commit_phid]->getFullName(), 'dateCommitted' => $handles[$commit_phid]->getTimestamp()); } $field_data = $this->loadCustomFieldsForRevisions($request->getUser(), array($revision)); $dict = array('id' => $revision->getID(), 'phid' => $revision->getPHID(), 'authorPHID' => $revision->getAuthorPHID(), 'uri' => PhabricatorEnv::getURI('/D' . $revision->getID()), 'title' => $revision->getTitle(), 'status' => $revision->getStatus(), 'statusName' => ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($revision->getStatus()), 'summary' => $revision->getSummary(), 'testPlan' => $revision->getTestPlan(), 'lineCount' => $revision->getLineCount(), 'reviewerPHIDs' => $reviewer_phids, 'diffs' => $diff_dicts, 'commits' => $commit_dicts, 'auxiliary' => idx($field_data, $revision->getPHID(), array())); return $dict; }
protected function execute(ConduitAPIRequest $request) { $type = $request->getValue('query'); $guids = $request->getValue('guids'); $results = array(); if (!$guids) { return $results; } $query = id(new DifferentialRevisionQuery())->setViewer($request->getUser()); switch ($type) { case 'open': $query->withStatus(DifferentialRevisionQuery::STATUS_OPEN)->withAuthors($guids); break; case 'committable': $query->withStatus(DifferentialRevisionQuery::STATUS_ACCEPTED)->withAuthors($guids); break; case 'revision-ids': $query->withIDs($guids); break; case 'owned': $query->withAuthors($guids); break; case 'phids': $query->withPHIDs($guids); break; } $revisions = $query->execute(); foreach ($revisions as $revision) { $diff = $revision->loadActiveDiff(); if (!$diff) { continue; } $id = $revision->getID(); $results[] = array('id' => $id, 'phid' => $revision->getPHID(), 'name' => $revision->getTitle(), 'uri' => PhabricatorEnv::getProductionURI('/D' . $id), 'dateCreated' => $revision->getDateCreated(), 'authorPHID' => $revision->getAuthorPHID(), 'statusName' => ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($revision->getStatus()), 'sourcePath' => $diff->getSourcePath()); } return $results; }
public static function renderTagForRevision(DifferentialRevision $revision) { $status = $revision->getStatus(); $status_name = ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($status); return id(new PHUITagView())->setType(PHUITagView::TYPE_STATE)->setName($status_name); }
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'); $path_pairs = $request->getValue('paths'); $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'); $query = id(new DifferentialRevisionQuery())->setViewer($request->getUser()); if ($authors) { $query->withAuthors($authors); } if ($ccs) { $query->withCCs($ccs); } if ($reviewers) { $query->withReviewers($reviewers); } if ($path_pairs) { $paths = array(); foreach ($path_pairs as $pair) { list($callsign, $path) = $pair; $paths[] = $path; } $path_map = id(new DiffusionPathIDQuery($paths))->loadPathIDs(); if (count($path_map) != count($paths)) { $unknown_paths = array(); foreach ($paths as $p) { if (!idx($path_map, $p)) { $unknown_paths[] = $p; } } throw id(new ConduitException('ERR-INVALID-PARAMETER'))->setErrorDescription(pht('Unknown paths: %s', implode(', ', $unknown_paths))); } $repos = array(); foreach ($path_pairs as $pair) { list($callsign, $path) = $pair; if (!idx($repos, $callsign)) { $repos[$callsign] = id(new PhabricatorRepositoryQuery())->setViewer($request->getUser())->withCallsigns(array($callsign))->executeOne(); if (!$repos[$callsign]) { throw id(new ConduitException('ERR-INVALID-PARAMETER'))->setErrorDescription(pht('Unknown repo callsign: %s', $callsign)); } } $repo = $repos[$callsign]; $query->withPath($repo->getID(), idx($path_map, $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->withCCs($subscribers); } if ($branches) { $query->withBranches($branches); } $query->needRelationships(true); $query->needCommitPHIDs(true); $query->needDiffIDs(true); $query->needActiveDiffs(true); $query->needHashes(true); $revisions = $query->execute(); $field_data = $this->loadCustomFieldsForRevisions($request->getUser(), $revisions); $results = array(); foreach ($revisions as $revision) { $diff = $revision->getActiveDiff(); if (!$diff) { continue; } $id = $revision->getID(); $phid = $revision->getPHID(); $result = array('id' => $id, 'phid' => $phid, '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()), 'properties' => $revision->getProperties(), 'branch' => $diff->getBranch(), 'summary' => $revision->getSummary(), 'testPlan' => $revision->getTestPlan(), 'lineCount' => $revision->getLineCount(), 'activeDiffPHID' => $diff->getPHID(), 'diffs' => $revision->getDiffIDs(), 'commits' => $revision->getCommitPHIDs(), 'reviewers' => array_values($revision->getReviewers()), 'ccs' => array_values($revision->getCCPHIDs()), 'hashes' => $revision->getHashes(), 'auxiliary' => idx($field_data, $phid, array()), 'repositoryPHID' => $diff->getRepositoryPHID()); // 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; }
public function renderValueForRevisionList(DifferentialRevision $revision) { return ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($revision->getStatus()); }
public static function renderFullDescription($status) { $status_name = ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($status); $tag = id(new PHUITagView())->setName($status_name)->setIcon(self::getRevisionStatusIcon($status))->setShade(self::getRevisionStatusColor($status))->setType(PHUITagView::TYPE_SHADE); return $tag; }
public function render() { $user = $this->user; if (!$user) { throw new PhutilInvalidStateException('setUser'); } $fresh = PhabricatorEnv::getEnvConfig('differential.days-fresh'); if ($fresh) { $fresh = PhabricatorCalendarHoliday::getNthBusinessDay(time(), -$fresh); } $stale = PhabricatorEnv::getEnvConfig('differential.days-stale'); if ($stale) { $stale = PhabricatorCalendarHoliday::getNthBusinessDay(time(), -$stale); } $this->initBehavior('phabricator-tooltips', array()); $this->requireResource('aphront-tooltip-css'); $list = new PHUIObjectItemListView(); foreach ($this->revisions as $revision) { $item = id(new PHUIObjectItemView())->setUser($user); $icons = array(); $phid = $revision->getPHID(); $flag = $revision->getFlag($user); if ($flag) { $flag_class = PhabricatorFlagColor::getCSSClass($flag->getColor()); $icons['flag'] = phutil_tag('div', array('class' => 'phabricator-flag-icon ' . $flag_class), ''); } if ($revision->getDrafts($user)) { $icons['draft'] = true; } $modified = $revision->getDateModified(); $status = $revision->getStatus(); $show_age = ($fresh || $stale) && $this->highlightAge && !$revision->isClosed(); if ($stale && $modified < $stale) { $object_age = PHUIObjectItemView::AGE_OLD; } else { if ($fresh && $modified < $fresh) { $object_age = PHUIObjectItemView::AGE_STALE; } else { $object_age = PHUIObjectItemView::AGE_FRESH; } } $status_name = ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($status); if (isset($icons['flag'])) { $item->addHeadIcon($icons['flag']); } $item->setObjectName('D' . $revision->getID()); $item->setHeader($revision->getTitle()); $item->setHref('/D' . $revision->getID()); if (isset($icons['draft'])) { $draft = id(new PHUIIconView())->setIcon('fa-comment yellow')->addSigil('has-tooltip')->setMetadata(array('tip' => pht('Unsubmitted Comments'))); $item->addAttribute($draft); } /* Most things 'Need Review', so accept it's the default */ if ($status != ArcanistDifferentialRevisionStatus::NEEDS_REVIEW) { $item->addAttribute($status_name); } // Author $author_handle = $this->handles[$revision->getAuthorPHID()]; $item->addByline(pht('Author: %s', $author_handle->renderLink())); $reviewers = array(); // TODO: As above, this should be based on `getReviewerStatus()`. foreach ($revision->getReviewers() as $reviewer) { $reviewers[] = $this->handles[$reviewer]->renderLink(); } if (!$reviewers) { $reviewers = phutil_tag('em', array(), pht('None')); } else { $reviewers = phutil_implode_html(', ', $reviewers); } $item->addAttribute(pht('Reviewers: %s', $reviewers)); $item->setEpoch($revision->getDateModified(), $object_age); switch ($status) { case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW: $item->setStatusIcon('fa-code grey', pht('Needs Review')); break; case ArcanistDifferentialRevisionStatus::NEEDS_REVISION: $item->setStatusIcon('fa-refresh red', pht('Needs Revision')); break; case ArcanistDifferentialRevisionStatus::CHANGES_PLANNED: $item->setStatusIcon('fa-headphones red', pht('Changes Planned')); break; case ArcanistDifferentialRevisionStatus::ACCEPTED: $item->setStatusIcon('fa-check green', pht('Accepted')); break; case ArcanistDifferentialRevisionStatus::CLOSED: $item->setDisabled(true); $item->setStatusIcon('fa-check-square-o black', pht('Closed')); break; case ArcanistDifferentialRevisionStatus::ABANDONED: $item->setDisabled(true); $item->setStatusIcon('fa-plane black', pht('Abandoned')); break; } $list->addItem($item); } $list->setNoDataString($this->noDataString); if ($this->header && !$this->noBox) { $list->setFlush(true); $list = id(new PHUIObjectBoxView())->setObjectList($list); if ($this->header instanceof PHUIHeaderView) { $list->setHeader($this->header); } else { $list->setHeaderText($this->header); } } else { $list->setHeader($this->header); } return $list; }
break; case DifferentialAction::ACTION_RECLAIM: case DifferentialAction::ACTION_UPDATE: $new_status = ArcanistDifferentialRevisionStatus::NEEDS_REVIEW; break; } } $revisions[$revision_id] = $revision; $map[$revision_id] = $new_status; } } if (!$revisions) { echo "Done -- nothing to do.\n"; } echo "Found " . count($revisions) . " revisions to update:\n\n"; foreach ($revisions as $id => $revision) { $old_status = ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($revision->getStatus()); $new_status = ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($map[$id]); echo " - D{$id}: " . $revision->getTitle() . "\n"; echo " Will update: {$old_status} -> {$new_status}\n\n"; } $ok = phutil_console_confirm('Apply these changes?'); if (!$ok) { echo "Aborted.\n"; exit(1); } echo "Saving changes...\n"; foreach ($revisions as $id => $revision) { queryfx($revision->establishConnection('r'), 'UPDATE %T SET status = %d WHERE id = %d', $revision->getTableName(), $map[$id], $id); } echo "Done.\n";
public function getStatusDisplayName() { $status = $this->getStatus(); return ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($status); }
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; }
public function render() { $viewer = $this->getViewer(); $this->initBehavior('phabricator-tooltips', array()); $this->requireResource('aphront-tooltip-css'); $list = new PHUIObjectItemListView(); foreach ($this->revisions as $revision) { $item = id(new PHUIObjectItemView())->setUser($viewer); $icons = array(); $phid = $revision->getPHID(); $flag = $revision->getFlag($viewer); if ($flag) { $flag_class = PhabricatorFlagColor::getCSSClass($flag->getColor()); $icons['flag'] = phutil_tag('div', array('class' => 'phabricator-flag-icon ' . $flag_class), ''); } if ($revision->getDrafts($viewer)) { $icons['draft'] = true; } $modified = $revision->getDateModified(); $status = $revision->getStatus(); $status_name = ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($status); if (isset($icons['flag'])) { $item->addHeadIcon($icons['flag']); } $item->setObjectName('D' . $revision->getID()); $item->setHeader($revision->getTitle()); $item->setHref('/D' . $revision->getID()); if (isset($icons['draft'])) { $draft = id(new PHUIIconView())->setIcon('fa-comment yellow')->addSigil('has-tooltip')->setMetadata(array('tip' => pht('Unsubmitted Comments'))); $item->addAttribute($draft); } // Author $author_handle = $this->handles[$revision->getAuthorPHID()]; $item->addByline(pht('Author: %s', $author_handle->renderLink())); $unlanded = idx($this->unlandedDependencies, $phid); if ($unlanded) { $item->addAttribute(array(id(new PHUIIconView())->setIcon('fa-chain-broken', 'red'), ' ', pht('Open Dependencies'))); } $reviewers = array(); // TODO: As above, this should be based on `getReviewerStatus()`. foreach ($revision->getReviewers() as $reviewer) { $reviewers[] = $this->handles[$reviewer]->renderLink(); } if (!$reviewers) { $reviewers = phutil_tag('em', array(), pht('None')); } else { $reviewers = phutil_implode_html(', ', $reviewers); } $item->addAttribute(pht('Reviewers: %s', $reviewers)); $item->setEpoch($revision->getDateModified()); switch ($status) { case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW: $item->setStatusIcon('fa-code grey', pht('Needs Review')); break; case ArcanistDifferentialRevisionStatus::NEEDS_REVISION: $item->setStatusIcon('fa-refresh red', pht('Needs Revision')); break; case ArcanistDifferentialRevisionStatus::CHANGES_PLANNED: $item->setStatusIcon('fa-headphones red', pht('Changes Planned')); break; case ArcanistDifferentialRevisionStatus::ACCEPTED: $item->setStatusIcon('fa-check green', pht('Accepted')); break; case ArcanistDifferentialRevisionStatus::CLOSED: $item->setDisabled(true); $item->setStatusIcon('fa-check-square-o black', pht('Closed')); break; case ArcanistDifferentialRevisionStatus::ABANDONED: $item->setDisabled(true); $item->setStatusIcon('fa-plane black', pht('Abandoned')); break; } $list->addItem($item); } $list->setNoDataString($this->noDataString); if ($this->header && !$this->noBox) { $list->setFlush(true); $list = id(new PHUIObjectBoxView())->setBackground($this->background)->setObjectList($list); if ($this->header instanceof PHUIHeaderView) { $list->setHeader($this->header); } else { $list->setHeaderText($this->header); } } else { $list->setHeader($this->header); } return $list; }