mirror of
https://we.phorge.it/source/phorge.git
synced 2025-04-06 17:38:29 +02:00
(stable) Promote 2019 Week 45
This commit is contained in:
commit
cf6df55dbe
21 changed files with 334 additions and 76 deletions
|
@ -10,7 +10,7 @@ return array(
|
||||||
'conpherence.pkg.css' => '3c8a0668',
|
'conpherence.pkg.css' => '3c8a0668',
|
||||||
'conpherence.pkg.js' => '020aebcf',
|
'conpherence.pkg.js' => '020aebcf',
|
||||||
'core.pkg.css' => '77de226f',
|
'core.pkg.css' => '77de226f',
|
||||||
'core.pkg.js' => '6e5c894f',
|
'core.pkg.js' => '705aec2c',
|
||||||
'differential.pkg.css' => '607c84be',
|
'differential.pkg.css' => '607c84be',
|
||||||
'differential.pkg.js' => '1b97518d',
|
'differential.pkg.js' => '1b97518d',
|
||||||
'diffusion.pkg.css' => '42c75c37',
|
'diffusion.pkg.css' => '42c75c37',
|
||||||
|
@ -448,7 +448,7 @@ return array(
|
||||||
'rsrc/js/application/uiexample/notification-example.js' => '29819b75',
|
'rsrc/js/application/uiexample/notification-example.js' => '29819b75',
|
||||||
'rsrc/js/core/Busy.js' => '5202e831',
|
'rsrc/js/core/Busy.js' => '5202e831',
|
||||||
'rsrc/js/core/DragAndDropFileUpload.js' => '4370900d',
|
'rsrc/js/core/DragAndDropFileUpload.js' => '4370900d',
|
||||||
'rsrc/js/core/DraggableList.js' => 'c9ad6f70',
|
'rsrc/js/core/DraggableList.js' => '0169e425',
|
||||||
'rsrc/js/core/Favicon.js' => '7930776a',
|
'rsrc/js/core/Favicon.js' => '7930776a',
|
||||||
'rsrc/js/core/FileUpload.js' => 'ab85e184',
|
'rsrc/js/core/FileUpload.js' => 'ab85e184',
|
||||||
'rsrc/js/core/Hovercard.js' => '074f0783',
|
'rsrc/js/core/Hovercard.js' => '074f0783',
|
||||||
|
@ -777,7 +777,7 @@ return array(
|
||||||
'phabricator-diff-changeset-list' => '0f5c016d',
|
'phabricator-diff-changeset-list' => '0f5c016d',
|
||||||
'phabricator-diff-inline' => 'a4a14a94',
|
'phabricator-diff-inline' => 'a4a14a94',
|
||||||
'phabricator-drag-and-drop-file-upload' => '4370900d',
|
'phabricator-drag-and-drop-file-upload' => '4370900d',
|
||||||
'phabricator-draggable-list' => 'c9ad6f70',
|
'phabricator-draggable-list' => '0169e425',
|
||||||
'phabricator-fatal-config-template-css' => '20babf50',
|
'phabricator-fatal-config-template-css' => '20babf50',
|
||||||
'phabricator-favicon' => '7930776a',
|
'phabricator-favicon' => '7930776a',
|
||||||
'phabricator-feed-css' => 'd8b6e3f8',
|
'phabricator-feed-css' => 'd8b6e3f8',
|
||||||
|
@ -920,6 +920,14 @@ return array(
|
||||||
'javelin-uri',
|
'javelin-uri',
|
||||||
'phabricator-notification',
|
'phabricator-notification',
|
||||||
),
|
),
|
||||||
|
'0169e425' => array(
|
||||||
|
'javelin-install',
|
||||||
|
'javelin-dom',
|
||||||
|
'javelin-stratcom',
|
||||||
|
'javelin-util',
|
||||||
|
'javelin-vector',
|
||||||
|
'javelin-magical-init',
|
||||||
|
),
|
||||||
'022516b4' => array(
|
'022516b4' => array(
|
||||||
'javelin-install',
|
'javelin-install',
|
||||||
'javelin-util',
|
'javelin-util',
|
||||||
|
@ -2032,14 +2040,6 @@ return array(
|
||||||
'javelin-util',
|
'javelin-util',
|
||||||
'phabricator-keyboard-shortcut-manager',
|
'phabricator-keyboard-shortcut-manager',
|
||||||
),
|
),
|
||||||
'c9ad6f70' => array(
|
|
||||||
'javelin-install',
|
|
||||||
'javelin-dom',
|
|
||||||
'javelin-stratcom',
|
|
||||||
'javelin-util',
|
|
||||||
'javelin-vector',
|
|
||||||
'javelin-magical-init',
|
|
||||||
),
|
|
||||||
'cf32921f' => array(
|
'cf32921f' => array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
|
|
|
@ -4648,6 +4648,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorSearchEngineExtensionModule' => 'applications/search/engineextension/PhabricatorSearchEngineExtensionModule.php',
|
'PhabricatorSearchEngineExtensionModule' => 'applications/search/engineextension/PhabricatorSearchEngineExtensionModule.php',
|
||||||
'PhabricatorSearchFerretNgramGarbageCollector' => 'applications/search/garbagecollector/PhabricatorSearchFerretNgramGarbageCollector.php',
|
'PhabricatorSearchFerretNgramGarbageCollector' => 'applications/search/garbagecollector/PhabricatorSearchFerretNgramGarbageCollector.php',
|
||||||
'PhabricatorSearchField' => 'applications/search/field/PhabricatorSearchField.php',
|
'PhabricatorSearchField' => 'applications/search/field/PhabricatorSearchField.php',
|
||||||
|
'PhabricatorSearchHandleController' => 'applications/search/controller/PhabricatorSearchHandleController.php',
|
||||||
'PhabricatorSearchHost' => 'infrastructure/cluster/search/PhabricatorSearchHost.php',
|
'PhabricatorSearchHost' => 'infrastructure/cluster/search/PhabricatorSearchHost.php',
|
||||||
'PhabricatorSearchHovercardController' => 'applications/search/controller/PhabricatorSearchHovercardController.php',
|
'PhabricatorSearchHovercardController' => 'applications/search/controller/PhabricatorSearchHovercardController.php',
|
||||||
'PhabricatorSearchIndexVersion' => 'applications/search/storage/PhabricatorSearchIndexVersion.php',
|
'PhabricatorSearchIndexVersion' => 'applications/search/storage/PhabricatorSearchIndexVersion.php',
|
||||||
|
@ -4872,6 +4873,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorSystemActionRateLimitException' => 'applications/system/exception/PhabricatorSystemActionRateLimitException.php',
|
'PhabricatorSystemActionRateLimitException' => 'applications/system/exception/PhabricatorSystemActionRateLimitException.php',
|
||||||
'PhabricatorSystemApplication' => 'applications/system/application/PhabricatorSystemApplication.php',
|
'PhabricatorSystemApplication' => 'applications/system/application/PhabricatorSystemApplication.php',
|
||||||
'PhabricatorSystemDAO' => 'applications/system/storage/PhabricatorSystemDAO.php',
|
'PhabricatorSystemDAO' => 'applications/system/storage/PhabricatorSystemDAO.php',
|
||||||
|
'PhabricatorSystemDebugUIEventListener' => 'applications/system/events/PhabricatorSystemDebugUIEventListener.php',
|
||||||
'PhabricatorSystemDestructionGarbageCollector' => 'applications/system/garbagecollector/PhabricatorSystemDestructionGarbageCollector.php',
|
'PhabricatorSystemDestructionGarbageCollector' => 'applications/system/garbagecollector/PhabricatorSystemDestructionGarbageCollector.php',
|
||||||
'PhabricatorSystemDestructionLog' => 'applications/system/storage/PhabricatorSystemDestructionLog.php',
|
'PhabricatorSystemDestructionLog' => 'applications/system/storage/PhabricatorSystemDestructionLog.php',
|
||||||
'PhabricatorSystemObjectController' => 'applications/system/controller/PhabricatorSystemObjectController.php',
|
'PhabricatorSystemObjectController' => 'applications/system/controller/PhabricatorSystemObjectController.php',
|
||||||
|
@ -11270,6 +11272,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorSearchEngineExtensionModule' => 'PhabricatorConfigModule',
|
'PhabricatorSearchEngineExtensionModule' => 'PhabricatorConfigModule',
|
||||||
'PhabricatorSearchFerretNgramGarbageCollector' => 'PhabricatorGarbageCollector',
|
'PhabricatorSearchFerretNgramGarbageCollector' => 'PhabricatorGarbageCollector',
|
||||||
'PhabricatorSearchField' => 'Phobject',
|
'PhabricatorSearchField' => 'Phobject',
|
||||||
|
'PhabricatorSearchHandleController' => 'PhabricatorSearchBaseController',
|
||||||
'PhabricatorSearchHost' => 'Phobject',
|
'PhabricatorSearchHost' => 'Phobject',
|
||||||
'PhabricatorSearchHovercardController' => 'PhabricatorSearchBaseController',
|
'PhabricatorSearchHovercardController' => 'PhabricatorSearchBaseController',
|
||||||
'PhabricatorSearchIndexVersion' => 'PhabricatorSearchDAO',
|
'PhabricatorSearchIndexVersion' => 'PhabricatorSearchDAO',
|
||||||
|
@ -11511,6 +11514,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorSystemActionRateLimitException' => 'Exception',
|
'PhabricatorSystemActionRateLimitException' => 'Exception',
|
||||||
'PhabricatorSystemApplication' => 'PhabricatorApplication',
|
'PhabricatorSystemApplication' => 'PhabricatorApplication',
|
||||||
'PhabricatorSystemDAO' => 'PhabricatorLiskDAO',
|
'PhabricatorSystemDAO' => 'PhabricatorLiskDAO',
|
||||||
|
'PhabricatorSystemDebugUIEventListener' => 'PhabricatorEventListener',
|
||||||
'PhabricatorSystemDestructionGarbageCollector' => 'PhabricatorGarbageCollector',
|
'PhabricatorSystemDestructionGarbageCollector' => 'PhabricatorGarbageCollector',
|
||||||
'PhabricatorSystemDestructionLog' => 'PhabricatorSystemDAO',
|
'PhabricatorSystemDestructionLog' => 'PhabricatorSystemDAO',
|
||||||
'PhabricatorSystemObjectController' => 'PhabricatorController',
|
'PhabricatorSystemObjectController' => 'PhabricatorController',
|
||||||
|
|
|
@ -14,7 +14,9 @@ final class PhutilAsanaAuthAdapter extends PhutilOAuthAuthAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAccountID() {
|
public function getAccountID() {
|
||||||
return $this->getOAuthAccountData('id');
|
// See T13453. The Asana API has changed to string IDs and now returns a
|
||||||
|
// "gid" field (previously, it returned an "id" field).
|
||||||
|
return $this->getOAuthAccountData('gid');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAccountEmail() {
|
public function getAccountEmail() {
|
||||||
|
|
|
@ -329,9 +329,16 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
|
||||||
$actions = array();
|
$actions = array();
|
||||||
|
|
||||||
if ($panel) {
|
if ($panel) {
|
||||||
|
try {
|
||||||
$panel_actions = $panel->newHeaderEditActions(
|
$panel_actions = $panel->newHeaderEditActions(
|
||||||
$viewer,
|
$viewer,
|
||||||
$context_phid);
|
$context_phid);
|
||||||
|
} catch (Exception $ex) {
|
||||||
|
$error_action = id(new PhabricatorActionView())
|
||||||
|
->setIcon('fa-exclamation-triangle red')
|
||||||
|
->setName(pht('<Rendering Exception>'));
|
||||||
|
$panel_actions[] = $error_action;
|
||||||
|
}
|
||||||
|
|
||||||
if ($panel_actions) {
|
if ($panel_actions) {
|
||||||
foreach ($panel_actions as $panel_action) {
|
foreach ($panel_actions as $panel_action) {
|
||||||
|
|
|
@ -22,6 +22,10 @@ final class DifferentialChangesetSearchEngine
|
||||||
return 'PhabricatorDifferentialApplication';
|
return 'PhabricatorDifferentialApplication';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function canUseInPanelContext() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function newQuery() {
|
public function newQuery() {
|
||||||
$query = id(new DifferentialChangesetQuery());
|
$query = id(new DifferentialChangesetQuery());
|
||||||
|
|
||||||
|
|
|
@ -371,7 +371,7 @@ final class DifferentialChangesetOneUpRenderer
|
||||||
$cell_classes = $block_diff->getNewClasses();
|
$cell_classes = $block_diff->getNewClasses();
|
||||||
}
|
}
|
||||||
} else if ($row_type === 'old') {
|
} else if ($row_type === 'old') {
|
||||||
if (!$old_ref) {
|
if (!$old_ref || !$old) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,7 +384,7 @@ final class DifferentialChangesetOneUpRenderer
|
||||||
|
|
||||||
$new_key = null;
|
$new_key = null;
|
||||||
} else if ($row_type === 'new') {
|
} else if ($row_type === 'new') {
|
||||||
if (!$new_ref) {
|
if (!$new_ref || !$new) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ final class DiffusionRepositoryBranchesManagementPanel
|
||||||
|
|
||||||
$has_any =
|
$has_any =
|
||||||
$repository->getDetail('default-branch') ||
|
$repository->getDetail('default-branch') ||
|
||||||
|
$repository->getFetchRules() ||
|
||||||
$repository->getTrackOnlyRules() ||
|
$repository->getTrackOnlyRules() ||
|
||||||
$repository->getPermanentRefRules();
|
$repository->getPermanentRefRules();
|
||||||
|
|
||||||
|
|
|
@ -123,8 +123,11 @@ final class DoorkeeperBridgeAsana extends DoorkeeperBridge {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function fillObjectFromData(DoorkeeperExternalObject $obj, $result) {
|
public function fillObjectFromData(DoorkeeperExternalObject $obj, $result) {
|
||||||
$id = $result['id'];
|
$gid = $result['gid'];
|
||||||
$uri = "https://app.asana.com/0/{$id}/{$id}";
|
$uri = urisprintf(
|
||||||
|
'https://app.asana.com/0/%s/%s',
|
||||||
|
$gid,
|
||||||
|
$gid);
|
||||||
$obj->setObjectURI($uri);
|
$obj->setObjectURI($uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,10 @@ final class PhabricatorAsanaConfigOptions
|
||||||
pht('Workspace Name'));
|
pht('Workspace Name'));
|
||||||
$out[] = '| ------------ | -------------- |';
|
$out[] = '| ------------ | -------------- |';
|
||||||
foreach ($workspaces as $workspace) {
|
foreach ($workspaces as $workspace) {
|
||||||
$out[] = sprintf('| `%s` | `%s` |', $workspace['id'], $workspace['name']);
|
$out[] = sprintf(
|
||||||
|
'| `%s` | `%s` |',
|
||||||
|
$workspace['gid'],
|
||||||
|
$workspace['name']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$out = implode("\n", $out);
|
$out = implode("\n", $out);
|
||||||
|
|
|
@ -358,7 +358,7 @@ final class DoorkeeperAsanaFeedWorker extends DoorkeeperFeedWorker {
|
||||||
'POST',
|
'POST',
|
||||||
$subtask_data + array(
|
$subtask_data + array(
|
||||||
'assignee' => $phid_aid_map[$user_phid],
|
'assignee' => $phid_aid_map[$user_phid],
|
||||||
'completed' => $is_completed,
|
'completed' => (int)$is_completed,
|
||||||
'parent' => $parent_ref->getObjectID(),
|
'parent' => $parent_ref->getObjectID(),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -393,7 +393,7 @@ final class DoorkeeperAsanaFeedWorker extends DoorkeeperFeedWorker {
|
||||||
'PUT',
|
'PUT',
|
||||||
$subtask_data + array(
|
$subtask_data + array(
|
||||||
'assignee' => $phid_aid_map[$user_phid],
|
'assignee' => $phid_aid_map[$user_phid],
|
||||||
'completed' => $is_completed,
|
'completed' => (int)$is_completed,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,7 +484,7 @@ final class DoorkeeperAsanaFeedWorker extends DoorkeeperFeedWorker {
|
||||||
return array(
|
return array(
|
||||||
'name' => $title,
|
'name' => $title,
|
||||||
'notes' => $notes,
|
'notes' => $notes,
|
||||||
'completed' => $is_completed,
|
'completed' => (int)$is_completed,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -632,7 +632,7 @@ final class DoorkeeperAsanaFeedWorker extends DoorkeeperFeedWorker {
|
||||||
->setApplicationType(DoorkeeperBridgeAsana::APPTYPE_ASANA)
|
->setApplicationType(DoorkeeperBridgeAsana::APPTYPE_ASANA)
|
||||||
->setApplicationDomain(DoorkeeperBridgeAsana::APPDOMAIN_ASANA)
|
->setApplicationDomain(DoorkeeperBridgeAsana::APPDOMAIN_ASANA)
|
||||||
->setObjectType($type)
|
->setObjectType($type)
|
||||||
->setObjectID($result['id'])
|
->setObjectID($result['gid'])
|
||||||
->setIsVisible(true);
|
->setIsVisible(true);
|
||||||
|
|
||||||
$xobj = $ref->newExternalObject();
|
$xobj = $ref->newExternalObject();
|
||||||
|
|
|
@ -399,7 +399,7 @@ abstract class HeraldAdapter extends Phobject {
|
||||||
self::CONDITION_IS_NOT_ANY => pht('is not any of'),
|
self::CONDITION_IS_NOT_ANY => pht('is not any of'),
|
||||||
self::CONDITION_INCLUDE_ALL => pht('include all of'),
|
self::CONDITION_INCLUDE_ALL => pht('include all of'),
|
||||||
self::CONDITION_INCLUDE_ANY => pht('include any of'),
|
self::CONDITION_INCLUDE_ANY => pht('include any of'),
|
||||||
self::CONDITION_INCLUDE_NONE => pht('do not include'),
|
self::CONDITION_INCLUDE_NONE => pht('include none of'),
|
||||||
self::CONDITION_IS_ME => pht('is myself'),
|
self::CONDITION_IS_ME => pht('is myself'),
|
||||||
self::CONDITION_IS_NOT_ME => pht('is not myself'),
|
self::CONDITION_IS_NOT_ME => pht('is not myself'),
|
||||||
self::CONDITION_REGEXP => pht('matches regexp'),
|
self::CONDITION_REGEXP => pht('matches regexp'),
|
||||||
|
|
|
@ -71,21 +71,30 @@ final class PhabricatorUserUsernameTransaction
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strlen($new)) {
|
if (!strlen($new)) {
|
||||||
$errors[] = $this->newRequiredError(
|
$errors[] = $this->newInvalidError(
|
||||||
pht('New username is required.'), $xaction);
|
pht('New username is required.'),
|
||||||
|
$xaction);
|
||||||
} else if (!PhabricatorUser::validateUsername($new)) {
|
} else if (!PhabricatorUser::validateUsername($new)) {
|
||||||
$errors[] = $this->newInvalidError(
|
$errors[] = $this->newInvalidError(
|
||||||
PhabricatorUser::describeValidUsername(), $xaction);
|
PhabricatorUser::describeValidUsername(),
|
||||||
|
$xaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = id(new PhabricatorPeopleQuery())
|
$user = id(new PhabricatorPeopleQuery())
|
||||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||||
->withUsernames(array($new))
|
->withUsernames(array($new))
|
||||||
->executeOne();
|
->executeOne();
|
||||||
|
|
||||||
if ($user) {
|
if ($user) {
|
||||||
|
// See T13446. We may be changing the letter case of a username, which
|
||||||
|
// is a perfectly fine edit.
|
||||||
|
$is_self = ($user->getPHID() === $object->getPHID());
|
||||||
|
if (!$is_self) {
|
||||||
$errors[] = $this->newInvalidError(
|
$errors[] = $this->newInvalidError(
|
||||||
pht('Another user already has that username.'), $xaction);
|
pht(
|
||||||
|
'Another user already has the username "%s".',
|
||||||
|
$new),
|
||||||
|
$xaction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,16 +257,15 @@ final class PhabricatorRepositoryPullEngine
|
||||||
|
|
||||||
$path = rtrim($repository->getLocalPath(), '/');
|
$path = rtrim($repository->getLocalPath(), '/');
|
||||||
|
|
||||||
if ($repository->isHosted()) {
|
// See T13448. In all cases, we create repositories by using "git init"
|
||||||
|
// to build a bare, empty working copy. If we try to use "git clone"
|
||||||
|
// instead, we'll pull in too many refs if "Fetch Refs" is also
|
||||||
|
// configured. There's no apparent way to make "git clone" behave narrowly
|
||||||
|
// and no apparent reason to bother.
|
||||||
|
|
||||||
$repository->execxRemoteCommand(
|
$repository->execxRemoteCommand(
|
||||||
'init --bare -- %s',
|
'init --bare -- %s',
|
||||||
$path);
|
$path);
|
||||||
} else {
|
|
||||||
$repository->execxRemoteCommand(
|
|
||||||
'clone --bare -- %P %s',
|
|
||||||
$repository->getRemoteURIEnvelope(),
|
|
||||||
$path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -290,29 +289,27 @@ final class PhabricatorRepositoryPullEngine
|
||||||
$files = Filesystem::listDirectory($path, $include_hidden = true);
|
$files = Filesystem::listDirectory($path, $include_hidden = true);
|
||||||
if (!$files) {
|
if (!$files) {
|
||||||
$message = pht(
|
$message = pht(
|
||||||
"Expected to find a git repository at '%s', but there ".
|
'Expected to find a Git repository at "%s", but there is an '.
|
||||||
"is an empty directory there. Remove the directory: the daemon ".
|
'empty directory there. Remove the directory. A daemon will '.
|
||||||
"will run '%s' for you.",
|
'construct the working copy for you.',
|
||||||
$path,
|
$path);
|
||||||
'git clone');
|
|
||||||
} else {
|
} else {
|
||||||
$message = pht(
|
$message = pht(
|
||||||
"Expected to find a git repository at '%s', but there is ".
|
'Expected to find a Git repository at "%s", but there is '.
|
||||||
"a non-repository directory (with other stuff in it) there. Move ".
|
'a non-repository directory (with other stuff in it) there. '.
|
||||||
"or remove this directory (or reconfigure the repository to use a ".
|
'Move or remove this directory. A daemon will construct '.
|
||||||
"different directory), and then either clone a repository ".
|
'the working copy for you.',
|
||||||
"yourself or let the daemon do it.",
|
|
||||||
$path);
|
$path);
|
||||||
}
|
}
|
||||||
} else if (is_file($path)) {
|
} else if (is_file($path)) {
|
||||||
$message = pht(
|
$message = pht(
|
||||||
"Expected to find a git repository at '%s', but there is a ".
|
'Expected to find a Git repository at "%s", but there is a '.
|
||||||
"file there instead. Remove it and let the daemon clone a ".
|
'file there instead. Move or remove this file. A daemon will '.
|
||||||
"repository for you.",
|
'construct the working copy for you.',
|
||||||
$path);
|
$path);
|
||||||
} else {
|
} else {
|
||||||
$message = pht(
|
$message = pht(
|
||||||
"Expected to find a git repository at '%s', but did not.",
|
'Expected to find a git repository at "%s", but did not.',
|
||||||
$path);
|
$path);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -327,11 +324,10 @@ final class PhabricatorRepositoryPullEngine
|
||||||
} else if (!Filesystem::pathsAreEquivalent($repo_path, $path)) {
|
} else if (!Filesystem::pathsAreEquivalent($repo_path, $path)) {
|
||||||
$err = true;
|
$err = true;
|
||||||
$message = pht(
|
$message = pht(
|
||||||
"Expected to find repo at '%s', but the actual git repository root ".
|
'Expected to find a Git repository at "%s", but the actual Git '.
|
||||||
"for this directory is '%s'. Something is misconfigured. ".
|
'repository root for this directory is "%s". Something is '.
|
||||||
"The repository's 'Local Path' should be set to some place where ".
|
'misconfigured. This directory should be writable by the daemons '.
|
||||||
"the daemon can check out a working copy, ".
|
'and not inside another Git repository.',
|
||||||
"and should not be inside another git repository.",
|
|
||||||
$path,
|
$path,
|
||||||
$repo_path);
|
$repo_path);
|
||||||
}
|
}
|
||||||
|
@ -353,13 +349,56 @@ final class PhabricatorRepositoryPullEngine
|
||||||
// Load the refs we're planning to fetch from the remote repository.
|
// Load the refs we're planning to fetch from the remote repository.
|
||||||
$remote_refs = $this->loadGitRemoteRefs(
|
$remote_refs = $this->loadGitRemoteRefs(
|
||||||
$repository,
|
$repository,
|
||||||
$repository->getRemoteURIEnvelope());
|
$repository->getRemoteURIEnvelope(),
|
||||||
|
$is_local = false);
|
||||||
|
|
||||||
// Load the refs we're planning to fetch from the local repository, by
|
// Load the refs we're planning to fetch from the local repository, by
|
||||||
// using the local working copy path as the "remote" repository URI.
|
// using the local working copy path as the "remote" repository URI.
|
||||||
$local_refs = $this->loadGitRemoteRefs(
|
$local_refs = $this->loadGitRemoteRefs(
|
||||||
$repository,
|
$repository,
|
||||||
new PhutilOpaqueEnvelope($path));
|
new PhutilOpaqueEnvelope($path),
|
||||||
|
$is_local = true);
|
||||||
|
|
||||||
|
// See T13448. The "git fetch --prune ..." flag only prunes local refs
|
||||||
|
// matching the refspecs we pass it. If "Fetch Refs" is configured, we'll
|
||||||
|
// pass it a very narrow list of refspecs, and it won't prune older refs
|
||||||
|
// that aren't currently subject to fetching.
|
||||||
|
|
||||||
|
// Since we want to prune everything that isn't (a) on the fetch list and
|
||||||
|
// (b) in the remote, handle pruning of any surplus leftover refs ourselves
|
||||||
|
// before we fetch anything.
|
||||||
|
|
||||||
|
// (We don't have to do this if "Fetch Refs" isn't set up, since "--prune"
|
||||||
|
// will work in that case, but it's a little simpler to always go down the
|
||||||
|
// same code path.)
|
||||||
|
|
||||||
|
$surplus_refs = array();
|
||||||
|
foreach ($local_refs as $local_ref => $local_hash) {
|
||||||
|
$remote_hash = idx($remote_refs, $local_ref);
|
||||||
|
if ($remote_hash === null) {
|
||||||
|
$surplus_refs[] = $local_ref;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($surplus_refs) {
|
||||||
|
$this->log(
|
||||||
|
pht(
|
||||||
|
'Found %s surplus local ref(s) to delete.',
|
||||||
|
phutil_count($surplus_refs)));
|
||||||
|
foreach ($surplus_refs as $surplus_ref) {
|
||||||
|
$this->log(
|
||||||
|
pht(
|
||||||
|
'Deleting surplus local ref "%s" ("%s").',
|
||||||
|
$surplus_ref,
|
||||||
|
$local_refs[$surplus_ref]));
|
||||||
|
|
||||||
|
$repository->execLocalCommand(
|
||||||
|
'update-ref -d %R --',
|
||||||
|
$surplus_ref);
|
||||||
|
|
||||||
|
unset($local_refs[$surplus_ref]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($remote_refs === $local_refs) {
|
if ($remote_refs === $local_refs) {
|
||||||
$this->log(
|
$this->log(
|
||||||
|
@ -378,7 +417,7 @@ final class PhabricatorRepositoryPullEngine
|
||||||
// checked out. See T13280.
|
// checked out. See T13280.
|
||||||
|
|
||||||
$future = $repository->getRemoteCommandFuture(
|
$future = $repository->getRemoteCommandFuture(
|
||||||
'fetch --prune --update-head-ok -- %P %Ls',
|
'fetch --no-tags --update-head-ok -- %P %Ls',
|
||||||
$repository->getRemoteURIEnvelope(),
|
$repository->getRemoteURIEnvelope(),
|
||||||
$fetch_rules);
|
$fetch_rules);
|
||||||
|
|
||||||
|
@ -474,8 +513,18 @@ final class PhabricatorRepositoryPullEngine
|
||||||
|
|
||||||
private function loadGitRemoteRefs(
|
private function loadGitRemoteRefs(
|
||||||
PhabricatorRepository $repository,
|
PhabricatorRepository $repository,
|
||||||
PhutilOpaqueEnvelope $remote_envelope) {
|
PhutilOpaqueEnvelope $remote_envelope,
|
||||||
|
$is_local) {
|
||||||
|
|
||||||
|
// See T13448. When listing local remotes, we want to list everything,
|
||||||
|
// not just refs we expect to fetch. This allows us to detect that we have
|
||||||
|
// undesirable refs (which have been deleted in the remote, but are still
|
||||||
|
// present locally) so we can update our state to reflect the correct
|
||||||
|
// remote state.
|
||||||
|
|
||||||
|
if ($is_local) {
|
||||||
|
$ref_rules = array();
|
||||||
|
} else {
|
||||||
$ref_rules = $this->getGitRefRules($repository);
|
$ref_rules = $this->getGitRefRules($repository);
|
||||||
|
|
||||||
// NOTE: "git ls-remote" does not support "--" until circa January 2016.
|
// NOTE: "git ls-remote" does not support "--" until circa January 2016.
|
||||||
|
@ -491,6 +540,7 @@ final class PhabricatorRepositoryPullEngine
|
||||||
$ref_rule));
|
$ref_rule));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
list($stdout) = $repository->execxRemoteCommand(
|
list($stdout) = $repository->execxRemoteCommand(
|
||||||
'ls-remote %P %Ls',
|
'ls-remote %P %Ls',
|
||||||
|
|
|
@ -33,6 +33,8 @@ final class PhabricatorSearchApplication extends PhabricatorApplication {
|
||||||
'index/(?P<phid>[^/]+)/' => 'PhabricatorSearchIndexController',
|
'index/(?P<phid>[^/]+)/' => 'PhabricatorSearchIndexController',
|
||||||
'hovercard/'
|
'hovercard/'
|
||||||
=> 'PhabricatorSearchHovercardController',
|
=> 'PhabricatorSearchHovercardController',
|
||||||
|
'handle/(?P<phid>[^/]+)/'
|
||||||
|
=> 'PhabricatorSearchHandleController',
|
||||||
'edit/' => array(
|
'edit/' => array(
|
||||||
'key/(?P<queryKey>[^/]+)/' => 'PhabricatorSearchEditController',
|
'key/(?P<queryKey>[^/]+)/' => 'PhabricatorSearchEditController',
|
||||||
'id/(?P<id>[^/]+)/' => 'PhabricatorSearchEditController',
|
'id/(?P<id>[^/]+)/' => 'PhabricatorSearchEditController',
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorSearchHandleController
|
||||||
|
extends PhabricatorSearchBaseController {
|
||||||
|
|
||||||
|
public function shouldAllowPublic() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleRequest(AphrontRequest $request) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
$phid = $request->getURIData('phid');
|
||||||
|
|
||||||
|
$handles = $viewer->loadHandles(array($phid));
|
||||||
|
$handle = $handles[$phid];
|
||||||
|
|
||||||
|
$cancel_uri = $handle->getURI();
|
||||||
|
if (!$cancel_uri) {
|
||||||
|
$cancel_uri = '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
$rows = array();
|
||||||
|
|
||||||
|
$rows[] = array(
|
||||||
|
pht('PHID'),
|
||||||
|
$phid,
|
||||||
|
);
|
||||||
|
|
||||||
|
$rows[] = array(
|
||||||
|
pht('PHID Type'),
|
||||||
|
phid_get_type($phid),
|
||||||
|
);
|
||||||
|
|
||||||
|
$rows[] = array(
|
||||||
|
pht('URI'),
|
||||||
|
$handle->getURI(),
|
||||||
|
);
|
||||||
|
|
||||||
|
$icon = $handle->getIcon();
|
||||||
|
if ($icon !== null) {
|
||||||
|
$icon = id(new PHUIIconView())
|
||||||
|
->setIcon($handle->getIcon());
|
||||||
|
}
|
||||||
|
|
||||||
|
$rows[] = array(
|
||||||
|
pht('Icon'),
|
||||||
|
$icon,
|
||||||
|
);
|
||||||
|
|
||||||
|
$rows[] = array(
|
||||||
|
pht('Object Name'),
|
||||||
|
$handle->getObjectName(),
|
||||||
|
);
|
||||||
|
|
||||||
|
$rows[] = array(
|
||||||
|
pht('Name'),
|
||||||
|
$handle->getName(),
|
||||||
|
);
|
||||||
|
|
||||||
|
$rows[] = array(
|
||||||
|
pht('Full Name'),
|
||||||
|
$handle->getFullName(),
|
||||||
|
);
|
||||||
|
|
||||||
|
$rows[] = array(
|
||||||
|
pht('Tag'),
|
||||||
|
$handle->renderTag(),
|
||||||
|
);
|
||||||
|
|
||||||
|
$rows[] = array(
|
||||||
|
pht('Link'),
|
||||||
|
$handle->renderLink(),
|
||||||
|
);
|
||||||
|
|
||||||
|
$table = id(new AphrontTableView($rows))
|
||||||
|
->setColumnClasses(
|
||||||
|
array(
|
||||||
|
'header',
|
||||||
|
'wide',
|
||||||
|
));
|
||||||
|
|
||||||
|
return $this->newDialog()
|
||||||
|
->setTitle(pht('Handle: %s', $phid))
|
||||||
|
->setWidth(AphrontDialogView::WIDTH_FORM)
|
||||||
|
->appendChild($table)
|
||||||
|
->addCancelButton($cancel_uri, pht('Done'));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -14,6 +14,12 @@ final class PhabricatorSystemApplication extends PhabricatorApplication {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getEventListeners() {
|
||||||
|
return array(
|
||||||
|
new PhabricatorSystemDebugUIEventListener(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function getRoutes() {
|
public function getRoutes() {
|
||||||
return array(
|
return array(
|
||||||
'/status/' => 'PhabricatorStatusController',
|
'/status/' => 'PhabricatorStatusController',
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorSystemDebugUIEventListener
|
||||||
|
extends PhabricatorEventListener {
|
||||||
|
|
||||||
|
public function register() {
|
||||||
|
$this->listen(PhabricatorEventType::TYPE_UI_DIDRENDERACTIONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleEvent(PhutilEvent $event) {
|
||||||
|
switch ($event->getType()) {
|
||||||
|
case PhabricatorEventType::TYPE_UI_DIDRENDERACTIONS:
|
||||||
|
$this->handleActionEvent($event);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function handleActionEvent($event) {
|
||||||
|
$viewer = $event->getUser();
|
||||||
|
$object = $event->getValue('object');
|
||||||
|
|
||||||
|
if (!PhabricatorEnv::getEnvConfig('phabricator.developer-mode')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$object || !$object->getPHID()) {
|
||||||
|
// If we have no object, or the object doesn't have a PHID, we can't
|
||||||
|
// do anything useful.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$phid = $object->getPHID();
|
||||||
|
|
||||||
|
$submenu = array();
|
||||||
|
|
||||||
|
$submenu[] = id(new PhabricatorActionView())
|
||||||
|
->setIcon('fa-asterisk')
|
||||||
|
->setName(pht('View Handle'))
|
||||||
|
->setHref(urisprintf('/search/handle/%s/', $phid))
|
||||||
|
->setWorkflow(true);
|
||||||
|
|
||||||
|
$submenu[] = id(new PhabricatorActionView())
|
||||||
|
->setIcon('fa-address-card-o')
|
||||||
|
->setName(pht('View Hovercard'))
|
||||||
|
->setHref(urisprintf('/search/hovercard/?phids[]=%s', $phid));
|
||||||
|
|
||||||
|
$developer_action = id(new PhabricatorActionView())
|
||||||
|
->setName(pht('Advanced/Developer...'))
|
||||||
|
->setIcon('fa-magic')
|
||||||
|
->setOrder(9001)
|
||||||
|
->setSubmenu($submenu);
|
||||||
|
|
||||||
|
$actions = $event->getValue('actions');
|
||||||
|
$actions[] = $developer_action;
|
||||||
|
$event->setValue('actions', $actions);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1133,6 +1133,8 @@ abstract class PhabricatorApplicationTransaction
|
||||||
} else {
|
} else {
|
||||||
$fragments = array();
|
$fragments = array();
|
||||||
foreach ($moves as $move) {
|
foreach ($moves as $move) {
|
||||||
|
$to_column = $move['columnPHID'];
|
||||||
|
$board_phid = $move['boardPHID'];
|
||||||
$fragments[] = pht(
|
$fragments[] = pht(
|
||||||
'%s (%s)',
|
'%s (%s)',
|
||||||
$this->renderHandleLink($board_phid),
|
$this->renderHandleLink($board_phid),
|
||||||
|
|
|
@ -52,6 +52,14 @@ final class PhabricatorActionListView extends AphrontTagView {
|
||||||
$action->setViewer($viewer);
|
$action->setViewer($viewer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$sort = array();
|
||||||
|
foreach ($actions as $key => $action) {
|
||||||
|
$sort[$key] = id(new PhutilSortVector())
|
||||||
|
->addInt($action->getOrder());
|
||||||
|
}
|
||||||
|
$sort = msortv($sort, 'getSelf');
|
||||||
|
$actions = array_select_keys($actions, array_keys($sort));
|
||||||
|
|
||||||
require_celerity_resource('phabricator-action-list-view-css');
|
require_celerity_resource('phabricator-action-list-view-css');
|
||||||
|
|
||||||
$items = array();
|
$items = array();
|
||||||
|
|
|
@ -379,10 +379,11 @@ final class PHUIObjectItemView extends AphrontTagView {
|
||||||
|
|
||||||
if ($this->objectName) {
|
if ($this->objectName) {
|
||||||
$header_name[] = array(
|
$header_name[] = array(
|
||||||
phutil_tag(
|
javelin_tag(
|
||||||
'span',
|
'span',
|
||||||
array(
|
array(
|
||||||
'class' => 'phui-oi-objname',
|
'class' => 'phui-oi-objname',
|
||||||
|
'sigil' => 'ungrabbable',
|
||||||
),
|
),
|
||||||
$this->objectName),
|
$this->objectName),
|
||||||
' ',
|
' ',
|
||||||
|
|
|
@ -181,6 +181,15 @@ JX.install('DraggableList', {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See T13452. If this is an ungrabble part of the item, don't start a
|
||||||
|
// drag. We use this to allow users to select text on cards.
|
||||||
|
var target = e.getTarget();
|
||||||
|
if (target) {
|
||||||
|
if (JX.Stratcom.hasSigil(target, 'ungrabbable')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (JX.Stratcom.pass()) {
|
if (JX.Stratcom.pass()) {
|
||||||
// Let other handlers deal with this event before we do.
|
// Let other handlers deal with this event before we do.
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Add table
Reference in a new issue