Page MenuHomePhorge

No OneTemporary

diff --git a/src/applications/releeph/conduit/ConduitAPI_releeph_request_Method.php b/src/applications/releeph/conduit/ConduitAPI_releeph_request_Method.php
index 2f37062428..bd9d0be36f 100644
--- a/src/applications/releeph/conduit/ConduitAPI_releeph_request_Method.php
+++ b/src/applications/releeph/conduit/ConduitAPI_releeph_request_Method.php
@@ -1,159 +1,157 @@
<?php
final class ConduitAPI_releeph_request_Method
extends ConduitAPI_releeph_Method {
public function getMethodDescription() {
return "Request a commit or diff to be picked to a branch.";
}
public function defineParamTypes() {
return array(
'branchPHID' => 'required string',
'things' => 'required string',
'fields' => 'dict<string, string>',
);
}
public function defineReturnType() {
return 'dict<string, wild>';
}
public function defineErrorTypes() {
return array(
"ERR_BRANCH" => 'Unknown Releeph branch.',
"ERR_FIELD_PARSE" => 'Unable to parse a Releeph field.',
);
}
protected function execute(ConduitAPIRequest $request) {
$user = $request->getUser();
+
+ $viewer_handle = id(new PhabricatorHandleQuery())
+ ->setViewer($user)
+ ->withPHIDs(array($user->getPHID()))
+ ->executeOne();
+
$branch_phid = $request->getValue('branchPHID');
$releeph_branch = id(new ReleephBranch())
->loadOneWhere('phid = %s', $branch_phid);
if (!$releeph_branch) {
throw id(new ConduitException("ERR_BRANCH"))->setErrorDescription(
"No ReleephBranch found with PHID {$branch_phid}!");
}
$releeph_project = $releeph_branch->loadReleephProject();
// Find the requested commit identifiers
$requested_commits = array();
$things = $request->getValue('things');
$finder = id(new ReleephCommitFinder())
->setUser($user)
->setReleephProject($releeph_project);
foreach ($things as $thing) {
try {
$requested_commits[$thing] = $finder->fromPartial($thing);
} catch (ReleephCommitFinderException $ex) {
throw id(new ConduitException('ERR_NO_MATCHES'))
->setErrorDescription($ex->getMessage());
}
}
$requested_commit_phids = mpull($requested_commits, 'getPHID');
// Find any existing requests that clash on the commit id, for this branch
$existing_releeph_requests = id(new ReleephRequest())->loadAllWhere(
'requestCommitPHID IN (%Ls) AND branchID = %d',
$requested_commit_phids,
$releeph_branch->getID());
$existing_releeph_requests = mpull(
$existing_releeph_requests,
null,
'getRequestCommitPHID');
$selector = $releeph_project->getReleephFieldSelector();
$fields = $selector->getFieldSpecifications();
foreach ($fields as $field) {
$field
->setReleephProject($releeph_project)
->setReleephBranch($releeph_branch);
}
$results = array();
$handles = id(new PhabricatorHandleQuery())
->setViewer($user)
->withPHIDs($requested_commit_phids)
->execute();
foreach ($requested_commits as $thing => $commit) {
$phid = $commit->getPHID();
$name = id($handles[$phid])->getName();
$releeph_request = null;
$existing_releeph_request = idx($existing_releeph_requests, $phid);
if ($existing_releeph_request) {
$releeph_request = $existing_releeph_request;
} else {
$releeph_request = id(new ReleephRequest())
->setRequestUserPHID($user->getPHID())
->setBranchID($releeph_branch->getID())
->setInBranch(0);
$xactions = array();
$xactions[] = id(new ReleephRequestTransaction())
->setTransactionType(ReleephRequestTransaction::TYPE_REQUEST)
->setNewValue($commit->getPHID());
$xactions[] = id(new ReleephRequestTransaction())
->setTransactionType(ReleephRequestTransaction::TYPE_USER_INTENT)
->setMetadataValue('userPHID', $user->getPHID())
->setMetadataValue(
'isAuthoritative',
$releeph_project->isAuthoritative($user))
->setNewValue(ReleephRequest::INTENT_WANT);
foreach ($fields as $field) {
if (!$field->isEditable()) {
continue;
}
$field->setReleephRequest($releeph_request);
try {
$field->setValueFromConduitAPIRequest($request);
} catch (ReleephFieldParseException $ex) {
throw id(new ConduitException('ERR_FIELD_PARSE'))
->setErrorDescription($ex->getMessage());
}
}
$editor = id(new ReleephRequestTransactionalEditor())
->setActor($user)
->setContinueOnNoEffect(true)
->setContentSource(
PhabricatorContentSource::newForSource(
PhabricatorContentSource::SOURCE_CONDUIT,
array()));
$editor->applyTransactions($releeph_request, $xactions);
}
- $releeph_branch->populateReleephRequestHandles(
- $user,
- array($releeph_request));
- $rq_handles = $releeph_request->getHandles();
- $requestor_phid = $releeph_request->getRequestUserPHID();
- $requestor = $rq_handles[$requestor_phid]->getName();
-
- $url = PhabricatorEnv::getProductionURI('/RQ'.$releeph_request->getID());
-
+ $url = PhabricatorEnv::getProductionURI('/Y'.$releeph_request->getID());
$results[$thing] = array(
'thing' => $thing,
'branch' => $releeph_branch->getDisplayNameWithDetail(),
'commitName' => $name,
'commitID' => $commit->getCommitIdentifier(),
'url' => $url,
'requestID' => $releeph_request->getID(),
- 'requestor' => $requestor,
+ 'requestor' => $viewer_handle->getName(),
'requestTime' => $releeph_request->getDateCreated(),
'existing' => $existing_releeph_request !== null,
);
}
return $results;
}
}
diff --git a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_nextrequest_Method.php b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_nextrequest_Method.php
index 15bb60b710..125d9f10da 100644
--- a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_nextrequest_Method.php
+++ b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_nextrequest_Method.php
@@ -1,209 +1,214 @@
<?php
final class ConduitAPI_releephwork_nextrequest_Method
extends ConduitAPI_releeph_Method {
private $project;
private $branch;
public function getMethodStatus() {
return self::METHOD_STATUS_UNSTABLE;
}
public function getMethodDescription() {
return
"Return info required to cut a branch, ".
"and pick and revert ReleephRequests";
}
public function defineParamTypes() {
return array(
- 'branchPHID' => 'required int',
- 'seen' => 'required list<string, bool>',
+ 'branchPHID' => 'required phid',
+ 'seen' => 'required map<string, bool>',
);
}
public function defineReturnType() {
return '';
}
public function defineErrorTypes() {
return array(
'ERR-NOT-PUSHER' =>
'You are not listed as a pusher for thie Releeph project!',
);
}
protected function execute(ConduitAPIRequest $request) {
+ $viewer = $request->getUser();
$seen = $request->getValue('seen');
$branch = id(new ReleephBranch())
->loadOneWhere('phid = %s', $request->getValue('branchPHID'));
$project = $branch->loadReleephProject();
$needs_pick = array();
$needs_revert = array();
- $releeph_requests = $branch->loadReleephRequests($request->getUser());
+ // Load every request ever made for this branch...?!!!
+ $releeph_requests = id(new ReleephRequestQuery())
+ ->setViewer($viewer)
+ ->withBranchIDs(array($branch->getID()))
+ ->execute();
foreach ($releeph_requests as $candidate) {
$phid = $candidate->getPHID();
if (idx($seen, $phid)) {
continue;
}
$should = $candidate->shouldBeInBranch();
$in = $candidate->getInBranch();
if ($should && !$in) {
$needs_pick[] = $candidate;
}
if (!$should && $in) {
$needs_revert[] = $candidate;
}
}
/**
* Sort both needs_pick and needs_revert in ascending commit order, as
* discovered by Phabricator (using the `id` column to perform that
* ordering).
*
* This is easy for $needs_pick as the ordinal is stored. It is hard for
* reverts, as we have to look that information up.
*/
$needs_pick = $this->sortPicks($needs_pick);
$needs_revert = $this->sortReverts($needs_revert);
/**
* Do reverts first in reverse order, then the picks in original-commit
* order.
*
* This seems like the correct thing to do, but there may be a better
* algorithm for the releephwork.nextrequest Conduit call that orders
* things better.
*
* We could also button-mash our way through everything that failed (at the
* end of the run) to try failed things again.
*/
$releeph_request = null;
$action = null;
if ($needs_revert) {
$releeph_request = last($needs_revert);
$action = 'revert';
$commit_id = $releeph_request->getCommitIdentifier();
$commit_phid = $releeph_request->getCommitPHID();
} elseif ($needs_pick) {
$releeph_request = head($needs_pick);
$action = 'pick';
$commit = $releeph_request->loadPhabricatorRepositoryCommit();
$commit_id = $commit->getCommitIdentifier();
$commit_phid = $commit->getPHID();
} else {
// Return early if there's nothing to do!
return array();
}
// Build the response
$phids = array();
$phids[] = $commit_phid;
$diff_phid = null;
$diff_rev_id = null;
$diff_rev = $releeph_request->loadDifferentialRevision();
if ($diff_rev) {
$diff_phid = $diff_rev->getPHID();
$phids[] = $diff_phid;
$diff_rev_id = $diff_rev->getID();
}
$phids[] = $releeph_request->getPHID();
$handles = id(new PhabricatorHandleQuery())
->setViewer($request->getUser())
->withPHIDs($phids)
->execute();
$diff_name = null;
if ($diff_rev) {
$diff_name = $handles[$diff_phid]->getName();
}
$new_author_phid = null;
if ($diff_rev) {
$new_author_phid = $diff_rev->getAuthorPHID();
} else {
$pr_commit = $releeph_request->loadPhabricatorRepositoryCommit();
if ($pr_commit) {
$new_author_phid = $pr_commit->getAuthorPHID();
}
}
return array(
'requestID' => $releeph_request->getID(),
'requestPHID' => $releeph_request->getPHID(),
'requestName' => $handles[$releeph_request->getPHID()]->getName(),
'requestorPHID' => $releeph_request->getRequestUserPHID(),
'action' => $action,
'diffRevID' => $diff_rev_id,
'diffName' => $diff_name,
'commitIdentifier' => $commit_id,
'commitPHID' => $commit_phid,
'commitName' => $handles[$commit_phid]->getName(),
'needsRevert' => mpull($needs_revert, 'getID'),
'needsPick' => mpull($needs_pick, 'getID'),
'newAuthorPHID' => $new_author_phid,
);
}
private function sortPicks(array $releeph_requests) {
$surrogate = array();
foreach ($releeph_requests as $rq) {
// TODO: it's likely that relying on the `id` column to provide
// trunk-commit-order is thoroughly broken.
$ordinal = (int) $rq->loadPhabricatorRepositoryCommit()->getID();
$surrogate[$ordinal] = $rq;
}
ksort($surrogate);
return $surrogate;
}
/**
* Sort an array of ReleephRequests, that have been picked into a branch, in
* the order in which they were picked to the branch.
*/
private function sortReverts(array $releeph_requests) {
if (!$releeph_requests) {
return array();
}
// ReleephRequests, keyed by <branch-commit-id>
$releeph_requests = mpull($releeph_requests, null, 'getCommitIdentifier');
$commits = id(new PhabricatorRepositoryCommit())
->loadAllWhere(
'commitIdentifier IN (%Ls)',
mpull($releeph_requests, 'getCommitIdentifier'));
// A map of <branch-commit-id> => <branch-commit-ordinal>
$surrogate = mpull($commits, 'getID', 'getCommitIdentifier');
$unparsed = array();
$result = array();
foreach ($releeph_requests as $commit_id => $releeph_request) {
$ordinal = idx($surrogate, $commit_id);
if ($ordinal) {
$result[$ordinal] = $releeph_request;
} else {
$unparsed[] = $releeph_request;
}
}
// Sort $result in ascending order
ksort($result);
// Unparsed commits we'll just have to guess, based on time
$unparsed = msort($unparsed, 'getDateModified');
return array_merge($result, $unparsed);
}
}
diff --git a/src/applications/releeph/controller/request/ReleephRequestEditController.php b/src/applications/releeph/controller/request/ReleephRequestEditController.php
index 89ca4e08b7..e9e78cabbd 100644
--- a/src/applications/releeph/controller/request/ReleephRequestEditController.php
+++ b/src/applications/releeph/controller/request/ReleephRequestEditController.php
@@ -1,301 +1,312 @@
<?php
final class ReleephRequestEditController extends ReleephBranchController {
private $requestID;
private $branchID;
public function willProcessRequest(array $data) {
$this->requestID = idx($data, 'requestID');
$this->branchID = idx($data, 'branchID');
}
public function processRequest() {
$request = $this->getRequest();
$viewer = $request->getUser();
if ($this->requestID) {
$pull = id(new ReleephRequestQuery())
->setViewer($viewer)
->withIDs(array($this->requestID))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$pull) {
return new Aphront404Response();
}
$branch = $pull->getBranch();
$is_edit = true;
} else {
$branch = id(new ReleephBranchQuery())
->setViewer($viewer)
->withIDs(array($this->branchID))
->executeOne();
if (!$branch) {
return new Aphront404Response();
}
$pull = id(new ReleephRequest())
->setRequestUserPHID($viewer->getPHID())
->setBranchID($branch->getID())
->setInBranch(0);
$is_edit = false;
}
$this->setBranch($branch);
$product = $branch->getProduct();
$request_identifier = $request->getStr('requestIdentifierRaw');
$e_request_identifier = true;
// Load all the ReleephFieldSpecifications
$selector = $branch->getProduct()->getReleephFieldSelector();
$fields = $selector->getFieldSpecifications();
foreach ($fields as $field) {
$field
->setReleephProject($product)
->setReleephBranch($branch)
->setReleephRequest($pull);
}
$field_list = PhabricatorCustomField::getObjectFields(
$pull,
PhabricatorCustomField::ROLE_EDIT);
foreach ($field_list->getFields() as $field) {
$field
->setReleephProject($product)
->setReleephBranch($branch)
->setReleephRequest($pull);
}
$field_list->readFieldsFromStorage($pull);
if ($this->branchID) {
$cancel_uri = $this->getApplicationURI('branch/'.$this->branchID.'/');
} else {
$cancel_uri = '/'.$pull->getMonogram();
}
// Make edits
$errors = array();
if ($request->isFormPost()) {
$xactions = array();
// The commit-identifier being requested...
if (!$is_edit) {
if ($request_identifier ===
ReleephRequestTypeaheadControl::PLACEHOLDER) {
$errors[] = "No commit ID was provided.";
$e_request_identifier = 'Required';
} else {
$pr_commit = null;
$finder = id(new ReleephCommitFinder())
->setUser($viewer)
->setReleephProject($product);
try {
$pr_commit = $finder->fromPartial($request_identifier);
} catch (Exception $e) {
$e_request_identifier = 'Invalid';
$errors[] =
"Request {$request_identifier} is probably not a valid commit";
$errors[] = $e->getMessage();
}
$pr_commit_data = null;
if (!$errors) {
$pr_commit_data = $pr_commit->loadCommitData();
if (!$pr_commit_data) {
$e_request_identifier = 'Not parsed yet';
$errors[] = "The requested commit hasn't been parsed yet.";
}
}
}
if (!$errors) {
$existing = id(new ReleephRequest())
->loadOneWhere('requestCommitPHID = %s AND branchID = %d',
$pr_commit->getPHID(), $branch->getID());
if ($existing) {
return id(new AphrontRedirectResponse())
->setURI('/releeph/request/edit/'.$existing->getID().
'?existing=1');
}
$xactions[] = id(new ReleephRequestTransaction())
->setTransactionType(ReleephRequestTransaction::TYPE_REQUEST)
->setNewValue($pr_commit->getPHID());
$xactions[] = id(new ReleephRequestTransaction())
->setTransactionType(ReleephRequestTransaction::TYPE_USER_INTENT)
// To help hide these implicit intents...
->setMetadataValue('isRQCreate', true)
->setMetadataValue('userPHID', $viewer->getPHID())
->setMetadataValue(
'isAuthoritative',
$product->isAuthoritative($viewer))
->setNewValue(ReleephRequest::INTENT_WANT);
}
}
// TODO: This should happen implicitly while building transactions
// instead.
foreach ($field_list->getFields() as $field) {
$field->readValueFromRequest($request);
}
if (!$errors) {
foreach ($fields as $field) {
if ($field->isEditable()) {
try {
$data = $request->getRequestData();
$value = idx($data, $field->getRequiredStorageKey());
$field->validate($value);
$xactions[] = id(new ReleephRequestTransaction())
->setTransactionType(ReleephRequestTransaction::TYPE_EDIT_FIELD)
->setMetadataValue('fieldClass', get_class($field))
->setNewValue($value);
} catch (ReleephFieldParseException $ex) {
$errors[] = $ex->getMessage();
}
}
}
}
if (!$errors) {
$editor = id(new ReleephRequestTransactionalEditor())
->setActor($viewer)
->setContinueOnNoEffect(true)
->setContentSourceFromRequest($request);
$editor->applyTransactions($pull, $xactions);
return id(new AphrontRedirectResponse())->setURI($cancel_uri);
}
}
- $branch->populateReleephRequestHandles($viewer, array($pull));
- $handles = $pull->getHandles();
+ $handle_phids = array(
+ $pull->getRequestUserPHID(),
+ $pull->getRequestCommitPHID(),
+ );
+ $handle_phids = array_filter($handle_phids);
+ if ($handle_phids) {
+ $handles = id(new PhabricatorHandleQuery())
+ ->setViewer($viewer)
+ ->withPHIDs($handle_phids)
+ ->execute();
+ } else {
+ $handles = array();
+ }
$age_string = '';
if ($is_edit) {
$age_string = phabricator_format_relative_time(
time() - $pull->getDateCreated()) . ' ago';
}
// Warn the user if we've been redirected here because we tried to
// re-request something.
$notice_view = null;
if ($request->getInt('existing')) {
$notice_messages = array(
'You are editing an existing pick request!',
hsprintf(
"Requested %s by %s",
$age_string,
$handles[$pull->getRequestUserPHID()]->renderLink())
);
$notice_view = id(new AphrontErrorView())
->setSeverity(AphrontErrorView::SEVERITY_NOTICE)
->setErrors($notice_messages);
}
$form = id(new AphrontFormView())
->setUser($viewer);
if ($is_edit) {
$form
->appendChild(
id(new AphrontFormMarkupControl())
->setLabel('Original Commit')
->setValue(
$handles[$pull->getRequestCommitPHID()]->renderLink()))
->appendChild(
id(new AphrontFormMarkupControl())
->setLabel('Requestor')
->setValue(hsprintf(
'%s %s',
$handles[$pull->getRequestUserPHID()]->renderLink(),
$age_string)));
} else {
$origin = null;
$diff_rev_id = $request->getStr('D');
if ($diff_rev_id) {
$diff_rev = id(new DifferentialRevisionQuery())
->setViewer($viewer)
->withIDs(array($diff_rev_id))
->executeOne();
$origin = '/D'.$diff_rev->getID();
$title = sprintf(
'D%d: %s',
$diff_rev_id,
$diff_rev->getTitle());
$form
->addHiddenInput('requestIdentifierRaw', 'D'.$diff_rev_id)
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('Diff')
->setValue($title));
} else {
$origin = $branch->getURI();
$repo = $product->loadPhabricatorRepository();
$branch_cut_point = id(new PhabricatorRepositoryCommit())
->loadOneWhere(
'phid = %s',
$branch->getCutPointCommitPHID());
$form->appendChild(
id(new ReleephRequestTypeaheadControl())
->setName('requestIdentifierRaw')
->setLabel('Commit ID')
->setRepo($repo)
->setValue($request_identifier)
->setError($e_request_identifier)
->setStartTime($branch_cut_point->getEpoch())
->setCaption(
'Start typing to autocomplete on commit title, '.
'or give a Phabricator commit identifier like rFOO1234'));
}
}
$field_list->appendFieldsToForm($form);
$crumbs = $this->buildApplicationCrumbs();
if ($is_edit) {
$title = pht('Edit Pull Request');
$submit_name = pht('Save');
$crumbs->addTextCrumb($pull->getMonogram(), '/'.$pull->getMonogram());
$crumbs->addTextCrumb(pht('Edit'));
} else {
$title = pht('Create Pull Request');
$submit_name = pht('Create Pull Request');
$crumbs->addTextCrumb(pht('New Pull Request'));
}
$form->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton($cancel_uri, 'Cancel')
->setValue($submit_name));
$box = id(new PHUIObjectBoxView())
->setHeaderText($title)
->setFormErrors($errors)
->appendChild($form);
return $this->buildApplicationPage(
array(
$crumbs,
$notice_view,
$box,
),
array(
'title' => $title,
'device' => true,
));
}
}
diff --git a/src/applications/releeph/field/specification/ReleephBranchCommitFieldSpecification.php b/src/applications/releeph/field/specification/ReleephBranchCommitFieldSpecification.php
index 24def10c0f..ea9c334bf9 100644
--- a/src/applications/releeph/field/specification/ReleephBranchCommitFieldSpecification.php
+++ b/src/applications/releeph/field/specification/ReleephBranchCommitFieldSpecification.php
@@ -1,34 +1,28 @@
<?php
final class ReleephBranchCommitFieldSpecification
extends ReleephFieldSpecification {
public function getFieldKey() {
return 'commit';
}
public function getName() {
return 'Commit';
}
- public function renderPropertyViewValue(array $handles) {
- $rr = $this->getReleephRequest();
- if (!$rr->getInBranch()) {
- return null;
+ public function getRequiredHandlePHIDsForPropertyView() {
+ $pull = $this->getReleephRequest();
+
+ if ($pull->getCommitPHID()) {
+ return array($pull->getCommitPHID());
}
- $c_phid = $rr->getCommitPHID();
- $c_id = $rr->getCommitIdentifier();
+ return array();
+ }
- if ($c_phid) {
- $handles = $rr->getHandles();
- $val = $handles[$c_phid]->renderLink();
- } else if ($c_id) {
- $val = $c_id;
- } else {
- $val = '???';
- }
- return $val;
+ public function renderPropertyViewValue(array $handles) {
+ return $this->renderHandleList($handles);
}
}
diff --git a/src/applications/releeph/storage/ReleephBranch.php b/src/applications/releeph/storage/ReleephBranch.php
index 2375bdbcfc..be6fc11428 100644
--- a/src/applications/releeph/storage/ReleephBranch.php
+++ b/src/applications/releeph/storage/ReleephBranch.php
@@ -1,202 +1,162 @@
<?php
final class ReleephBranch extends ReleephDAO
implements PhabricatorPolicyInterface {
protected $releephProjectID;
protected $isActive;
protected $createdByUserPHID;
// The immutable name of this branch ('releases/foo-2013.01.24')
protected $name;
protected $basename;
// The symbolic name of this branch (LATEST, PRODUCTION, RC, ...)
// See SYMBOLIC_NAME_NOTE below
protected $symbolicName;
// Where to cut the branch
protected $cutPointCommitPHID;
protected $details = array();
private $project = self::ATTACHABLE;
private $cutPointCommit = self::ATTACHABLE;
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_SERIALIZATION => array(
'details' => self::SERIALIZATION_JSON,
),
) + parent::getConfiguration();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(ReleephPHIDTypeBranch::TYPECONST);
}
public function getDetail($key, $default = null) {
return idx($this->getDetails(), $key, $default);
}
public function setDetail($key, $value) {
$this->details[$key] = $value;
return $this;
}
public function willWriteData(array &$data) {
// If symbolicName is omitted, set it to the basename.
//
// This means that we can enforce symbolicName as a UNIQUE column in the
// DB. We'll interpret symbolicName === basename as meaning "no symbolic
// name".
//
// SYMBOLIC_NAME_NOTE
if (!$data['symbolicName']) {
$data['symbolicName'] = $data['basename'];
}
parent::willWriteData($data);
}
public function getSymbolicName() {
// See SYMBOLIC_NAME_NOTE above for why this is needed
if ($this->symbolicName == $this->getBasename()) {
return '';
}
return $this->symbolicName;
}
public function setSymbolicName($name) {
if ($name) {
parent::setSymbolicName($name);
} else {
parent::setSymbolicName($this->getBasename());
}
return $this;
}
public function getDisplayName() {
if ($sn = $this->getSymbolicName()) {
return $sn;
}
return $this->getBasename();
}
public function getDisplayNameWithDetail() {
$n = $this->getBasename();
if ($sn = $this->getSymbolicName()) {
return "{$sn} ({$n})";
} else {
return $n;
}
}
public function getURI($path = null) {
$components = array(
'/releeph',
rawurlencode($this->loadReleephProject()->getName()),
rawurlencode($this->getBasename()),
$path
);
return implode('/', $components);
}
public function loadReleephProject() {
return $this->loadOneRelative(
new ReleephProject(),
'id',
'getReleephProjectID');
}
- private function loadReleephRequestHandles(PhabricatorUser $user, $reqs) {
- $phids_to_phetch = array();
- foreach ($reqs as $rr) {
- $phids_to_phetch[] = $rr->getRequestCommitPHID();
- $phids_to_phetch[] = $rr->getRequestUserPHID();
- $phids_to_phetch[] = $rr->getCommitPHID();
-
- $intents = $rr->getUserIntents();
- if ($intents) {
- foreach ($intents as $user_phid => $intent) {
- $phids_to_phetch[] = $user_phid;
- }
- }
-
- $request_commit = $rr->loadPhabricatorRepositoryCommit();
- if ($request_commit) {
- $phids_to_phetch[] = $request_commit->getAuthorPHID();
- $phids_to_phetch[] = $rr->loadRequestCommitDiffPHID();
- }
- }
- $handles = id(new PhabricatorHandleQuery())
- ->setViewer($user)
- ->withPHIDs($phids_to_phetch)
- ->execute();
- return $handles;
- }
-
- public function populateReleephRequestHandles(PhabricatorUser $user, $reqs) {
- $handles = $this->loadReleephRequestHandles($user, $reqs);
- foreach ($reqs as $req) {
- $req->setHandles($handles);
- }
- }
-
- public function loadReleephRequests(PhabricatorUser $user) {
- $reqs = $this->loadRelatives(new ReleephRequest(), 'branchID');
- $this->populateReleephRequestHandles($user, $reqs);
- return $reqs;
- }
-
public function isActive() {
return $this->getIsActive();
}
public function attachProject(ReleephProject $project) {
$this->project = $project;
return $this;
}
public function getProject() {
return $this->assertAttached($this->project);
}
public function getProduct() {
return $this->getProject();
}
public function attachCutPointCommit(
PhabricatorRepositoryCommit $commit = null) {
$this->cutPointCommit = $commit;
return $this;
}
public function getCutPointCommit() {
return $this->assertAttached($this->cutPointCommit);
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */
public function getCapabilities() {
return $this->getProduct()->getCapabilities();
}
public function getPolicy($capability) {
return $this->getProduct()->getPolicy($capability);
}
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
return $this->getProduct()->hasAutomaticCapability($capability, $viewer);
}
public function describeAutomaticCapability($capability) {
return pht(
'Release branches have the same policies as the product they are a '.
'part of.');
}
}
diff --git a/src/applications/releeph/storage/ReleephRequest.php b/src/applications/releeph/storage/ReleephRequest.php
index 6a1f442831..92f7de87a5 100644
--- a/src/applications/releeph/storage/ReleephRequest.php
+++ b/src/applications/releeph/storage/ReleephRequest.php
@@ -1,342 +1,330 @@
<?php
final class ReleephRequest extends ReleephDAO
implements
PhabricatorPolicyInterface,
PhabricatorCustomFieldInterface {
protected $branchID;
protected $requestUserPHID;
protected $details = array();
protected $userIntents = array();
protected $inBranch;
protected $pickStatus;
protected $mailKey;
// Information about the thing being requested
protected $requestCommitPHID;
// Information about the last commit to the releeph branch
protected $commitIdentifier;
protected $commitPHID;
- // Pre-populated handles that we'll bulk load in ReleephBranch
- private $handles = self::ATTACHABLE;
-
private $customFields = self::ATTACHABLE;
private $branch = self::ATTACHABLE;
-
/* -( Constants and helper methods )--------------------------------------- */
const INTENT_WANT = 'want';
const INTENT_PASS = 'pass';
const PICK_PENDING = 1; // old
const PICK_FAILED = 2;
const PICK_OK = 3;
const PICK_MANUAL = 4; // old
const REVERT_OK = 5;
const REVERT_FAILED = 6;
public function shouldBeInBranch() {
return
$this->getPusherIntent() == self::INTENT_WANT &&
/**
* We use "!= pass" instead of "== want" in case the requestor intent is
* not present. In other words, only revert if the requestor explicitly
* passed.
*/
$this->getRequestorIntent() != self::INTENT_PASS;
}
/**
* Will return INTENT_WANT if any pusher wants this request, and no pusher
* passes on this request.
*/
public function getPusherIntent() {
$project = $this->loadReleephProject();
if (!$project) {
return null;
}
if (!$project->getPushers()) {
return self::INTENT_WANT;
}
$found_pusher_want = false;
foreach ($this->userIntents as $phid => $intent) {
if ($project->isAuthoritativePHID($phid)) {
if ($intent == self::INTENT_PASS) {
return self::INTENT_PASS;
}
$found_pusher_want = true;
}
}
if ($found_pusher_want) {
return self::INTENT_WANT;
} else {
return null;
}
}
public function getRequestorIntent() {
return idx($this->userIntents, $this->requestUserPHID);
}
public function getStatus() {
return $this->calculateStatus();
}
public function getMonogram() {
return 'Y'.$this->getID();
}
public function getBranch() {
return $this->assertAttached($this->branch);
}
public function attachBranch(ReleephBranch $branch) {
$this->branch = $branch;
return $this;
}
private function calculateStatus() {
if ($this->shouldBeInBranch()) {
if ($this->getInBranch()) {
return ReleephRequestStatus::STATUS_PICKED;
} else {
return ReleephRequestStatus::STATUS_NEEDS_PICK;
}
} else {
if ($this->getInBranch()) {
return ReleephRequestStatus::STATUS_NEEDS_REVERT;
} else {
$has_been_in_branch = $this->getCommitIdentifier();
// Regardless of why we reverted something, always say reverted if it
// was once in the branch.
if ($has_been_in_branch) {
return ReleephRequestStatus::STATUS_REVERTED;
} elseif ($this->getPusherIntent() === ReleephRequest::INTENT_PASS) {
// Otherwise, if it has never been in the branch, explicitly say why:
return ReleephRequestStatus::STATUS_REJECTED;
} elseif ($this->getRequestorIntent() === ReleephRequest::INTENT_WANT) {
return ReleephRequestStatus::STATUS_REQUESTED;
} else {
return ReleephRequestStatus::STATUS_ABANDONED;
}
}
}
}
/* -( Lisk mechanics )----------------------------------------------------- */
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_SERIALIZATION => array(
'details' => self::SERIALIZATION_JSON,
'userIntents' => self::SERIALIZATION_JSON,
),
) + parent::getConfiguration();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
ReleephPHIDTypeRequest::TYPECONST);
}
public function save() {
if (!$this->getMailKey()) {
$this->setMailKey(Filesystem::readRandomCharacters(20));
}
return parent::save();
}
/* -( Helpful accessors )--------------------------------------------------- */
- public function setHandles($handles) {
- $this->handles = $handles;
- return $this;
- }
-
- public function getHandles() {
- return $this->assertAttached($this->handles);
- }
public function getDetail($key, $default = null) {
return idx($this->getDetails(), $key, $default);
}
public function setDetail($key, $value) {
$this->details[$key] = $value;
return $this;
}
public function getReason() {
// Backward compatibility: reason used to be called comments
$reason = $this->getDetail('reason');
if (!$reason) {
return $this->getDetail('comments');
}
return $reason;
}
/**
* Allow a null summary, and fall back to the title of the commit.
*/
public function getSummaryForDisplay() {
$summary = $this->getDetail('summary');
if (!strlen($summary)) {
$commit = $this->loadPhabricatorRepositoryCommit();
if ($commit) {
$summary = $commit->getSummary();
}
}
if (!strlen($summary)) {
$summary = pht('None');
}
return $summary;
}
public function loadRequestCommitDiffPHID() {
$phids = array();
$commit = $this->loadPhabricatorRepositoryCommit();
if ($commit) {
$phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
$commit->getPHID(),
PhabricatorEdgeConfig::TYPE_COMMIT_HAS_DREV);
}
return head($phids);
}
/* -( Loading external objects )------------------------------------------- */
public function loadReleephBranch() {
return $this->loadOneRelative(
new ReleephBranch(),
'id',
'getBranchID');
}
public function loadReleephProject() {
$branch = $this->loadReleephBranch();
if ($branch) {
return $branch->loadReleephProject();
}
}
public function loadPhabricatorRepositoryCommit() {
return $this->loadOneRelative(
new PhabricatorRepositoryCommit(),
'phid',
'getRequestCommitPHID');
}
public function loadPhabricatorRepositoryCommitData() {
$commit = $this->loadPhabricatorRepositoryCommit();
if ($commit) {
return $commit->loadOneRelative(
new PhabricatorRepositoryCommitData(),
'commitID');
}
}
// TODO: (T603) Get rid of all this one-off ad-hoc loading.
public function loadDifferentialRevision() {
$diff_phid = $this->loadRequestCommitDiffPHID();
if (!$diff_phid) {
return null;
}
return $this->loadOneRelative(
new DifferentialRevision(),
'phid',
'loadRequestCommitDiffPHID');
}
/* -( State change helpers )----------------------------------------------- */
public function setUserIntent(PhabricatorUser $user, $intent) {
$this->userIntents[$user->getPHID()] = $intent;
return $this;
}
/* -( Migrating to status-less ReleephRequests )--------------------------- */
protected function didReadData() {
if ($this->userIntents === null) {
$this->userIntents = array();
}
}
public function setStatus($value) {
throw new Exception('`status` is now deprecated!');
}
/* -( Make magic Lisk methods private )------------------------------------ */
private function setUserIntents(array $ar) {
return parent::setUserIntents($ar);
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
);
}
public function getPolicy($capability) {
return $this->getBranch()->getPolicy($capability);
}
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
return $this->getBranch()->hasAutomaticCapability($capability, $viewer);
}
public function describeAutomaticCapability($capability) {
return pht(
'Pull requests have the same policies as the branches they are '.
'requested against.');
}
/* -( PhabricatorCustomFieldInterface )------------------------------------ */
public function getCustomFieldSpecificationForRole($role) {
return PhabricatorEnv::getEnvConfig('releeph.fields');
}
public function getCustomFieldBaseClass() {
return 'ReleephFieldSpecification';
}
public function getCustomFields() {
return $this->assertAttached($this->customFields);
}
public function attachCustomFields(PhabricatorCustomFieldAttachment $fields) {
$this->customFields = $fields;
return $this;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Sun, Jan 19, 20:15 (1 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1128360
Default Alt Text
(39 KB)

Event Timeline