#!/usr/bin/env php $arg) { if ($arg == '--') { break; } else if ($arg == '--trace') { unset($args[$key]); $config_trace_mode = true; } else if ($arg == '--no-ansi') { unset($args[$key]); PhutilConsoleFormatter::disableANSI(true); } else if (preg_match('/^--load-phutil-library=(.*)$/', $arg, $matches)) { unset($args[$key]); $load['?'] = $matches[1]; } else if (preg_match('/^--conduit-uri=(.*)$/', $arg, $matches)) { unset($args[$key]); $force_conduit = $matches[1]; } } // The POSIX extension is not available by default in some PHP installs. if (function_exists('posix_isatty') && !posix_isatty(STDOUT)) { PhutilConsoleFormatter::disableANSI(true); } $args = array_values($args); try { if ($config_trace_mode) { PhutilServiceProfiler::installEchoListener(); } if (!$args) { throw new ArcanistUsageException("No command provided. Try 'arc help'."); } $working_copy = ArcanistWorkingCopyIdentity::newFromPath($_SERVER['PWD']); if ($load) { $libs = $load; } else { $libs = $working_copy->getConfig('phutil_libraries'); } if ($libs) { foreach ($libs as $name => $location) { if ($config_trace_mode) { echo "Loading phutil library '{$name}' from '{$location}'...\n"; } $resolved_location = Filesystem::resolvePath( $location, $working_copy->getProjectRoot()); if (Filesystem::pathExists($resolved_location)) { $location = $resolved_location; } try { phutil_load_library($location); } catch (PhutilBootloaderException $ex) { $error_msg = sprintf( 'Failed to load library "%s" at location "%s". Please check the '. '"phutil_libraries" setting in your .arcconfig file. Refer to page '. 'http://phabricator.com/docs/arcanist/article/'. 'Setting_Up_.arcconfig.html for more info.', $name, $location); throw new ArcanistUsageException($error_msg); } } } $user_config = array(); $user_config_path = getenv('HOME').'/.arcrc'; if (Filesystem::pathExists($user_config_path)) { $user_config_data = Filesystem::readFile($user_config_path); $user_config = json_decode($user_config_data, true); if (!is_array($user_config)) { throw new ArcanistUsageException( "Your '~/.arcrc' file is not a valid JSON file."); } } $config = $working_copy->getConfig('arcanist_configuration'); if ($config) { PhutilSymbolLoader::loadClass($config); $config = new $config(); } else { $config = new ArcanistConfiguration(); } $command = strtolower($args[0]); $workflow = $config->buildWorkflow($command); if (!$workflow) { throw new ArcanistUsageException( "Unknown command '{$command}'. Try 'arc help'."); } $workflow->setArcanistConfiguration($config); $workflow->setCommand($command); $workflow->parseArguments(array_slice($args, 1)); $need_working_copy = $workflow->requiresWorkingCopy(); $need_conduit = $workflow->requiresConduit(); $need_auth = $workflow->requiresAuthentication(); $need_repository_api = $workflow->requiresRepositoryAPI(); $need_conduit = $need_conduit || $need_auth; $need_working_copy = $need_working_copy || $need_conduit || $need_repository_api; if ($need_working_copy) { if (!$working_copy->getProjectRoot()) { throw new ArcanistUsageException( "There is no '.arcconfig' file in this directory or any parent ". "directory. Create a '.arcconfig' file to configure this project ". "for use with Arcanist."); } $workflow->setWorkingCopy($working_copy); } $set_guid = false; if ($need_conduit) { if ($force_conduit) { $conduit_uri = $force_conduit; } else { $conduit_uri = $working_copy->getConduitURI(); } if (!$conduit_uri) { throw new ArcanistUsageException( "No Conduit URI is specified in the .arcconfig file for this project. ". "Specify the Conduit URI for the host Differential is running on."); } $conduit = new ConduitClient($conduit_uri); $workflow->setConduit($conduit); $hosts_config = idx($user_config, 'hosts', array()); $host_config = idx($hosts_config, $conduit_uri, array()); $user_name = idx($host_config, 'user', getenv('USER')); $certificate = idx($host_config, 'cert'); $description = implode(' ', $argv); try { $connection = $conduit->callMethodSynchronous( 'conduit.connect', array( 'client' => 'arc', 'clientVersion' => 2, 'clientDescription' => php_uname('n').':'.$description, 'user' => $user_name, 'certificate' => $certificate, )); } catch (ConduitClientException $ex) { if ($ex->getErrorCode() == 'ERR-NO-CERTIFICATE') { $message = "\n\n". phutil_console_format( "YOU NEED TO __INSTALL A CERTIFICATE__ TO LOGIN TO PHABRICATOR"). "\n\n". "The server '{$conduit_uri}' rejected your request:". "\n\n". $ex->getMessage(). "\n\n"; $hosts_with_cert = ifilter($hosts_config, 'cert'); if (!empty($hosts_with_cert)) { if (count($hosts_with_cert) == 1) { $message .= "You currently have a certificate installed for one host:\n\n"; } else { $message .= "You currently have certificates installed for these hosts:\n\n"; } $message .= ' '.implode("\n ", array_keys($hosts_with_cert)); $message .= "\n"; } throw new ArcanistUsageException($message); } else { throw $ex; } } $workflow->setUserName($user_name); $user_phid = idx($connection, 'userPHID'); if ($user_phid) { $set_guid = true; $workflow->setUserGUID($user_phid); } } if ($need_repository_api) { $repository_api = ArcanistRepositoryAPI::newAPIFromWorkingCopyIdentity( $working_copy); $workflow->setRepositoryAPI($repository_api); } if ($need_auth && !$set_guid) { $user_name = getenv('USER'); $user_find_future = $conduit->callMethod( 'user.find', array( 'aliases' => array( $user_name, ), )); $user_guids = $user_find_future->resolve(); if (empty($user_guids[$user_name])) { throw new ArcanistUsageException( "Username '{$user_name}' is not recognized."); } $user_guid = $user_guids[$user_name]; $workflow->setUserGUID($user_guid); $workflow->setUserName($user_name); } $config->willRunWorkflow($command, $workflow); $workflow->willRunWorkflow(); $err = $workflow->run(); if ($err == 0) { $config->didRunWorkflow($command, $workflow); } exit($err); } catch (ArcanistUsageException $ex) { echo phutil_console_format( "**Usage Exception:** %s\n", $ex->getMessage()); if ($config_trace_mode) { echo "\n"; throw $ex; } exit(1); } catch (Exception $ex) { if ($config_trace_mode) { throw $ex; } echo phutil_console_format( "\n**Exception:**\n%s\n%s\n", $ex->getMessage(), "(Run with --trace for a full exception trace.)"); exit(1); }