2013-06-21 21:54:29 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
final class DifferentialTransaction extends PhabricatorApplicationTransaction {
|
|
|
|
|
Migrate Differential comments to ApplicationTransactions
Summary:
Ref T2222. This is the big one.
This migrates each `DifferentialComment` to one or more ApplicationTransactions (action, cc, reviewers, update, comment, inlines), and makes `DifferentialComment` a double-reader for ApplicationTransactions.
The migration is pretty straightforward:
- If a comment took an action not otherwise covered, it gets an "action" transaction. This is something like "epriestley abandoned this revision.".
- If a comment updated the diff, it gets an "updated diff" transaction. Very old transactions of this type may not have a diff ID (probably only at Facebook).
- If a comment added or removed reviewers, it gets a "changed reviewers" transaction.
- If a comment added CCs, it gets a "subscribers" transaction.
- If a comment added comment text, it gets a "comment" transaction.
- For each inline attached to a comment, we generate an "inline" transaction.
Most comments generate a small number of transactions, but a few generate a significant number.
At HEAD, the code is basically already doing this, so comments in the last day or two already obey these rules, roughly, and will all generate only one transaction (except inlines).
Because we've already preallocated PHIDs in the comment text table, we only need to write to the transaction table.
NOTE: This significantly degrades Differential, making inline comments pretty much useless (they each get their own transaction, and don't show line numbers or files). The data is all fine, but the UI is garbage now. This needs to be fixed before we can deploy this to users, but it's easily separable since it's all just display code.
Specifically, they look like this:
{F112270}
Test Plan:
I've migrated locally and put things through their paces, but it's hard to catch sketchy stuff locally because most of my test data is nonsense and bad migrations wouldn't necessarily look out of place.
IMPORTANT: I'm planning to push this to a branch and then shift production over to the branch, and run it for a day or two before bringing it to master.
I generally feel good about this change: it's not that big since we were able to separate a lot of pieces out of it, and it's pretty straightforward. That said, it's still one of the most scary/dangerous changes we've ever made.
Reviewers: btrahan
CC: chad, aran
Maniphest Tasks: T2222
Differential Revision: https://secure.phabricator.com/D8210
2014-02-12 00:36:58 +01:00
|
|
|
const TYPE_INLINE = 'differential:inline';
|
|
|
|
const TYPE_UPDATE = 'differential:update';
|
|
|
|
const TYPE_ACTION = 'differential:action';
|
|
|
|
|
2013-06-21 21:54:29 +02:00
|
|
|
public function getApplicationName() {
|
|
|
|
return 'differential';
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getApplicationTransactionType() {
|
2013-07-21 17:11:37 +02:00
|
|
|
return DifferentialPHIDTypeRevision::TYPECONST;
|
2013-06-21 21:54:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function getApplicationTransactionCommentObject() {
|
|
|
|
return new DifferentialTransactionComment();
|
|
|
|
}
|
|
|
|
|
2014-02-12 23:05:40 +01:00
|
|
|
public function getTitle() {
|
|
|
|
$author_phid = $this->getAuthorPHID();
|
2014-02-14 00:35:44 +01:00
|
|
|
$author_handle = $this->renderHandleLink($author_phid);
|
2014-02-12 23:05:40 +01:00
|
|
|
|
|
|
|
$old = $this->getOldValue();
|
|
|
|
$new = $this->getNewValue();
|
|
|
|
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case self::TYPE_INLINE:
|
|
|
|
return pht(
|
|
|
|
'%s added inline comments.',
|
2014-02-14 00:35:44 +01:00
|
|
|
$author_handle);
|
|
|
|
case self::TYPE_UPDATE:
|
|
|
|
if ($new) {
|
|
|
|
// TODO: Migrate to PHIDs and use handles here?
|
|
|
|
// TODO: Link this?
|
|
|
|
return pht(
|
|
|
|
'%s updated this revision to Diff #%d.',
|
|
|
|
$author_handle,
|
|
|
|
$new);
|
|
|
|
} else {
|
|
|
|
return pht(
|
|
|
|
'%s updated this revision.',
|
|
|
|
$author_handle);
|
|
|
|
}
|
|
|
|
case self::TYPE_ACTION:
|
|
|
|
return DifferentialAction::getBasicStoryText($new, $author_handle);
|
2014-02-12 23:05:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return parent::getTitle();
|
|
|
|
}
|
|
|
|
|
2014-02-14 00:35:44 +01:00
|
|
|
public function getIcon() {
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case self::TYPE_INLINE:
|
|
|
|
return 'comment';
|
|
|
|
case self::TYPE_UPDATE:
|
|
|
|
return 'refresh';
|
|
|
|
case self::TYPE_ACTION:
|
|
|
|
switch ($this->getNewValue()) {
|
|
|
|
case DifferentialAction::ACTION_CLOSE:
|
|
|
|
return 'ok';
|
|
|
|
case DifferentialAction::ACTION_ACCEPT:
|
|
|
|
return 'enable';
|
|
|
|
case DifferentialAction::ACTION_REJECT:
|
|
|
|
case DifferentialAction::ACTION_ABANDON:
|
|
|
|
return 'delete';
|
|
|
|
case DifferentialAction::ACTION_RETHINK:
|
|
|
|
return 'disable';
|
|
|
|
case DifferentialAction::ACTION_REQUEST:
|
|
|
|
return 'refresh';
|
|
|
|
case DifferentialAction::ACTION_RECLAIM:
|
|
|
|
case DifferentialAction::ACTION_REOPEN:
|
|
|
|
return 'new';
|
|
|
|
case DifferentialAction::ACTION_RESIGN:
|
|
|
|
return 'undo';
|
|
|
|
case DifferentialAction::ACTION_CLAIM:
|
|
|
|
return 'user';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return parent::getIcon();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getColor() {
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case self::TYPE_UPDATE:
|
|
|
|
return PhabricatorTransactions::COLOR_SKY;
|
|
|
|
case self::TYPE_ACTION:
|
|
|
|
switch ($this->getNewValue()) {
|
|
|
|
case DifferentialAction::ACTION_CLOSE:
|
|
|
|
return PhabricatorTransactions::COLOR_BLUE;
|
|
|
|
case DifferentialAction::ACTION_ACCEPT:
|
|
|
|
return PhabricatorTransactions::COLOR_GREEN;
|
|
|
|
case DifferentialAction::ACTION_REJECT:
|
|
|
|
return PhabricatorTransactions::COLOR_RED;
|
|
|
|
case DifferentialAction::ACTION_ABANDON:
|
|
|
|
return PhabricatorTransactions::COLOR_BLACK;
|
|
|
|
case DifferentialAction::ACTION_RETHINK:
|
|
|
|
return PhabricatorTransactions::COLOR_RED;
|
|
|
|
case DifferentialAction::ACTION_REQUEST:
|
|
|
|
return PhabricatorTransactions::COLOR_SKY;
|
|
|
|
case DifferentialAction::ACTION_RECLAIM:
|
|
|
|
return PhabricatorTransactions::COLOR_SKY;
|
|
|
|
case DifferentialAction::ACTION_REOPEN:
|
|
|
|
return PhabricatorTransactions::COLOR_SKY;
|
|
|
|
case DifferentialAction::ACTION_RESIGN:
|
|
|
|
return PhabricatorTransactions::COLOR_ORANGE;
|
|
|
|
case DifferentialAction::ACTION_CLAIM:
|
|
|
|
return PhabricatorTransactions::COLOR_YELLOW;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return parent::getColor();
|
|
|
|
}
|
|
|
|
|
2014-02-25 00:57:26 +01:00
|
|
|
public function getNoEffectDescription() {
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case PhabricatorTransactions::TYPE_EDGE:
|
|
|
|
switch ($this->getMetadataValue('edge:type')) {
|
|
|
|
case PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER:
|
|
|
|
return pht(
|
|
|
|
'Those reviewers are already reviewing this revision.');
|
|
|
|
}
|
2014-02-25 00:57:49 +01:00
|
|
|
break;
|
|
|
|
case DifferentialTransaction::TYPE_ACTION:
|
|
|
|
switch ($this->getNewValue()) {
|
|
|
|
case DifferentialAction::ACTION_CLOSE:
|
|
|
|
return pht('This revision is already closed.');
|
|
|
|
case DifferentialAction::ACTION_ABANDON:
|
|
|
|
return pht('This revision has already been abandoned.');
|
|
|
|
case DifferentialAction::ACTION_RECLAIM:
|
|
|
|
return pht(
|
|
|
|
'You can not reclaim this revision because his revision is '.
|
|
|
|
'not abandoned.');
|
|
|
|
case DifferentialAction::ACTION_REOPEN:
|
|
|
|
return pht(
|
|
|
|
'You can not reopen this revision because this revision is '.
|
|
|
|
'not closed.');
|
|
|
|
case DifferentialAction::ACTION_RETHINK:
|
|
|
|
return pht('This revision already requires changes.');
|
|
|
|
case DifferentialAction::ACTION_REQUEST:
|
|
|
|
return pht('Review is already requested for this revision.');
|
|
|
|
}
|
|
|
|
break;
|
2014-02-25 00:57:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return parent::getNoEffectDescription();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-21 21:54:29 +02:00
|
|
|
}
|