Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: Add command aliases as requested in #110 #122

Merged
merged 3 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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