Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F211524
clone-membership.php
No One
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Authored By
cburroughs
Oct 1 2014, 9:06 PM
2014-10-01 21:06:47 (UTC+0)
Size
3 KB
Referenced Files
None
Subscribers
None
clone-membership.php
View Options
#!/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
Details
Attached
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)
Attached To
Mode
P1266 clone-membership.php
Attached
Detach File
Event Timeline
Log In to Comment