protected function run() { $argv = $this->getArgv(); if (count($argv) !== 1) { throw new Exception(pht('Usage: %s %s', __CLASS__, '<json_config_file>')); } $json_raw = Filesystem::readFile($argv[0]); try { $config = phutil_json_decode($json_raw); } catch (PhutilJSONParserException $ex) { throw new PhutilProxyException(pht("File '%s' is not valid JSON!", $argv[0]), $ex); } $nick = idx($config, 'nick', 'phabot'); $handlers = idx($config, 'handlers', array()); $protocol_adapter_class = idx($config, 'protocol-adapter', 'PhabricatorIRCProtocolAdapter'); $this->pollFrequency = idx($config, 'poll-frequency', 1); $this->config = $config; foreach ($handlers as $handler) { $obj = newv($handler, array($this)); $this->handlers[] = $obj; } $ca_bundle = idx($config, 'https.cabundle'); if ($ca_bundle) { HTTPSFuture::setGlobalCABundleFromPath($ca_bundle); } $conduit_uri = idx($config, 'conduit.uri'); if ($conduit_uri) { $conduit_token = idx($config, 'conduit.token'); // Normalize the path component of the URI so users can enter the // domain without the "/api/" part. $conduit_uri = new PhutilURI($conduit_uri); $conduit_host = (string) $conduit_uri->setPath('/'); $conduit_uri = (string) $conduit_uri->setPath('/api/'); $conduit = new ConduitClient($conduit_uri); if ($conduit_token) { $conduit->setConduitToken($conduit_token); } else { $conduit_user = idx($config, 'conduit.user'); $conduit_cert = idx($config, 'conduit.cert'); $response = $conduit->callMethodSynchronous('conduit.connect', array('client' => __CLASS__, 'clientVersion' => '1.0', 'clientDescription' => php_uname('n') . ':' . $nick, 'host' => $conduit_host, 'user' => $conduit_user, 'certificate' => $conduit_cert)); } $this->conduit = $conduit; } // Instantiate Protocol Adapter, for now follow same technique as // handler instantiation $this->protocolAdapter = newv($protocol_adapter_class, array()); $this->protocolAdapter->setConfig($this->config)->connect(); $this->runLoop(); $this->protocolAdapter->disconnect(); }
if ($conduit_uri) { // Set the URI path to '/api/'. TODO: Originally, I contemplated letting // you deploy Phabricator somewhere other than the domain root, but ended // up never pursuing that. We should get rid of all "/api/" silliness // in things users are expected to configure. This is already happening // to some degree, e.g. "arc install-certificate" does it for you. $conduit_uri = new PhutilURI($conduit_uri); $conduit_uri->setPath('/api/'); $conduit_uri = (string) $conduit_uri; } $workflow->setConduitURI($conduit_uri); // Apply global CA bundle from configs. $ca_bundle = $configuration_manager->getConfigFromAnySource('https.cabundle'); if ($ca_bundle) { $ca_bundle = Filesystem::resolvePath($ca_bundle, $working_copy->getProjectRoot()); HTTPSFuture::setGlobalCABundleFromPath($ca_bundle); } $blind_key = 'https.blindly-trust-domains'; $blind_trust = $configuration_manager->getConfigFromAnySource($blind_key); if ($blind_trust) { HTTPSFuture::setBlindlyTrustDomains($blind_trust); } if ($need_conduit) { if (!$conduit_uri) { $message = phutil_console_format("This command requires arc to connect to a Phabricator install, but " . "no Phabricator installation is configured. To configure a " . "Phabricator URI:\n\n" . " - set a default location with `arc set-config default <uri>`; or\n" . " - specify '--conduit-uri=uri' explicitly; or\n" . " - run 'arc' in a working copy with an '.arcconfig'.\n"); $message = phutil_console_wrap($message); throw new ArcanistUsageException($message); } $workflow->establishConduit(); } $hosts_config = idx($user_config, 'hosts', array());