New feature: asdf extension commands

It's possible for plugins to define new asdf commands. This way plugins can extend asdf capabilities or expose utilities related to their managed tool.

For example, a `foo` plugin might expose the command `asdf foo bar` by providing an executable file at `bin/bar`.
If `bin/bar` is a file but has no executable bit set, then its considered a source-able bash script, and will be sourced
with all the functions in `$ASDF_DIR/lib/utils.sh` already loaded.

A good example of this feature is the `nodejs` plugin, where people must import the release team keyring before
installing a nodejs version. People can execute the following command without having to know where exactly is the plugin located.
This commit is contained in:
Victor Hugo Borja 2019-11-25 02:24:46 -06:00
parent fd3469ab60
commit 0e8e1f8f84
4 changed files with 93 additions and 2 deletions

View File

@ -4,6 +4,23 @@
Features
* Add support for asdf extension commands.
When a plugin provides custom executables or bash-scripts under its `bin/` directory,
it's now possible to invoke them with:
```shell
asdf nodejs import-release-team-keyring
# instead of people having to know where the executable is installed:
~/.asdf/plugins/nodejs/bin/import-release-team-keyring
```
As in nodejs case, plugin authors can use this feature to provide utilities,
or people can create plugins that are just extensions to asdf itself.
See `docs/plugins-create.md` for more info.
* Add support for installing the latest stable version of a tool (#216, #575)
```shell

View File

@ -114,8 +114,23 @@ case "$1" in
"--version")
asdf_version "${cmd_args[@]}";;
*)
"--help")
load_cmd "help"
help_command
help_command;;
*)
plugin_cmd="$(get_plugin_path "$1")/bin/${cmd_args[0]}"
if [ -x "$plugin_cmd" ]; then
exec "$plugin_cmd" "${cmd_args[@]:1}"
elif [ -f "$plugin_cmd" ]; then
set -- "${cmd_args[@]:1}"
source "$plugin_cmd"
exit $?
fi
echo "Unknown asdf command: \`${*}\`" >&2
load_cmd "help"
help_command >&2
exit 1;;
esac

View File

@ -88,6 +88,23 @@ Note: This will only apply for users who have enabled the `legacy_version_file`
This can be used to further parse the legacy file found by asdf. If `parse-legacy-file` isn't implemented, asdf will simply cat the file to determine the version. The script will be passed the file path as its first argument.
## asdf extension commands
It's possible for plugins to define new asdf commands. This way plugins can extend asdf capabilities or expose utilities related to their managed tool.
For example, a `foo` plugin might expose the command `asdf foo bar` by providing an executable file at `bin/bar`.
If `bin/bar` is a file but has no executable bit set, then its considered a source-able bash script, and will be sourced
with all the functions in `$ASDF_DIR/lib/utils.sh` already loaded.
A good example of this feature is the `nodejs` plugin, where people must import the release team keyring before
installing a nodejs version. People can execute the following command without having to know where exactly is the plugin located.
```bash
asdf nodejs import-release-team-keyring
```
If your plugin provides an asdf extension command, be sure to mention about it on your plugin's README.
## Custom shim templates
**PLEASE use this feature only if absolutely required**

View File

@ -0,0 +1,42 @@
#!/usr/bin/env bats
load test_helpers
setup() {
setup_asdf_dir
install_dummy_plugin
}
teardown() {
clean_asdf_dir
}
@test "asdf can execute plugin bin commands" {
plugin_path="$(get_plugin_path dummy)"
# this plugin defines a new `asdf dummy foo` command
cat <<'EOF' > "$plugin_path/bin/foo"
#!/usr/bin/env bash
echo this is an executable $*
EOF
chmod +x "$plugin_path/bin/foo"
expected="this is an executable bar"
run asdf dummy foo bar
[ "$status" -eq 0 ]
[ "$output" = "$expected" ]
}
@test "asdf can source plugin bin scripts" {
plugin_path="$(get_plugin_path dummy)"
# this plugin defines a new `asdf dummy foo` command
echo 'echo sourced script has asdf utils $(get_plugin_path dummy) $*' > "$plugin_path/bin/foo"
expected="sourced script has asdf utils $plugin_path bar"
run asdf dummy foo bar
[ "$status" -eq 0 ]
[ "$output" = "$expected" ]
}