diff --git a/src/IDF/Plugin/SyncMonotone.php b/src/IDF/Plugin/SyncMonotone.php new file mode 100644 index 0000000..2280a0b --- /dev/null +++ b/src/IDF/Plugin/SyncMonotone.php @@ -0,0 +1,137 @@ +processMonotoneCreate($params['project']); + break; + } + } + + /** + * Run mtn init command to create the corresponding monotone + * repository and add the database to the configured usher instance + * + * @param IDF_Project + */ + function processMonotoneCreate($project) + { + if ($project->getConf()->getVal('scm') != 'mtn') { + return; + } + + $repotempl = Pluf::f('mtn_repositories', false); + if ($repotempl === false) { + throw new IDF_Scm_Exception( + '"mtn_repositories" must be defined in your configuration file.' + ); + } + + $usher_config = Pluf::f('mtn_usher', array()); + if (!array_key_exists('rcfile', $usher_config) || + !is_writable($usher_config['rcfile'])) { + throw new IDF_Scm_Exception( + '"rcfile" in "mtn_usher" does not exist or is not writable.' + ); + } + + $shortname = $project->shortname; + $dbfile = sprintf($repotempl, $shortname); + if (file_exists($dbfile)) { + throw new IDF_Scm_Exception(sprintf( + __('The repository %s already exists.'), $dbfile + )); + } + $return = 0; + $output = array(); + $cmd = sprintf( + Pluf::f('mtn_path', 'mtn').' db init -d %s', + escapeshellarg($dbfile) + ); + $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; + $ll = exec($cmd, $output, $return); + if ($return != 0) { + throw new IDF_Scm_Exception(sprintf( + __('Could not create repository %s - please check '. + 'your error log for details.'), + $dbfile + )); + } + + $usher_rc = file_get_contents($usher_config['rcfile']); + $parsed_config = array(); + try { + $parsed_config = IDF_Scm_Monotone_BasicIO::parse($usher_rc); + } + catch (Exception $e) { + throw new IDF_Scm_Exception(sprintf( + __('Could not parse usher configuration in "%s": %s'), + $usher_config['rcfile'], $e->getMessage() + )); + } + + // ensure we haven't configured a server with this name already + foreach ($parsed_config as $stanzas) + { + foreach ($stanzas as $stanza_line) + { + if ($stanza_line['key'] == 'server' && + $stanza_line['values'][0] == $shortname) + { + throw new IDF_Scm_Exception(sprintf( + __('usher configuration already contains a server '. + 'entry named "%s"'), + $shortname + )); + } + } + } + + $new_server = array( + array('key' => 'server', 'values' => array($shortname)), + array('key' => 'local', 'values' => array('-d', $dbfile)), + ); + + $parsed_config[] = $new_server; + $usher_rc = IDF_Scm_Monotone_BasicIO::compile($parsed_config); + + // FIXME: more sanity - what happens on failing writes? + $fp = fopen($usher_config['rcfile'], 'w'); + fwrite($fp, $usher_rc); + fclose($fp); + + IDF_Scm_Monotone_Usher::reload(); + } +} diff --git a/src/IDF/conf/idf.php-dist b/src/IDF/conf/idf.php-dist index 390ce36..31c4661 100644 --- a/src/IDF/conf/idf.php-dist +++ b/src/IDF/conf/idf.php-dist @@ -147,13 +147,16 @@ $cfg['mtn_db_access'] = 'remote'; # # 'host' and 'port' must be set to the specific bits from usher's # configured 'adminaddr', 'user' and 'pass' must match the values set for -# the configured 'userpass' combination +# the configured 'userpass' combination. The 'rcfile' variable must point +# to the full (writable) path of the usher configuration file which gets +# updated when new projects are added # #$cfg['mtn_usher'] = array( -# 'host' => 'localhost', -# 'port' => 12345, -# 'user' => 'admin', -# 'pass' => 'admin', +# 'host' => 'localhost', +# 'port' => 12345, +# 'user' => 'admin', +# 'pass' => 'admin', +# 'rcfile' => '/path/to/usher.conf', #); # diff --git a/src/IDF/relations.php b/src/IDF/relations.php index f5a5925..bf4e32e 100644 --- a/src/IDF/relations.php +++ b/src/IDF/relations.php @@ -49,51 +49,55 @@ Pluf_Signal::connect('Pluf_Template_Compiler::construct_template_tags_modifiers' # -- Standard plugins, they will run only if configured -- # # Subversion synchronization -Pluf_Signal::connect('IDF_Project::membershipsUpdated', +Pluf_Signal::connect('IDF_Project::membershipsUpdated', array('IDF_Plugin_SyncSvn', 'entry')); -Pluf_Signal::connect('IDF_Project::created', +Pluf_Signal::connect('IDF_Project::created', array('IDF_Plugin_SyncSvn', 'entry')); -Pluf_Signal::connect('Pluf_User::passwordUpdated', +Pluf_Signal::connect('Pluf_User::passwordUpdated', array('IDF_Plugin_SyncSvn', 'entry')); -Pluf_Signal::connect('IDF_Project::preDelete', +Pluf_Signal::connect('IDF_Project::preDelete', array('IDF_Plugin_SyncSvn', 'entry')); -Pluf_Signal::connect('svnpostcommit.php::run', +Pluf_Signal::connect('svnpostcommit.php::run', array('IDF_Plugin_SyncSvn', 'entry')); # # Mercurial synchronization -Pluf_Signal::connect('IDF_Project::membershipsUpdated', +Pluf_Signal::connect('IDF_Project::membershipsUpdated', array('IDF_Plugin_SyncMercurial', 'entry')); -Pluf_Signal::connect('IDF_Project::created', +Pluf_Signal::connect('IDF_Project::created', array('IDF_Plugin_SyncMercurial', 'entry')); -Pluf_Signal::connect('Pluf_User::passwordUpdated', +Pluf_Signal::connect('Pluf_User::passwordUpdated', array('IDF_Plugin_SyncMercurial', 'entry')); -Pluf_Signal::connect('hgchangegroup.php::run', +Pluf_Signal::connect('hgchangegroup.php::run', array('IDF_Plugin_SyncMercurial', 'entry')); # # Git synchronization -Pluf_Signal::connect('IDF_Project::membershipsUpdated', +Pluf_Signal::connect('IDF_Project::membershipsUpdated', array('IDF_Plugin_SyncGit', 'entry')); -Pluf_Signal::connect('IDF_Key::postSave', +Pluf_Signal::connect('IDF_Key::postSave', array('IDF_Plugin_SyncGit', 'entry')); -Pluf_Signal::connect('IDF_Project::created', +Pluf_Signal::connect('IDF_Project::created', array('IDF_Plugin_SyncGit', 'entry')); -Pluf_Signal::connect('IDF_Key::preDelete', +Pluf_Signal::connect('IDF_Key::preDelete', array('IDF_Plugin_SyncGit', 'entry')); -Pluf_Signal::connect('gitpostupdate.php::run', +Pluf_Signal::connect('gitpostupdate.php::run', array('IDF_Plugin_SyncGit', 'entry')); # +# monotone synchronization +Pluf_Signal::connect('IDF_Project::created', + array('IDF_Plugin_SyncMonotone', 'entry')); +# # -- Processing of the webhook queue -- -Pluf_Signal::connect('queuecron.php::run', +Pluf_Signal::connect('queuecron.php::run', array('IDF_Queue', 'process')); # -# Processing of a given webhook, the hook can be configured -# directly in the configuration file if a different solution +# Processing of a given webhook, the hook can be configured +# directly in the configuration file if a different solution # is required. -Pluf_Signal::connect('IDF_Queue::processItem', - Pluf::f('idf_hook_process_item', +Pluf_Signal::connect('IDF_Queue::processItem', + Pluf::f('idf_hook_process_item', array('IDF_Webhook', 'process'))); return $m;