'argv', ); } public static function getAliases( ArcanistConfigurationManager $configuration_manager) { $working_copy_config_aliases = $configuration_manager->getProjectConfig('aliases'); if (!$working_copy_config_aliases) { $working_copy_config_aliases = array(); } $user_config_aliases = idx( $configuration_manager->readUserConfigurationFile(), 'aliases', array()); return $user_config_aliases + $working_copy_config_aliases; } private function writeAliases(array $aliases) { $config = $this->getConfigurationManager()->readUserConfigurationFile(); $config['aliases'] = $aliases; $this->getConfigurationManager()->writeUserConfigurationFile($config); } public function run() { $aliases = self::getAliases($this->getConfigurationManager()); $argv = $this->getArgument('argv'); if (count($argv) == 0) { $this->printAliases($aliases); } else if (count($argv) == 1) { $this->removeAlias($aliases, $argv[0]); } else { $arc_config = $this->getArcanistConfiguration(); $alias = $argv[0]; if ($arc_config->buildWorkflow($alias)) { throw new ArcanistUsageException( pht( 'You can not create an alias for "%s" because it is a '. 'builtin command. "%s" can only create new commands.', "arc {$alias}", 'arc alias')); } $new_alias = array_slice($argv, 1); $command = implode(' ', $new_alias); if (self::isShellCommandAlias($command)) { echo tsprintf( "%s\n", pht( 'Aliased "%s" to shell command "%s".', "arc {$alias}", substr($command, 1))); } else { echo tsprintf( "%s\n", pht( 'Aliased "%s" to "%s".', "arc {$alias}", "arc {$command}")); } $aliases[$alias] = $new_alias; $this->writeAliases($aliases); } return 0; } public static function isShellCommandAlias($command) { return preg_match('/^!/', $command); } public static function resolveAliases( $command, ArcanistConfiguration $config, array $argv, ArcanistConfigurationManager $configuration_manager) { $aliases = self::getAliases($configuration_manager); if (!isset($aliases[$command])) { return array(null, $argv); } $new_command = head($aliases[$command]); if (self::isShellCommandAlias($new_command)) { return array($new_command, $argv); } $workflow = $config->buildWorkflow($new_command); if (!$workflow) { return array(null, $argv); } $alias_argv = array_slice($aliases[$command], 1); foreach (array_reverse($alias_argv) as $alias_arg) { if (!in_array($alias_arg, $argv)) { array_unshift($argv, $alias_arg); } } return array($new_command, $argv); } private function printAliases(array $aliases) { if (!$aliases) { echo tsprintf( "%s\n", pht('You have not defined any aliases yet.')); return; } $table = id(new PhutilConsoleTable()) ->addColumn('input', array('title' => pht('Alias'))) ->addColumn('command', array('title' => pht('Command'))) ->addColumn('type', array('title' => pht('Type'))); ksort($aliases); foreach ($aliases as $alias => $binding) { $command = implode(' ', $binding); if (self::isShellCommandAlias($command)) { $command = substr($command, 1); $type = pht('Shell Command'); } else { $command = "arc {$command}"; $type = pht('Arcanist Command'); } $row = array( 'input' => "arc {$alias}", 'type' => $type, 'command' => $command, ); $table->addRow($row); } $table->draw(); } private function removeAlias(array $aliases, $alias) { if (empty($aliases[$alias])) { echo tsprintf( "%s\n", pht('No alias "%s" to remove.', $alias)); return; } $command = implode(' ', $aliases[$alias]); if (self::isShellCommandAlias($command)) { echo tsprintf( "%s\n", pht( '"%s" is currently aliased to shell command "%s".', "arc {$alias}", substr($command, 1))); } else { echo tsprintf( "%s\n", pht( '"%s" is currently aliased to "%s".', "arc {$alias}", "arc {$command}")); } $ok = phutil_console_confirm(pht('Delete this alias?')); if (!$ok) { throw new ArcanistUserAbortException(); } unset($aliases[$alias]); $this->writeAliases($aliases); echo tsprintf( "%s\n", pht( 'Removed alias "%s".', "arc {$alias}")); } }