Add support for aliases in sub-command namespaces
- Dominant language
- Python
- Stars
- 17.3k
- Forks
- 4.6k
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 13
Description
### Describe the feature
The AWS CLI has support for creating aliases at the "service command" level [(original PR)](https://github.com/aws/aws-cli/pull/2287), [user docs](https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-alias.html). This is a proposal to add aliases at any level of a command space, e.g. `aws ec2 `, `aws ec2 wait `, etc.
### Use Case
Initially, we chose not to support aliases at any other level within the command hierarchy, primarily for scope. However, there are a few issues with aliases as they exist today:
* We have 300+ services which makes the top level namespace incredibly cluttered with increasing likelihood that an alias you define could overwrite an existing service or prevent a newly launched service from being accessible because a pre-existing alias overwrites it.
* It's hard to quickly find which top level commands are service commands vs. your aliases (ignoring the fact that user defined aliases are explicitly excluded from help/documentation).
* It creates an inconsistent usage between user defined aliases and built-in commands, e.g. `aws ec2-regions` could be a valid command that invokes a service specific API, but `aws ec2` or `aws iam`, which are built-in, are not valid (specifically incomplete) commands. Being able to create aliases as the "operation" level of the command hierarchy makes aliases more consistent with built in commands, e.g. `aws cloudformation list-stacks` vs. `aws cloudformation list`.
* You have to rely on a naming convention to be able to easily group aliases for a service together, i.e. `aws iam-roles`, `aws iam-`.
### Proposed Solution
In addition to the `[toplevel]` key, you can now specify additional sections in the alias file. The sections are denoted as:
`[command (\s+)+]`
or in other words `command` followed by one or more whitespace separated command names. For example:
* `[command ec2]`
* `[command iam]`
* `[command cloudformation wait]`
The contents of each section are the same as defined in the existing `[toplevel]` section.
## Replacement rules
For internal aliases (alias values without the `!` prefix), the alias value is replaced relative to the existing command hierarchy. In other words, the command namespace is prefixed to the alias value. For example, given:
```
[command ec2]
regions = describe-regions --query Regions[].RegionName
```
Then the following invocations are replaced as follows:
```
# Running:
aws ec2 regions
# Is (conceptually) replaced with:
aws ec2 describe-regions --query Regions[].RegionName
```
If you want to "break out" of the defined command namespace, you can use an external alias that invokes the AWS CLI:
```
[command ec2]
instance-profiles = !aws iam list-instance-profiles
```
Additional constraints/notes:
* You can't create a brand new command namespace, you can only add to existing command namespaces. In other words creating a section `[command james]` will not create any aliases if the `aws james` namespace does not already exist. I like the idea, but I'm not sure we should go down that path just yet.
* A namespace (in terms of implementation) specifically refers to having a command table of subcommands. So, for example, `aws cloudformation list-stacks` is *not* a namespace (there are no subcommands under that command, only arguments), so you couldn't create any aliases under `[command cloudformation list-stacks]`. FWIW this wouldn't be hard to implement, but I'm not sure it's a good idea. It would enable you to create pre configured sets of options that you can reference by an alias name, so you could do crazy stuff like:
```
[command cloudformation list-stacks]
# Note the alias value contains only options, no commands.
created = --stack-status-filter CREATE_COMPLETE --query StackSummaries[].[StackName,StackStatus] --output text
deleted = --stack-status-filter DELETE_COMPLETE --query StackSummaries[].[StackName,StackStatus] --output text
```
Invoked as:
```
aws cloudformation list-stacks created
aws cloudformation list-stacks deleted
```
which if you really wanted to customize, you could combine this with the recursive replacement of aliases and add:
```
[toplevel]
cfn = cloudformation
[command cloudformation]
stacks = list-stacks
```
which I *think*, but have not actually tried to implement this, should allow you to run things like:
```
# This is equivalent to:
# aws cloudformation list-stacks --stack-status-filter CREATE_COMPLETE --query StackSummaries[].[StackName,StackStatus] --output text
aws cfn stacks created
# This is equivalent to:
# aws cloudformation list-stacks --stack-status-filter DELETE_COMPLETE --query StackSummaries[].[StackName,StackStatus] --output text
aws cfn stacks deleted
```
On second thought, that actually is kinda awesome and I'm 99% sure this would work. Should we support this?
### Other Information
I volunteer to implement this feature.
### Acknowledgements
- [X] I may be able to implement this feature request
- [ ] This feature might incur a breaking change
### CLI version used
v2
### Environment details (OS name and version, etc.)
All of them
Contributor guide
Assessment
This issue has not been assessed yet.