Make sure extension commands are properly displayed by asdf help

This commit is contained in:
Victor Hugo Borja 2020-03-15 11:45:09 -06:00
parent cdb39caf52
commit a26bed6586
5 changed files with 54 additions and 25 deletions

View File

@ -2,6 +2,17 @@
## 0.7.8-dev
Fixed Bugs
* Make sure extension commands are properly displayed by `asdf help`
Extension commands are now expected to be inside plugins's `lib/commands/command-*.bash` instead of `bin/command*`.
This change was made for two reasons: Keep the convention that all files to be sourced by bash should end with
the `.bash` extension. And the `lib/commands/` directoy mirrors the location of asdf own core commands.
Added tests to make sure `asdf help` properly displays available extension commands.
## 0.7.7
Features

View File

@ -49,7 +49,7 @@ find_asdf_cmd() {
find_plugin_cmd() {
local ASDF_CMD_FILE args_offset
if [ -d "$(get_plugin_path "$1")/bin" ]; then
IFS=' ' read -r ASDF_CMD_FILE args_offset <<<"$(find_cmd "$(get_plugin_path "$1")/bin" "${@:2}")"
IFS=' ' read -r ASDF_CMD_FILE args_offset <<<"$(find_cmd "$(get_plugin_path "$1")/lib/commands" "${@:2}")"
if [ -n "$ASDF_CMD_FILE" ]; then
args_offset=$((args_offset + 1)) # since the first argument is the plugin name
echo "$ASDF_CMD_FILE" "$args_offset"

View File

@ -90,14 +90,14 @@ This can be used to further parse the legacy file found by asdf. If `parse-legac
## Extension commands for asdf CLI.
It's possible for plugins to define new asdf commands by providing `bin/command*.bash` scripts or executables that
It's possible for plugins to define new asdf commands by providing `lib/commands/command*.bash` scripts or executables that
will be callable using the asdf command line interface by using the plugin name as a subcommand.
For example, suppose a `foo` plugin has:
```shell
foo/
bin/
lib/commands/
command.bash
command-bat.bash
command-bat-man.bash
@ -107,24 +107,24 @@ foo/
Users can now execute
```shell
$ asdf foo # same as running `$ASDF_DATA_DIR/plugins/foo/bin/command`
$ asdf foo bar # same as running `$ASDF_DATA_DIR/plugins/foo/bin/command bar`
$ asdf foo help # same as running `$ASDF_DATA_DIR/plugins/foo/bin/command-help`
$ asdf foo bat man # same as running `$ASDF_DATA_DIR/plugins/foo/bin/command-bat-man`
$ asdf foo bat baz # same as running `$ASDF_DATA_DIR/plugins/foo/bin/command-bat baz`
$ asdf foo # same as running `$ASDF_DATA_DIR/plugins/foo/lib/commands/command`
$ asdf foo bar # same as running `$ASDF_DATA_DIR/plugins/foo/lib/commands/command bar`
$ asdf foo help # same as running `$ASDF_DATA_DIR/plugins/foo/lib/commands/command-help`
$ asdf foo bat man # same as running `$ASDF_DATA_DIR/plugins/foo/lib/commands/command-bat-man`
$ asdf foo bat baz # same as running `$ASDF_DATA_DIR/plugins/foo/lib/commands/command-bat baz`
```
Plugin authors can use this feature to provide utilities related to their tools,
or even create plugins that are just new command extensions for asdf itself.
When `command*` files exists but have no executable bit set, they are considered to be
bash scripts and will be sourced having all the functions from `$ASDF_DIR/lib/utils.bash`
available. Also, the `$ASDF_CMD_FILE` resolves to the full path of the file being sourced.
When invoked, if extension commands are have not executable-bit set, they will be
sourced as bash scripts, having all of the functions from `$ASDF_DIR/lib/utils.bash` available.
Also, the `$ASDF_CMD_FILE` resolves to the full path of the file being sourced.
If the executable bit is set, they are just executed and replace the asdf execution.
A good example of this feature is for plugins like `nodejs`, where people must import the release team keyring before
installing a nodejs version. Authors can provide a handy extension command for this without users
having to know where exactly is the plugin was installed.
A good example of this feature is for plugins like [`haxe`](https://github.com/asdf-community/asdf-haxe)
which provides the `asdf haxe neko-dylibs-link` to fix an issue where haxe executables expect to find
dynamic libraries relative to the executable directory.
If your plugin provides an asdf extension command, be sure to mention about it on your plugin's README.

View File

@ -15,16 +15,17 @@ EOF
}
asdf_extension_cmds() {
local plugins_path ext_cmds
local plugins_path ext_cmds plugin
plugins_path="$(get_plugin_path)"
# use find instead of ls -1
# shellcheck disable=SC2012
ext_cmds="$(ls -1 "$plugins_path"/*/bin/command* 2>/dev/null | sed "s#$plugins_path/# asdf #;"'s#/bin/command##g;s#-# #g')"
ext_cmds="$(ls -1 "$plugins_path"/*/lib/commands/command*.bash 2>/dev/null |
sed "s#^$plugins_path/##;s#lib/commands/command##;s/.bash//;s/^-//;s/-/ /g")"
if test -n "$ext_cmds"; then
echo "$ext_cmds" | cut -d' ' -f 4 | uniq | while read -r plugin; do
echo "$ext_cmds" | cut -d'/' -f 1 | uniq | while read -r plugin; do
echo
echo "PLUGIN $plugin"
echo "$ext_cmds" | grep " asdf $plugin"
echo "$ext_cmds" | grep "$plugin/" | sed "s#^$plugin/# asdf $plugin#" | sort
done
fi
}

View File

@ -5,21 +5,38 @@ load test_helpers
setup() {
setup_asdf_dir
install_dummy_plugin
local plugin_path
plugin_path="$(get_plugin_path dummy)"
mkdir -p "$plugin_path/lib/commands"
}
teardown() {
clean_asdf_dir
}
@test "asdf help shows plugin extension commands" {
local plugin_path listed_cmds
plugin_path="$(get_plugin_path dummy)"
touch "$plugin_path/lib/commands/command.bash"
touch "$plugin_path/lib/commands/command-foo.bash"
touch "$plugin_path/lib/commands/command-foo-bar.bash"
run asdf help
[ "$status" -eq 0 ]
echo "$output" | grep "PLUGIN dummy" # should present plugin section
listed_cmds=$(echo "$output" | grep "asdf dummy" | wc -l)
[ "$listed_cmds" -eq 3 ]
echo "$output" | grep "asdf dummy foo bar" # should present commands without hipens
}
@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/command-foo.bash"
cat <<'EOF' > "$plugin_path/lib/commands/command-foo.bash"
#!/usr/bin/env bash
echo this is an executable $*
EOF
chmod +x "$plugin_path/bin/command-foo.bash"
chmod +x "$plugin_path/lib/commands/command-foo.bash"
expected="this is an executable bar"
@ -32,7 +49,7 @@ EOF
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/command-foo.bash"
echo 'echo sourced script has asdf utils $(get_plugin_path dummy) $*' > "$plugin_path/lib/commands/command-foo.bash"
expected="sourced script has asdf utils $plugin_path bar"
@ -45,11 +62,11 @@ EOF
plugin_path="$(get_plugin_path dummy)"
# this plugin defines a new `asdf dummy` command
cat <<'EOF' > "$plugin_path/bin/command.bash"
cat <<'EOF' > "$plugin_path/lib/commands/command.bash"
#!/usr/bin/env bash
echo hello
EOF
chmod +x "$plugin_path/bin/command.bash"
chmod +x "$plugin_path/lib/commands/command.bash"
expected="hello"
@ -62,11 +79,11 @@ EOF
plugin_path="$(get_plugin_path dummy)"
# this plugin defines a new `asdf dummy` command
cat <<'EOF' > "$plugin_path/bin/command.bash"
cat <<'EOF' > "$plugin_path/lib/commands/command.bash"
#!/usr/bin/env bash
echo hello $*
EOF
chmod +x "$plugin_path/bin/command.bash"
chmod +x "$plugin_path/lib/commands/command.bash"
expected="hello world"