Skip to content

Commit

Permalink
Merge pull request #122 from ahoy-cli/add-command-aliases
Browse files Browse the repository at this point in the history
feature: Add command aliases as requested in #110
  • Loading branch information
ocean authored Sep 5, 2024
2 parents cb468d7 + 92d0806 commit c0cd36d
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 12 deletions.
44 changes: 34 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,39 @@ os=$(uname -s | tr [:upper:] [:lower:]) && architecture=$(case $(uname -m) in x8

For WSL2, use the Linux binary above for your architecture.

## Command Aliases

Ahoy now supports command aliases. This feature allows you to define alternative names for your commands, making them more convenient to use and remember.

### Usage

In your `.ahoy.yml` file, you can add an `aliases` field to any command definition. The `aliases` field should be an array of strings, each representing one or more alternative names for the command.

Example:

```yaml
ahoyapi: v2
commands:
hello:
usage: Say hello
cmd: echo "Hello, World!"
aliases: ["hi", "greet"]
```
In this example, the `hello` command can also be invoked using `hi` or `greet`.

### Benefits

- Improved usability: Users can call commands using shorter or more intuitive names.
- Flexibility: You can provide multiple ways to access the same functionality without duplicating command definitions.
- Backward compatibility: You can introduce new, more descriptive command names while keeping old names as aliases.

### Notes

- Aliases are displayed in the help output for each command.
- Bash completion works with aliases as well as primary command names.
- **If multiple commands share the same alias, the "last in wins" rule is used and the last matching command will be executed.**

## Some additions in v2

- Implements a new feature to import multiple config files using the "imports" field.
Expand Down Expand Up @@ -117,18 +150,9 @@ commands:
- ./some-file3.ahoy.yml
```

### Planned Features
## Planned Features

- Enable specifying specific arguments and flags in the ahoy file itself to cut down on parsing arguments in scripts.
- Support for more built-in commands or a "verify" YAML option that would create a yes / no prompt for potentially destructive commands. (Are you sure you want to delete all your containers?)
- Pipe tab completion to another command (allows you to get tab completion).
- Support for configuration.
## Previewing the Read the Docs documentation locally.
* Change to the `./docs` directory.
* Run `ahoy deps` to install the python dependencies.
* Make changes to any of the .md files.
* Run `ahoy build-docs` (This will convert all the .md files to docs)
* You should have several html files in docs/_build/html directory of which Home.html and index.html are the parent files.
* For more information on how to compile the docs from scratch visit: https://read-the-docs.readthedocs.io/en/latest/intro/getting-started-with-mkdocs.html
9 changes: 7 additions & 2 deletions ahoy.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type Command struct {
Hide bool
Optional bool
Imports []string
Aliases []string
}

var app *cli.App
Expand Down Expand Up @@ -188,7 +189,7 @@ func getCommands(config Config) []cli.Command {
logger("fatal", "Command ["+name+"] has neither 'cmd' or 'imports' set. Check your yaml file.")
}

// Check that a command has 'cmd' AND 'imports' set.
// Check if a command has 'cmd' AND 'imports' set.
if cmd.Cmd != "" && cmd.Imports != nil {
logger("fatal", "Command ["+name+"] has both 'cmd' and 'imports' set, but only one is allowed. Check your yaml file.")
}
Expand All @@ -200,6 +201,7 @@ func getCommands(config Config) []cli.Command {

newCmd := cli.Command{
Name: name,
Aliases: cmd.Aliases,
SkipFlagParsing: true,
HideHelp: cmd.Hide,
}
Expand Down Expand Up @@ -451,7 +453,7 @@ AUTHOR(S):
{{range .Authors}}{{ . }}{{end}}
{{end}}{{if .Commands}}
COMMANDS:
{{range .Commands}}{{if not .HideHelp}} {{join .Names ", "}}{{ if len .Subcommands }}{{" \u25BC"}}{{end}}{{ "\t" }}{{.Usage}}{{ "\n" }}{{end}}{{end}}{{end}}{{if .Flags}}
{{range .Commands}}{{if not .HideHelp}} {{join .Names ", "}}{{ if len .Subcommands }}{{" \u25BC"}}{{end}}{{ "\t" }}{{.Usage}} {{if .Aliases}}[ Aliases: {{join .Aliases ", "}} ]{{end}}{{ "\n" }}{{end}}{{end}}{{end}}{{if .Flags}}
GLOBAL OPTIONS:
{{range .Flags}}{{.}}
{{end}}{{end}}{{if .Copyright }}
Expand All @@ -461,6 +463,9 @@ COPYRIGHT:
VERSION:
{{.Version}}
{{end}}
ALIASES:
Commands can have aliases for easier invocation. Aliases are displayed next to each command that has them.
You can use any of a command's aliases interchangeably with its primary name.
`

return app
Expand Down
11 changes: 11 additions & 0 deletions testdata/command-aliases.ahoy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
ahoyapi: v2
commands:
hello:
usage: Say hello
cmd: echo "Hello, World!"
aliases: ["hi", "greet", "ahoy"]

ahoy-there:
usage: Say "ahoy there!"
cmd: echo "ahoy there!"
aliases: ["ahoy"]
41 changes: 41 additions & 0 deletions tests/command-aliases.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env bats

load 'test_helpers/bats-support/load'
load 'test_helpers/bats-assert/load'

@test "Command aliases work correctly" {
run ./ahoy -f testdata/command-aliases.ahoy.yml hello
[[ "$output" =~ "Hello, World!" ]]
[ "$status" -eq 0 ]

run ./ahoy -f testdata/command-aliases.ahoy.yml hi
[[ "$output" =~ "Hello, World!" ]]
[ "$status" -eq 0 ]

run ./ahoy -f testdata/command-aliases.ahoy.yml greet
[[ "$output" =~ "Hello, World!" ]]
[ "$status" -eq 0 ]

run ./ahoy -f testdata/command-aliases.ahoy.yml
[[ "$output" =~ "hello, hi, greet" ]]
[[ "$output" =~ "Aliases: hi, greet" ]]

# Should exit with error as no command was supplied.
[ "$status" -eq 1 ]
}

@test "Say ahoy there" {
run ./ahoy -f testdata/command-aliases.ahoy.yml ahoy-there
[[ "$output" =~ "ahoy there!" ]]
[ "$status" -eq 0 ]

run ./ahoy -f testdata/command-aliases.ahoy.yml ahoy
[[ "$output" =~ "ahoy there!" ]]
[ "$status" -eq 0 ]
}

@test "Multiple conflicting aliases means the last one loaded takes precedence" {
run ./ahoy -f testdata/command-aliases.ahoy.yml ahoy
[[ "$output" =~ "ahoy there!" ]]
[ "$status" -eq 0 ]
}
1 change: 1 addition & 0 deletions tests/no-ahoy-file.bats
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ setup() {

teardown() {
mv tmp.ahoy.yml .ahoy.yml
rm -rf wget-lo*
}

@test "Run ahoy without a command and without an .ahoy.yml file" {
Expand Down

0 comments on commit c0cd36d

Please sign in to comment.