mirror of
https://we.phorge.it/source/arcanist.git
synced 2025-01-08 13:51:01 +01:00
4a680c762b
Summary: Fixes T9873. Instead of printing something like this: > Aliased "arc ls" to "arc !ls". ...print this: > Aliased "arc ls" to shell command "ls". Test Plan: - Added shell commands and internal aliases. - Removed aliases. - Listed aliases. Reviewers: chad Reviewed By: chad Maniphest Tasks: T9873 Differential Revision: https://secure.phabricator.com/D14651
243 lines
6.2 KiB
PHP
243 lines
6.2 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Manages aliases for commands with options.
|
|
*/
|
|
final class ArcanistAliasWorkflow extends ArcanistWorkflow {
|
|
|
|
public function getWorkflowName() {
|
|
return 'alias';
|
|
}
|
|
|
|
public function getCommandSynopses() {
|
|
return phutil_console_format(<<<EOTEXT
|
|
**alias**
|
|
**alias** __command__
|
|
**alias** __command__ __target__ -- [__options__]
|
|
EOTEXT
|
|
);
|
|
}
|
|
|
|
public function getCommandHelp() {
|
|
return phutil_console_format(<<<EOTEXT
|
|
Supports: cli
|
|
Create an alias from __command__ to __target__ (optionally, with
|
|
__options__). For example:
|
|
|
|
arc alias fpatch patch -- --force
|
|
|
|
...will create a new 'arc' command, 'arc fpatch', which invokes
|
|
'arc patch --force ...' when run. NOTE: use "--" before specifying
|
|
options!
|
|
|
|
If you start an alias with "!", the remainder of the alias will be
|
|
invoked as a shell command. For example, if you want to implement
|
|
'arc ls', you can do so like this:
|
|
|
|
arc alias ls '!ls'
|
|
|
|
You can now run "arc ls" and it will behave like "ls". Of course, this
|
|
example is silly and would make your life worse.
|
|
|
|
You can not overwrite builtins, including 'alias' itself. The builtin
|
|
will always execute, even if it was added after your alias.
|
|
|
|
To remove an alias, run:
|
|
|
|
arc alias fpatch
|
|
|
|
Without any arguments, 'arc alias' will list aliases.
|
|
EOTEXT
|
|
);
|
|
}
|
|
|
|
public function getArguments() {
|
|
return array(
|
|
'*' => '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}"));
|
|
}
|
|
|
|
}
|