diff --git a/scripts/gitadmin/gitx-ssh b/scripts/gitadmin/gitx-ssh new file mode 100755 index 0000000000..26f810f35c --- /dev/null +++ b/scripts/gitadmin/gitx-ssh @@ -0,0 +1,6 @@ +#!/bin/bash + +set -e +set -u + +ssh -i $SSH_KEYFILE $@ diff --git a/scripts/gitadmin/rebuild_gitadmin.php b/scripts/gitadmin/rebuild_gitadmin.php index eaa090854a..38a194183d 100755 --- a/scripts/gitadmin/rebuild_gitadmin.php +++ b/scripts/gitadmin/rebuild_gitadmin.php @@ -28,6 +28,7 @@ function write_ini_file($array, $file) { file_put_contents($file, implode("\n", $res)); } +// Get user's heys and put them to the configuration function handleSingleUserPHID( $keydir, $viewer, $userPHID, &$used_keys) { $user = id(new PhabricatorPeopleQuery()) @@ -58,6 +59,7 @@ function handleSingleUserPHID( return $members; } +// Parse repository and put it's members to the config file function handleSingleRepository( $keydir, $viewer, $repository, &$new_configuration, &$used_keys) { $policies = PhabricatorPolicyQuery::loadPolicies( @@ -124,39 +126,114 @@ function removeUnusedPublicKeys($keydir, $used_keys) { } } -if (count($argv) != 2) { - print("Usage: {$argv[0]} /path/to/gitosis-admin\n"); +function rebuildConfiguration($gitosis_root) { + $keydir = "$gitosis_root/keydir"; + $configuration_file = "$gitosis_root/gitosis.conf"; + + if (!file_exists($configuration_file)) { + print("Not found: $configuration_file\n"); + return false; + } + + $viewer = id(new PhabricatorUser()) + ->loadOneWhere('username = %s', 'sergey'); + + $old_configuration = parse_ini_file( + $configuration_file, true, INI_SCANNER_RAW); + + $new_configuration = getCleanOldConfiguration( + $old_configuration); + + // Fill in new configuration and keys + $used_keys = array(); + $repositories = id(new PhabricatorRepositoryQuery()) + ->setViewer($viewer) + ->execute(); + + foreach ($repositories as $repository_id => $repository) { + handleSingleRepository( + $keydir, $viewer, $repository, $new_configuration, $used_keys); + } + + write_ini_file($new_configuration, $configuration_file); + removeUnusedPublicKeys($keydir, $used_keys); + + return true; +} + +function getGitCommand($repository, $need_workdir) { + $git_dir = realpath("$repository/.git"); + $git = "git --git-dir='$git_dir'"; + if ($need_workdir) { + $git .= ' --work-tree='.realpath($repository); + } + return $git; +} + +function runGitCommand($repository, $need_workdir, $arguments, + &$output=null, &$return_var=null) { + $git = getGitCommand($repository, $need_workdir); + $git .= " $arguments"; + exec($git, $output, $return_var); + return $return_var == 0; +} + +function runGitSshCommand($repository, $key, $need_workdir, $arguments, + &$output=null, &$return_var=null) { + $gitx_ssh = realpath(dirname(__FILE__) . "/gitx-ssh"); + $abs_key = realpath($key); + $git = "SSH_KEYFILE=$abs_key GIT_SSH=$gitx_ssh "; + $git .= getGitCommand($repository, $need_workdir); + $git .= " $arguments"; + exec($git, $output, $return_var); + return $return_var == 0; +} + +function repositoryPull($repository) { + return runGitCommand($repository, false, 'pull'); +} + +function repositoryCommitAll($repository, $message) { + if (!runGitCommand( + $repository, true, + 'ls-files --other --exclude-standard', $untracked_files)) { + return false; + } + if (count($untracked_files)) { + $flat_files = join(' ', $untracked_files); + if (!runGitCommand($repository, true, "add $flat_files")) { + return false; + } + } + runGitCommand($repository, true, "update-index -q --refresh", $output); + runGitCommand($repository, true, "diff-index --name-only HEAD --", $output); + if (count($output)) { + return runGitCommand($repository, true, "commit -a -m '$message'", $output); + } + return true; +} + +if (count($argv) != 3) { + print("Usage: {$argv[0]} /path/to/gitosis-admin /path/to/id_rsa.pub\n"); exit(1); } $gitosis_root = $argv[1]; -$configuration_file = "$gitosis_root/gitosis.conf"; -$keydir = "$gitosis_root/keydir"; -if (!file_exists($configuration_file)) { - print("Not found: $configuration_file\n"); +$key = $argv[2]; + +if (!repositoryPull($gitosis_root)) { + print("Failed to pull changes from server.\n"); exit(1); } -$viewer = id(new PhabricatorUser()) - ->loadOneWhere('username = %s', 'sergey'); - -$old_configuration = parse_ini_file( - $configuration_file, true, INI_SCANNER_RAW); - -$new_configuration = getCleanOldConfiguration( - $old_configuration); - -// Fill in new configuration and keys -$used_keys = array(); -$repositories = id(new PhabricatorRepositoryQuery()) - ->setViewer($viewer) - ->execute(); - -foreach ($repositories as $repository_id => $repository) { - handleSingleRepository( - $keydir, $viewer, $repository, $new_configuration, $used_keys); +if (!rebuildConfiguration($gitosis_root)) { + exit(1); } -write_ini_file($new_configuration, $configuration_file); -removeUnusedPublicKeys($keydir, $used_keys); +if (!repositoryCommitAll($gitosis_root, 'Update to correspond changes in Phabricator')) { + print("Failed to commit changes.\n"); + exit(1); +} + +runGitSshCommand($gitosis_root, $key, true, 'push'); ?>