mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-26 16:52:41 +01:00
Allow projects to own packages
Summary: - The UI is pretty straightforward, since Handle just works (tm) - Added two methods to the owners object to handle the new layer of indirection. Then ran git grep PhabricatorOwnersOwner and changed callsites as appropriate. Sending this to get a round of feedback before I test the non-trivial changes in this diff. Test Plan: - owners tool: edit, view, list for basic functionality. - phlog for the two new methods I added Reviewers: epriestley, blair, jungejason CC: aran Differential Revision: https://secure.phabricator.com/D2079
This commit is contained in:
parent
8813c7be0e
commit
591d50008f
10 changed files with 66 additions and 11 deletions
|
@ -929,6 +929,7 @@ phutil_register_library_map(array(
|
||||||
),
|
),
|
||||||
'function' =>
|
'function' =>
|
||||||
array(
|
array(
|
||||||
|
'__phabricator_date_format' => 'view/utils',
|
||||||
'__phabricator_format_local_time' => 'view/utils',
|
'__phabricator_format_local_time' => 'view/utils',
|
||||||
'_qsprintf_check_scalar_type' => 'storage/qsprintf',
|
'_qsprintf_check_scalar_type' => 'storage/qsprintf',
|
||||||
'_qsprintf_check_type' => 'storage/qsprintf',
|
'_qsprintf_check_type' => 'storage/qsprintf',
|
||||||
|
@ -939,8 +940,12 @@ phutil_register_library_map(array(
|
||||||
'phabricator_datetime' => 'view/utils',
|
'phabricator_datetime' => 'view/utils',
|
||||||
'phabricator_format_relative_time' => 'view/utils',
|
'phabricator_format_relative_time' => 'view/utils',
|
||||||
'phabricator_format_units_generic' => 'view/utils',
|
'phabricator_format_units_generic' => 'view/utils',
|
||||||
|
'phabricator_on_relative_date' => 'view/utils',
|
||||||
|
'phabricator_relative_date' => 'view/utils',
|
||||||
'phabricator_render_form' => 'infrastructure/javelin/markup',
|
'phabricator_render_form' => 'infrastructure/javelin/markup',
|
||||||
'phabricator_time' => 'view/utils',
|
'phabricator_time' => 'view/utils',
|
||||||
|
'phid_get_type' => 'applications/phid/utils',
|
||||||
|
'phid_group_by_type' => 'applications/phid/utils',
|
||||||
'qsprintf' => 'storage/qsprintf',
|
'qsprintf' => 'storage/qsprintf',
|
||||||
'queryfx' => 'storage/queryfx',
|
'queryfx' => 'storage/queryfx',
|
||||||
'queryfx_all' => 'storage/queryfx',
|
'queryfx_all' => 'storage/queryfx',
|
||||||
|
|
|
@ -202,9 +202,9 @@ final class PhabricatorAuditCommentEditor {
|
||||||
$phids[$user->getPHID()] = true;
|
$phids[$user->getPHID()] = true;
|
||||||
|
|
||||||
// The user can audit on behalf of all packages they own.
|
// The user can audit on behalf of all packages they own.
|
||||||
$owned_packages = id(new PhabricatorOwnersOwner())->loadAllWhere(
|
$owned_packages = PhabricatorOwnersOwner::loadAffiliatedPackages(
|
||||||
'userPHID = %s',
|
|
||||||
$user->getPHID());
|
$user->getPHID());
|
||||||
|
|
||||||
if ($owned_packages) {
|
if ($owned_packages) {
|
||||||
$packages = id(new PhabricatorOwnersPackage())->loadAllWhere(
|
$packages = id(new PhabricatorOwnersPackage())->loadAllWhere(
|
||||||
'id IN (%Ld)',
|
'id IN (%Ld)',
|
||||||
|
|
|
@ -217,8 +217,8 @@ final class HeraldDifferentialRevisionAdapter extends HeraldObjectAdapter {
|
||||||
return mpull($packages, 'getPHID');
|
return mpull($packages, 'getPHID');
|
||||||
case HeraldFieldConfig::FIELD_AFFECTED_PACKAGE_OWNER:
|
case HeraldFieldConfig::FIELD_AFFECTED_PACKAGE_OWNER:
|
||||||
$packages = $this->loadAffectedPackages();
|
$packages = $this->loadAffectedPackages();
|
||||||
$owners = PhabricatorOwnersOwner::loadAllForPackages($packages);
|
return PhabricatorOwnersOwner::loadAffiliatedUserPHIDs(
|
||||||
return mpull($owners, 'getUserPHID');
|
mpull($packages, 'getID'));
|
||||||
default:
|
default:
|
||||||
throw new Exception("Invalid field '{$field}'.");
|
throw new Exception("Invalid field '{$field}'.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -203,7 +203,7 @@ final class PhabricatorOwnersEditController
|
||||||
->setError($e_name))
|
->setError($e_name))
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormTokenizerControl())
|
id(new AphrontFormTokenizerControl())
|
||||||
->setDatasource('/typeahead/common/users/')
|
->setDatasource('/typeahead/common/usersorprojects/')
|
||||||
->setLabel('Primary Owner')
|
->setLabel('Primary Owner')
|
||||||
->setName('primary')
|
->setName('primary')
|
||||||
->setLimit(1)
|
->setLimit(1)
|
||||||
|
@ -211,7 +211,7 @@ final class PhabricatorOwnersEditController
|
||||||
->setError($e_primary))
|
->setError($e_primary))
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormTokenizerControl())
|
id(new AphrontFormTokenizerControl())
|
||||||
->setDatasource('/typeahead/common/users/')
|
->setDatasource('/typeahead/common/usersorprojects/')
|
||||||
->setLabel('Owners')
|
->setLabel('Owners')
|
||||||
->setName('owners')
|
->setName('owners')
|
||||||
->setValue($token_all_owners)
|
->setValue($token_all_owners)
|
||||||
|
|
|
@ -171,7 +171,7 @@ final class PhabricatorOwnersListController
|
||||||
->setValue($request->getStr('name')))
|
->setValue($request->getStr('name')))
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormTokenizerControl())
|
id(new AphrontFormTokenizerControl())
|
||||||
->setDatasource('/typeahead/common/users/')
|
->setDatasource('/typeahead/common/usersorprojects/')
|
||||||
->setLimit(1)
|
->setLimit(1)
|
||||||
->setName('owner')
|
->setName('owner')
|
||||||
->setLabel('Owner')
|
->setLabel('Owner')
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
final class PhabricatorOwnersOwner extends PhabricatorOwnersDAO {
|
final class PhabricatorOwnersOwner extends PhabricatorOwnersDAO {
|
||||||
|
|
||||||
protected $packageID;
|
protected $packageID;
|
||||||
|
|
||||||
|
// this can be a project or a user. We assume that all members of a project
|
||||||
|
// owner also own the package; use the loadAffiliatedUserPHIDs method if
|
||||||
|
// you want to recursively grab all user ids that own a package
|
||||||
protected $userPHID;
|
protected $userPHID;
|
||||||
|
|
||||||
public function getConfiguration() {
|
public function getConfiguration() {
|
||||||
|
@ -37,4 +41,43 @@ final class PhabricatorOwnersOwner extends PhabricatorOwnersDAO {
|
||||||
mpull($packages, 'getID'));
|
mpull($packages, 'getID'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Loads all user phids affiliated with a set of packages. This includes both
|
||||||
|
// user owners and all members of any project owners
|
||||||
|
public static function loadAffiliatedUserPHIDs(array $package_ids) {
|
||||||
|
$owners = id(new PhabricatorOwnersOwner())->loadAllWhere(
|
||||||
|
'packageID IN (%Ls)',
|
||||||
|
$package_ids);
|
||||||
|
|
||||||
|
$all_phids = phid_group_by_type(mpull($owners, 'getUserPHID'));
|
||||||
|
|
||||||
|
$user_phids = idx($all_phids,
|
||||||
|
PhabricatorPHIDConstants::PHID_TYPE_USER,
|
||||||
|
array());
|
||||||
|
|
||||||
|
$users_in_project_phids = array();
|
||||||
|
if (idx($all_phids, PhabricatorPHIDConstants::PHID_TYPE_PROJ)) {
|
||||||
|
$users_in_project_phids = mpull(
|
||||||
|
id(new PhabricatorProjectAffiliation())->loadAllWhere(
|
||||||
|
'projectPHID IN (%Ls)',
|
||||||
|
idx($all_phids, PhabricatorPHIDConstants::PHID_TYPE_PROJ, array())),
|
||||||
|
'getUserPHID');
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_unique(array_merge($users_in_project_phids, $user_phids));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loads all affiliated packages for a user. This includes packages owned by
|
||||||
|
// any project the user is a member of.
|
||||||
|
public static function loadAffiliatedPackages($user_phid) {
|
||||||
|
$query = new PhabricatorProjectQuery();
|
||||||
|
$query->setMembers(array($user_phid));
|
||||||
|
$query->withStatus(PhabricatorProjectQuery::STATUS_ACTIVE);
|
||||||
|
$projects = $query->execute();
|
||||||
|
|
||||||
|
$phids = mpull($projects, 'getPHID') + array($user_phid);
|
||||||
|
return
|
||||||
|
id(new PhabricatorOwnersOwner())->loadAllWhere(
|
||||||
|
'userPHID in (%Ls)',
|
||||||
|
$phids);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,10 @@
|
||||||
|
|
||||||
|
|
||||||
phutil_require_module('phabricator', 'applications/owners/storage/base');
|
phutil_require_module('phabricator', 'applications/owners/storage/base');
|
||||||
|
phutil_require_module('phabricator', 'applications/phid/constants');
|
||||||
|
phutil_require_module('phabricator', 'applications/phid/utils');
|
||||||
|
phutil_require_module('phabricator', 'applications/project/query/project');
|
||||||
|
phutil_require_module('phabricator', 'applications/project/storage/affiliation');
|
||||||
|
|
||||||
phutil_require_module('phutil', 'utils');
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
|
@ -126,10 +126,8 @@ final class PhabricatorRepositoryCommitOwnersWorker
|
||||||
$reasons[] = "No Revision Specified";
|
$reasons[] = "No Revision Specified";
|
||||||
}
|
}
|
||||||
|
|
||||||
$owners = id(new PhabricatorOwnersOwner())->loadAllWhere(
|
$owners_phids = PhabricatorOwnersOwner::loadAffiliatedUserPHIDs(
|
||||||
'packageID = %d',
|
array($package->getID()));
|
||||||
$package->getID());
|
|
||||||
$owners_phids = mpull($owners, 'getUserPHID');
|
|
||||||
|
|
||||||
if (!($commit_author_phid && in_array($commit_author_phid, $owners_phids) ||
|
if (!($commit_author_phid && in_array($commit_author_phid, $owners_phids) ||
|
||||||
$commit_reviewedby_phid && in_array($commit_reviewedby_phid,
|
$commit_reviewedby_phid && in_array($commit_reviewedby_phid,
|
||||||
|
|
|
@ -61,6 +61,10 @@ final class PhabricatorTypeaheadCommonDatasourceController
|
||||||
case 'projects':
|
case 'projects':
|
||||||
$need_projs = true;
|
$need_projs = true;
|
||||||
break;
|
break;
|
||||||
|
case 'usersorprojects':
|
||||||
|
$need_users = true;
|
||||||
|
$need_projs = true;
|
||||||
|
break;
|
||||||
case 'repositories':
|
case 'repositories':
|
||||||
$need_repos = true;
|
$need_repos = true;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -105,6 +105,7 @@ final class AphrontFormTokenizerControl extends AphrontFormControl {
|
||||||
|
|
||||||
$map = array(
|
$map = array(
|
||||||
'users' => 'Type a user name...',
|
'users' => 'Type a user name...',
|
||||||
|
'usersorprojects' => 'Type a user or project name...',
|
||||||
'searchowner' => 'Type a user name...',
|
'searchowner' => 'Type a user name...',
|
||||||
'accounts' => 'Type a user name...',
|
'accounts' => 'Type a user name...',
|
||||||
'mailable' => 'Type a user or mailing list...',
|
'mailable' => 'Type a user or mailing list...',
|
||||||
|
|
Loading…
Reference in a new issue