Merge branch 'master' into blender-tweaks

This commit is contained in:
2018-10-22 12:31:30 +02:00
242 changed files with 5182 additions and 1957 deletions

View File

@@ -9,10 +9,10 @@ return array(
'names' => array(
'conpherence.pkg.css' => 'e68cf1fa',
'conpherence.pkg.js' => '15191c65',
'core.pkg.css' => '84d8ab9a',
'core.pkg.js' => '2058ec09',
'core.pkg.css' => '5efaf405',
'core.pkg.js' => 'b5a949ca',
'differential.pkg.css' => '06dc617c',
'differential.pkg.js' => 'ef19e026',
'differential.pkg.js' => 'c1cfa143',
'diffusion.pkg.css' => 'a2d17c7d',
'diffusion.pkg.js' => '6134c5a1',
'maniphest.pkg.css' => '4845691a',
@@ -75,7 +75,7 @@ return array(
'rsrc/css/application/feed/feed.css' => 'ecd4ec57',
'rsrc/css/application/files/global-drag-and-drop.css' => 'b556a948',
'rsrc/css/application/flag/flag.css' => 'bba8f811',
'rsrc/css/application/harbormaster/harbormaster.css' => '730a4a3c',
'rsrc/css/application/harbormaster/harbormaster.css' => '7446ce72',
'rsrc/css/application/herald/herald-test.css' => 'a52e323e',
'rsrc/css/application/herald/herald.css' => 'cd8d0134',
'rsrc/css/application/maniphest/report.css' => '9b9580b7',
@@ -122,7 +122,7 @@ return array(
'rsrc/css/layout/phabricator-source-code-view.css' => '2ab25dfa',
'rsrc/css/phui/button/phui-button-bar.css' => 'f1ff5494',
'rsrc/css/phui/button/phui-button-simple.css' => '8e1baf68',
'rsrc/css/phui/button/phui-button.css' => '1863cc6e',
'rsrc/css/phui/button/phui-button.css' => '6ccb303c',
'rsrc/css/phui/calendar/phui-calendar-day.css' => '572b1893',
'rsrc/css/phui/calendar/phui-calendar-list.css' => '576be600',
'rsrc/css/phui/calendar/phui-calendar-month.css' => '21154caf',
@@ -146,15 +146,15 @@ return array(
'rsrc/css/phui/phui-comment-panel.css' => 'f50152ad',
'rsrc/css/phui/phui-crumbs-view.css' => '10728aaa',
'rsrc/css/phui/phui-curtain-view.css' => '2bdaf026',
'rsrc/css/phui/phui-document-pro.css' => '8af7ea27',
'rsrc/css/phui/phui-document-pro.css' => 'dd79b5df',
'rsrc/css/phui/phui-document-summary.css' => '9ca48bdf',
'rsrc/css/phui/phui-document.css' => '878c2f52',
'rsrc/css/phui/phui-document.css' => 'c4ac41f9',
'rsrc/css/phui/phui-feed-story.css' => '44a9c8e9',
'rsrc/css/phui/phui-fontkit.css' => '1320ed01',
'rsrc/css/phui/phui-form-view.css' => 'b446e8ff',
'rsrc/css/phui/phui-form-view.css' => '739c78df',
'rsrc/css/phui/phui-form.css' => '7aaa04e3',
'rsrc/css/phui/phui-head-thing.css' => 'fd311e5f',
'rsrc/css/phui/phui-header-view.css' => 'edeb9252',
'rsrc/css/phui/phui-header-view.css' => '1ba8b707',
'rsrc/css/phui/phui-hovercard.css' => 'f0592bcf',
'rsrc/css/phui/phui-icon-set-selector.css' => '87db8fee',
'rsrc/css/phui/phui-icon.css' => 'cf24ceec',
@@ -375,12 +375,12 @@ return array(
'rsrc/js/application/dashboard/behavior-dashboard-query-panel-select.js' => '453c5375',
'rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js' => 'd4eecc63',
'rsrc/js/application/diff/DiffChangeset.js' => 'b49b59d6',
'rsrc/js/application/diff/DiffChangesetList.js' => 'f0ffe8c3',
'rsrc/js/application/diff/DiffChangesetList.js' => 'e0b984b5',
'rsrc/js/application/diff/DiffInline.js' => 'e83d28f3',
'rsrc/js/application/diff/behavior-preview-link.js' => '051c7832',
'rsrc/js/application/differential/behavior-comment-preview.js' => '51c5ad07',
'rsrc/js/application/differential/behavior-diff-radios.js' => 'e1ff79b1',
'rsrc/js/application/differential/behavior-populate.js' => '419998ab',
'rsrc/js/application/differential/behavior-populate.js' => 'f0eb6708',
'rsrc/js/application/differential/behavior-user-select.js' => 'a8d8459d',
'rsrc/js/application/diffusion/DiffusionLocateFileSource.js' => '00676f00',
'rsrc/js/application/diffusion/behavior-audit-preview.js' => 'd835b03a',
@@ -395,7 +395,7 @@ return array(
'rsrc/js/application/files/behavior-launch-icon-composer.js' => '48086888',
'rsrc/js/application/harbormaster/behavior-harbormaster-log.js' => '549459b8',
'rsrc/js/application/herald/HeraldRuleEditor.js' => 'dca75c0e',
'rsrc/js/application/herald/PathTypeahead.js' => '662e9cea',
'rsrc/js/application/herald/PathTypeahead.js' => '6d8c7912',
'rsrc/js/application/herald/herald-rule-editor.js' => '7ebaeed3',
'rsrc/js/application/maniphest/behavior-batch-selector.js' => 'ad54037e',
'rsrc/js/application/maniphest/behavior-line-chart.js' => 'e4232876',
@@ -425,7 +425,7 @@ return array(
'rsrc/js/application/search/behavior-reorder-profile-menu-items.js' => 'e2e0a072',
'rsrc/js/application/search/behavior-reorder-queries.js' => 'e9581f08',
'rsrc/js/application/slowvote/behavior-slowvote-embed.js' => '887ad43f',
'rsrc/js/application/transactions/behavior-comment-actions.js' => '9a6dd75c',
'rsrc/js/application/transactions/behavior-comment-actions.js' => '038bf27f',
'rsrc/js/application/transactions/behavior-reorder-configs.js' => 'd7a74243',
'rsrc/js/application/transactions/behavior-reorder-fields.js' => 'b59e1e96',
'rsrc/js/application/transactions/behavior-show-older-transactions.js' => '8f29b364',
@@ -475,7 +475,7 @@ return array(
'rsrc/js/core/behavior-more.js' => 'a80d0378',
'rsrc/js/core/behavior-object-selector.js' => '77c1f0b0',
'rsrc/js/core/behavior-oncopy.js' => '2926fff2',
'rsrc/js/core/behavior-phabricator-nav.js' => '94b7c320',
'rsrc/js/core/behavior-phabricator-nav.js' => '9d32bc88',
'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => 'acd29eee',
'rsrc/js/core/behavior-read-only-warning.js' => 'ba158207',
'rsrc/js/core/behavior-redirect.js' => '0213259f',
@@ -508,7 +508,7 @@ return array(
'rsrc/js/phuix/PHUIXActionListView.js' => 'b5c256b8',
'rsrc/js/phuix/PHUIXActionView.js' => '8d4a8c72',
'rsrc/js/phuix/PHUIXAutocomplete.js' => 'df1bbd34',
'rsrc/js/phuix/PHUIXButtonView.js' => '8a91e1ac',
'rsrc/js/phuix/PHUIXButtonView.js' => '85ac9772',
'rsrc/js/phuix/PHUIXDropdownMenu.js' => '04b2ae03',
'rsrc/js/phuix/PHUIXExample.js' => '68af71ca',
'rsrc/js/phuix/PHUIXFormControl.js' => '210a16c1',
@@ -556,7 +556,7 @@ return array(
'font-fontawesome' => 'e838e088',
'font-lato' => 'c7ccd872',
'global-drag-and-drop-css' => 'b556a948',
'harbormaster-css' => '730a4a3c',
'harbormaster-css' => '7446ce72',
'herald-css' => 'cd8d0134',
'herald-rule-editor' => 'dca75c0e',
'herald-test-css' => 'a52e323e',
@@ -577,7 +577,7 @@ return array(
'javelin-behavior-bulk-job-reload' => 'edf8a145',
'javelin-behavior-calendar-month-view' => 'fe33e256',
'javelin-behavior-choose-control' => '327a00d1',
'javelin-behavior-comment-actions' => '9a6dd75c',
'javelin-behavior-comment-actions' => '038bf27f',
'javelin-behavior-config-reorder-fields' => 'b6993408',
'javelin-behavior-conpherence-menu' => '4047cd35',
'javelin-behavior-conpherence-participant-pane' => 'd057e45a',
@@ -596,7 +596,7 @@ return array(
'javelin-behavior-diff-preview-link' => '051c7832',
'javelin-behavior-differential-diff-radios' => 'e1ff79b1',
'javelin-behavior-differential-feedback-preview' => '51c5ad07',
'javelin-behavior-differential-populate' => '419998ab',
'javelin-behavior-differential-populate' => 'f0eb6708',
'javelin-behavior-differential-user-select' => 'a8d8459d',
'javelin-behavior-diffusion-commit-branches' => 'bdaf4d04',
'javelin-behavior-diffusion-commit-graph' => '75b83cbb',
@@ -633,7 +633,7 @@ return array(
'javelin-behavior-phabricator-keyboard-pager' => 'a8da01f0',
'javelin-behavior-phabricator-keyboard-shortcuts' => '01fca1f0',
'javelin-behavior-phabricator-line-linker' => '66a62306',
'javelin-behavior-phabricator-nav' => '94b7c320',
'javelin-behavior-phabricator-nav' => '9d32bc88',
'javelin-behavior-phabricator-notification-example' => '8ce821c5',
'javelin-behavior-phabricator-object-selector' => '77c1f0b0',
'javelin-behavior-phabricator-oncopy' => '2926fff2',
@@ -741,7 +741,7 @@ return array(
'owners-path-editor' => 'c96502cf',
'owners-path-editor-css' => '9c136c29',
'paste-css' => '9fcc9773',
'path-typeahead' => '662e9cea',
'path-typeahead' => '6d8c7912',
'people-picture-menu-item-css' => 'a06f7f34',
'people-profile-css' => '4df76faf',
'phabricator-action-list-view-css' => '0bcd9a45',
@@ -754,7 +754,7 @@ return array(
'phabricator-darkmessage' => 'c48cccdd',
'phabricator-dashboard-css' => 'fe5b1869',
'phabricator-diff-changeset' => 'b49b59d6',
'phabricator-diff-changeset-list' => 'f0ffe8c3',
'phabricator-diff-changeset-list' => 'e0b984b5',
'phabricator-diff-inline' => 'e83d28f3',
'phabricator-drag-and-drop-file-upload' => '58dea2fa',
'phabricator-draggable-list' => 'bea6e7f4',
@@ -803,7 +803,7 @@ return array(
'phui-box-css' => '4bd6cdb9',
'phui-bulk-editor-css' => '9a81e5d5',
'phui-button-bar-css' => 'f1ff5494',
'phui-button-css' => '1863cc6e',
'phui-button-css' => '6ccb303c',
'phui-button-simple-css' => '8e1baf68',
'phui-calendar-css' => 'f1ddf11c',
'phui-calendar-day-css' => '572b1893',
@@ -816,15 +816,15 @@ return array(
'phui-crumbs-view-css' => '10728aaa',
'phui-curtain-view-css' => '2bdaf026',
'phui-document-summary-view-css' => '9ca48bdf',
'phui-document-view-css' => '878c2f52',
'phui-document-view-pro-css' => '8af7ea27',
'phui-document-view-css' => 'c4ac41f9',
'phui-document-view-pro-css' => 'dd79b5df',
'phui-feed-story-css' => '44a9c8e9',
'phui-font-icon-base-css' => '870a7360',
'phui-fontkit-css' => '1320ed01',
'phui-form-css' => '7aaa04e3',
'phui-form-view-css' => 'b446e8ff',
'phui-form-view-css' => '739c78df',
'phui-head-thing-view-css' => 'fd311e5f',
'phui-header-view-css' => 'edeb9252',
'phui-header-view-css' => '1ba8b707',
'phui-hovercard' => '1bd28176',
'phui-hovercard-view-css' => 'f0592bcf',
'phui-icon-set-selector-css' => '87db8fee',
@@ -861,7 +861,7 @@ return array(
'phuix-action-list-view' => 'b5c256b8',
'phuix-action-view' => '8d4a8c72',
'phuix-autocomplete' => 'df1bbd34',
'phuix-button-view' => '8a91e1ac',
'phuix-button-view' => '85ac9772',
'phuix-dropdown-menu' => '04b2ae03',
'phuix-form-control-view' => '210a16c1',
'phuix-icon-view' => 'bff6884b',
@@ -908,6 +908,15 @@ return array(
'javelin-behavior',
'javelin-uri',
),
'038bf27f' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-workflow',
'javelin-dom',
'phuix-form-control-view',
'phuix-icon-view',
'javelin-behavior-phabricator-gesture',
),
'040fce04' => array(
'javelin-behavior',
'javelin-request',
@@ -1133,14 +1142,6 @@ return array(
'javelin-workflow',
'phabricator-draggable-list',
),
'419998ab' => array(
'javelin-behavior',
'javelin-dom',
'javelin-stratcom',
'phabricator-tooltip',
'phabricator-diff-changeset-list',
'phabricator-diff-changeset',
),
'4250a34e' => array(
'javelin-behavior',
'javelin-dom',
@@ -1361,14 +1362,6 @@ return array(
'javelin-workflow',
'javelin-dom',
),
'662e9cea' => array(
'javelin-install',
'javelin-typeahead',
'javelin-dom',
'javelin-request',
'javelin-typeahead-ondemand-source',
'javelin-util',
),
66888767 => array(
'javelin-behavior',
'javelin-stratcom',
@@ -1444,6 +1437,14 @@ return array(
'javelin-typeahead',
'javelin-uri',
),
'6d8c7912' => array(
'javelin-install',
'javelin-typeahead',
'javelin-dom',
'javelin-request',
'javelin-typeahead-ondemand-source',
'javelin-util',
),
'70baed2f' => array(
'javelin-install',
'javelin-dom',
@@ -1540,6 +1541,10 @@ return array(
'javelin-dom',
'javelin-stratcom',
),
'85ac9772' => array(
'javelin-install',
'javelin-dom',
),
'85ee8ce6' => array(
'aphront-dialog-view-css',
),
@@ -1567,10 +1572,6 @@ return array(
'javelin-install',
'javelin-dom',
),
'8a91e1ac' => array(
'javelin-install',
'javelin-dom',
),
'8ce821c5' => array(
'phabricator-notification',
'javelin-stratcom',
@@ -1630,16 +1631,6 @@ return array(
'javelin-resource',
'javelin-routable',
),
'94b7c320' => array(
'javelin-behavior',
'javelin-behavior-device',
'javelin-stratcom',
'javelin-dom',
'javelin-magical-init',
'javelin-vector',
'javelin-request',
'javelin-util',
),
'960f6a39' => array(
'javelin-behavior',
'javelin-dom',
@@ -1647,15 +1638,6 @@ return array(
'javelin-mask',
'phabricator-drag-and-drop-file-upload',
),
'9a6dd75c' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-workflow',
'javelin-dom',
'phuix-form-control-view',
'phuix-icon-view',
'javelin-behavior-phabricator-gesture',
),
'9a860428' => array(
'javelin-behavior',
'javelin-dom',
@@ -1669,6 +1651,16 @@ return array(
'javelin-workflow',
'javelin-stratcom',
),
'9d32bc88' => array(
'javelin-behavior',
'javelin-behavior-device',
'javelin-stratcom',
'javelin-dom',
'javelin-magical-init',
'javelin-vector',
'javelin-request',
'javelin-util',
),
'9d9685d6' => array(
'phui-oi-list-view-css',
),
@@ -2028,6 +2020,10 @@ return array(
'phuix-icon-view',
'phabricator-prefab',
),
'e0b984b5' => array(
'javelin-install',
'phuix-button-view',
),
'e1d25dfb' => array(
'javelin-behavior',
'javelin-stratcom',
@@ -2120,9 +2116,13 @@ return array(
'javelin-workflow',
'javelin-json',
),
'f0ffe8c3' => array(
'javelin-install',
'phuix-button-view',
'f0eb6708' => array(
'javelin-behavior',
'javelin-dom',
'javelin-stratcom',
'phabricator-tooltip',
'phabricator-diff-changeset-list',
'phabricator-diff-changeset',
),
'f1ff5494' => array(
'phui-button-css',

View File

@@ -0,0 +1,20 @@
<?php
// Advise installs to rebuild the repository identities.
// If the install has no commits (or no commits that lack an
// authorIdentityPHID), don't require a rebuild.
$commits = id(new PhabricatorRepositoryCommit())
->loadAllWhere('authorIdentityPHID IS NULL LIMIT 1');
if (!$commits) {
return;
}
try {
id(new PhabricatorConfigManualActivity())
->setActivityType(PhabricatorConfigManualActivity::TYPE_IDENTITIES)
->save();
} catch (AphrontDuplicateKeyQueryException $ex) {
// If we've already noted that this activity is required, just move on.
}

View File

@@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_drydock.drydock_lease
ADD acquiredEpoch INT UNSIGNED;

View File

@@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_drydock.drydock_lease
ADD activatedEpoch INT UNSIGNED;

View File

@@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_phriction.phriction_document
ADD contentPHID VARBINARY(64) NOT NULL;

View File

@@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_phriction.phriction_content
ADD documentPHID VARBINARY(64) NOT NULL;

View File

@@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_phriction.phriction_document
ADD editedEpoch INT UNSIGNED NOT NULL;

View File

@@ -0,0 +1,57 @@
<?php
// Update the PhrictionDocument and PhrictionContent tables to refer to one
// another by PHID instead of by ID.
$document_table = new PhrictionDocument();
$content_table = new PhrictionContent();
$conn = $document_table->establishConnection('w');
$document_iterator = new LiskRawMigrationIterator(
$conn,
$document_table->getTableName());
foreach ($document_iterator as $row) {
$content_id = $row['contentID'];
$content_row = queryfx_one(
$conn,
'SELECT phid, dateCreated FROM %T WHERE id = %d',
$content_table->getTableName(),
$content_id);
if (!$content_row) {
continue;
}
queryfx(
$conn,
'UPDATE %T SET contentPHID = %s, editedEpoch = %d WHERE id = %d',
$document_table->getTableName(),
$content_row['phid'],
$content_row['dateCreated'],
$row['id']);
}
$content_iterator = new LiskRawMigrationIterator(
$conn,
$content_table->getTableName());
foreach ($content_iterator as $row) {
$document_id = $row['documentID'];
$document_row = queryfx_one(
$conn,
'SELECT phid FROM %T WHERE id = %d',
$document_table->getTableName(),
$document_id);
if (!$document_row) {
continue;
}
queryfx(
$conn,
'UPDATE %T SET documentPHID = %s WHERE id = %d',
$content_table->getTableName(),
$document_row['phid'],
$row['id']);
}

View File

@@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_phriction.phriction_document
DROP contentID;

View File

@@ -0,0 +1,20 @@
<?php
// See T13193. We're about to drop the "documentID" column, which is part of
// a UNIQUE KEY. In MariaDB, we must first drop the "documentID" key or we get
// into deep trouble.
// There's no "IF EXISTS" modifier for "ALTER TABLE" so run this as a PHP patch
// instead of an SQL patch.
$table = new PhrictionContent();
$conn = $table->establishConnection('w');
try {
queryfx(
$conn,
'ALTER TABLE %T DROP KEY documentID',
$table->getTableName());
} catch (AphrontQueryException $ex) {
// Ignore.
}

View File

@@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_phriction.phriction_content
DROP documentID;

View File

@@ -0,0 +1 @@
DELETE FROM {$NAMESPACE}_phriction.phriction_content WHERE documentPHID = '';

View File

@@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_phriction.phriction_content
ADD UNIQUE KEY `key_version` (documentPHID, version);

View File

@@ -0,0 +1,26 @@
<?php
$document_table = new PhrictionDocument();
$document_conn = $document_table->establishConnection('w');
$document_name = $document_table->getTableName();
$properties_table = new PhabricatorMetaMTAMailProperties();
$conn = $properties_table->establishConnection('w');
$iterator = new LiskRawMigrationIterator($document_conn, $document_name);
foreach ($iterator as $row) {
queryfx(
$conn,
'INSERT IGNORE INTO %T
(objectPHID, mailProperties, dateCreated, dateModified)
VALUES
(%s, %s, %d, %d)',
$properties_table->getTableName(),
$row['phid'],
phutil_json_encode(
array(
'mailKey' => $row['mailKey'],
)),
PhabricatorTime::getNow(),
PhabricatorTime::getNow());
}

View File

@@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_phriction.phriction_document
DROP mailKey;

View File

@@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_phriction.phriction_document
ADD maxVersion INT UNSIGNED NOT NULL;

View File

@@ -0,0 +1,30 @@
<?php
// Populate the "maxVersion" column by copying the maximum "version" from the
// content table.
$document_table = new PhrictionDocument();
$content_table = new PhrictionContent();
$conn = $document_table->establishConnection('w');
$iterator = new LiskRawMigrationIterator(
$conn,
$document_table->getTableName());
foreach ($iterator as $row) {
$content = queryfx_one(
$conn,
'SELECT MAX(version) max FROM %T WHERE documentPHID = %s',
$content_table->getTableName(),
$row['phid']);
if (!$content) {
continue;
}
queryfx(
$conn,
'UPDATE %T SET maxVersion = %d WHERE id = %d',
$document_table->getTableName(),
$content['max'],
$row['id']);
}

View File

@@ -0,0 +1,54 @@
<?php
$table = new PhabricatorSavedQuery();
$conn = $table->establishConnection('w');
$status_map = array(
0 => 'none',
1 => 'needs-audit',
2 => 'concern-raised',
3 => 'partially-audited',
4 => 'audited',
5 => 'needs-verification',
);
foreach (new LiskMigrationIterator($table) as $query) {
if ($query->getEngineClassName() !== 'PhabricatorCommitSearchEngine') {
continue;
}
$parameters = $query->getParameters();
$status = idx($parameters, 'statuses');
if (!$status) {
// No saved "status" constraint.
continue;
}
if (!is_array($status)) {
// Saved constraint isn't a list.
continue;
}
// Migrate old integer values to new string values.
$old_status = $status;
foreach ($status as $key => $value) {
if (is_numeric($value)) {
$status[$key] = $status_map[$value];
}
}
if ($status === $old_status) {
// Nothing changed.
continue;
}
$parameters['statuses'] = $status;
queryfx(
$conn,
'UPDATE %T SET parameters = %s WHERE id = %d',
$table->getTableName(),
phutil_json_encode($parameters),
$query->getID());
}

View File

@@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_repository.repository_commit
CHANGE auditStatus auditStatus VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT};

View File

@@ -0,0 +1,28 @@
<?php
$table = new PhabricatorRepositoryCommit();
$conn = $table->establishConnection('w');
$status_map = array(
0 => 'none',
1 => 'needs-audit',
2 => 'concern-raised',
3 => 'partially-audited',
4 => 'audited',
5 => 'needs-verification',
);
foreach (new LiskMigrationIterator($table) as $commit) {
$status = $commit->getAuditStatus();
if (!isset($status_map[$status])) {
continue;
}
queryfx(
$conn,
'UPDATE %T SET auditStatus = %s WHERE id = %d',
$table->getTableName(),
$status_map[$status],
$commit->getID());
}

View File

@@ -0,0 +1,48 @@
<?php
$table = new PhabricatorAuditTransaction();
$conn = $table->establishConnection('w');
$status_map = array(
0 => 'none',
1 => 'needs-audit',
2 => 'concern-raised',
3 => 'partially-audited',
4 => 'audited',
5 => 'needs-verification',
);
$state_type = DiffusionCommitStateTransaction::TRANSACTIONTYPE;
foreach (new LiskMigrationIterator($table) as $xaction) {
if ($xaction->getTransactionType() !== $state_type) {
continue;
}
$old_value = $xaction->getOldValue();
$new_value = $xaction->getNewValue();
$any_change = false;
if (isset($status_map[$old_value])) {
$old_value = $status_map[$old_value];
$any_change = true;
}
if (isset($status_map[$new_value])) {
$new_value = $status_map[$new_value];
$any_change = true;
}
if (!$any_change) {
continue;
}
queryfx(
$conn,
'UPDATE %T SET oldValue = %s, newValue = %s WHERE id = %d',
$table->getTableName(),
phutil_json_encode($old_value),
phutil_json_encode($new_value),
$xaction->getID());
}

View File

@@ -0,0 +1,26 @@
<?php
$commit_table = new PhabricatorRepositoryCommit();
$commit_conn = $commit_table->establishConnection('w');
$commit_name = $commit_table->getTableName();
$properties_table = new PhabricatorMetaMTAMailProperties();
$conn = $properties_table->establishConnection('w');
$iterator = new LiskRawMigrationIterator($commit_conn, $commit_name);
foreach ($iterator as $commit) {
queryfx(
$conn,
'INSERT IGNORE INTO %T
(objectPHID, mailProperties, dateCreated, dateModified)
VALUES
(%s, %s, %d, %d)',
$properties_table->getTableName(),
$commit['phid'],
phutil_json_encode(
array(
'mailKey' => $commit['mailKey'],
)),
PhabricatorTime::getNow(),
PhabricatorTime::getNow());
}

View File

@@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_repository.repository_commit
DROP mailKey;

View File

@@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_drydock.drydock_log
ADD operationPHID VARBINARY(64);

View File

@@ -1,53 +0,0 @@
#!/usr/bin/env php
<?php
$root = dirname(dirname(dirname(__FILE__)));
require_once $root.'/scripts/__init_script__.php';
$commit = new PhabricatorRepositoryCommit();
$conn_w = id(new PhabricatorRepository())->establishConnection('w');
$sizes = queryfx_all(
$conn_w,
'SELECT repositoryID, count(*) N FROM %T GROUP BY repositoryID',
$commit->getTableName());
$sizes = ipull($sizes, 'N', 'repositoryID');
$maxes = queryfx_all(
$conn_w,
'SELECT repositoryID, max(epoch) maxEpoch FROM %T GROUP BY repositoryID',
$commit->getTableName());
$maxes = ipull($maxes, 'maxEpoch', 'repositoryID');
$repository_ids = array_keys($sizes + $maxes);
echo pht('Updating %d repositories', count($repository_ids));
foreach ($repository_ids as $repository_id) {
$last_commit = queryfx_one(
$conn_w,
'SELECT id FROM %T WHERE repositoryID = %d AND epoch = %d LIMIT 1',
$commit->getTableName(),
$repository_id,
idx($maxes, $repository_id, 0));
if ($last_commit) {
$last_commit = $last_commit['id'];
} else {
$last_commit = 0;
}
queryfx(
$conn_w,
'INSERT INTO %T (repositoryID, lastCommitID, size, epoch)
VALUES (%d, %d, %d, %d) ON DUPLICATE KEY UPDATE
lastCommitID = VALUES(lastCommitID),
size = VALUES(size),
epoch = VALUES(epoch)',
PhabricatorRepository::TABLE_SUMMARY,
$repository_id,
$last_commit,
idx($sizes, $repository_id, 0),
idx($maxes, $repository_id, 0));
echo '.';
}
echo "\n".pht('Done.')."\n";

View File

@@ -2,13 +2,27 @@
<?php
$root = dirname(dirname(dirname(__FILE__)));
require_once $root.'/scripts/__init_script__.php';
require_once $root.'/scripts/init/init-script.php';
// NOTE: We are caching a datastructure rather than the flat key file because
// the path on disk to "ssh-exec" is arbitrarily mutable at runtime. See T12397.
$cache = PhabricatorCaches::getMutableCache();
$authfile_key = PhabricatorAuthSSHKeyQuery::AUTHFILE_CACHEKEY;
$authfile = $cache->getKey($authfile_key);
$authstruct_key = PhabricatorAuthSSHKeyQuery::AUTHSTRUCT_CACHEKEY;
$authstruct_raw = $cache->getKey($authstruct_key);
if ($authfile === null) {
$authstruct = null;
if (strlen($authstruct_raw)) {
try {
$authstruct = phutil_json_decode($authstruct_raw);
} catch (Exception $ex) {
// Ignore any issues with the cached data; we'll just rebuild the
// structure below.
}
}
if ($authstruct === null) {
$keys = id(new PhabricatorAuthSSHKeyQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withIsActive(true)
@@ -19,7 +33,7 @@ if ($authfile === null) {
exit(1);
}
$bin = $root.'/bin/ssh-exec';
$key_list = array();
foreach ($keys as $ssh_key) {
$key_argv = array();
$object = $ssh_key->getObject();
@@ -42,18 +56,7 @@ if ($authfile === null) {
$key_argv[] = '--phabricator-ssh-key';
$key_argv[] = $ssh_key->getID();
$cmd = csprintf('%s %Ls', $bin, $key_argv);
$instance = PhabricatorEnv::getEnvConfig('cluster.instance');
if (strlen($instance)) {
$cmd = csprintf('PHABRICATOR_INSTANCE=%s %C', $instance, $cmd);
}
// This is additional escaping for the SSH 'command="..."' string.
$cmd = addcslashes($cmd, '"\\');
// Strip out newlines and other nonsense from the key type and key body.
$type = $ssh_key->getKeyType();
$type = preg_replace('@[\x00-\x20]+@', '', $type);
if (!strlen($type)) {
@@ -66,22 +69,54 @@ if ($authfile === null) {
continue;
}
$options = array(
'command="'.$cmd.'"',
'no-port-forwarding',
'no-X11-forwarding',
'no-agent-forwarding',
'no-pty',
$key_list[] = array(
'argv' => $key_argv,
'type' => $type,
'key' => $key,
);
$options = implode(',', $options);
$lines[] = $options.' '.$type.' '.$key."\n";
}
$authfile = implode('', $lines);
$authstruct = array(
'keys' => $key_list,
);
$authstruct_raw = phutil_json_encode($authstruct);
$ttl = phutil_units('24 hours in seconds');
$cache->setKey($authfile_key, $authfile, $ttl);
$cache->setKey($authstruct_key, $authstruct_raw, $ttl);
}
$bin = $root.'/bin/ssh-exec';
$instance = PhabricatorEnv::getEnvConfig('cluster.instance');
$lines = array();
foreach ($authstruct['keys'] as $key_struct) {
$key_argv = $key_struct['argv'];
$key = $key_struct['key'];
$type = $key_struct['type'];
$cmd = csprintf('%s %Ls', $bin, $key_argv);
if (strlen($instance)) {
$cmd = csprintf('PHABRICATOR_INSTANCE=%s %C', $instance, $cmd);
}
// This is additional escaping for the SSH 'command="..."' string.
$cmd = addcslashes($cmd, '"\\');
$options = array(
'command="'.$cmd.'"',
'no-port-forwarding',
'no-X11-forwarding',
'no-agent-forwarding',
'no-pty',
);
$options = implode(',', $options);
$lines[] = $options.' '.$type.' '.$key."\n";
}
$authfile = implode('', $lines);
echo $authfile;
exit(0);

View File

@@ -27,7 +27,15 @@ $args->parsePartial(
'param' => pht('port'),
'help' => pht('Port number to connect to.'),
),
array(
'name' => 'options',
'short' => 'o',
'param' => pht('options'),
'repeat' => true,
'help' => pht('SSH options.'),
),
));
$unconsumed_argv = $args->getUnconsumedArgumentVector();
if (function_exists('pcntl_signal')) {
@@ -113,6 +121,25 @@ if ($port) {
$arguments[] = $port;
}
$options = $args->getArg('options');
$allowed_ssh_options = array('SendEnv=GIT_PROTOCOL');
if (!empty($options)) {
foreach ($options as $option) {
if (array_search($option, $allowed_ssh_options) !== false) {
$pattern[] = '-o %s';
$arguments[] = $option;
} else {
throw new Exception(
pht(
'Disallowed ssh option "%s" given with "-o". '.
'Allowed options are: %s.',
$option,
implode(', ', $allowed_ssh_options)));
}
}
}
$pattern[] = '--';
$pattern[] = '%s';

View File

@@ -39,6 +39,10 @@ $data = array();
$futures = array();
foreach (explode("\n", trim($input)) as $file) {
if (!strlen($file)) {
continue;
}
$file = Filesystem::readablePath($file);
$futures[$file] = ctags_get_parser_future($file);
}

View File

@@ -27,6 +27,10 @@ $data = array();
$futures = array();
foreach (explode("\n", trim($input)) as $file) {
if (!strlen($file)) {
continue;
}
$file = Filesystem::readablePath($file);
$data[$file] = Filesystem::readFile($file);
$futures[$file] = PhutilXHPASTBinary::getParserFuture($data[$file]);

View File

@@ -313,6 +313,7 @@ phutil_register_library_map(array(
'ConduitCallTestCase' => 'applications/conduit/call/__tests__/ConduitCallTestCase.php',
'ConduitColumnsParameterType' => 'applications/conduit/parametertype/ConduitColumnsParameterType.php',
'ConduitConnectConduitAPIMethod' => 'applications/conduit/method/ConduitConnectConduitAPIMethod.php',
'ConduitConstantDescription' => 'applications/conduit/data/ConduitConstantDescription.php',
'ConduitEpochParameterType' => 'applications/conduit/parametertype/ConduitEpochParameterType.php',
'ConduitException' => 'applications/conduit/protocol/exception/ConduitException.php',
'ConduitGetCapabilitiesConduitAPIMethod' => 'applications/conduit/method/ConduitGetCapabilitiesConduitAPIMethod.php',
@@ -644,6 +645,7 @@ phutil_register_library_map(array(
'DifferentialRevisionStatusTransaction' => 'applications/differential/xaction/DifferentialRevisionStatusTransaction.php',
'DifferentialRevisionSummaryHeraldField' => 'applications/differential/herald/DifferentialRevisionSummaryHeraldField.php',
'DifferentialRevisionSummaryTransaction' => 'applications/differential/xaction/DifferentialRevisionSummaryTransaction.php',
'DifferentialRevisionTestPlanHeraldField' => 'applications/differential/herald/DifferentialRevisionTestPlanHeraldField.php',
'DifferentialRevisionTestPlanTransaction' => 'applications/differential/xaction/DifferentialRevisionTestPlanTransaction.php',
'DifferentialRevisionTitleHeraldField' => 'applications/differential/herald/DifferentialRevisionTitleHeraldField.php',
'DifferentialRevisionTitleTransaction' => 'applications/differential/xaction/DifferentialRevisionTitleTransaction.php',
@@ -702,6 +704,7 @@ phutil_register_library_map(array(
'DiffusionCommitAcceptTransaction' => 'applications/diffusion/xaction/DiffusionCommitAcceptTransaction.php',
'DiffusionCommitActionTransaction' => 'applications/diffusion/xaction/DiffusionCommitActionTransaction.php',
'DiffusionCommitAffectedFilesHeraldField' => 'applications/diffusion/herald/DiffusionCommitAffectedFilesHeraldField.php',
'DiffusionCommitAuditStatus' => 'applications/diffusion/DiffusionCommitAuditStatus.php',
'DiffusionCommitAuditTransaction' => 'applications/diffusion/xaction/DiffusionCommitAuditTransaction.php',
'DiffusionCommitAuditorsHeraldField' => 'applications/diffusion/herald/DiffusionCommitAuditorsHeraldField.php',
'DiffusionCommitAuditorsTransaction' => 'applications/diffusion/xaction/DiffusionCommitAuditorsTransaction.php',
@@ -1165,6 +1168,7 @@ phutil_register_library_map(array(
'DrydockManagementUpdateResourceWorkflow' => 'applications/drydock/management/DrydockManagementUpdateResourceWorkflow.php',
'DrydockManagementWorkflow' => 'applications/drydock/management/DrydockManagementWorkflow.php',
'DrydockObjectAuthorizationView' => 'applications/drydock/view/DrydockObjectAuthorizationView.php',
'DrydockOperationWorkLogType' => 'applications/drydock/logtype/DrydockOperationWorkLogType.php',
'DrydockQuery' => 'applications/drydock/query/DrydockQuery.php',
'DrydockRepositoryOperation' => 'applications/drydock/storage/DrydockRepositoryOperation.php',
'DrydockRepositoryOperationController' => 'applications/drydock/controller/DrydockRepositoryOperationController.php',
@@ -1202,6 +1206,7 @@ phutil_register_library_map(array(
'DrydockSlotLockException' => 'applications/drydock/exception/DrydockSlotLockException.php',
'DrydockSlotLockFailureLogType' => 'applications/drydock/logtype/DrydockSlotLockFailureLogType.php',
'DrydockTestRepositoryOperation' => 'applications/drydock/operation/DrydockTestRepositoryOperation.php',
'DrydockTextLogType' => 'applications/drydock/logtype/DrydockTextLogType.php',
'DrydockWebrootInterface' => 'applications/drydock/interface/webroot/DrydockWebrootInterface.php',
'DrydockWorker' => 'applications/drydock/worker/DrydockWorker.php',
'DrydockWorkingCopyBlueprintImplementation' => 'applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php',
@@ -1646,13 +1651,8 @@ phutil_register_library_map(array(
'ManiphestDAO' => 'applications/maniphest/storage/ManiphestDAO.php',
'ManiphestDefaultEditCapability' => 'applications/maniphest/capability/ManiphestDefaultEditCapability.php',
'ManiphestDefaultViewCapability' => 'applications/maniphest/capability/ManiphestDefaultViewCapability.php',
'ManiphestEditAssignCapability' => 'applications/maniphest/capability/ManiphestEditAssignCapability.php',
'ManiphestEditConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestEditConduitAPIMethod.php',
'ManiphestEditEngine' => 'applications/maniphest/editor/ManiphestEditEngine.php',
'ManiphestEditPoliciesCapability' => 'applications/maniphest/capability/ManiphestEditPoliciesCapability.php',
'ManiphestEditPriorityCapability' => 'applications/maniphest/capability/ManiphestEditPriorityCapability.php',
'ManiphestEditProjectsCapability' => 'applications/maniphest/capability/ManiphestEditProjectsCapability.php',
'ManiphestEditStatusCapability' => 'applications/maniphest/capability/ManiphestEditStatusCapability.php',
'ManiphestEmailCommand' => 'applications/maniphest/command/ManiphestEmailCommand.php',
'ManiphestGetTaskTransactionsConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestGetTaskTransactionsConduitAPIMethod.php',
'ManiphestHovercardEngineExtension' => 'applications/maniphest/engineextension/ManiphestHovercardEngineExtension.php',
@@ -1918,7 +1918,7 @@ phutil_register_library_map(array(
'PHUIDiffTableOfContentsListView' => 'infrastructure/diff/view/PHUIDiffTableOfContentsListView.php',
'PHUIDiffTwoUpInlineCommentRowScaffold' => 'infrastructure/diff/view/PHUIDiffTwoUpInlineCommentRowScaffold.php',
'PHUIDocumentSummaryView' => 'view/phui/PHUIDocumentSummaryView.php',
'PHUIDocumentViewPro' => 'view/phui/PHUIDocumentViewPro.php',
'PHUIDocumentView' => 'view/phui/PHUIDocumentView.php',
'PHUIFeedStoryExample' => 'applications/uiexample/examples/PHUIFeedStoryExample.php',
'PHUIFeedStoryView' => 'view/phui/PHUIFeedStoryView.php',
'PHUIFormDividerControl' => 'view/form/control/PHUIFormDividerControl.php',
@@ -2048,6 +2048,7 @@ phutil_register_library_map(array(
'PasteSearchConduitAPIMethod' => 'applications/paste/conduit/PasteSearchConduitAPIMethod.php',
'PeopleBrowseUserDirectoryCapability' => 'applications/people/capability/PeopleBrowseUserDirectoryCapability.php',
'PeopleCreateUsersCapability' => 'applications/people/capability/PeopleCreateUsersCapability.php',
'PeopleDisableUsersCapability' => 'applications/people/capability/PeopleDisableUsersCapability.php',
'PeopleHovercardEngineExtension' => 'applications/people/engineextension/PeopleHovercardEngineExtension.php',
'PeopleMainMenuBarExtension' => 'applications/people/engineextension/PeopleMainMenuBarExtension.php',
'PeopleUserLogGarbageCollector' => 'applications/people/garbagecollector/PeopleUserLogGarbageCollector.php',
@@ -2152,7 +2153,6 @@ phutil_register_library_map(array(
'PhabricatorAuditActionConstants' => 'applications/audit/constants/PhabricatorAuditActionConstants.php',
'PhabricatorAuditApplication' => 'applications/audit/application/PhabricatorAuditApplication.php',
'PhabricatorAuditCommentEditor' => 'applications/audit/editor/PhabricatorAuditCommentEditor.php',
'PhabricatorAuditCommitStatusConstants' => 'applications/audit/constants/PhabricatorAuditCommitStatusConstants.php',
'PhabricatorAuditController' => 'applications/audit/controller/PhabricatorAuditController.php',
'PhabricatorAuditEditor' => 'applications/audit/editor/PhabricatorAuditEditor.php',
'PhabricatorAuditInlineComment' => 'applications/audit/storage/PhabricatorAuditInlineComment.php',
@@ -4567,6 +4567,8 @@ phutil_register_library_map(array(
'PhabricatorUserCustomFieldNumericIndex' => 'applications/people/storage/PhabricatorUserCustomFieldNumericIndex.php',
'PhabricatorUserCustomFieldStringIndex' => 'applications/people/storage/PhabricatorUserCustomFieldStringIndex.php',
'PhabricatorUserDAO' => 'applications/people/storage/PhabricatorUserDAO.php',
'PhabricatorUserDisableTransaction' => 'applications/people/xaction/PhabricatorUserDisableTransaction.php',
'PhabricatorUserEditEngine' => 'applications/people/editor/PhabricatorUserEditEngine.php',
'PhabricatorUserEditor' => 'applications/people/editor/PhabricatorUserEditor.php',
'PhabricatorUserEditorTestCase' => 'applications/people/editor/__tests__/PhabricatorUserEditorTestCase.php',
'PhabricatorUserEmail' => 'applications/people/storage/PhabricatorUserEmail.php',
@@ -4588,7 +4590,6 @@ phutil_register_library_map(array(
'PhabricatorUserPreferencesTransaction' => 'applications/settings/storage/PhabricatorUserPreferencesTransaction.php',
'PhabricatorUserPreferencesTransactionQuery' => 'applications/settings/query/PhabricatorUserPreferencesTransactionQuery.php',
'PhabricatorUserProfile' => 'applications/people/storage/PhabricatorUserProfile.php',
'PhabricatorUserProfileEditor' => 'applications/people/editor/PhabricatorUserProfileEditor.php',
'PhabricatorUserProfileImageCacheType' => 'applications/people/cache/PhabricatorUserProfileImageCacheType.php',
'PhabricatorUserRealNameField' => 'applications/people/customfield/PhabricatorUserRealNameField.php',
'PhabricatorUserRolesField' => 'applications/people/customfield/PhabricatorUserRolesField.php',
@@ -4598,6 +4599,8 @@ phutil_register_library_map(array(
'PhabricatorUserTestCase' => 'applications/people/storage/__tests__/PhabricatorUserTestCase.php',
'PhabricatorUserTitleField' => 'applications/people/customfield/PhabricatorUserTitleField.php',
'PhabricatorUserTransaction' => 'applications/people/storage/PhabricatorUserTransaction.php',
'PhabricatorUserTransactionEditor' => 'applications/people/editor/PhabricatorUserTransactionEditor.php',
'PhabricatorUserTransactionType' => 'applications/people/xaction/PhabricatorUserTransactionType.php',
'PhabricatorUsersEditField' => 'applications/transactions/editfield/PhabricatorUsersEditField.php',
'PhabricatorUsersPolicyRule' => 'applications/people/policyrule/PhabricatorUsersPolicyRule.php',
'PhabricatorUsersSearchField' => 'applications/people/searchfield/PhabricatorUsersSearchField.php',
@@ -5025,6 +5028,9 @@ phutil_register_library_map(array(
'PhrictionDocumentController' => 'applications/phriction/controller/PhrictionDocumentController.php',
'PhrictionDocumentDatasource' => 'applications/phriction/typeahead/PhrictionDocumentDatasource.php',
'PhrictionDocumentDeleteTransaction' => 'applications/phriction/xaction/PhrictionDocumentDeleteTransaction.php',
'PhrictionDocumentDraftTransaction' => 'applications/phriction/xaction/PhrictionDocumentDraftTransaction.php',
'PhrictionDocumentEditEngine' => 'applications/phriction/editor/PhrictionDocumentEditEngine.php',
'PhrictionDocumentEditTransaction' => 'applications/phriction/xaction/PhrictionDocumentEditTransaction.php',
'PhrictionDocumentFerretEngine' => 'applications/phriction/search/PhrictionDocumentFerretEngine.php',
'PhrictionDocumentFulltextEngine' => 'applications/phriction/search/PhrictionDocumentFulltextEngine.php',
'PhrictionDocumentHeraldAdapter' => 'applications/phriction/herald/PhrictionDocumentHeraldAdapter.php',
@@ -5035,6 +5041,7 @@ phutil_register_library_map(array(
'PhrictionDocumentPHIDType' => 'applications/phriction/phid/PhrictionDocumentPHIDType.php',
'PhrictionDocumentPathHeraldField' => 'applications/phriction/herald/PhrictionDocumentPathHeraldField.php',
'PhrictionDocumentPolicyCodex' => 'applications/phriction/codex/PhrictionDocumentPolicyCodex.php',
'PhrictionDocumentPublishTransaction' => 'applications/phriction/xaction/PhrictionDocumentPublishTransaction.php',
'PhrictionDocumentQuery' => 'applications/phriction/query/PhrictionDocumentQuery.php',
'PhrictionDocumentSearchConduitAPIMethod' => 'applications/phriction/conduit/PhrictionDocumentSearchConduitAPIMethod.php',
'PhrictionDocumentSearchEngine' => 'applications/phriction/query/PhrictionDocumentSearchEngine.php',
@@ -5042,8 +5049,10 @@ phutil_register_library_map(array(
'PhrictionDocumentTitleHeraldField' => 'applications/phriction/herald/PhrictionDocumentTitleHeraldField.php',
'PhrictionDocumentTitleTransaction' => 'applications/phriction/xaction/PhrictionDocumentTitleTransaction.php',
'PhrictionDocumentTransactionType' => 'applications/phriction/xaction/PhrictionDocumentTransactionType.php',
'PhrictionDocumentVersionTransaction' => 'applications/phriction/xaction/PhrictionDocumentVersionTransaction.php',
'PhrictionEditConduitAPIMethod' => 'applications/phriction/conduit/PhrictionEditConduitAPIMethod.php',
'PhrictionEditController' => 'applications/phriction/controller/PhrictionEditController.php',
'PhrictionEditEngineController' => 'applications/phriction/controller/PhrictionEditEngineController.php',
'PhrictionHistoryConduitAPIMethod' => 'applications/phriction/conduit/PhrictionHistoryConduitAPIMethod.php',
'PhrictionHistoryController' => 'applications/phriction/controller/PhrictionHistoryController.php',
'PhrictionInfoConduitAPIMethod' => 'applications/phriction/conduit/PhrictionInfoConduitAPIMethod.php',
@@ -5051,6 +5060,7 @@ phutil_register_library_map(array(
'PhrictionMarkupPreviewController' => 'applications/phriction/controller/PhrictionMarkupPreviewController.php',
'PhrictionMoveController' => 'applications/phriction/controller/PhrictionMoveController.php',
'PhrictionNewController' => 'applications/phriction/controller/PhrictionNewController.php',
'PhrictionPublishController' => 'applications/phriction/controller/PhrictionPublishController.php',
'PhrictionRemarkupRule' => 'applications/phriction/markup/PhrictionRemarkupRule.php',
'PhrictionReplyHandler' => 'applications/phriction/mail/PhrictionReplyHandler.php',
'PhrictionSchemaSpec' => 'applications/phriction/storage/PhrictionSchemaSpec.php',
@@ -5239,6 +5249,7 @@ phutil_register_library_map(array(
'TransactionSearchConduitAPIMethod' => 'applications/transactions/conduit/TransactionSearchConduitAPIMethod.php',
'UserConduitAPIMethod' => 'applications/people/conduit/UserConduitAPIMethod.php',
'UserDisableConduitAPIMethod' => 'applications/people/conduit/UserDisableConduitAPIMethod.php',
'UserEditConduitAPIMethod' => 'applications/people/conduit/UserEditConduitAPIMethod.php',
'UserEnableConduitAPIMethod' => 'applications/people/conduit/UserEnableConduitAPIMethod.php',
'UserFindConduitAPIMethod' => 'applications/people/conduit/UserFindConduitAPIMethod.php',
'UserQueryConduitAPIMethod' => 'applications/people/conduit/UserQueryConduitAPIMethod.php',
@@ -5631,6 +5642,7 @@ phutil_register_library_map(array(
'ConduitCallTestCase' => 'PhabricatorTestCase',
'ConduitColumnsParameterType' => 'ConduitParameterType',
'ConduitConnectConduitAPIMethod' => 'ConduitAPIMethod',
'ConduitConstantDescription' => 'Phobject',
'ConduitEpochParameterType' => 'ConduitParameterType',
'ConduitException' => 'Exception',
'ConduitGetCapabilitiesConduitAPIMethod' => 'ConduitAPIMethod',
@@ -6008,6 +6020,7 @@ phutil_register_library_map(array(
'DifferentialRevisionStatusTransaction' => 'DifferentialRevisionTransactionType',
'DifferentialRevisionSummaryHeraldField' => 'DifferentialRevisionHeraldField',
'DifferentialRevisionSummaryTransaction' => 'DifferentialRevisionTransactionType',
'DifferentialRevisionTestPlanHeraldField' => 'DifferentialRevisionHeraldField',
'DifferentialRevisionTestPlanTransaction' => 'DifferentialRevisionTransactionType',
'DifferentialRevisionTitleHeraldField' => 'DifferentialRevisionHeraldField',
'DifferentialRevisionTitleTransaction' => 'DifferentialRevisionTransactionType',
@@ -6066,6 +6079,7 @@ phutil_register_library_map(array(
'DiffusionCommitAcceptTransaction' => 'DiffusionCommitAuditTransaction',
'DiffusionCommitActionTransaction' => 'DiffusionCommitTransactionType',
'DiffusionCommitAffectedFilesHeraldField' => 'DiffusionCommitHeraldField',
'DiffusionCommitAuditStatus' => 'Phobject',
'DiffusionCommitAuditTransaction' => 'DiffusionCommitActionTransaction',
'DiffusionCommitAuditorsHeraldField' => 'DiffusionCommitHeraldField',
'DiffusionCommitAuditorsTransaction' => 'DiffusionCommitTransactionType',
@@ -6570,6 +6584,7 @@ phutil_register_library_map(array(
'DrydockManagementUpdateResourceWorkflow' => 'DrydockManagementWorkflow',
'DrydockManagementWorkflow' => 'PhabricatorManagementWorkflow',
'DrydockObjectAuthorizationView' => 'AphrontView',
'DrydockOperationWorkLogType' => 'DrydockLogType',
'DrydockQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'DrydockRepositoryOperation' => array(
'DrydockDAO',
@@ -6613,6 +6628,7 @@ phutil_register_library_map(array(
'DrydockSlotLockException' => 'Exception',
'DrydockSlotLockFailureLogType' => 'DrydockLogType',
'DrydockTestRepositoryOperation' => 'DrydockRepositoryOperationType',
'DrydockTextLogType' => 'DrydockLogType',
'DrydockWebrootInterface' => 'DrydockInterface',
'DrydockWorker' => 'PhabricatorWorker',
'DrydockWorkingCopyBlueprintImplementation' => 'DrydockBlueprintImplementation',
@@ -7155,13 +7171,8 @@ phutil_register_library_map(array(
'ManiphestDAO' => 'PhabricatorLiskDAO',
'ManiphestDefaultEditCapability' => 'PhabricatorPolicyCapability',
'ManiphestDefaultViewCapability' => 'PhabricatorPolicyCapability',
'ManiphestEditAssignCapability' => 'PhabricatorPolicyCapability',
'ManiphestEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod',
'ManiphestEditEngine' => 'PhabricatorEditEngine',
'ManiphestEditPoliciesCapability' => 'PhabricatorPolicyCapability',
'ManiphestEditPriorityCapability' => 'PhabricatorPolicyCapability',
'ManiphestEditProjectsCapability' => 'PhabricatorPolicyCapability',
'ManiphestEditStatusCapability' => 'PhabricatorPolicyCapability',
'ManiphestEmailCommand' => 'MetaMTAEmailTransactionCommand',
'ManiphestGetTaskTransactionsConduitAPIMethod' => 'ManiphestConduitAPIMethod',
'ManiphestHovercardEngineExtension' => 'PhabricatorHovercardEngineExtension',
@@ -7466,7 +7477,7 @@ phutil_register_library_map(array(
'PHUIDiffTableOfContentsListView' => 'AphrontView',
'PHUIDiffTwoUpInlineCommentRowScaffold' => 'PHUIDiffInlineCommentRowScaffold',
'PHUIDocumentSummaryView' => 'AphrontTagView',
'PHUIDocumentViewPro' => 'AphrontTagView',
'PHUIDocumentView' => 'AphrontTagView',
'PHUIFeedStoryExample' => 'PhabricatorUIExample',
'PHUIFeedStoryView' => 'AphrontView',
'PHUIFormDividerControl' => 'AphrontFormControl',
@@ -7606,6 +7617,7 @@ phutil_register_library_map(array(
'PasteSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
'PeopleBrowseUserDirectoryCapability' => 'PhabricatorPolicyCapability',
'PeopleCreateUsersCapability' => 'PhabricatorPolicyCapability',
'PeopleDisableUsersCapability' => 'PhabricatorPolicyCapability',
'PeopleHovercardEngineExtension' => 'PhabricatorHovercardEngineExtension',
'PeopleMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension',
'PeopleUserLogGarbageCollector' => 'PhabricatorGarbageCollector',
@@ -7722,7 +7734,6 @@ phutil_register_library_map(array(
'PhabricatorAuditActionConstants' => 'Phobject',
'PhabricatorAuditApplication' => 'PhabricatorApplication',
'PhabricatorAuditCommentEditor' => 'PhabricatorEditor',
'PhabricatorAuditCommitStatusConstants' => 'Phobject',
'PhabricatorAuditController' => 'PhabricatorController',
'PhabricatorAuditEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorAuditInlineComment' => array(
@@ -8305,10 +8316,7 @@ phutil_register_library_map(array(
'PhabricatorConfigManualActivity' => 'PhabricatorConfigEntryDAO',
'PhabricatorConfigModule' => 'Phobject',
'PhabricatorConfigModuleController' => 'PhabricatorConfigController',
'PhabricatorConfigOption' => array(
'Phobject',
'PhabricatorMarkupInterface',
),
'PhabricatorConfigOption' => 'Phobject',
'PhabricatorConfigOptionType' => 'Phobject',
'PhabricatorConfigPHIDModule' => 'PhabricatorConfigModule',
'PhabricatorConfigProxySource' => 'PhabricatorConfigSource',
@@ -10558,6 +10566,8 @@ phutil_register_library_map(array(
'PhabricatorUserCustomFieldNumericIndex' => 'PhabricatorCustomFieldNumericIndexStorage',
'PhabricatorUserCustomFieldStringIndex' => 'PhabricatorCustomFieldStringIndexStorage',
'PhabricatorUserDAO' => 'PhabricatorLiskDAO',
'PhabricatorUserDisableTransaction' => 'PhabricatorUserTransactionType',
'PhabricatorUserEditEngine' => 'PhabricatorEditEngine',
'PhabricatorUserEditor' => 'PhabricatorEditor',
'PhabricatorUserEditorTestCase' => 'PhabricatorTestCase',
'PhabricatorUserEmail' => 'PhabricatorUserDAO',
@@ -10587,7 +10597,6 @@ phutil_register_library_map(array(
'PhabricatorUserPreferencesTransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorUserPreferencesTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorUserProfile' => 'PhabricatorUserDAO',
'PhabricatorUserProfileEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorUserProfileImageCacheType' => 'PhabricatorUserCacheType',
'PhabricatorUserRealNameField' => 'PhabricatorUserCustomField',
'PhabricatorUserRolesField' => 'PhabricatorUserCustomField',
@@ -10596,7 +10605,9 @@ phutil_register_library_map(array(
'PhabricatorUserStatusField' => 'PhabricatorUserCustomField',
'PhabricatorUserTestCase' => 'PhabricatorTestCase',
'PhabricatorUserTitleField' => 'PhabricatorUserCustomField',
'PhabricatorUserTransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorUserTransaction' => 'PhabricatorModularTransaction',
'PhabricatorUserTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorUserTransactionType' => 'PhabricatorModularTransactionType',
'PhabricatorUsersEditField' => 'PhabricatorTokenizerEditField',
'PhabricatorUsersPolicyRule' => 'PhabricatorPolicyRule',
'PhabricatorUsersSearchField' => 'PhabricatorSearchTokenizerField',
@@ -11145,29 +11156,35 @@ phutil_register_library_map(array(
),
'PhrictionDocumentAuthorHeraldField' => 'PhrictionDocumentHeraldField',
'PhrictionDocumentContentHeraldField' => 'PhrictionDocumentHeraldField',
'PhrictionDocumentContentTransaction' => 'PhrictionDocumentTransactionType',
'PhrictionDocumentContentTransaction' => 'PhrictionDocumentEditTransaction',
'PhrictionDocumentController' => 'PhrictionController',
'PhrictionDocumentDatasource' => 'PhabricatorTypeaheadDatasource',
'PhrictionDocumentDeleteTransaction' => 'PhrictionDocumentTransactionType',
'PhrictionDocumentDeleteTransaction' => 'PhrictionDocumentVersionTransaction',
'PhrictionDocumentDraftTransaction' => 'PhrictionDocumentEditTransaction',
'PhrictionDocumentEditEngine' => 'PhabricatorEditEngine',
'PhrictionDocumentEditTransaction' => 'PhrictionDocumentVersionTransaction',
'PhrictionDocumentFerretEngine' => 'PhabricatorFerretEngine',
'PhrictionDocumentFulltextEngine' => 'PhabricatorFulltextEngine',
'PhrictionDocumentHeraldAdapter' => 'HeraldAdapter',
'PhrictionDocumentHeraldField' => 'HeraldField',
'PhrictionDocumentHeraldFieldGroup' => 'HeraldFieldGroup',
'PhrictionDocumentMoveAwayTransaction' => 'PhrictionDocumentTransactionType',
'PhrictionDocumentMoveToTransaction' => 'PhrictionDocumentTransactionType',
'PhrictionDocumentMoveAwayTransaction' => 'PhrictionDocumentVersionTransaction',
'PhrictionDocumentMoveToTransaction' => 'PhrictionDocumentVersionTransaction',
'PhrictionDocumentPHIDType' => 'PhabricatorPHIDType',
'PhrictionDocumentPathHeraldField' => 'PhrictionDocumentHeraldField',
'PhrictionDocumentPolicyCodex' => 'PhabricatorPolicyCodex',
'PhrictionDocumentPublishTransaction' => 'PhrictionDocumentTransactionType',
'PhrictionDocumentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhrictionDocumentSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
'PhrictionDocumentSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhrictionDocumentStatus' => 'PhabricatorObjectStatus',
'PhrictionDocumentTitleHeraldField' => 'PhrictionDocumentHeraldField',
'PhrictionDocumentTitleTransaction' => 'PhrictionDocumentTransactionType',
'PhrictionDocumentTitleTransaction' => 'PhrictionDocumentVersionTransaction',
'PhrictionDocumentTransactionType' => 'PhabricatorModularTransactionType',
'PhrictionDocumentVersionTransaction' => 'PhrictionDocumentTransactionType',
'PhrictionEditConduitAPIMethod' => 'PhrictionConduitAPIMethod',
'PhrictionEditController' => 'PhrictionController',
'PhrictionEditEngineController' => 'PhrictionController',
'PhrictionHistoryConduitAPIMethod' => 'PhrictionConduitAPIMethod',
'PhrictionHistoryController' => 'PhrictionController',
'PhrictionInfoConduitAPIMethod' => 'PhrictionConduitAPIMethod',
@@ -11175,6 +11192,7 @@ phutil_register_library_map(array(
'PhrictionMarkupPreviewController' => 'PhabricatorController',
'PhrictionMoveController' => 'PhrictionController',
'PhrictionNewController' => 'PhrictionController',
'PhrictionPublishController' => 'PhrictionController',
'PhrictionRemarkupRule' => 'PhutilRemarkupRule',
'PhrictionReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
'PhrictionSchemaSpec' => 'PhabricatorConfigSchemaSpec',
@@ -11400,6 +11418,7 @@ phutil_register_library_map(array(
'TransactionSearchConduitAPIMethod' => 'ConduitAPIMethod',
'UserConduitAPIMethod' => 'ConduitAPIMethod',
'UserDisableConduitAPIMethod' => 'UserConduitAPIMethod',
'UserEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod',
'UserEnableConduitAPIMethod' => 'UserConduitAPIMethod',
'UserFindConduitAPIMethod' => 'UserConduitAPIMethod',
'UserQueryConduitAPIMethod' => 'UserConduitAPIMethod',

View File

@@ -127,6 +127,9 @@ final class AlmanacInterfaceEditEngine
}
protected function getObjectCreateCancelURI($object) {
if ($this->getDevice()) {
return $this->getDevice()->getURI();
}
return '/almanac/interface/';
}

View File

@@ -68,17 +68,17 @@ final class AuditQueryConduitAPIMethod extends AuditConduitAPIMethod {
$status_map = array(
self::AUDIT_LEGACYSTATUS_OPEN => array(
PhabricatorAuditCommitStatusConstants::NEEDS_AUDIT,
PhabricatorAuditCommitStatusConstants::CONCERN_RAISED,
DiffusionCommitAuditStatus::NEEDS_AUDIT,
DiffusionCommitAuditStatus::CONCERN_RAISED,
),
self::AUDIT_LEGACYSTATUS_CONCERN => array(
PhabricatorAuditCommitStatusConstants::CONCERN_RAISED,
DiffusionCommitAuditStatus::CONCERN_RAISED,
),
self::AUDIT_LEGACYSTATUS_ACCEPTED => array(
PhabricatorAuditCommitStatusConstants::FULLY_AUDITED,
DiffusionCommitAuditStatus::AUDITED,
),
self::AUDIT_LEGACYSTATUS_PARTIAL => array(
PhabricatorAuditCommitStatusConstants::PARTIALLY_AUDITED,
DiffusionCommitAuditStatus::PARTIALLY_AUDITED,
),
);

View File

@@ -1,92 +0,0 @@
<?php
final class PhabricatorAuditCommitStatusConstants extends Phobject {
const NONE = 0;
const NEEDS_AUDIT = 1;
const CONCERN_RAISED = 2;
const PARTIALLY_AUDITED = 3;
const FULLY_AUDITED = 4;
const NEEDS_VERIFICATION = 5;
public static function getStatusNameMap() {
$map = array(
self::NONE => pht('No Audits'),
self::NEEDS_AUDIT => pht('Audit Required'),
self::CONCERN_RAISED => pht('Concern Raised'),
self::NEEDS_VERIFICATION => pht('Needs Verification'),
self::PARTIALLY_AUDITED => pht('Partially Audited'),
self::FULLY_AUDITED => pht('Audited'),
);
return $map;
}
public static function getStatusName($code) {
return idx(self::getStatusNameMap(), $code, pht('Unknown'));
}
public static function getOpenStatusConstants() {
return array(
self::CONCERN_RAISED,
self::NEEDS_AUDIT,
self::NEEDS_VERIFICATION,
self::PARTIALLY_AUDITED,
);
}
public static function getStatusColor($code) {
switch ($code) {
case self::CONCERN_RAISED:
$color = 'red';
break;
case self::NEEDS_AUDIT:
$color = 'orange';
break;
case self::PARTIALLY_AUDITED:
$color = 'yellow';
break;
case self::FULLY_AUDITED:
$color = 'green';
break;
case self::NONE:
$color = 'bluegrey';
break;
case self::NEEDS_VERIFICATION:
$color = 'indigo';
break;
default:
$color = null;
break;
}
return $color;
}
public static function getStatusIcon($code) {
switch ($code) {
case self::CONCERN_RAISED:
$icon = 'fa-times-circle';
break;
case self::NEEDS_AUDIT:
$icon = 'fa-exclamation-circle';
break;
case self::PARTIALLY_AUDITED:
$icon = 'fa-check-circle-o';
break;
case self::FULLY_AUDITED:
$icon = 'fa-check-circle';
break;
case self::NONE:
$icon = 'fa-check';
break;
case self::NEEDS_VERIFICATION:
$icon = 'fa-refresh';
break;
default:
$icon = null;
break;
}
return $icon;
}
}

View File

@@ -206,12 +206,10 @@ final class PhabricatorAuditEditor
$object->writeImportStatusFlag($import_status_flag);
}
$partial_status = PhabricatorAuditCommitStatusConstants::PARTIALLY_AUDITED;
// If the commit has changed state after this edit, add an informational
// transaction about the state change.
if ($old_status != $new_status) {
if ($new_status == $partial_status) {
if ($object->isAuditStatusPartiallyAudited()) {
// This state isn't interesting enough to get a transaction. The
// best way we could lead the user forward is something like "This
// commit still requires additional audits." but that's redundant and
@@ -258,19 +256,31 @@ final class PhabricatorAuditEditor
$this->didExpandInlineState = true;
$actor_phid = $this->getActingAsPHID();
$actor_is_author = ($object->getAuthorPHID() == $actor_phid);
if (!$actor_is_author) {
break;
}
$author_phid = $object->getAuthorPHID();
$actor_is_author = ($actor_phid == $author_phid);
$state_map = PhabricatorTransactions::getInlineStateMap();
$inlines = id(new DiffusionDiffInlineCommentQuery())
$query = id(new DiffusionDiffInlineCommentQuery())
->setViewer($this->getActor())
->withCommitPHIDs(array($object->getPHID()))
->withFixedStates(array_keys($state_map))
->withFixedStates(array_keys($state_map));
$inlines = array();
$inlines[] = id(clone $query)
->withAuthorPHIDs(array($actor_phid))
->withHasTransaction(false)
->execute();
if ($actor_is_author) {
$inlines[] = id(clone $query)
->withHasTransaction(true)
->execute();
}
$inlines = array_mergev($inlines);
if (!$inlines) {
break;
}

View File

@@ -30,11 +30,11 @@ final class PhabricatorAuditSynchronizeManagementWorkflow
continue;
}
$old_status = $commit->getAuditStatus();
$old_status = $commit->getAuditStatusObject();
$commit->updateAuditStatus($commit->getAudits());
$new_status = $commit->getAuditStatus();
$new_status = $commit->getAuditStatusObject();
if ($old_status == $new_status) {
if ($old_status->getKey() == $new_status->getKey()) {
echo tsprintf(
"%s\n",
pht(
@@ -46,10 +46,8 @@ final class PhabricatorAuditSynchronizeManagementWorkflow
pht(
'Updating "%s": "%s" -> "%s".',
$commit->getDisplayName(),
PhabricatorAuditCommitStatusConstants::getStatusName(
$old_status),
PhabricatorAuditCommitStatusConstants::getStatusName(
$new_status)));
$old_status->getName(),
$new_status->getName()));
$commit->save();
}

View File

@@ -15,6 +15,7 @@ final class PhabricatorCommitSearchEngine
return id(new DiffusionCommitQuery())
->needAuditRequests(true)
->needCommitData(true)
->needIdentities(true)
->needDrafts(true);
}
@@ -67,35 +68,50 @@ final class PhabricatorCommitSearchEngine
->setKey('responsiblePHIDs')
->setConduitKey('responsible')
->setAliases(array('responsible', 'responsibles', 'responsiblePHID'))
->setDatasource(new DifferentialResponsibleDatasource()),
->setDatasource(new DifferentialResponsibleDatasource())
->setDescription(
pht(
'Find commits where given users, projects, or packages are '.
'responsible for the next steps in the audit workflow.')),
id(new PhabricatorUsersSearchField())
->setLabel(pht('Authors'))
->setKey('authorPHIDs')
->setConduitKey('authors')
->setAliases(array('author', 'authors', 'authorPHID')),
->setAliases(array('author', 'authors', 'authorPHID'))
->setDescription(pht('Find commits authored by particular users.')),
id(new PhabricatorSearchDatasourceField())
->setLabel(pht('Auditors'))
->setKey('auditorPHIDs')
->setConduitKey('auditors')
->setAliases(array('auditor', 'auditors', 'auditorPHID'))
->setDatasource(new DiffusionAuditorFunctionDatasource()),
->setDatasource(new DiffusionAuditorFunctionDatasource())
->setDescription(
pht(
'Find commits where given users, projects, or packages are '.
'auditors.')),
id(new PhabricatorSearchCheckboxesField())
->setLabel(pht('Audit Status'))
->setKey('statuses')
->setAliases(array('status'))
->setOptions(PhabricatorAuditCommitStatusConstants::getStatusNameMap()),
->setOptions(DiffusionCommitAuditStatus::newOptions())
->setDeprecatedOptions(
DiffusionCommitAuditStatus::newDeprecatedOptions())
->setDescription(pht('Find commits with given audit statuses.')),
id(new PhabricatorSearchDatasourceField())
->setLabel(pht('Repositories'))
->setKey('repositoryPHIDs')
->setConduitKey('repositories')
->setAliases(array('repository', 'repositories', 'repositoryPHID'))
->setDatasource(new DiffusionRepositoryFunctionDatasource()),
->setDatasource(new DiffusionRepositoryFunctionDatasource())
->setDescription(pht('Find commits in particular repositories.')),
id(new PhabricatorSearchDatasourceField())
->setLabel(pht('Packages'))
->setKey('packagePHIDs')
->setConduitKey('packages')
->setAliases(array('package', 'packages', 'packagePHID'))
->setDatasource(new PhabricatorOwnersPackageDatasource()),
->setDatasource(new PhabricatorOwnersPackageDatasource())
->setDescription(
pht('Find commits which affect given packages.')),
id(new PhabricatorSearchThreeStateField())
->setLabel(pht('Unreachable'))
->setKey('unreachable')
@@ -147,7 +163,7 @@ final class PhabricatorCommitSearchEngine
case 'active':
$bucket_key = DiffusionCommitRequiredActionResultBucket::BUCKETKEY;
$open = PhabricatorAuditCommitStatusConstants::getOpenStatusConstants();
$open = DiffusionCommitAuditStatus::getOpenStatusConstants();
$query
->setParameter('responsiblePHIDs', array($viewer_phid))

View File

@@ -120,14 +120,11 @@ final class PhabricatorAuditListView extends AphrontView {
$commit_desc = $this->getCommitDescription($commit_phid);
$committed = phabricator_datetime($commit->getEpoch(), $viewer);
$status = $commit->getAuditStatus();
$status = $commit->getAuditStatusObject();
$status_text =
PhabricatorAuditCommitStatusConstants::getStatusName($status);
$status_color =
PhabricatorAuditCommitStatusConstants::getStatusColor($status);
$status_icon =
PhabricatorAuditCommitStatusConstants::getStatusIcon($status);
$status_text = $status->getName();
$status_color = $status->getColor();
$status_icon = $status->getIcon();
$author_phid = $commit->getAuthorPHID();
if ($author_phid) {

View File

@@ -490,8 +490,7 @@ final class PhabricatorAuthSessionEngine extends Phobject {
PhabricatorAuthSession $session,
$force = false) {
$until = $session->getHighSecurityUntil();
if ($until > time() || $force) {
if ($session->isHighSecuritySession() || $force) {
return new PhabricatorAuthHighSecurityToken();
}

View File

@@ -154,6 +154,7 @@ final class PhabricatorTOTPAuthFactor extends PhabricatorAuthFactor {
id(new PHUIFormNumberControl())
->setName($this->getParameterName($config, 'totpcode'))
->setLabel(pht('App Code'))
->setDisableAutocomplete(true)
->setCaption(pht('Factor Name: %s', $config->getFactorName()))
->setValue(idx($validation_result, 'value'))
->setError(idx($validation_result, 'error', true)));

View File

@@ -3,7 +3,7 @@
final class PhabricatorAuthSSHKeyQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
const AUTHFILE_CACHEKEY = 'ssh.authfile';
const AUTHSTRUCT_CACHEKEY = 'ssh.authstruct';
private $ids;
private $phids;
@@ -13,7 +13,7 @@ final class PhabricatorAuthSSHKeyQuery
public static function deleteSSHKeyCache() {
$cache = PhabricatorCaches::getMutableCache();
$authfile_key = self::AUTHFILE_CACHEKEY;
$authfile_key = self::AUTHSTRUCT_CACHEKEY;
$cache->deleteKey($authfile_key);
}

View File

@@ -184,6 +184,7 @@ final class PhabricatorAuthPassword
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
);
}
@@ -201,7 +202,7 @@ final class PhabricatorAuthPassword
public function getExtendedPolicy($capability, PhabricatorUser $viewer) {
return array(
array($this->getObject(), PhabricatorPolicyCapability::CAN_VIEW),
array($this->getObject(), $capability),
);
}

View File

@@ -74,6 +74,22 @@ final class PhabricatorAuthSession extends PhabricatorAuthDAO
}
}
public function isHighSecuritySession() {
$until = $this->getHighSecurityUntil();
if (!$until) {
return false;
}
$now = PhabricatorTime::getNow();
if ($until < $now) {
return false;
}
return true;
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */

View File

@@ -106,8 +106,21 @@ final class PhabricatorDataCacheSpec extends PhabricatorCacheSpec {
$cache = $info['cache_list'];
$state = array();
foreach ($cache as $item) {
$info = idx($item, 'info', '<unknown-key>');
$key = self::getKeyPattern($info);
// Some older versions of APCu report the cachekey as "key", while
// newer APCu and APC report it as "info". Just check both indexes
// for commpatibility. See T13164 for details.
$info = idx($item, 'info');
if ($info === null) {
$info = idx($item, 'key');
}
if ($info === null) {
$key = '<unknown-key>';
} else {
$key = self::getKeyPattern($info);
}
if (empty($state[$key])) {
$state[$key] = array(
'max' => 0,

View File

@@ -0,0 +1,36 @@
<?php
final class ConduitConstantDescription extends Phobject {
private $key;
private $value;
private $isDeprecated;
public function setKey($key) {
$this->key = $key;
return $this;
}
public function getKey() {
return $this->key;
}
public function setValue($value) {
$this->value = $value;
return $this;
}
public function getValue() {
return $this->value;
}
public function setIsDeprecated($is_deprecated) {
$this->isDeprecated = $is_deprecated;
return $this;
}
public function getIsDeprecated() {
return $this->isDeprecated;
}
}

View File

@@ -21,6 +21,13 @@ final class PhabricatorConduitCallManagementWorkflow
'File to read parameters from, or "-" to read from '.
'stdin.'),
),
array(
'name' => 'as',
'param' => 'username',
'help' => pht(
'Execute the call as the given user. (If omitted, the call will '.
'be executed as an omnipotent user.)'),
),
));
}
@@ -39,6 +46,22 @@ final class PhabricatorConduitCallManagementWorkflow
pht('Specify a file to read parameters from with "--input".'));
}
$as = $args->getArg('as');
if (strlen($as)) {
$actor = id(new PhabricatorPeopleQuery())
->setViewer($viewer)
->withUsernames(array($as))
->executeOne();
if (!$actor) {
throw new PhutilArgumentUsageException(
pht(
'No such user "%s" exists.',
$as));
}
} else {
$actor = $viewer;
}
if ($input === '-') {
fprintf(STDERR, tsprintf("%s\n", pht('Reading input from stdin...')));
$input_json = file_get_contents('php://stdin');
@@ -49,7 +72,7 @@ final class PhabricatorConduitCallManagementWorkflow
$params = phutil_json_decode($input_json);
$result = id(new ConduitCall($method, $params))
->setUser($viewer)
->setUser($actor)
->execute();
$output = array(

View File

@@ -84,8 +84,6 @@ final class PhabricatorExtraConfigSetupCheck extends PhabricatorSetupCheck {
$issue->addPhabricatorConfig($key);
}
}
$this->executeManiphestFieldChecks();
}
/**
@@ -361,69 +359,4 @@ final class PhabricatorExtraConfigSetupCheck extends PhabricatorSetupCheck {
return $ancient_config;
}
private function executeManiphestFieldChecks() {
$maniphest_appclass = 'PhabricatorManiphestApplication';
if (!PhabricatorApplication::isClassInstalled($maniphest_appclass)) {
return;
}
$capabilities = array(
ManiphestEditAssignCapability::CAPABILITY,
ManiphestEditPoliciesCapability::CAPABILITY,
ManiphestEditPriorityCapability::CAPABILITY,
ManiphestEditProjectsCapability::CAPABILITY,
ManiphestEditStatusCapability::CAPABILITY,
);
// Check for any of these capabilities set to anything other than
// "All Users".
$any_set = false;
$app = new PhabricatorManiphestApplication();
foreach ($capabilities as $capability) {
$setting = $app->getPolicy($capability);
if ($setting != PhabricatorPolicies::POLICY_USER) {
$any_set = true;
break;
}
}
if (!$any_set) {
return;
}
$issue_summary = pht(
'Maniphest is currently configured with deprecated policy settings '.
'which will be removed in a future version of Phabricator.');
$message = pht(
'Some policy settings in Maniphest are now deprecated and will be '.
'removed in a future version of Phabricator. You are currently using '.
'at least one of these settings.'.
"\n\n".
'The deprecated settings are "Can Assign Tasks", '.
'"Can Edit Task Policies", "Can Prioritize Tasks", '.
'"Can Edit Task Projects", and "Can Edit Task Status". You can '.
'find these settings in Applications, or follow the link below.'.
"\n\n".
'You can find discussion of this change (including rationale and '.
'recommendations on how to configure similar features) in the upstream, '.
'at the link below.'.
"\n\n".
'To resolve this issue, set all of these policies to "All Users" after '.
'making any necessary form customization changes.');
$more_href = 'https://secure.phabricator.com/T10003';
$edit_href = '/applications/view/PhabricatorManiphestApplication/';
$issue = $this->newIssue('maniphest.T10003-per-field-policies')
->setShortName(pht('Deprecated Policies'))
->setName(pht('Deprecated Maniphest Field Policies'))
->setSummary($issue_summary)
->setMessage($message)
->addLink($more_href, pht('Learn More: Upstream Discussion'))
->addLink($edit_href, pht('Edit These Settings'));
}
}

View File

@@ -13,63 +13,134 @@ final class PhabricatorManualActivitySetupCheck
foreach ($activities as $activity) {
$type = $activity->getActivityType();
// For now, there is only one type of manual activity. It's not clear
// if we're really going to have too much more of this stuff so this
// is a bit under-designed for now.
switch ($type) {
case PhabricatorConfigManualActivity::TYPE_REINDEX:
$this->raiseSearchReindexIssue();
break;
$activity_name = pht('Rebuild Search Index');
$activity_summary = pht(
'The search index algorithm has been updated and the index needs '.
'be rebuilt.');
case PhabricatorConfigManualActivity::TYPE_IDENTITIES:
$this->raiseRebuildIdentitiesIssue();
break;
$message = array();
$message[] = pht(
'The indexing algorithm for the fulltext search index has been '.
'updated and the index needs to be rebuilt. Until you rebuild the '.
'index, global search (and other fulltext search) will not '.
'function correctly.');
$message[] = pht(
'You can rebuild the search index while Phabricator is running.');
$message[] = pht(
'To rebuild the index, run this command:');
$message[] = phutil_tag(
'pre',
array(),
(string)csprintf(
'phabricator/ $ ./bin/search index --all --force --background'));
$message[] = pht(
'You can find more information about rebuilding the search '.
'index here: %s',
phutil_tag(
'a',
array(
'href' => 'https://phurl.io/u/reindex',
'target' => '_blank',
),
'https://phurl.io/u/reindex'));
$message[] = pht(
'After rebuilding the index, run this command to clear this setup '.
'warning:');
$message[] = phutil_tag(
'pre',
array(),
(string)csprintf('phabricator/ $ ./bin/config done %R', $type));
$activity_message = phutil_implode_html("\n\n", $message);
$this->newIssue('manual.'.$type)
->setName($activity_name)
->setSummary($activity_summary)
->setMessage($activity_message);
default:
}
}
}
private function raiseSearchReindexIssue() {
$activity_name = pht('Rebuild Search Index');
$activity_summary = pht(
'The search index algorithm has been updated and the index needs '.
'be rebuilt.');
$message = array();
$message[] = pht(
'The indexing algorithm for the fulltext search index has been '.
'updated and the index needs to be rebuilt. Until you rebuild the '.
'index, global search (and other fulltext search) will not '.
'function correctly.');
$message[] = pht(
'You can rebuild the search index while Phabricator is running.');
$message[] = pht(
'To rebuild the index, run this command:');
$message[] = phutil_tag(
'pre',
array(),
(string)csprintf(
'phabricator/ $ ./bin/search index --all --force --background'));
$message[] = pht(
'You can find more information about rebuilding the search '.
'index here: %s',
phutil_tag(
'a',
array(
'href' => 'https://phurl.io/u/reindex',
'target' => '_blank',
),
'https://phurl.io/u/reindex'));
$message[] = pht(
'After rebuilding the index, run this command to clear this setup '.
'warning:');
$message[] = phutil_tag(
'pre',
array(),
'phabricator/ $ ./bin/config done reindex');
$activity_message = phutil_implode_html("\n\n", $message);
$this->newIssue('manual.reindex')
->setName($activity_name)
->setSummary($activity_summary)
->setMessage($activity_message);
}
private function raiseRebuildIdentitiesIssue() {
$activity_name = pht('Rebuild Repository Identities');
$activity_summary = pht(
'The mapping from VCS users to Phabricator users has changed '.
'and must be rebuilt.');
$message = array();
$message[] = pht(
'The way Phabricator attributes VCS activity to Phabricator users '.
'has changed. There is a new indirection layer between the strings '.
'that appear as VCS authors and committers (such as "John Developer '.
'<johnd@bigcorp.com>") and the Phabricator user that gets associated '.
'with VCS commits. This is to support situations where users '.
'are incorrectly associated with commits by Phabricator making bad '.
'guesses about the identity of the corresponding Phabricator user. '.
'This also helps with situations where existing repositories are '.
'imported without having created accounts for all the committers to '.
'that repository. Until you rebuild these repository identities, you '.
'are likely to encounter problems with future Phabricator features '.
'which will rely on the existence of these identities.');
$message[] = pht(
'You can rebuild repository identities while Phabricator is running.');
$message[] = pht(
'To rebuild identities, run this command:');
$message[] = phutil_tag(
'pre',
array(),
(string)csprintf(
'phabricator/ $ ./bin/repository rebuild-identities --all'));
$message[] = pht(
'You can find more information about this new identity mapping '.
'here: %s',
phutil_tag(
'a',
array(
'href' => 'https://phurl.io/u/repoIdentities',
'target' => '_blank',
),
'https://phurl.io/u/repoIdentities'));
$message[] = pht(
'After rebuilding repository identities, run this command to clear '.
'this setup warning:');
$message[] = phutil_tag(
'pre',
array(),
'phabricator/ $ ./bin/config done identities');
$activity_message = phutil_implode_html("\n\n", $message);
$this->newIssue('manual.identities')
->setName($activity_name)
->setSummary($activity_summary)
->setMessage($activity_message);
}
}

View File

@@ -153,30 +153,16 @@ final class PhabricatorConfigEditController
$e_value);
}
$engine = new PhabricatorMarkupEngine();
$engine->setViewer($viewer);
$engine->addObject($option, 'description');
$engine->process();
$description = phutil_tag(
'div',
array(
'class' => 'phabricator-remarkup',
),
$engine->getOutput($option, 'description'));
$form
->setUser($viewer)
->addHiddenInput('issue', $request->getStr('issue'));
$description = $option->getDescription();
if (strlen($description)) {
$description_view = new PHUIRemarkupView($viewer, $description);
$form
->appendChild(
id(new AphrontFormMarkupControl())
->setLabel(pht('Description'))
->setValue($description_view));
$description = $option->newDescriptionRemarkupView($viewer);
if ($description) {
$form->appendChild(
id(new AphrontFormMarkupControl())
->setLabel(pht('Description'))
->setValue($description));
}
if ($group) {

View File

@@ -60,17 +60,10 @@ final class PhabricatorConfigGroupController
$db_values = mpull($db_values, null, 'getConfigKey');
}
$engine = id(new PhabricatorMarkupEngine())
->setViewer($this->getRequest()->getUser());
foreach ($options as $option) {
$engine->addObject($option, 'summary');
}
$engine->process();
$list = new PHUIObjectItemListView();
$list->setBig(true);
foreach ($options as $option) {
$summary = $engine->getOutput($option, 'summary');
$summary = $option->getSummary();
$item = id(new PHUIObjectItemView())
->setHeader($option->getKey())

View File

@@ -33,27 +33,26 @@ final class PhabricatorConfigIssueListController
PhabricatorSetupCheck::GROUP_OTHER,
'fa-question-circle');
$no_issues = null;
if (empty($issues)) {
$no_issues = id(new PHUIInfoView())
$title = pht('Setup Issues');
$header = $this->buildHeaderView($title);
if (!$issues) {
$issue_list = id(new PHUIInfoView())
->setTitle(pht('No Issues'))
->appendChild(
pht('Your install has no current setup issues to resolve.'))
->setSeverity(PHUIInfoView::SEVERITY_NOTICE);
} else {
$issue_list = array(
$important,
$php,
$mysql,
$other,
);
$issue_list = $this->buildConfigBoxView(pht('Issues'), $issue_list);
}
$title = pht('Setup Issues');
$header = $this->buildHeaderView($title);
$issue_list = array(
$important,
$php,
$mysql,
$other,
);
$issue_list = $this->buildConfigBoxView(pht('Issues'), $issue_list);
$crumbs = $this->buildApplicationCrumbs()
->addTextCrumb($title)
->setBorder(true);
@@ -62,10 +61,7 @@ final class PhabricatorConfigIssueListController
->setHeader($header)
->setNavigation($nav)
->setFixed(true)
->setMainColumn(array(
$no_issues,
$issue_list,
));
->setMainColumn($issue_list);
return $this->newPage()
->setTitle($title)

View File

@@ -1,8 +1,7 @@
<?php
final class PhabricatorConfigOption
extends Phobject
implements PhabricatorMarkupInterface {
extends Phobject {
private $key;
private $default;
@@ -204,43 +203,19 @@ final class PhabricatorConfigOption
return $this;
}
/* -( PhabricatorMarkupInterface )----------------------------------------- */
public function getMarkupFieldKey($field) {
return $this->getKey().':'.$field;
}
public function newMarkupEngine($field) {
return PhabricatorMarkupEngine::newMarkupEngine(array());
}
public function getMarkupText($field) {
switch ($field) {
case 'description':
$text = $this->getDescription();
break;
case 'summary':
$text = $this->getSummary();
break;
public function newDescriptionRemarkupView(PhabricatorUser $viewer) {
$description = $this->getDescription();
if (!strlen($description)) {
return null;
}
// TODO: We should probably implement this as a real Markup rule, but
// markup rules are a bit of a mess right now and it doesn't hurt us to
// fake this.
$text = preg_replace(
// TODO: Some day, we should probably implement this as a real rule.
$description = preg_replace(
'/{{([^}]+)}}/',
'[[/config/edit/\\1/ | \\1]]',
$text);
$description);
return $text;
}
public function didMarkupText($field, $output, PhutilMarkupEngine $engine) {
return $output;
}
public function shouldUseMarkupCache($field) {
return false;
return new PHUIRemarkupView($viewer, $description);
}
}

View File

@@ -34,9 +34,14 @@ final class PhabricatorPHDConfigOptions
->setSummary(pht('Maximum taskmaster daemon pool size.'))
->setDescription(
pht(
'Maximum number of taskmaster daemons to run at once. Raising '.
'this can increase the maximum throughput of the task queue. The '.
'pool will automatically scale down when unutilized.')),
"Maximum number of taskmaster daemons to run at once. Raising ".
"this can increase the maximum throughput of the task queue. The ".
"pool will automatically scale down when unutilized.".
"\n\n".
"If you are running a cluster, this limit applies separately ".
"to each instance of `phd`. For example, if this limit is set ".
"to `4` and you have three hosts running daemons, the effective ".
"global limit will be 12.")),
$this->newOption('phd.verbose', 'bool', false)
->setLocked(true)
->setBoolOptions(

View File

@@ -7,6 +7,8 @@ final class PhabricatorConfigManualActivity
protected $parameters = array();
const TYPE_REINDEX = 'reindex';
const TYPE_IDENTITIES = 'identities';
protected function getConfiguration() {
return array(

View File

@@ -146,49 +146,6 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
return $xactions;
}
protected function requireCapabilities(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
parent::requireCapabilities($object, $xaction);
switch ($xaction->getTransactionType()) {
case ConpherenceThreadParticipantsTransaction::TRANSACTIONTYPE:
$old_map = array_fuse($xaction->getOldValue());
$new_map = array_fuse($xaction->getNewValue());
$add = array_keys(array_diff_key($new_map, $old_map));
$rem = array_keys(array_diff_key($old_map, $new_map));
$actor_phid = $this->getActingAsPHID();
$is_join = (($add === array($actor_phid)) && !$rem);
$is_leave = (($rem === array($actor_phid)) && !$add);
if ($is_join) {
// Anyone can join a thread they can see.
} else if ($is_leave) {
// Anyone can leave a thread.
} else {
// You need CAN_EDIT to add or remove participants. For additional
// discussion, see D17696 and T4411.
PhabricatorPolicyFilter::requireCapability(
$this->requireActor(),
$object,
PhabricatorPolicyCapability::CAN_EDIT);
}
break;
case ConpherenceThreadTitleTransaction::TRANSACTIONTYPE:
case ConpherenceThreadTopicTransaction::TRANSACTIONTYPE:
PhabricatorPolicyFilter::requireCapability(
$this->requireActor(),
$object,
PhabricatorPolicyCapability::CAN_EDIT);
break;
}
}
protected function shouldSendMail(
PhabricatorLiskDAO $object,
array $xactions) {

View File

@@ -114,4 +114,34 @@ final class ConpherenceThreadParticipantsTransaction
return $errors;
}
public function getRequiredCapabilities(
$object,
PhabricatorApplicationTransaction $xaction) {
$old_map = array_fuse($xaction->getOldValue());
$new_map = array_fuse($xaction->getNewValue());
$add = array_keys(array_diff_key($new_map, $old_map));
$rem = array_keys(array_diff_key($old_map, $new_map));
$actor_phid = $this->getActingAsPHID();
$is_join = (($add === array($actor_phid)) && !$rem);
$is_leave = (($rem === array($actor_phid)) && !$add);
if ($is_join) {
// Anyone can join a thread they can see.
return null;
}
if ($is_leave) {
// Anyone can leave a thread.
return null;
}
// You need CAN_EDIT to add or remove participants. For additional
// discussion, see D17696 and T4411.
return PhabricatorPolicyCapability::CAN_EDIT;
}
}

View File

@@ -1,6 +1,7 @@
<?php
final class PhabricatorDifferentialApplication extends PhabricatorApplication {
final class PhabricatorDifferentialApplication
extends PhabricatorApplication {
public function getBaseURI() {
return '/differential/';
@@ -48,8 +49,7 @@ final class PhabricatorDifferentialApplication extends PhabricatorApplication {
'/(?P<filter>new)/' => 'DifferentialRevisionViewController',
),
'/differential/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?'
=> 'DifferentialRevisionListController',
$this->getQueryRoutePattern() => 'DifferentialRevisionListController',
'diff/' => array(
'(?P<id>[1-9]\d*)/' => array(
'' => 'DifferentialDiffViewController',

View File

@@ -276,6 +276,7 @@ final class DifferentialChangesetViewController extends DifferentialController {
->setDiff($diff)
->setTitle(pht('Standalone View'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setIsStandalone(true)
->setParser($parser);
if ($revision_id) {

View File

@@ -77,19 +77,17 @@ final class DifferentialInlineCommentEditController
}
protected function loadCommentForEdit($id) {
$request = $this->getRequest();
$user = $request->getUser();
$viewer = $this->getViewer();
$inline = $this->loadComment($id);
if (!$this->canEditInlineComment($user, $inline)) {
if (!$this->canEditInlineComment($viewer, $inline)) {
throw new Exception(pht('That comment is not editable!'));
}
return $inline;
}
protected function loadCommentForDone($id) {
$request = $this->getRequest();
$viewer = $request->getUser();
$viewer = $this->getViewer();
$inline = $this->loadComment($id);
if (!$inline) {
@@ -120,19 +118,32 @@ final class DifferentialInlineCommentEditController
throw new Exception(pht('Unable to load revision.'));
}
if ($revision->getAuthorPHID() !== $viewer->getPHID()) {
throw new Exception(pht('You are not the revision owner.'));
$viewer_phid = $viewer->getPHID();
$is_owner = ($viewer_phid == $revision->getAuthorPHID());
$is_author = ($viewer_phid == $inline->getAuthorPHID());
$is_draft = ($inline->isDraft());
if ($is_owner) {
// You own the revision, so you can mark the comment as "Done".
} else if ($is_author && $is_draft) {
// You made this comment and it's still a draft, so you can mark
// it as "Done".
} else {
throw new Exception(
pht(
'You are not the revision owner, and this is not a draft comment '.
'you authored.'));
}
return $inline;
}
private function canEditInlineComment(
PhabricatorUser $user,
PhabricatorUser $viewer,
DifferentialInlineComment $inline) {
// Only the author may edit a comment.
if ($inline->getAuthorPHID() != $user->getPHID()) {
if ($inline->getAuthorPHID() != $viewer->getPHID()) {
return false;
}

View File

@@ -463,7 +463,7 @@ final class DifferentialRevisionViewController
}
}
$tab_group = id(new PHUITabGroupView());
$tab_group = new PHUITabGroupView();
if ($toc_view) {
$tab_group->addTab(
@@ -473,17 +473,30 @@ final class DifferentialRevisionViewController
->appendChild($toc_view));
}
$tab_group
->addTab(
id(new PHUITabView())
->setName(pht('History'))
->setKey('history')
->appendChild($history))
->addTab(
id(new PHUITabView())
->setName(pht('Commits'))
->setKey('commits')
->appendChild($local_table));
$tab_group->addTab(
id(new PHUITabView())
->setName(pht('History'))
->setKey('history')
->appendChild($history));
$filetree_on = $viewer->compareUserSetting(
PhabricatorShowFiletreeSetting::SETTINGKEY,
PhabricatorShowFiletreeSetting::VALUE_ENABLE_FILETREE);
$collapsed_key = PhabricatorFiletreeVisibleSetting::SETTINGKEY;
$filetree_collapsed = (bool)$viewer->getUserSetting($collapsed_key);
// See PHI811. If the viewer has the file tree on, the files tab with the
// table of contents is redundant, so default to the "History" tab instead.
if ($filetree_on && !$filetree_collapsed) {
$tab_group->selectTab('history');
}
$tab_group->addTab(
id(new PHUITabView())
->setName(pht('Commits'))
->setKey('commits')
->appendChild($local_table));
$stack_graph = id(new DifferentialRevisionGraph())
->setViewer($viewer)
@@ -601,22 +614,15 @@ final class DifferentialRevisionViewController
$crumbs->addTextCrumb($monogram);
$crumbs->setBorder(true);
$filetree_on = $viewer->compareUserSetting(
PhabricatorShowFiletreeSetting::SETTINGKEY,
PhabricatorShowFiletreeSetting::VALUE_ENABLE_FILETREE);
$nav = null;
if ($filetree_on && !$this->isVeryLargeDiff()) {
$collapsed_key = PhabricatorFiletreeVisibleSetting::SETTINGKEY;
$collapsed_value = $viewer->getUserSetting($collapsed_key);
$width_key = PhabricatorFiletreeWidthSetting::SETTINGKEY;
$width_value = $viewer->getUserSetting($width_key);
$nav = id(new DifferentialChangesetFileTreeSideNavBuilder())
->setTitle($monogram)
->setBaseURI(new PhutilURI($revision->getURI()))
->setCollapsed((bool)$collapsed_value)
->setCollapsed($filetree_collapsed)
->setWidth((int)$width_value)
->build($changesets);
}
@@ -1309,7 +1315,7 @@ final class DifferentialRevisionViewController
}
return id(new HarbormasterUnitSummaryView())
->setUser($viewer)
->setViewer($viewer)
->setExcuse($excuse)
->setBuildable($diff->getBuildable())
->setUnitMessages($diff->getUnitMessages())

View File

@@ -248,19 +248,34 @@ final class DifferentialTransactionEditor
$this->didExpandInlineState = true;
$actor_phid = $this->getActingAsPHID();
$actor_is_author = ($object->getAuthorPHID() == $actor_phid);
if (!$actor_is_author) {
break;
}
$author_phid = $object->getAuthorPHID();
$actor_is_author = ($actor_phid == $author_phid);
$state_map = PhabricatorTransactions::getInlineStateMap();
$inlines = id(new DifferentialDiffInlineCommentQuery())
$query = id(new DifferentialDiffInlineCommentQuery())
->setViewer($this->getActor())
->withRevisionPHIDs(array($object->getPHID()))
->withFixedStates(array_keys($state_map))
->withFixedStates(array_keys($state_map));
$inlines = array();
// We're going to undraft any "done" marks on your own inlines.
$inlines[] = id(clone $query)
->withAuthorPHIDs(array($actor_phid))
->withHasTransaction(false)
->execute();
// If you're the author, we also undraft any "done" marks on other
// inlines.
if ($actor_is_author) {
$inlines[] = id(clone $query)
->withHasTransaction(true)
->execute();
}
$inlines = array_mergev($inlines);
if (!$inlines) {
break;
}
@@ -621,8 +636,8 @@ final class DifferentialTransactionEditor
$viewer = $this->requireActor();
$body = new PhabricatorMetaMTAMailBody();
$body->setViewer($this->requireActor());
$body = id(new PhabricatorMetaMTAMailBody())
->setViewer($viewer);
$revision_uri = $object->getURI();
$revision_uri = PhabricatorEnv::getProductionURI($revision_uri);
@@ -671,7 +686,7 @@ final class DifferentialTransactionEditor
$this->addCustomFieldsToMailBody($body, $object, $xactions);
if (!$this->getIsNewObject()) {
if (!$this->isFirstBroadcast()) {
$body->addLinkSection(pht('CHANGES SINCE LAST ACTION'), $new_uri);
}
@@ -892,6 +907,17 @@ final class DifferentialTransactionEditor
array $inlines,
PhabricatorMetaMTAMailBody $body) {
$limit = 100;
$limit_note = null;
if (count($inlines) > $limit) {
$limit_note = pht(
'(Showing first %s of %s inline comments.)',
new PhutilNumber($limit),
phutil_count($inlines));
$inlines = array_slice($inlines, 0, $limit, true);
}
$section = id(new DifferentialInlineCommentMailView())
->setViewer($this->getActor())
->setInlines($inlines)
@@ -900,6 +926,9 @@ final class DifferentialTransactionEditor
$header = pht('INLINE COMMENTS');
$section_text = "\n".$section->getPlaintext();
if ($limit_note) {
$section_text = $limit_note."\n".$section_text;
}
$style = array(
'margin: 6px 0 12px 0;',
@@ -912,6 +941,16 @@ final class DifferentialTransactionEditor
),
$section->getHTML());
if ($limit_note) {
$section_html = array(
phutil_tag(
'em',
array(),
$limit_note),
$section_html,
);
}
$body->addPlaintextSection($header, $section_text, false);
$body->addHTMLSection($header, $section_html);
}

View File

@@ -88,6 +88,20 @@ final class DifferentialChangesetEngine extends Phobject {
private function detectCopiedCode(array $changesets) {
// See PHI944. If the total number of changed lines is excessively large,
// don't bother with copied code detection. This can take a lot of time and
// memory and it's not generally of any use for very large changes.
$max_size = 65535;
$total_size = 0;
foreach ($changesets as $changeset) {
$total_size += ($changeset->getAddLines() + $changeset->getDelLines());
}
if ($total_size > $max_size) {
return;
}
$min_width = 30;
$min_lines = 3;

View File

@@ -54,4 +54,28 @@ final class DifferentialBuildableEngine
$this->applyTransactions(array($xaction));
}
public function getAuthorIdentity() {
$object = $this->getObject();
if ($object instanceof DifferentialRevision) {
$object = $object->loadActiveDiff();
}
$authorship = $object->getDiffAuthorshipDict();
if (!isset($authorship['authorName'])) {
return null;
}
$name = $authorship['authorName'];
$address = idx($authorship, 'authorEmail');
$full = id(new PhutilEmailAddress())
->setDisplayName($name)
->setAddress($address);
return id(new PhabricatorRepositoryIdentity())
->setIdentityName((string)$full)
->makeEphemeral();
}
}

View File

@@ -10,10 +10,7 @@ final class DifferentialRevisionSummaryHeraldField
}
public function getHeraldFieldValue($object) {
// NOTE: For historical reasons, this field includes the test plan. We
// could maybe try to fix this some day, but it probably aligns reasonably
// well with user expectation without harming anything.
return $object->getSummary()."\n\n".$object->getTestPlan();
return $object->getSummary();
}
protected function getHeraldFieldStandardType() {

View File

@@ -0,0 +1,20 @@
<?php
final class DifferentialRevisionTestPlanHeraldField
extends DifferentialRevisionHeraldField {
const FIELDCONST = 'differential.revision.test-plan';
public function getHeraldFieldName() {
return pht('Revision test plan');
}
public function getHeraldFieldValue($object) {
return $object->getTestPlan();
}
protected function getHeraldFieldStandardType() {
return self::STANDARD_TEXT;
}
}

View File

@@ -345,7 +345,13 @@ final class DifferentialInlineCommentMailView
$offset_mode = 'old';
}
// See PHI894. Use the parse cache since we can end up with a large
// rendering cost otherwise when users or bots leave hundreds of inline
// comments on diffs with long recipient lists.
$cache_key = $changeset->getID();
$parser = id(new DifferentialChangesetParser())
->setRenderCacheKey($cache_key)
->setUser($viewer)
->setChangeset($changeset)
->setOffsetMode($offset_mode)
@@ -440,7 +446,18 @@ final class DifferentialInlineCommentMailView
'style' => implode(' ', $link_style),
'href' => $link_href,
),
pht('View Inline'));
array(
pht('View Inline'),
// See PHI920. Add a space after the link so we render this into
// the document:
//
// View Inline filename.txt
//
// Otherwise, we render "Inlinefilename.txt" and double-clicking
// the file name selects the word "Inline" as well.
' ',
));
} else {
$link = null;
}

View File

@@ -25,6 +25,8 @@ final class DifferentialRevisionQuery
private $updatedEpochMax;
private $statuses;
private $isOpen;
private $createdEpochMin;
private $createdEpochMax;
const ORDER_MODIFIED = 'order-modified';
const ORDER_CREATED = 'order-created';
@@ -206,6 +208,12 @@ final class DifferentialRevisionQuery
return $this;
}
public function withCreatedEpochBetween($min, $max) {
$this->createdEpochMin = $min;
$this->createdEpochMax = $max;
return $this;
}
/**
* Set whether or not the query should load the active diff for each
@@ -687,6 +695,20 @@ final class DifferentialRevisionQuery
$this->updatedEpochMax);
}
if ($this->createdEpochMin !== null) {
$where[] = qsprintf(
$conn_r,
'r.dateCreated >= %d',
$this->createdEpochMin);
}
if ($this->createdEpochMax !== null) {
$where[] = qsprintf(
$conn_r,
'r.dateCreated <= %d',
$this->createdEpochMax);
}
if ($this->statuses !== null) {
$where[] = qsprintf(
$conn_r,

View File

@@ -45,6 +45,12 @@ final class DifferentialRevisionSearchEngine
$query->withStatuses($map['statuses']);
}
if ($map['createdStart'] || $map['createdEnd']) {
$query->withCreatedEpochBetween(
$map['createdStart'],
$map['createdEnd']);
}
return $query;
}
@@ -84,6 +90,16 @@ final class DifferentialRevisionSearchEngine
->setDatasource(new DifferentialRevisionStatusFunctionDatasource())
->setDescription(
pht('Find revisions with particular statuses.')),
id(new PhabricatorSearchDateField())
->setLabel(pht('Created After'))
->setKey('createdStart')
->setDescription(
pht('Find revisions created at or after a particular time.')),
id(new PhabricatorSearchDateField())
->setLabel(pht('Created Before'))
->setKey('createdEnd')
->setDescription(
pht('Find revisions created at or before a particular time.')),
);
}
@@ -277,4 +293,77 @@ final class DifferentialRevisionSearchEngine
return $result;
}
protected function newExportFields() {
$fields = array(
id(new PhabricatorStringExportField())
->setKey('monogram')
->setLabel(pht('Monogram')),
id(new PhabricatorPHIDExportField())
->setKey('authorPHID')
->setLabel(pht('Author PHID')),
id(new PhabricatorStringExportField())
->setKey('author')
->setLabel(pht('Author')),
id(new PhabricatorStringExportField())
->setKey('status')
->setLabel(pht('Status')),
id(new PhabricatorStringExportField())
->setKey('statusName')
->setLabel(pht('Status Name')),
id(new PhabricatorURIExportField())
->setKey('uri')
->setLabel(pht('URI')),
id(new PhabricatorStringExportField())
->setKey('title')
->setLabel(pht('Title')),
id(new PhabricatorStringExportField())
->setKey('summary')
->setLabel(pht('Summary')),
id(new PhabricatorStringExportField())
->setKey('testPlan')
->setLabel(pht('Test Plan')),
);
return $fields;
}
protected function newExportData(array $revisions) {
$viewer = $this->requireViewer();
$phids = array();
foreach ($revisions as $revision) {
$phids[] = $revision->getAuthorPHID();
}
$handles = $viewer->loadHandles($phids);
$export = array();
foreach ($revisions as $revision) {
$author_phid = $revision->getAuthorPHID();
if ($author_phid) {
$author_name = $handles[$author_phid]->getName();
} else {
$author_name = null;
}
$status = $revision->getStatusObject();
$status_name = $status->getDisplayName();
$status_value = $status->getKey();
$export[] = array(
'monogram' => $revision->getMonogram(),
'authorPHID' => $author_phid,
'author' => $author_name,
'status' => $status_value,
'statusName' => $status_name,
'uri' => PhabricatorEnv::getProductionURI($revision->getURI()),
'title' => (string)$revision->getTitle(),
'summary' => (string)$revision->getSummary(),
'testPlan' => (string)$revision->getTestPlan(),
);
}
return $export;
}
}

View File

@@ -1152,6 +1152,20 @@ final class DifferentialRevision extends DifferentialDAO
->setKey('testPlan')
->setType('string')
->setDescription(pht('Revision test plan.')),
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('isDraft')
->setType('bool')
->setDescription(
pht(
'True if this revision is in any draft state, and thus not '.
'notifying reviewers and subscribers about changes.')),
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('holdAsDraft')
->setType('bool')
->setDescription(
pht(
'True if this revision is being held as a draft. It will not be '.
'automatically submitted for review even if tests pass.')),
);
}
@@ -1172,6 +1186,8 @@ final class DifferentialRevision extends DifferentialDAO
'diffPHID' => $this->getActiveDiffPHID(),
'summary' => $this->getSummary(),
'testPlan' => $this->getTestPlan(),
'isDraft' => !$this->getShouldBroadcast(),
'holdAsDraft' => (bool)$this->getHoldAsDraft(),
);
}

View File

@@ -10,6 +10,7 @@ final class DifferentialChangesetListView extends AphrontView {
private $whitespace;
private $background;
private $header;
private $isStandalone;
private $standaloneURI;
private $leftRawFileURI;
@@ -124,6 +125,15 @@ final class DifferentialChangesetListView extends AphrontView {
return $this;
}
public function setIsStandalone($is_standalone) {
$this->isStandalone = $is_standalone;
return $this;
}
public function getIsStandalone() {
return $this->isStandalone;
}
public function setBackground($background) {
$this->background = $background;
return $this;
@@ -219,6 +229,7 @@ final class DifferentialChangesetListView extends AphrontView {
'changesetViewIDs' => $ids,
'inlineURI' => $this->inlineURI,
'inlineListURI' => $this->inlineListURI,
'isStandalone' => $this->getIsStandalone(),
'pht' => array(
'Open in Editor' => pht('Open in Editor'),
'Show All Context' => pht('Show All Context'),
@@ -298,6 +309,7 @@ final class DifferentialChangesetListView extends AphrontView {
'Show All Inlines' => pht('Show All Inlines'),
'List Inline Comments' => pht('List Inline Comments'),
'Display Options' => pht('Display Options'),
'Hide or show all inline comments.' =>
pht('Hide or show all inline comments.'),

View File

@@ -0,0 +1,173 @@
<?php
final class DiffusionCommitAuditStatus extends Phobject {
private $key;
private $spec = array();
const NONE = 'none';
const NEEDS_AUDIT = 'needs-audit';
const CONCERN_RAISED = 'concern-raised';
const PARTIALLY_AUDITED = 'partially-audited';
const AUDITED = 'audited';
const NEEDS_VERIFICATION = 'needs-verification';
public static function newModernKeys(array $values) {
$map = self::getMap();
$modern = array();
foreach ($map as $key => $spec) {
if (isset($spec['legacy'])) {
$modern[$spec['legacy']] = $key;
}
}
foreach ($values as $key => $value) {
$values[$key] = idx($modern, $value, $value);
}
return $values;
}
public static function newForStatus($status) {
$result = new self();
$result->key = $status;
$map = self::getMap();
if (isset($map[$status])) {
$result->spec = $map[$status];
}
return $result;
}
public function getKey() {
return $this->key;
}
public function getIcon() {
return idx($this->spec, 'icon');
}
public function getColor() {
return idx($this->spec, 'color');
}
public function getAnsiColor() {
return idx($this->spec, 'color.ansi');
}
public function getName() {
return idx($this->spec, 'name', pht('Unknown ("%s")', $this->key));
}
public function isNoAudit() {
return ($this->key == self::NONE);
}
public function isNeedsAudit() {
return ($this->key == self::NEEDS_AUDIT);
}
public function isConcernRaised() {
return ($this->key == self::CONCERN_RAISED);
}
public function isNeedsVerification() {
return ($this->key == self::NEEDS_VERIFICATION);
}
public function isPartiallyAudited() {
return ($this->key == self::PARTIALLY_AUDITED);
}
public function isAudited() {
return ($this->key == self::AUDITED);
}
public function getIsClosed() {
return idx($this->spec, 'closed');
}
public static function getOpenStatusConstants() {
$constants = array();
foreach (self::getMap() as $key => $map) {
if (!$map['closed']) {
$constants[] = $key;
}
}
return $constants;
}
public static function newOptions() {
$map = self::getMap();
return ipull($map, 'name');
}
public static function newDeprecatedOptions() {
$map = self::getMap();
$results = array();
foreach ($map as $key => $spec) {
if (isset($spec['legacy'])) {
$results[$spec['legacy']] = $key;
}
}
return $results;
}
private static function getMap() {
return array(
self::NONE => array(
'name' => pht('No Audits'),
'legacy' => 0,
'icon' => 'fa-check',
'color' => 'bluegrey',
'closed' => true,
'color.ansi' => null,
),
self::NEEDS_AUDIT => array(
'name' => pht('Audit Required'),
'legacy' => 1,
'icon' => 'fa-exclamation-circle',
'color' => 'orange',
'closed' => false,
'color.ansi' => 'magenta',
),
self::CONCERN_RAISED => array(
'name' => pht('Concern Raised'),
'legacy' => 2,
'icon' => 'fa-times-circle',
'color' => 'red',
'closed' => false,
'color.ansi' => 'red',
),
self::PARTIALLY_AUDITED => array(
'name' => pht('Partially Audited'),
'legacy' => 3,
'icon' => 'fa-check-circle-o',
'color' => 'yellow',
'closed' => false,
'color.ansi' => 'yellow',
),
self::AUDITED => array(
'name' => pht('Audited'),
'legacy' => 4,
'icon' => 'fa-check-circle',
'color' => 'green',
'closed' => true,
'color.ansi' => 'green',
),
self::NEEDS_VERIFICATION => array(
'name' => pht('Needs Verification'),
'legacy' => 5,
'icon' => 'fa-refresh',
'color' => 'indigo',
'closed' => false,
'color.ansi' => 'magenta',
),
);
}
}

View File

@@ -9,6 +9,14 @@ final class DiffusionGetRecentCommitsByPathConduitAPIMethod
return 'diffusion.getrecentcommitsbypath';
}
public function getMethodStatus() {
return self::METHOD_STATUS_DEPRECATED;
}
public function getMethodStatusDescription() {
return pht('Obsoleted by "diffusion.historyquery".');
}
public function getMethodDescription() {
return pht(
'Get commit identifiers for recent commits affecting a given path.');
@@ -23,6 +31,12 @@ final class DiffusionGetRecentCommitsByPathConduitAPIMethod
);
}
protected function defineErrorTypes() {
return array(
'ERR_NOT_FOUND' => pht('Repository was not found.'),
);
}
protected function defineReturnType() {
return 'nonempty list<string>';
}
@@ -36,6 +50,10 @@ final class DiffusionGetRecentCommitsByPathConduitAPIMethod
'branch' => $request->getValue('branch'),
));
if ($drequest === null) {
throw new ConduitException('ERR_NOT_FOUND');
}
$limit = nonempty(
$request->getValue('limit'),
self::DEFAULT_LIMIT);

View File

@@ -24,6 +24,7 @@ final class DiffusionBlameController extends DiffusionController {
->setViewer($viewer)
->withRepository($repository)
->withIdentifiers($identifiers)
->needIdentities(true)
->execute();
$commits = mpull($commits, null, 'getCommitIdentifier');
} else {
@@ -68,10 +69,7 @@ final class DiffusionBlameController extends DiffusionController {
$handle_phids = array();
foreach ($commits as $commit) {
$author_phid = $commit->getAuthorPHID();
if ($author_phid) {
$handle_phids[] = $author_phid;
}
$handle_phids[] = $commit->getAuthorDisplayPHID();
}
foreach ($revisions as $revision) {
@@ -117,11 +115,7 @@ final class DiffusionBlameController extends DiffusionController {
$author_phid = null;
if ($commit) {
$author_phid = $commit->getAuthorPHID();
}
if (!$author_phid && $revision) {
$author_phid = $revision->getAuthorPHID();
$author_phid = $commit->getAuthorDisplayPHID();
}
if (!$author_phid) {
@@ -139,6 +133,7 @@ final class DiffusionBlameController extends DiffusionController {
$author_meta = array(
'tip' => $handles[$author_phid]->getName(),
'align' => 'E',
'size' => 'auto',
);
}

View File

@@ -46,6 +46,7 @@ final class DiffusionCommitController extends DiffusionController {
->needCommitData(true)
->needAuditRequests(true)
->setLimit(100)
->needIdentities(true)
->execute();
$multiple_results = count($commits) > 1;
@@ -170,13 +171,12 @@ final class DiffusionCommitController extends DiffusionController {
->setHeaderIcon('fa-code-fork')
->addTag($commit_tag);
if ($commit->getAuditStatus()) {
$icon = PhabricatorAuditCommitStatusConstants::getStatusIcon(
$commit->getAuditStatus());
$color = PhabricatorAuditCommitStatusConstants::getStatusColor(
$commit->getAuditStatus());
$status = PhabricatorAuditCommitStatusConstants::getStatusName(
$commit->getAuditStatus());
if (!$commit->isAuditStatusNoAudit()) {
$status = $commit->getAuditStatusObject();
$icon = $status->getIcon();
$color = $status->getColor();
$status = $status->getName();
$header->setStatus($icon, $color, $status);
}
@@ -504,15 +504,13 @@ final class DiffusionCommitController extends DiffusionController {
$phids = $edge_query->getDestinationPHIDs(array($commit_phid));
if ($data->getCommitDetail('authorPHID')) {
$phids[] = $data->getCommitDetail('authorPHID');
}
if ($data->getCommitDetail('reviewerPHID')) {
$phids[] = $data->getCommitDetail('reviewerPHID');
}
if ($data->getCommitDetail('committerPHID')) {
$phids[] = $data->getCommitDetail('committerPHID');
}
$phids[] = $commit->getCommitterDisplayPHID();
$phids[] = $commit->getAuthorDisplayPHID();
// NOTE: We should never normally have more than a single push log, but
// it can occur naturally if a commit is pushed, then the branch it was
@@ -573,24 +571,11 @@ final class DiffusionCommitController extends DiffusionController {
}
}
$author_phid = $data->getCommitDetail('authorPHID');
$author_name = $data->getAuthorName();
$author_epoch = $data->getCommitDetail('authorEpoch');
$committed_info = id(new PHUIStatusItemView())
->setNote(phabricator_datetime($commit->getEpoch(), $viewer));
$committer_phid = $data->getCommitDetail('committerPHID');
$committer_name = $data->getCommitDetail('committer');
if ($committer_phid) {
$committed_info->setTarget($handles[$committer_phid]->renderLink());
} else if (strlen($committer_name)) {
$committed_info->setTarget($committer_name);
} else if ($author_phid) {
$committed_info->setTarget($handles[$author_phid]->renderLink());
} else if (strlen($author_name)) {
$committed_info->setTarget($author_name);
}
->setNote(phabricator_datetime($commit->getEpoch(), $viewer))
->setTarget($commit->renderAnyCommitter($viewer, $handles));
$committed_list = new PHUIStatusListView();
$committed_list->addItem($committed_info);
@@ -716,7 +701,7 @@ final class DiffusionCommitController extends DiffusionController {
return null;
}
$author_phid = $data->getCommitDetail('authorPHID');
$author_phid = $commit->getAuthorDisplayPHID();
$author_name = $data->getAuthorName();
$author_epoch = $data->getCommitDetail('authorEpoch');
$date = null;
@@ -748,10 +733,8 @@ final class DiffusionCommitController extends DiffusionController {
->setImage($image_uri)
->setImageHref($image_href)
->setContent($content);
}
private function buildComments(PhabricatorRepositoryCommit $commit) {
$timeline = $this->buildTransactionTimeline(
$commit,

View File

@@ -50,19 +50,17 @@ final class DiffusionInlineCommentController
}
protected function loadCommentForEdit($id) {
$request = $this->getRequest();
$user = $request->getUser();
$viewer = $this->getViewer();
$inline = $this->loadComment($id);
if (!$this->canEditInlineComment($user, $inline)) {
if (!$this->canEditInlineComment($viewer, $inline)) {
throw new Exception(pht('That comment is not editable!'));
}
return $inline;
}
protected function loadCommentForDone($id) {
$request = $this->getRequest();
$viewer = $request->getUser();
$viewer = $this->getViewer();
$inline = $this->loadComment($id);
if (!$inline) {
@@ -77,20 +75,32 @@ final class DiffusionInlineCommentController
throw new Exception(pht('Failed to load commit.'));
}
if ((!$commit->getAuthorPHID()) ||
($commit->getAuthorPHID() != $viewer->getPHID())) {
throw new Exception(pht('You can not mark this comment as complete.'));
$owner_phid = $commit->getAuthorPHID();
$viewer_phid = $viewer->getPHID();
$viewer_is_owner = ($owner_phid && ($owner_phid == $viewer_phid));
$viewer_is_author = ($viewer_phid == $inline->getAuthorPHID());
$is_draft = $inline->isDraft();
if ($viewer_is_owner) {
// You can mark inlines on your own commits as "Done".
} else if ($viewer_is_author && $is_draft) {
// You can mark your own unsubmitted inlines as "Done".
} else {
throw new Exception(
pht(
'You can not mark this comment as complete: you did not author '.
'the commit and the comment is not a draft you wrote.'));
}
return $inline;
}
private function canEditInlineComment(
PhabricatorUser $user,
PhabricatorUser $viewer,
PhabricatorAuditInlineComment $inline) {
// Only the author may edit a comment.
if ($inline->getAuthorPHID() != $user->getPHID()) {
if ($inline->getAuthorPHID() != $viewer->getPHID()) {
return false;
}

View File

@@ -35,6 +35,7 @@ final class DiffusionLastModifiedController extends DiffusionController {
->withRepository($drequest->getRepository())
->withIdentifiers(array_values($modified_map))
->needCommitData(true)
->needIdentities(true)
->execute();
$commit_map = mpull($commit_map, null, 'getCommitIdentifier');
} else {
@@ -54,9 +55,8 @@ final class DiffusionLastModifiedController extends DiffusionController {
$phids = array();
foreach ($commits as $commit) {
$data = $commit->getCommitData();
$phids[] = $data->getCommitDetail('authorPHID');
$phids[] = $data->getCommitDetail('committerPHID');
$phids[] = $commit->getCommitterDisplayPHID();
$phids[] = $commit->getAuthorDisplayPHID();
}
$phids = array_filter($phids);
$handles = $this->loadViewerHandles($phids);
@@ -110,38 +110,21 @@ final class DiffusionLastModifiedController extends DiffusionController {
$date = '';
}
$data = $commit->getCommitData();
if ($data) {
$author_phid = $data->getCommitDetail('authorPHID');
if ($author_phid && isset($handles[$author_phid])) {
$author = $handles[$author_phid]->renderLink();
} else {
$author = DiffusionView::renderName($data->getAuthorName());
}
$author = $commit->renderAuthor($viewer, $handles);
$committer = $commit->renderCommitter($viewer, $handles);
$committer = $data->getCommitDetail('committer');
if ($committer) {
$committer_phid = $data->getCommitDetail('committerPHID');
if ($committer_phid && isset($handles[$committer_phid])) {
$committer = $handles[$committer_phid]->renderLink();
} else {
$committer = DiffusionView::renderName($committer);
}
if ($author != $committer) {
$author = hsprintf('%s/%s', $author, $committer);
}
}
$details = DiffusionView::linkDetail(
$drequest->getRepository(),
$commit->getCommitIdentifier(),
$data->getSummary());
$details = AphrontTableView::renderSingleDisplayLine($details);
} else {
$author = '';
$details = '';
if ($author != $committer) {
$author = hsprintf('%s/%s', $author, $committer);
}
$data = $commit->getCommitData();
$details = DiffusionView::linkDetail(
$drequest->getRepository(),
$commit->getCommitIdentifier(),
$data->getSummary());
$details = AphrontTableView::renderSingleDisplayLine($details);
$return = array(
'commit' => $modified,
'date' => $date,

View File

@@ -31,8 +31,6 @@ final class DiffusionDoorkeeperCommitFeedStoryPublisher
// After ApplicationTransactions, we could annotate feed stories more
// explicitly.
$fully_audited = PhabricatorAuditCommitStatusConstants::FULLY_AUDITED;
$story = $this->getFeedStory();
$xaction = $story->getPrimaryTransaction();
switch ($xaction->getTransactionType()) {
@@ -41,7 +39,7 @@ final class DiffusionDoorkeeperCommitFeedStoryPublisher
case PhabricatorAuditActionConstants::CLOSE:
return true;
case PhabricatorAuditActionConstants::ACCEPT:
if ($object->getAuditStatus() == $fully_audited) {
if ($object->isAuditStatusAudited()) {
return true;
}
break;
@@ -165,14 +163,7 @@ final class DiffusionDoorkeeperCommitFeedStoryPublisher
}
public function isObjectClosed($object) {
switch ($object->getAuditStatus()) {
case PhabricatorAuditCommitStatusConstants::NEEDS_AUDIT:
case PhabricatorAuditCommitStatusConstants::CONCERN_RAISED:
case PhabricatorAuditCommitStatusConstants::PARTIALLY_AUDITED:
return false;
default:
return true;
}
return $object->getAuditStatusObject()->getIsClosed();
}
public function getResponsibilityTitle($object) {

View File

@@ -41,12 +41,12 @@ final class DiffusionHovercardEngineExtension
$hovercard->addField(pht('Date'),
phabricator_date($commit->getEpoch(), $viewer));
if ($commit->getAuditStatus() !=
PhabricatorAuditCommitStatusConstants::NONE) {
if (!$commit->isAuditStatusNoAudit()) {
$status = $commit->getAuditStatusObject();
$hovercard->addField(pht('Audit Status'),
PhabricatorAuditCommitStatusConstants::getStatusName(
$commit->getAuditStatus()));
$hovercard->addField(
pht('Audit Status'),
$status->getName());
}
}

View File

@@ -34,4 +34,10 @@ final class DiffusionBuildableEngine
$this->applyTransactions(array($xaction));
}
public function getAuthorIdentity() {
return $this->getObject()
->loadIdentities($this->getViewer())
->getAuthorIdentity();
}
}

View File

@@ -23,12 +23,16 @@ final class DiffusionMercurialWireProtocol extends Phobject {
'listkeys' => array('namespace'),
'lookup' => array('key'),
'pushkey' => array('namespace', 'key', 'old', 'new'),
'protocaps' => array('caps'),
'stream_out' => array(''),
'unbundle' => array('heads'),
);
if (!isset($commands[$command])) {
throw new Exception(pht("Unknown Mercurial command '%s!", $command));
throw new Exception(
pht(
'Unknown Mercurial command "%s"!',
$command));
}
return $commands[$command];
@@ -49,6 +53,7 @@ final class DiffusionMercurialWireProtocol extends Phobject {
'known' => true,
'listkeys' => true,
'lookup' => true,
'protocaps' => true,
'stream_out' => true,
);

View File

@@ -170,12 +170,13 @@ final class DiffusionRepositoryClusterEngine extends Phobject {
pht(
'Acquired read lock immediately.'));
}
} catch (Exception $ex) {
} catch (PhutilLockException $ex) {
throw new PhutilProxyException(
pht(
'Failed to acquire read lock after waiting %s second(s). You '.
'may be able to retry later.',
new PhutilNumber($lock_wait)),
'may be able to retry later. (%s)',
new PhutilNumber($lock_wait),
$ex->getHint()),
$ex);
}
@@ -207,7 +208,7 @@ final class DiffusionRepositoryClusterEngine extends Phobject {
$this->synchronizeWorkingCopyFromDevices($fetchable);
} else {
$this->synchornizeWorkingCopyFromRemote();
$this->synchronizeWorkingCopyFromRemote();
}
PhabricatorRepositoryWorkingCopyVersion::updateVersion(
@@ -349,12 +350,13 @@ final class DiffusionRepositoryClusterEngine extends Phobject {
pht(
'Acquired write lock immediately.'));
}
} catch (Exception $ex) {
} catch (PhutilLockException $ex) {
throw new PhutilProxyException(
pht(
'Failed to acquire write lock after waiting %s second(s). You '.
'may be able to retry later.',
new PhutilNumber($lock_wait)),
'may be able to retry later. (%s)',
new PhutilNumber($lock_wait),
$ex->getHint()),
$ex);
}
@@ -607,7 +609,7 @@ final class DiffusionRepositoryClusterEngine extends Phobject {
/**
* @task internal
*/
private function synchornizeWorkingCopyFromRemote() {
private function synchronizeWorkingCopyFromRemote() {
$repository = $this->getRepository();
$device = AlmanacKeys::getLiveDevice();
@@ -686,6 +688,9 @@ final class DiffusionRepositoryClusterEngine extends Phobject {
'fetchable.'));
}
// If we can synchronize from multiple sources, choose one at random.
shuffle($fetchable);
$caught = null;
foreach ($fetchable as $binding) {
try {

View File

@@ -714,10 +714,13 @@ final class DiffusionCommitQuery
}
if ($this->statuses !== null) {
$statuses = DiffusionCommitAuditStatus::newModernKeys(
$this->statuses);
$where[] = qsprintf(
$conn,
'commit.auditStatus IN (%Ld)',
$this->statuses);
'commit.auditStatus IN (%Ls)',
$statuses);
}
if ($this->packagePHIDs !== null) {

View File

@@ -69,14 +69,12 @@ final class DiffusionCommitRequiredActionResultBucket
$results = array();
$objects = $this->objects;
$status_concern = PhabricatorAuditCommitStatusConstants::CONCERN_RAISED;
foreach ($objects as $key => $object) {
if (empty($phids[$object->getAuthorPHID()])) {
continue;
}
if ($object->getAuditStatus() != $status_concern) {
if (!$object->isAuditStatusConcernRaised()) {
continue;
}
@@ -91,7 +89,6 @@ final class DiffusionCommitRequiredActionResultBucket
$results = array();
$objects = $this->objects;
$status_verify = PhabricatorAuditCommitStatusConstants::NEEDS_VERIFICATION;
$has_concern = array(
PhabricatorAuditStatusConstants::CONCERNED,
);
@@ -102,7 +99,7 @@ final class DiffusionCommitRequiredActionResultBucket
continue;
}
if ($object->getAuditStatus() != $status_verify) {
if (!$object->isAuditStatusNeedsVerification()) {
continue;
}
@@ -147,10 +144,8 @@ final class DiffusionCommitRequiredActionResultBucket
$results = array();
$objects = $this->objects;
$status_concern = PhabricatorAuditCommitStatusConstants::CONCERN_RAISED;
foreach ($objects as $key => $object) {
if ($object->getAuditStatus() != $status_concern) {
if (!$object->isAuditStatusConcernRaised()) {
continue;
}
@@ -169,15 +164,13 @@ final class DiffusionCommitRequiredActionResultBucket
$results = array();
$objects = $this->objects;
$status_waiting = array(
PhabricatorAuditCommitStatusConstants::NEEDS_AUDIT,
PhabricatorAuditCommitStatusConstants::NEEDS_VERIFICATION,
PhabricatorAuditCommitStatusConstants::PARTIALLY_AUDITED,
);
$status_waiting = array_fuse($status_waiting);
foreach ($objects as $key => $object) {
if (empty($status_waiting[$object->getAuditStatus()])) {
$any_waiting =
$object->isAuditStatusNeedsAudit() ||
$object->isAuditStatusNeedsVerification() ||
$object->isAuditStatusPartiallyAudited();
if (!$any_waiting) {
continue;
}

View File

@@ -114,10 +114,10 @@ final class DiffusionHistoryTableView extends DiffusionHistoryView {
'type' => $history->getFileType(),
));
$status = $commit->getAuditStatus();
$icon = PhabricatorAuditCommitStatusConstants::getStatusIcon($status);
$color = PhabricatorAuditCommitStatusConstants::getStatusColor($status);
$name = PhabricatorAuditCommitStatusConstants::getStatusName($status);
$status = $commit->getAuditStatusObject();
$icon = $status->getIcon();
$color = $status->getColor();
$name = $status->getName();
$audit_view = id(new PHUIIconView())
->setIcon($icon, $color)

View File

@@ -94,7 +94,7 @@ final class DiffusionReadmeView extends DiffusionView {
}
$readme_content = phutil_tag_div($class, $readme_content);
$document = id(new PHUIDocumentViewPro())
$document = id(new PHUIDocumentView())
->setFluid(true)
->appendChild($readme_content);

View File

@@ -33,8 +33,7 @@ final class DiffusionCommitConcernTransaction
public function applyInternalEffects($object, $value) {
// NOTE: We force the commit directly into "Concern Raised" so that we
// override a possible "Needs Verification" state.
$object->setAuditStatus(
PhabricatorAuditCommitStatusConstants::CONCERN_RAISED);
$object->setAuditStatus(DiffusionCommitAuditStatus::CONCERN_RAISED);
}
public function applyExternalEffects($object, $value) {
@@ -54,10 +53,8 @@ final class DiffusionCommitConcernTransaction
// Even if you've already raised a concern, you can raise again as long
// as the author requested you verify.
$state_verify = PhabricatorAuditCommitStatusConstants::NEEDS_VERIFICATION;
if ($this->isViewerFullyRejected($object, $viewer)) {
if ($object->getAuditStatus() != $state_verify) {
if (!$object->isAuditStatusNeedsVerification()) {
throw new Exception(
pht(
'You can not raise a concern with this commit because you have '.

View File

@@ -11,29 +11,32 @@ final class DiffusionCommitStateTransaction
throw new PhutilMethodNotImplementedException();
}
public function getIcon() {
private function getAuditStatusObject() {
$new = $this->getNewValue();
return PhabricatorAuditCommitStatusConstants::getStatusIcon($new);
return DiffusionCommitAuditStatus::newForStatus($new);
}
public function getIcon() {
return $this->getAuditStatusObject()->getIcon();
}
public function getColor() {
$new = $this->getNewValue();
return PhabricatorAuditCommitStatusConstants::getStatusColor($new);
return $this->getAuditStatusObject()->getColor();
}
public function getTitle() {
$new = $this->getNewValue();
$status = $this->getAuditStatusObject();
switch ($new) {
case PhabricatorAuditCommitStatusConstants::NONE:
switch ($status->getKey()) {
case DiffusionCommitAuditStatus::NONE:
return pht('This commit no longer requires audit.');
case PhabricatorAuditCommitStatusConstants::NEEDS_AUDIT:
case DiffusionCommitAuditStatus::NEEDS_AUDIT:
return pht('This commit now requires audit.');
case PhabricatorAuditCommitStatusConstants::CONCERN_RAISED:
case DiffusionCommitAuditStatus::CONCERN_RAISED:
return pht('This commit now has outstanding concerns.');
case PhabricatorAuditCommitStatusConstants::NEEDS_VERIFICATION:
case DiffusionCommitAuditStatus::NEEDS_VERIFICATION:
return pht('This commit now requires verification by auditors.');
case PhabricatorAuditCommitStatusConstants::FULLY_AUDITED:
case DiffusionCommitAuditStatus::AUDITED:
return pht('All concerns with this commit have now been addressed.');
}
@@ -41,26 +44,26 @@ final class DiffusionCommitStateTransaction
}
public function getTitleForFeed() {
$new = $this->getNewValue();
$status = $this->getAuditStatusObject();
switch ($new) {
case PhabricatorAuditCommitStatusConstants::NONE:
switch ($status->getKey()) {
case DiffusionCommitAuditStatus::NONE:
return pht(
'%s no longer requires audit.',
$this->renderObject());
case PhabricatorAuditCommitStatusConstants::NEEDS_AUDIT:
case DiffusionCommitAuditStatus::NEEDS_AUDIT:
return pht(
'%s now requires audit.',
$this->renderObject());
case PhabricatorAuditCommitStatusConstants::CONCERN_RAISED:
case DiffusionCommitAuditStatus::CONCERN_RAISED:
return pht(
'%s now has outstanding concerns.',
$this->renderObject());
case PhabricatorAuditCommitStatusConstants::NEEDS_VERIFICATION:
case DiffusionCommitAuditStatus::NEEDS_VERIFICATION:
return pht(
'%s now requires verification by auditors.',
$this->renderObject());
case PhabricatorAuditCommitStatusConstants::FULLY_AUDITED:
case DiffusionCommitAuditStatus::AUDITED:
return pht(
'All concerns with %s have now been addressed.',
$this->renderObject());

View File

@@ -36,8 +36,7 @@ final class DiffusionCommitVerifyTransaction
}
public function applyInternalEffects($object, $value) {
$object->setAuditStatus(
PhabricatorAuditCommitStatusConstants::NEEDS_VERIFICATION);
$object->setAuditStatus(DiffusionCommitAuditStatus::NEEDS_VERIFICATION);
}
protected function validateAction($object, PhabricatorUser $viewer) {
@@ -48,8 +47,7 @@ final class DiffusionCommitVerifyTransaction
'are not the author.'));
}
$status = $object->getAuditStatus();
if ($status != PhabricatorAuditCommitStatusConstants::CONCERN_RAISED) {
if (!$object->isAuditStatusConcernRaised()) {
throw new Exception(
pht(
'You can not request verification of this commit because no '.

View File

@@ -72,7 +72,7 @@ final class DivinerAtomController extends DivinerController {
$prop_list = new PHUIPropertyGroupView();
$prop_list->addPropertyList($properties);
$document = id(new PHUIDocumentViewPro())
$document = id(new PHUIDocumentView())
->setBook($book->getTitle(), $group_name)
->setHeader($header)
->addClass('diviner-view');

View File

@@ -45,7 +45,7 @@ final class DivinerBookController extends DivinerController {
->setName($book->getRepository()->getMonogram()));
}
$document = new PHUIDocumentViewPro();
$document = new PHUIDocumentView();
$document->setHeader($header);
$document->addClass('diviner-view');

View File

@@ -27,7 +27,7 @@ final class DivinerMainController extends DivinerController {
->setHeader(pht('Documentation Books'))
->addActionLink($query_button);
$document = new PHUIDocumentViewPro();
$document = new PHUIDocumentView();
$document->setHeader($header);
$document->addClass('diviner-view');

View File

@@ -93,6 +93,8 @@ final class PhabricatorDrydockApplication extends PhabricatorApplication {
'' => 'DrydockRepositoryOperationViewController',
'status/' => 'DrydockRepositoryOperationStatusController',
'dismiss/' => 'DrydockRepositoryOperationDismissController',
'logs/(?:query/(?P<queryKey>[^/]+)/)?' =>
'DrydockLogListController',
),
),
),

View File

@@ -58,8 +58,11 @@ final class DrydockBlueprintViewController extends DrydockBlueprintController {
$log_query = id(new DrydockLogQuery())
->withBlueprintPHIDs(array($blueprint->getPHID()));
$log_table = $this->buildLogTable($log_query)
->setHideBlueprints(true);
$logs = $this->buildLogBox(
$log_query,
$log_table,
$this->getApplicationURI("blueprint/{$id}/logs/query/all/"));
$view = id(new PHUITwoColumnView())

View File

@@ -79,7 +79,7 @@ abstract class DrydockController extends PhabricatorController {
->addRawContent($table);
}
protected function buildLogBox(DrydockLogQuery $query, $all_uri) {
protected function buildLogTable(DrydockLogQuery $query) {
$viewer = $this->getViewer();
$logs = $query
@@ -89,9 +89,12 @@ abstract class DrydockController extends PhabricatorController {
$log_table = id(new DrydockLogListView())
->setUser($viewer)
->setLogs($logs)
->render();
->setLogs($logs);
return $log_table;
}
protected function buildLogBox(DrydockLogListView $log_table, $all_uri) {
$log_header = id(new PHUIHeaderView())
->setHeader(pht('Logs'))
->addActionLink(

View File

@@ -43,8 +43,11 @@ final class DrydockLeaseViewController extends DrydockLeaseController {
$log_query = id(new DrydockLogQuery())
->withLeasePHIDs(array($lease->getPHID()));
$log_table = $this->buildLogTable($log_query)
->setHideLeases(true);
$logs = $this->buildLogBox(
$log_query,
$log_table,
$this->getApplicationURI("lease/{$id}/logs/query/all/"));
$crumbs = $this->buildApplicationCrumbs();
@@ -163,6 +166,30 @@ final class DrydockLeaseViewController extends DrydockLeaseController {
}
$view->addProperty(pht('Expires'), $until_display);
$acquired_epoch = $lease->getAcquiredEpoch();
$activated_epoch = $lease->getActivatedEpoch();
if ($acquired_epoch) {
$acquired_display = phabricator_datetime($acquired_epoch, $viewer);
} else {
if ($activated_epoch) {
$acquired_display = phutil_tag(
'em',
array(),
pht('Activated on Acquisition'));
} else {
$acquired_display = phutil_tag('em', array(), pht('Not Acquired'));
}
}
$view->addProperty(pht('Acquired'), $acquired_display);
if ($activated_epoch) {
$activated_display = phabricator_datetime($activated_epoch, $viewer);
} else {
$activated_display = phutil_tag('em', array(), pht('Not Activated'));
}
$view->addProperty(pht('Activated'), $activated_display);
$attributes = $lease->getAttributes();
if ($attributes) {
$view->addSectionHeader(

View File

@@ -6,6 +6,7 @@ abstract class DrydockLogController
private $blueprint;
private $resource;
private $lease;
private $operation;
public function setBlueprint(DrydockBlueprint $blueprint) {
$this->blueprint = $blueprint;
@@ -34,6 +35,15 @@ abstract class DrydockLogController
return $this->lease;
}
public function setOperation(DrydockRepositoryOperation $operation) {
$this->operation = $operation;
return $this;
}
public function getOperation() {
return $this->operation;
}
public function buildSideNavView() {
$nav = new AphrontSideNavFilterView();
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
@@ -56,6 +66,11 @@ abstract class DrydockLogController
$engine->setLease($lease);
}
$operation = $this->getOperation();
if ($operation) {
$engine->setOperation($operation);
}
$engine->addNavigationItems($nav->getMenu());
$nav->selectFilter(null);
@@ -66,9 +81,12 @@ abstract class DrydockLogController
protected function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
$viewer = $this->getViewer();
$blueprint = $this->getBlueprint();
$resource = $this->getResource();
$lease = $this->getLease();
$operation = $this->getOperation();
if ($blueprint) {
$id = $blueprint->getID();
@@ -111,6 +129,20 @@ abstract class DrydockLogController
$crumbs->addTextCrumb(
pht('Logs'),
$this->getApplicationURI("lease/{$id}/logs/"));
} else if ($operation) {
$id = $operation->getID();
$crumbs->addTextCrumb(
pht('Operations'),
$this->getApplicationURI('operation/'));
$crumbs->addTextCrumb(
pht('Repository Operation %d', $id),
$this->getApplicationURI("operation/{$id}/"));
$crumbs->addTextCrumb(
pht('Logs'),
$this->getApplicationURI("operation/{$id}/logs/"));
}
return $crumbs;

View File

@@ -46,6 +46,17 @@ final class DrydockLogListController extends DrydockLogController {
$engine->setLease($lease);
$this->setLease($lease);
break;
case 'operation':
$operation = id(new DrydockRepositoryOperationQuery())
->setViewer($viewer)
->withIDs(array($id))
->executeOne();
if (!$operation) {
return new Aphront404Response();
}
$engine->setOperation($operation);
$this->setOperation($operation);
break;
default:
return new Aphront404Response();
}

View File

@@ -47,13 +47,25 @@ final class DrydockRepositoryOperationViewController
->setUser($viewer)
->setOperation($operation);
$log_query = id(new DrydockLogQuery())
->withOperationPHIDs(array($operation->getPHID()));
$log_table = $this->buildLogTable($log_query)
->setHideOperations(true);
$logs = $this->buildLogBox(
$log_table,
$this->getApplicationURI("operation/{$id}/logs/query/all/"));
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
->addPropertySection(pht('Properties'), $properties)
->setMainColumn(array(
$status_view,
));
->setMainColumn(
array(
$status_view,
$logs,
));
return $this->newPage()
->setTitle($title)

View File

@@ -48,8 +48,11 @@ final class DrydockResourceViewController extends DrydockResourceController {
$log_query = id(new DrydockLogQuery())
->withResourcePHIDs(array($resource->getPHID()));
$log_box = $this->buildLogBox(
$log_query,
$log_table = $this->buildLogTable($log_query)
->setHideResources(true);
$logs = $this->buildLogBox(
$log_table,
$this->getApplicationURI("resource/{$id}/logs/query/all/"));
$crumbs = $this->buildApplicationCrumbs();
@@ -86,11 +89,12 @@ final class DrydockResourceViewController extends DrydockResourceController {
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
->setMainColumn(array(
$object_box,
$lease_box,
$log_box,
));
->setMainColumn(
array(
$object_box,
$lease_box,
$logs,
));
return $this->newPage()
->setTitle($title)

View File

@@ -0,0 +1,19 @@
<?php
final class DrydockOperationWorkLogType extends DrydockLogType {
const LOGCONST = 'core.operation.work';
public function getLogTypeName() {
return pht('Started Work');
}
public function getLogTypeIcon(array $data) {
return 'fa-check green';
}
public function renderLog(array $data) {
return pht('Started this operation in a working copy.');
}
}

View File

@@ -0,0 +1,27 @@
<?php
/**
* Simple convenience log type for logging arbitrary text.
*
* Drydock logs can be given formal types, which allows them to be translated
* and filtered. If you don't particularly care about fancy logging features,
* you can use this log type to just dump some text into the log. Maybe you
* could upgrade to more formal logging later.
*/
final class DrydockTextLogType extends DrydockLogType {
const LOGCONST = 'core.text';
public function getLogTypeName() {
return pht('Text');
}
public function getLogTypeIcon(array $data) {
return 'fa-file-text-o grey';
}
public function renderLog(array $data) {
return idx($data, 'text');
}
}

Some files were not shown because too many files have changed in this diff Show More