From 1c454ea6d97a2bd128907eb04af077a71c94e62d Mon Sep 17 00:00:00 2001 From: epriestley Date: Fri, 26 Jul 2013 10:31:35 -0700 Subject: [PATCH] Add commits/audits to Asana bridge Summary: Ref T2852. Adds sync for commits/audits. Test Plan: {F51660} Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T2852 Differential Revision: https://secure.phabricator.com/D6573 --- src/__phutil_library_map__.php | 2 + ...sionDoorkeeperCommitFeedStoryPublisher.php | 163 ++++++++++++++++++ .../feed/story/PhabricatorFeedStoryAudit.php | 27 +++ .../storage/PhabricatorRepositoryCommit.php | 3 +- 4 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 src/applications/diffusion/doorkeeper/DiffusionDoorkeeperCommitFeedStoryPublisher.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 07b76d8362..27025879ae 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -446,6 +446,7 @@ phutil_register_library_map(array( 'DiffusionCommitTagsController' => 'applications/diffusion/controller/DiffusionCommitTagsController.php', 'DiffusionController' => 'applications/diffusion/controller/DiffusionController.php', 'DiffusionDiffController' => 'applications/diffusion/controller/DiffusionDiffController.php', + 'DiffusionDoorkeeperCommitFeedStoryPublisher' => 'applications/diffusion/doorkeeper/DiffusionDoorkeeperCommitFeedStoryPublisher.php', 'DiffusionEmptyResultView' => 'applications/diffusion/view/DiffusionEmptyResultView.php', 'DiffusionExpandCommitQueryException' => 'applications/diffusion/exception/DiffusionExpandCommitQueryException.php', 'DiffusionExpandShortNameQuery' => 'applications/diffusion/query/expandshortname/DiffusionExpandShortNameQuery.php', @@ -2436,6 +2437,7 @@ phutil_register_library_map(array( 'DiffusionCommitTagsController' => 'DiffusionController', 'DiffusionController' => 'PhabricatorController', 'DiffusionDiffController' => 'DiffusionController', + 'DiffusionDoorkeeperCommitFeedStoryPublisher' => 'DoorkeeperFeedStoryPublisher', 'DiffusionEmptyResultView' => 'DiffusionView', 'DiffusionExpandCommitQueryException' => 'Exception', 'DiffusionExpandShortNameQuery' => 'DiffusionQuery', diff --git a/src/applications/diffusion/doorkeeper/DiffusionDoorkeeperCommitFeedStoryPublisher.php b/src/applications/diffusion/doorkeeper/DiffusionDoorkeeperCommitFeedStoryPublisher.php new file mode 100644 index 0000000000..cf17b95a5b --- /dev/null +++ b/src/applications/diffusion/doorkeeper/DiffusionDoorkeeperCommitFeedStoryPublisher.php @@ -0,0 +1,163 @@ +auditRequests; + } + + public function canPublishStory(PhabricatorFeedStory $story, $object) { + return ($object instanceof PhabricatorRepositoryCommit); + } + + public function willPublishStory($commit) { + $requests = id(new PhabricatorAuditQuery()) + ->withCommitPHIDs(array($commit->getPHID())) + ->execute(); + + // TODO: This is messy and should be generalized, but we don't have a good + // query for it yet. Since we run in the daemons, just do the easiest thing + // we can for the moment. Figure out who all of the "active" (need to + // audit) and "passive" (no action necessary) user are. + + $auditor_phids = mpull($requests, 'getAuditorPHID'); + $objects = id(new PhabricatorObjectHandleData($auditor_phids)) + ->setViewer($this->getViewer()) + ->loadObjects(); + + $active = array(); + $passive = array(); + + foreach ($requests as $request) { + $status = $request->getAuditStatus(); + if ($status == PhabricatorAuditStatusConstants::CC) { + // We handle these specially below. + continue; + } + + $object = idx($objects, $request->getAuditorPHID()); + if (!$object) { + continue; + } + + $request_phids = array(); + if ($object instanceof PhabricatorUser) { + $request_phids = array($object->getPHID()); + } else if ($object instanceof PhabricatorOwnersPackage) { + $request_phids = PhabricatorOwnersOwner::loadAffiliatedUserPHIDs( + array($object->getID())); + } else if ($object instanceof PhabricatorProject) { + $request_phids = $object->loadMemberPHIDs(); + } else { + // Dunno what this is. + $request_phids = array(); + } + + switch ($status) { + case PhabricatorAuditStatusConstants::AUDIT_REQUIRED: + case PhabricatorAuditStatusConstants::AUDIT_REQUESTED: + case PhabricatorAuditStatusConstants::CONCERNED: + $active += array_fuse($request_phids); + break; + default: + $passive += array_fuse($request_phids); + break; + } + } + + + + // Remove "Active" users from the "Passive" list. + $passive = array_diff_key($passive, $active); + + $this->activePHIDs = $active; + $this->passivePHIDs = $passive; + $this->auditRequests = $requests; + + return $commit; + } + + public function getOwnerPHID($object) { + return $object->getAuthorPHID(); + } + + public function getActiveUserPHIDs($object) { + return $this->activePHIDs; + } + + public function getPassiveUserPHIDs($object) { + return $this->passivePHIDs; + } + + public function getCCUserPHIDs($object) { + $ccs = array(); + foreach ($this->getAuditRequests() as $request) { + if ($request->getAuditStatus() == PhabricatorAuditStatusConstants::CC) { + $ccs[] = $request->getAuditorPHID(); + } + } + return $ccs; + } + + public function getObjectTitle($object) { + $prefix = $this->getTitlePrefix($object); + + $repository = $object->getRepository(); + $name = $repository->formatCommitName($object->getCommitIdentifier()); + + $title = $object->getSummary(); + + return "{$prefix} {$name}: {$title}"; + } + + public function getObjectURI($object) { + $repository = $object->getRepository(); + $name = $repository->formatCommitName($object->getCommitIdentifier()); + return PhabricatorEnv::getProductionURI('/'.$name); + } + + public function getObjectDescription($object) { + $data = $object->loadCommitData(); + if ($data) { + return $data->getCommitMessage(); + } + return null; + } + + public function isObjectClosed($object) { + switch ($object->getAuditStatus()) { + case PhabricatorAuditCommitStatusConstants::NEEDS_AUDIT: + case PhabricatorAuditCommitStatusConstants::CONCERN_RAISED: + case PhabricatorAuditCommitStatusConstants::PARTIALLY_AUDITED: + return false; + default: + return true; + } + } + + public function getResponsibilityTitle($object) { + $prefix = $this->getTitlePrefix($object); + return pht('%s Audit', $prefix); + } + + public function getStoryText($object) { + $story = $this->getFeedStory(); + if ($story instanceof PhabricatorFeedStoryAudit) { + $text = $story->renderForAsanaBridge(); + } else { + $text = $story->renderText(); + } + return $text; + } + + private function getTitlePrefix(PhabricatorRepositoryCommit $commit) { + $prefix_key = 'metamta.diffusion.subject-prefix'; + return PhabricatorEnv::getEnvConfig($prefix_key); + } + +} diff --git a/src/applications/feed/story/PhabricatorFeedStoryAudit.php b/src/applications/feed/story/PhabricatorFeedStoryAudit.php index 5dd3051290..5fa66fd19f 100644 --- a/src/applications/feed/story/PhabricatorFeedStoryAudit.php +++ b/src/applications/feed/story/PhabricatorFeedStoryAudit.php @@ -44,4 +44,31 @@ final class PhabricatorFeedStoryAudit extends PhabricatorFeedStory { return $text; } + + + // TODO: At some point, make feed rendering not terrible and remove this + // hacky mess. + public function renderForAsanaBridge() { + $data = $this->getStoryData(); + $comment = $data->getValue('content'); + + $author_name = $this->getHandle($this->getAuthorPHID())->getName(); + $action = $this->getValue('action'); + $verb = PhabricatorAuditActionConstants::getActionPastTenseVerb($action); + + $title = "{$author_name} {$verb} this commit."; + if (strlen($comment)) { + $engine = PhabricatorMarkupEngine::newMarkupEngine(array()) + ->setConfig('viewer', new PhabricatorUser()) + ->setMode(PhutilRemarkupEngine::MODE_TEXT); + + $comment = $engine->markupText($comment); + + $title .= "\n\n"; + $title .= $comment; + } + + return $title; + } + } diff --git a/src/applications/repository/storage/PhabricatorRepositoryCommit.php b/src/applications/repository/storage/PhabricatorRepositoryCommit.php index 33504d237a..51002bdc77 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryCommit.php +++ b/src/applications/repository/storage/PhabricatorRepositoryCommit.php @@ -2,7 +2,8 @@ final class PhabricatorRepositoryCommit extends PhabricatorRepositoryDAO - implements PhabricatorPolicyInterface, + implements + PhabricatorPolicyInterface, PhabricatorTokenReceiverInterface { protected $repositoryID;