Page MenuHomePhabricator

clone-membership.php

Authored By
cburroughs
Oct 1 2014, 9:06 PM
Size
3 KB
Referenced Files
None
Subscribers
None

clone-membership.php

#!/usr/bin/env php
<?php
$root = dirname(dirname(__FILE__));
require_once $root.'/scripts/__init_script__.php';
$args = new PhutilArgumentParser($argv);
$args->setTagline('set members');
$args->setSynopsis(<<<EOSYNOPSIS
cat list | **clone-members.php** '#project'
Set members of '#preffix' to be the same as '#project'.
EOSYNOPSIS
);
$args->parseStandardArguments();
$args->parse(
array(
array(
'name' => 'dry-run',
'help' => pht('Only show what changes would be made.'),
),
));
$viewer = PhabricatorUser::getOmnipotentUser();
// manually maintained config
$conf = array(
'Zelda' => 'Zelda-Sprint'
);
echo "Run at ".date(DateTime::ISO8601)."...\n";
foreach($conf as $master_project_name => $clone_prefix) {
$slug = trim($master_project_name, '#');
$project = id(new PhabricatorProjectQuery())
->setViewer($viewer)
->withSlugs(array($slug))
->needMembers(true)
->executeOne();
if (!$project) {
throw new Exception(pht('No project "%s" exists!', $slug));
}
echo "Processing master project: ".$project->getName()."\n";
$current_master_phids = $project->getMemberPHIDs();
$current_master_users = array();
if (!$current_master_users) {
$current_master_users = id(new PhabricatorPeopleQuery())
->setViewer($viewer)
->withPHIDs($current_master_phids)
->execute();
}
// We need all projects since there is no way to search by prefix
$all_projects = id(new PhabricatorProjectQuery())
->setViewer($viewer)
->needMembers(true)
->execute();
$clone_projects = array();
foreach ($all_projects as $canidate_project) {
if (startsWith($canidate_project->getName(), $clone_prefix)) {
echo "Clone Project: ".$canidate_project->getName()."\n";
cloneProjectMembers($viewer,
mpull($current_master_users, null, 'getPHID'),
$canidate_project,
$args->getArg('dry-run'));
}
}
}
echo "Done.\n";
// http://stackoverflow.com/questions/834303/startswith-and-endswith-functions-in-php
function startsWith($haystack, $needle) {
return $needle === "" || strpos($haystack, $needle) === 0;
}
function cloneProjectMembers($viewer, $current_master_users, $clone_project, $dry_run) {
$current_clone_phids = $clone_project->getMemberPHIDs();
$current_clone_users = array();
if (!empty($current_clone_phids)) {
$current_clone_users = id(new PhabricatorPeopleQuery())
->setViewer($viewer)
->withPHIDs($current_clone_phids)
->execute();
}
$all_users = mpull($current_master_users, null, 'getPHID') +
mpull($current_clone_users, null, 'getPHID');
$add = array_diff_key($current_master_users, array_fuse($current_clone_phids));
$rem = array_diff_key(array_fuse($current_clone_phids), $current_master_users);
$add_users = array_select_keys($all_users, array_keys($add));
$rem_users = array_select_keys($all_users, array_keys($rem));
if (!$add) {
echo "No users will be added.\n\n";
} else {
echo "These users will be added:\n";
foreach ($add_users as $user) {
echo " ".$user->getUsername()."\n";
}
echo "\n";
}
if (!$rem) {
echo "No users will be removed.\n\n";
} else {
echo "These users will be removed:\n";
foreach ($rem as $rem_phid => $ignored) {
$name = $rem_phid;
if (isset($rem_users[$rem_phid])) {
$name = $rem_users[$rem_phid]->getUsername();
}
echo " ".$name."\n";
}
echo "\n";
}
if ($dry_run) {
echo "End of dry run.\n";
exit(0);
}
if (!$add && !$rem) {
echo "No changes to apply.\n";
exit(0);
}
echo "Applying changes...\n";
$type_member = PhabricatorEdgeConfig::TYPE_PROJ_MEMBER;
$editor = id(new PhabricatorEdgeEditor());
foreach ($add as $phid => $ignored) {
$editor->addEdge($clone_project->getPHID(), $type_member, $phid);
}
foreach ($rem as $phid => $ignored) {
$editor->removeEdge($clone_project->getPHID(), $type_member, $phid);
}
$editor->save();
}

File Metadata

Mime Type
text/plain; charset=utf-8
Storage Engine
amazon-s3
Storage Format
Raw Data
Storage Handle
phabricator/zh/iq/jxwyakmjch75jauj
Default Alt Text
clone-membership.php (3 KB)

Event Timeline