2014-08-20 23:26:29 +02:00
|
|
|
<?php
|
|
|
|
|
2014-11-19 00:32:23 +01:00
|
|
|
final class DifferentialDiffEditor
|
|
|
|
extends PhabricatorApplicationTransactionEditor {
|
2014-08-20 23:26:29 +02:00
|
|
|
|
2014-11-19 00:32:23 +01:00
|
|
|
private $diffDataDict;
|
Differential - refine selecting a repository diff --> revision workflow
Summary: Fixes T6200. Ref T6237. When creating a diff from the web view, allow the user to select the repository at that time. When viewing a diff that has no associated revision and then creating a revision, pass along the repository phid to the create revision controller. Within the create revision controller, default the repository selector to this repository phid. Finally, in the editor, stop aggressively resetting the repository phid for every TYPE_UPDATE; rather, do so if its not a new object -- the diff should reign supreme in that case -- or if there's no repository -- let the diff be the guide.
Test Plan:
- made a diff with an associated repo, made a revision from the diff, saw the associated repo and it stuck on save!
- made a diff with an associated repo, made a revision from the diff but changed the repo and it stuck on save!
- made a diff with an associated repo, made a revision from the diff but changed the repo to nothing and it stuck on save!
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin, epriestley
Maniphest Tasks: T6237, T6200
Differential Revision: https://secure.phabricator.com/D10872
2014-11-19 20:11:09 +01:00
|
|
|
private $lookupRepository = true;
|
|
|
|
|
|
|
|
public function setLookupRepository($bool) {
|
|
|
|
$this->lookupRepository = $bool;
|
|
|
|
return $this;
|
|
|
|
}
|
2014-08-20 23:26:29 +02:00
|
|
|
|
2014-11-19 00:32:23 +01:00
|
|
|
public function getEditorApplicationClass() {
|
|
|
|
return 'PhabricatorDifferentialApplication';
|
2014-08-20 23:26:29 +02:00
|
|
|
}
|
|
|
|
|
2014-11-19 00:32:23 +01:00
|
|
|
public function getEditorObjectsDescription() {
|
|
|
|
return pht('Differential Diffs');
|
2014-08-20 23:26:29 +02:00
|
|
|
}
|
|
|
|
|
2014-11-19 00:32:23 +01:00
|
|
|
public function getTransactionTypes() {
|
|
|
|
$types = parent::getTransactionTypes();
|
2014-08-20 23:26:29 +02:00
|
|
|
|
2014-11-19 21:16:07 +01:00
|
|
|
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
|
2014-11-19 00:32:23 +01:00
|
|
|
$types[] = DifferentialDiffTransaction::TYPE_DIFF_CREATE;
|
2014-08-20 23:26:29 +02:00
|
|
|
|
2014-11-19 00:32:23 +01:00
|
|
|
return $types;
|
|
|
|
}
|
2014-08-20 23:26:29 +02:00
|
|
|
|
2014-11-19 00:32:23 +01:00
|
|
|
protected function getCustomTransactionOldValue(
|
|
|
|
PhabricatorLiskDAO $object,
|
|
|
|
PhabricatorApplicationTransaction $xaction) {
|
2014-08-20 23:26:29 +02:00
|
|
|
|
2014-11-19 00:32:23 +01:00
|
|
|
switch ($xaction->getTransactionType()) {
|
|
|
|
case DifferentialDiffTransaction::TYPE_DIFF_CREATE:
|
|
|
|
return null;
|
|
|
|
}
|
2014-08-20 23:26:29 +02:00
|
|
|
|
2014-11-19 00:32:23 +01:00
|
|
|
return parent::getCustomTransactionOldValue($object, $xaction);
|
|
|
|
}
|
2014-08-20 23:26:29 +02:00
|
|
|
|
2014-11-19 00:32:23 +01:00
|
|
|
protected function getCustomTransactionNewValue(
|
|
|
|
PhabricatorLiskDAO $object,
|
|
|
|
PhabricatorApplicationTransaction $xaction) {
|
2014-08-20 23:26:29 +02:00
|
|
|
|
2014-11-19 00:32:23 +01:00
|
|
|
switch ($xaction->getTransactionType()) {
|
|
|
|
case DifferentialDiffTransaction::TYPE_DIFF_CREATE:
|
|
|
|
$this->diffDataDict = $xaction->getNewValue();
|
|
|
|
return true;
|
2014-08-20 23:26:29 +02:00
|
|
|
}
|
|
|
|
|
2014-11-19 00:32:23 +01:00
|
|
|
return parent::getCustomTransactionNewValue($object, $xaction);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function applyCustomInternalTransaction(
|
|
|
|
PhabricatorLiskDAO $object,
|
|
|
|
PhabricatorApplicationTransaction $xaction) {
|
|
|
|
|
|
|
|
switch ($xaction->getTransactionType()) {
|
|
|
|
case DifferentialDiffTransaction::TYPE_DIFF_CREATE:
|
|
|
|
$dict = $this->diffDataDict;
|
|
|
|
$this->updateDiffFromDict($object, $dict);
|
|
|
|
return;
|
2014-11-19 21:16:07 +01:00
|
|
|
case PhabricatorTransactions::TYPE_VIEW_POLICY:
|
|
|
|
$object->setViewPolicy($xaction->getNewValue());
|
|
|
|
return;
|
2014-11-19 00:32:23 +01:00
|
|
|
}
|
2014-08-20 23:26:29 +02:00
|
|
|
|
2014-11-19 00:32:23 +01:00
|
|
|
return parent::applyCustomInternalTransaction($object, $xaction);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function applyCustomExternalTransaction(
|
|
|
|
PhabricatorLiskDAO $object,
|
|
|
|
PhabricatorApplicationTransaction $xaction) {
|
|
|
|
|
|
|
|
switch ($xaction->getTransactionType()) {
|
|
|
|
case DifferentialDiffTransaction::TYPE_DIFF_CREATE:
|
2014-11-19 21:16:07 +01:00
|
|
|
case PhabricatorTransactions::TYPE_VIEW_POLICY:
|
2014-11-19 00:32:23 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
return parent::applyCustomExternalTransaction($object, $xaction);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function applyFinalEffects(
|
|
|
|
PhabricatorLiskDAO $object,
|
|
|
|
array $xactions) {
|
|
|
|
|
|
|
|
// 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.
|
|
|
|
|
Differential - refine selecting a repository diff --> revision workflow
Summary: Fixes T6200. Ref T6237. When creating a diff from the web view, allow the user to select the repository at that time. When viewing a diff that has no associated revision and then creating a revision, pass along the repository phid to the create revision controller. Within the create revision controller, default the repository selector to this repository phid. Finally, in the editor, stop aggressively resetting the repository phid for every TYPE_UPDATE; rather, do so if its not a new object -- the diff should reign supreme in that case -- or if there's no repository -- let the diff be the guide.
Test Plan:
- made a diff with an associated repo, made a revision from the diff, saw the associated repo and it stuck on save!
- made a diff with an associated repo, made a revision from the diff but changed the repo and it stuck on save!
- made a diff with an associated repo, made a revision from the diff but changed the repo to nothing and it stuck on save!
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin, epriestley
Maniphest Tasks: T6237, T6200
Differential Revision: https://secure.phabricator.com/D10872
2014-11-19 20:11:09 +01:00
|
|
|
if ($this->lookupRepository && !$object->getRepositoryPHID()) {
|
2014-11-19 00:32:23 +01:00
|
|
|
$repository = id(new DifferentialRepositoryLookup())
|
|
|
|
->setDiff($object)
|
|
|
|
->setViewer($this->getActor())
|
|
|
|
->lookupRepository();
|
|
|
|
if ($repository) {
|
|
|
|
$object->setRepositoryPHID($repository->getPHID());
|
|
|
|
$object->setRepositoryUUID($repository->getUUID());
|
|
|
|
$object->save();
|
2014-08-20 23:26:29 +02:00
|
|
|
}
|
2014-11-19 00:32:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return $xactions;
|
|
|
|
}
|
2014-08-20 23:26:29 +02:00
|
|
|
|
2014-11-19 00:32:23 +01:00
|
|
|
/**
|
|
|
|
* We run Herald as part of transaction validation because Herald can
|
|
|
|
* block diff creation for Differential diffs. Its important to do this
|
|
|
|
* separately so no Herald logs are saved; these logs could expose
|
|
|
|
* information the Herald rules are inteneded to block.
|
|
|
|
*/
|
|
|
|
protected function validateTransaction(
|
|
|
|
PhabricatorLiskDAO $object,
|
|
|
|
$type,
|
|
|
|
array $xactions) {
|
|
|
|
|
|
|
|
$errors = parent::validateTransaction($object, $type, $xactions);
|
|
|
|
|
|
|
|
foreach ($xactions as $xaction) {
|
|
|
|
switch ($type) {
|
|
|
|
case DifferentialDiffTransaction::TYPE_DIFF_CREATE:
|
|
|
|
$diff = clone $object;
|
|
|
|
$diff = $this->updateDiffFromDict($diff, $xaction->getNewValue());
|
|
|
|
|
|
|
|
$adapter = $this->buildHeraldAdapter($diff, $xactions);
|
|
|
|
$adapter->setContentSource($this->getContentSource());
|
|
|
|
$adapter->setIsNewObject($this->getIsNewObject());
|
|
|
|
|
|
|
|
$engine = new HeraldEngine();
|
|
|
|
|
|
|
|
$rules = $engine->loadRulesForAdapter($adapter);
|
|
|
|
$rules = mpull($rules, null, 'getID');
|
|
|
|
|
|
|
|
$effects = $engine->applyRules($rules, $adapter);
|
|
|
|
|
|
|
|
$blocking_effect = null;
|
|
|
|
foreach ($effects as $effect) {
|
|
|
|
if ($effect->getAction() == HeraldAdapter::ACTION_BLOCK) {
|
|
|
|
$blocking_effect = $effect;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($blocking_effect) {
|
|
|
|
$rule = idx($rules, $effect->getRuleID());
|
|
|
|
if ($rule && strlen($rule->getName())) {
|
|
|
|
$rule_name = $rule->getName();
|
|
|
|
} else {
|
|
|
|
$rule_name = pht('Unnamed Herald Rule');
|
|
|
|
}
|
|
|
|
|
|
|
|
$message = $effect->getTarget();
|
|
|
|
if (!strlen($message)) {
|
|
|
|
$message = pht('(None.)');
|
|
|
|
}
|
|
|
|
|
|
|
|
$errors[] = new PhabricatorApplicationTransactionValidationError(
|
|
|
|
$type,
|
|
|
|
pht('Rejected by Herald'),
|
|
|
|
pht(
|
|
|
|
"Creation of this diff was rejected by Herald rule %s.\n".
|
|
|
|
" Rule: %s\n".
|
|
|
|
"Reason: %s",
|
|
|
|
'H'.$effect->getRuleID(),
|
|
|
|
$rule_name,
|
|
|
|
$message));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2014-08-20 23:26:29 +02:00
|
|
|
}
|
|
|
|
|
2014-11-19 00:32:23 +01:00
|
|
|
return $errors;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected function shouldPublishFeedStory(
|
|
|
|
PhabricatorLiskDAO $object,
|
|
|
|
array $xactions) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function shouldSendMail(
|
|
|
|
PhabricatorLiskDAO $object,
|
|
|
|
array $xactions) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function supportsSearch() {
|
|
|
|
return false;
|
|
|
|
}
|
2014-08-20 23:26:29 +02:00
|
|
|
|
2014-11-19 00:32:23 +01:00
|
|
|
/* -( Herald Integration )------------------------------------------------- */
|
2014-08-20 23:26:29 +02:00
|
|
|
|
2014-11-19 00:32:23 +01:00
|
|
|
/**
|
|
|
|
* See @{method:validateTransaction}. The only Herald action is to block
|
|
|
|
* the creation of Diffs. We thus have to be careful not to save any
|
|
|
|
* data and do this validation very early.
|
|
|
|
*/
|
|
|
|
protected function shouldApplyHeraldRules(
|
|
|
|
PhabricatorLiskDAO $object,
|
|
|
|
array $xactions) {
|
2014-08-20 23:26:29 +02:00
|
|
|
|
2014-11-19 00:32:23 +01:00
|
|
|
return false;
|
2014-08-20 23:26:29 +02:00
|
|
|
}
|
|
|
|
|
2014-11-19 00:32:23 +01:00
|
|
|
protected function buildHeraldAdapter(
|
|
|
|
PhabricatorLiskDAO $object,
|
|
|
|
array $xactions) {
|
|
|
|
|
|
|
|
$adapter = id(new HeraldDifferentialDiffAdapter())
|
|
|
|
->setDiff($object);
|
|
|
|
|
|
|
|
return $adapter;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function didApplyHeraldRules(
|
|
|
|
PhabricatorLiskDAO $object,
|
|
|
|
HeraldAdapter $adapter,
|
|
|
|
HeraldTranscript $transcript) {
|
|
|
|
|
|
|
|
$xactions = array();
|
|
|
|
return $xactions;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function updateDiffFromDict(DifferentialDiff $diff, $dict) {
|
|
|
|
$diff
|
|
|
|
->setSourcePath(idx($dict, 'sourcePath'))
|
|
|
|
->setSourceMachine(idx($dict, 'sourceMachine'))
|
|
|
|
->setBranch(idx($dict, 'branch'))
|
|
|
|
->setCreationMethod(idx($dict, 'creationMethod'))
|
|
|
|
->setAuthorPHID(idx($dict, 'authorPHID', $this->getActor()))
|
|
|
|
->setBookmark(idx($dict, 'bookmark'))
|
|
|
|
->setRepositoryPHID(idx($dict, 'repositoryPHID'))
|
|
|
|
->setRepositoryUUID(idx($dict, 'repositoryUUID'))
|
|
|
|
->setSourceControlSystem(idx($dict, 'sourceControlSystem'))
|
|
|
|
->setSourceControlPath(idx($dict, 'sourceControlPath'))
|
|
|
|
->setSourceControlBaseRevision(idx($dict, 'sourceControlBaseRevision'))
|
|
|
|
->setLintStatus(idx($dict, 'lintStatus'))
|
|
|
|
->setUnitStatus(idx($dict, 'unitStatus'))
|
|
|
|
->setArcanistProjectPHID(idx($dict, 'arcanistProjectPHID'));
|
|
|
|
|
|
|
|
return $diff;
|
|
|
|
}
|
2014-08-20 23:26:29 +02:00
|
|
|
}
|