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 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) * Add support for installing the latest stable version of a tool (#216, #575)
```shell ```shell

View File

@ -114,8 +114,23 @@ case "$1" in
"--version") "--version")
asdf_version "${cmd_args[@]}";; asdf_version "${cmd_args[@]}";;
*) "--help")
load_cmd "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;; exit 1;;
esac 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. 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 ## Custom shim templates
**PLEASE use this feature only if absolutely required** **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" ]
}