Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/differential/constants/DifferentialRevisionStatus.php b/src/applications/differential/constants/DifferentialRevisionStatus.php
index 70f0e33b28..e3acace3f0 100644
--- a/src/applications/differential/constants/DifferentialRevisionStatus.php
+++ b/src/applications/differential/constants/DifferentialRevisionStatus.php
@@ -1,184 +1,184 @@
<?php
final class DifferentialRevisionStatus extends Phobject {
const NEEDS_REVIEW = 'needs-review';
const NEEDS_REVISION = 'needs-revision';
const CHANGES_PLANNED = 'changes-planned';
const ACCEPTED = 'accepted';
const PUBLISHED = 'published';
const ABANDONED = 'abandoned';
const DRAFT = 'draft';
private $key;
private $spec = array();
public function getKey() {
return $this->key;
}
public function getLegacyKey() {
return idx($this->spec, 'legacy');
}
public function getIcon() {
return idx($this->spec, 'icon');
}
public function getIconColor() {
return idx($this->spec, 'color.icon', 'bluegrey');
}
public function getTagColor() {
return idx($this->spec, 'color.tag', 'bluegrey');
}
public function getTimelineIcon() {
return idx($this->spec, 'icon.timeline');
}
public function getTimelineColor() {
return idx($this->spec, 'color.timeline');
}
public function getANSIColor() {
return idx($this->spec, 'color.ansi');
}
public function getDisplayName() {
return idx($this->spec, 'name');
}
public function isClosedStatus() {
return idx($this->spec, 'closed');
}
public function isAbandoned() {
return ($this->key === self::ABANDONED);
}
public function isAccepted() {
return ($this->key === self::ACCEPTED);
}
public function isNeedsReview() {
return ($this->key === self::NEEDS_REVIEW);
}
public function isNeedsRevision() {
return ($this->key === self::NEEDS_REVISION);
}
public function isPublished() {
return ($this->key === self::PUBLISHED);
}
public function isChangePlanned() {
return ($this->key === self::CHANGES_PLANNED);
}
public function isDraft() {
return ($this->key === self::DRAFT);
}
public static function newForStatus($status) {
$result = new self();
$map = self::getMap();
if (isset($map[$status])) {
$result->key = $status;
$result->spec = $map[$status];
}
return $result;
}
public static function getAll() {
$result = array();
foreach (self::getMap() as $key => $spec) {
$result[$key] = self::newForStatus($key);
}
return $result;
}
private static function getMap() {
$close_on_accept = PhabricatorEnv::getEnvConfig(
'differential.close-on-accept');
return array(
self::NEEDS_REVIEW => array(
'name' => pht('Needs Review'),
'legacy' => 0,
'icon' => 'fa-code',
'icon.timeline' => 'fa-undo',
'closed' => false,
'color.icon' => 'grey',
'color.tag' => 'bluegrey',
'color.ansi' => 'magenta',
'color.timeline' => 'orange',
),
self::NEEDS_REVISION => array(
'name' => pht('Needs Revision'),
'legacy' => 1,
'icon' => 'fa-refresh',
'icon.timeline' => 'fa-times',
'closed' => false,
'color.icon' => 'red',
'color.tag' => 'red',
'color.ansi' => 'red',
'color.timeline' => 'red',
),
self::CHANGES_PLANNED => array(
'name' => pht('Changes Planned'),
'legacy' => 5,
'icon' => 'fa-headphones',
'closed' => false,
'color.icon' => 'red',
'color.tag' => 'red',
'color.ansi' => 'red',
),
self::ACCEPTED => array(
'name' => pht('Accepted'),
'legacy' => 2,
'icon' => 'fa-check',
'icon.timeline' => 'fa-check',
'closed' => $close_on_accept,
'color.icon' => 'green',
'color.tag' => 'green',
'color.ansi' => 'green',
'color.timeline' => 'green',
),
self::PUBLISHED => array(
'name' => pht('Closed'),
'legacy' => 3,
'icon' => 'fa-check-square-o',
'closed' => true,
'color.icon' => 'black',
'color.tag' => 'indigo',
'color.ansi' => 'cyan',
),
self::ABANDONED => array(
'name' => pht('Abandoned'),
'legacy' => 4,
'icon' => 'fa-plane',
'closed' => true,
'color.icon' => 'black',
'color.tag' => 'indigo',
'color.ansi' => null,
),
self::DRAFT => array(
'name' => pht('Draft'),
// For legacy clients, treat this as though it is "Needs Review".
'legacy' => 0,
- 'icon' => 'fa-file-text-o',
+ 'icon' => 'fa-spinner',
'closed' => false,
- 'color.icon' => 'grey',
- 'color.tag' => 'grey',
+ 'color.icon' => 'pink',
+ 'color.tag' => 'pink',
'color.ansi' => null,
),
);
}
}
diff --git a/src/applications/differential/customfield/DifferentialDraftField.php b/src/applications/differential/customfield/DifferentialDraftField.php
index 5d625e3ce9..8147708bca 100644
--- a/src/applications/differential/customfield/DifferentialDraftField.php
+++ b/src/applications/differential/customfield/DifferentialDraftField.php
@@ -1,96 +1,116 @@
<?php
final class DifferentialDraftField
extends DifferentialCoreCustomField {
public function getFieldKey() {
return 'differential:draft';
}
public function getFieldName() {
return pht('Draft');
}
public function getFieldDescription() {
return pht('Show a warning about draft revisions.');
}
protected function readValueFromRevision(
DifferentialRevision $revision) {
return null;
}
public function shouldAppearInPropertyView() {
return true;
}
public function renderPropertyViewValue(array $handles) {
return null;
}
public function getWarningsForRevisionHeader(array $handles) {
$viewer = $this->getViewer();
$revision = $this->getObject();
if (!$revision->isDraft()) {
return array();
}
// If the author has held this revision as a draft explicitly, don't
- // show any misleading messages about it autosubmitting later.
+ // show any misleading messages about it autosubmitting later. We do show
+ // reminder text.
if ($revision->getHoldAsDraft()) {
- return array();
+ return array(
+ pht(
+ 'This is a draft revision that has not yet been submitted for '.
+ 'review.'),
+ );
}
$warnings = array();
$blocking_map = array(
HarbormasterBuildStatus::STATUS_FAILED,
HarbormasterBuildStatus::STATUS_ABORTED,
HarbormasterBuildStatus::STATUS_ERROR,
HarbormasterBuildStatus::STATUS_PAUSED,
HarbormasterBuildStatus::STATUS_DEADLOCKED,
);
$blocking_map = array_fuse($blocking_map);
$builds = $revision->loadActiveBuilds($viewer);
$waiting = array();
$blocking = array();
foreach ($builds as $build) {
if (isset($blocking_map[$build->getBuildStatus()])) {
$blocking[] = $build;
} else {
$waiting[] = $build;
}
}
$blocking_list = $viewer->renderHandleList(mpull($blocking, 'getPHID'))
->setAsInline(true);
$waiting_list = $viewer->renderHandleList(mpull($waiting, 'getPHID'))
->setAsInline(true);
if ($blocking) {
$warnings[] = pht(
'This draft revision will not be submitted for review because %s '.
'build(s) failed: %s.',
phutil_count($blocking),
$blocking_list);
$warnings[] = pht(
'Fix build failures and update the revision.');
} else if ($waiting) {
$warnings[] = pht(
'This draft revision will be sent for review once %s '.
'build(s) pass: %s.',
phutil_count($waiting),
$waiting_list);
} else {
$warnings[] = pht(
'This is a draft revision that has not yet been submitted for '.
'review.');
}
return $warnings;
}
+ public function getWarningsForDetailView() {
+ $revision = $this->getObject();
+
+ if (!$revision->isDraft()) {
+ return array();
+ }
+
+ return array(
+ pht(
+ 'This revision is currently a draft. You can leave comments, but '.
+ 'no one will be notified until the revision is submitted for '.
+ 'review.'),
+ );
+ }
+
}
diff --git a/src/applications/differential/editor/DifferentialRevisionEditEngine.php b/src/applications/differential/editor/DifferentialRevisionEditEngine.php
index fe1b983f1a..d462fd7571 100644
--- a/src/applications/differential/editor/DifferentialRevisionEditEngine.php
+++ b/src/applications/differential/editor/DifferentialRevisionEditEngine.php
@@ -1,338 +1,346 @@
<?php
final class DifferentialRevisionEditEngine
extends PhabricatorEditEngine {
private $diff;
const ENGINECONST = 'differential.revision';
const ACTIONGROUP_REVIEW = 'review';
const ACTIONGROUP_REVISION = 'revision';
public function getEngineName() {
return pht('Revisions');
}
public function getSummaryHeader() {
return pht('Configure Revision Forms');
}
public function getSummaryText() {
return pht(
'Configure creation and editing revision forms in Differential.');
}
public function getEngineApplicationClass() {
return 'PhabricatorDifferentialApplication';
}
public function isEngineConfigurable() {
return false;
}
protected function newEditableObject() {
$viewer = $this->getViewer();
return DifferentialRevision::initializeNewRevision($viewer);
}
protected function newObjectQuery() {
return id(new DifferentialRevisionQuery())
->needActiveDiffs(true)
->needReviewers(true)
->needReviewerAuthority(true);
}
protected function getObjectCreateTitleText($object) {
return pht('Create New Revision');
}
protected function getObjectEditTitleText($object) {
$monogram = $object->getMonogram();
$title = $object->getTitle();
$diff = $this->getDiff();
if ($diff) {
return pht('Update Revision %s: %s', $monogram, $title);
} else {
return pht('Edit Revision %s: %s', $monogram, $title);
}
}
protected function getObjectEditShortText($object) {
return $object->getMonogram();
}
protected function getObjectCreateShortText() {
return pht('Create Revision');
}
protected function getObjectName() {
return pht('Revision');
}
+ protected function getCommentViewButtonText($object) {
+ if ($object->isDraft()) {
+ return pht('Submit Quietly');
+ }
+
+ return parent::getCommentViewButtonText();
+ }
+
protected function getObjectViewURI($object) {
return $object->getURI();
}
protected function getEditorURI() {
return $this->getApplication()->getApplicationURI('revision/edit/');
}
public function setDiff(DifferentialDiff $diff) {
$this->diff = $diff;
return $this;
}
public function getDiff() {
return $this->diff;
}
protected function newCommentActionGroups() {
return array(
id(new PhabricatorEditEngineCommentActionGroup())
->setKey(self::ACTIONGROUP_REVIEW)
->setLabel(pht('Review Actions')),
id(new PhabricatorEditEngineCommentActionGroup())
->setKey(self::ACTIONGROUP_REVISION)
->setLabel(pht('Revision Actions')),
);
}
protected function buildCustomEditFields($object) {
$viewer = $this->getViewer();
$plan_required = PhabricatorEnv::getEnvConfig(
'differential.require-test-plan-field');
$plan_enabled = $this->isCustomFieldEnabled(
$object,
'differential:test-plan');
$diff = $this->getDiff();
if ($diff) {
$diff_phid = $diff->getPHID();
} else {
$diff_phid = null;
}
$is_create = $this->getIsCreate();
$is_update = ($diff && !$is_create);
$fields = array();
$fields[] = id(new PhabricatorHandlesEditField())
->setKey(DifferentialRevisionUpdateTransaction::EDITKEY)
->setLabel(pht('Update Diff'))
->setDescription(pht('New diff to create or update the revision with.'))
->setConduitDescription(pht('Create or update a revision with a diff.'))
->setConduitTypeDescription(pht('PHID of the diff.'))
->setTransactionType(
DifferentialRevisionUpdateTransaction::TRANSACTIONTYPE)
->setHandleParameterType(new AphrontPHIDListHTTPParameterType())
->setSingleValue($diff_phid)
->setIsConduitOnly(!$diff)
->setIsReorderable(false)
->setIsDefaultable(false)
->setIsInvisible(true)
->setIsLockable(false);
if ($is_update) {
$fields[] = id(new PhabricatorInstructionsEditField())
->setKey('update.help')
->setValue(pht('Describe the updates you have made to the diff.'));
$fields[] = id(new PhabricatorCommentEditField())
->setKey('update.comment')
->setLabel(pht('Comment'))
->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)
->setIsWebOnly(true)
->setDescription(pht('Comments providing context for the update.'));
$fields[] = id(new PhabricatorSubmitEditField())
->setKey('update.submit')
->setValue($this->getObjectEditButtonText($object));
$fields[] = id(new PhabricatorDividerEditField())
->setKey('update.note');
}
$fields[] = id(new PhabricatorTextEditField())
->setKey(DifferentialRevisionTitleTransaction::EDITKEY)
->setLabel(pht('Title'))
->setIsRequired(true)
->setTransactionType(
DifferentialRevisionTitleTransaction::TRANSACTIONTYPE)
->setDescription(pht('The title of the revision.'))
->setConduitDescription(pht('Retitle the revision.'))
->setConduitTypeDescription(pht('New revision title.'))
->setValue($object->getTitle());
$fields[] = id(new PhabricatorRemarkupEditField())
->setKey(DifferentialRevisionSummaryTransaction::EDITKEY)
->setLabel(pht('Summary'))
->setTransactionType(
DifferentialRevisionSummaryTransaction::TRANSACTIONTYPE)
->setDescription(pht('The summary of the revision.'))
->setConduitDescription(pht('Change the revision summary.'))
->setConduitTypeDescription(pht('New revision summary.'))
->setValue($object->getSummary());
if ($plan_enabled) {
$fields[] = id(new PhabricatorRemarkupEditField())
->setKey(DifferentialRevisionTestPlanTransaction::EDITKEY)
->setLabel(pht('Test Plan'))
->setIsRequired($plan_required)
->setTransactionType(
DifferentialRevisionTestPlanTransaction::TRANSACTIONTYPE)
->setDescription(
pht('Actions performed to verify the behavior of the change.'))
->setConduitDescription(pht('Update the revision test plan.'))
->setConduitTypeDescription(pht('New test plan.'))
->setValue($object->getTestPlan());
}
$fields[] = id(new PhabricatorDatasourceEditField())
->setKey(DifferentialRevisionReviewersTransaction::EDITKEY)
->setLabel(pht('Reviewers'))
->setDatasource(new DifferentialReviewerDatasource())
->setUseEdgeTransactions(true)
->setTransactionType(
DifferentialRevisionReviewersTransaction::TRANSACTIONTYPE)
->setCommentActionLabel(pht('Change Reviewers'))
->setDescription(pht('Reviewers for this revision.'))
->setConduitDescription(pht('Change the reviewers for this revision.'))
->setConduitTypeDescription(pht('New reviewers.'))
->setValue($object->getReviewerPHIDsForEdit());
$fields[] = id(new PhabricatorDatasourceEditField())
->setKey('repositoryPHID')
->setLabel(pht('Repository'))
->setDatasource(new DiffusionRepositoryDatasource())
->setTransactionType(
DifferentialRevisionRepositoryTransaction::TRANSACTIONTYPE)
->setDescription(pht('The repository the revision belongs to.'))
->setConduitDescription(pht('Change the repository for this revision.'))
->setConduitTypeDescription(pht('New repository.'))
->setSingleValue($object->getRepositoryPHID());
// This is a little flimsy, but allows "Maniphest Tasks: ..." to continue
// working properly in commit messages until we fully sort out T5873.
$fields[] = id(new PhabricatorHandlesEditField())
->setKey('tasks')
->setUseEdgeTransactions(true)
->setIsConduitOnly(true)
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
->setMetadataValue(
'edge:type',
DifferentialRevisionHasTaskEdgeType::EDGECONST)
->setDescription(pht('Tasks associated with this revision.'))
->setConduitDescription(pht('Change associated tasks.'))
->setConduitTypeDescription(pht('List of tasks.'))
->setValue(array());
$actions = DifferentialRevisionActionTransaction::loadAllActions();
$actions = msortv($actions, 'getRevisionActionOrderVector');
foreach ($actions as $key => $action) {
$fields[] = $action->newEditField($object, $viewer);
}
$fields[] = id(new PhabricatorBoolEditField())
->setKey('draft')
->setLabel(pht('Hold as Draft'))
->setIsConduitOnly(true)
->setOptions(
pht('Autosubmit Once Builds Finish'),
pht('Hold as Draft'))
->setTransactionType(
DifferentialRevisionHoldDraftTransaction::TRANSACTIONTYPE)
->setDescription(pht('Hold revision as as draft.'))
->setConduitDescription(
pht(
'Change autosubmission from draft state after builds finish.'))
->setConduitTypeDescription(pht('New "Hold as Draft" setting.'))
->setValue($object->getHoldAsDraft());
return $fields;
}
private function isCustomFieldEnabled(DifferentialRevision $revision, $key) {
$field_list = PhabricatorCustomField::getObjectFields(
$revision,
PhabricatorCustomField::ROLE_VIEW);
$fields = $field_list->getFields();
return isset($fields[$key]);
}
protected function newAutomaticCommentTransactions($object) {
$viewer = $this->getViewer();
$xactions = array();
$inlines = DifferentialTransactionQuery::loadUnsubmittedInlineComments(
$viewer,
$object);
$inlines = msort($inlines, 'getID');
foreach ($inlines as $inline) {
$xactions[] = id(new DifferentialTransaction())
->setTransactionType(DifferentialTransaction::TYPE_INLINE)
->attachComment($inline);
}
$viewer_phid = $viewer->getPHID();
$viewer_is_author = ($object->getAuthorPHID() == $viewer_phid);
if ($viewer_is_author) {
$state_map = PhabricatorTransactions::getInlineStateMap();
$inlines = id(new DifferentialDiffInlineCommentQuery())
->setViewer($viewer)
->withRevisionPHIDs(array($object->getPHID()))
->withFixedStates(array_keys($state_map))
->execute();
if ($inlines) {
$old_value = mpull($inlines, 'getFixedState', 'getPHID');
$new_value = array();
foreach ($old_value as $key => $state) {
$new_value[$key] = $state_map[$state];
}
$xactions[] = id(new DifferentialTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_INLINESTATE)
->setIgnoreOnNoEffect(true)
->setOldValue($old_value)
->setNewValue($new_value);
}
}
return $xactions;
}
protected function newCommentPreviewContent($object, array $xactions) {
$viewer = $this->getViewer();
$type_inline = DifferentialTransaction::TYPE_INLINE;
$inlines = array();
foreach ($xactions as $xaction) {
if ($xaction->getTransactionType() === $type_inline) {
$inlines[] = $xaction->getComment();
}
}
$content = array();
if ($inlines) {
$inline_preview = id(new PHUIDiffInlineCommentPreviewListView())
->setViewer($viewer)
->setInlineComments($inlines);
$content[] = phutil_tag(
'div',
array(
'id' => 'inline-comment-preview',
),
$inline_preview);
}
return $content;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Thu, Jul 3, 8:44 PM (1 h, 19 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
166383
Default Alt Text
(20 KB)

Event Timeline