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 ## 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 ## 0.7.7
Features Features

View File

@ -49,7 +49,7 @@ find_asdf_cmd() {
find_plugin_cmd() { find_plugin_cmd() {
local ASDF_CMD_FILE args_offset local ASDF_CMD_FILE args_offset
if [ -d "$(get_plugin_path "$1")/bin" ]; then 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 if [ -n "$ASDF_CMD_FILE" ]; then
args_offset=$((args_offset + 1)) # since the first argument is the plugin name args_offset=$((args_offset + 1)) # since the first argument is the plugin name
echo "$ASDF_CMD_FILE" "$args_offset" 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. ## 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. will be callable using the asdf command line interface by using the plugin name as a subcommand.
For example, suppose a `foo` plugin has: For example, suppose a `foo` plugin has:
```shell ```shell
foo/ foo/
bin/ lib/commands/
command.bash command.bash
command-bat.bash command-bat.bash
command-bat-man.bash command-bat-man.bash
@ -107,24 +107,24 @@ foo/
Users can now execute Users can now execute
```shell ```shell
$ asdf foo # same as running `$ASDF_DATA_DIR/plugins/foo/bin/command` $ asdf foo # same as running `$ASDF_DATA_DIR/plugins/foo/lib/commands/command`
$ asdf foo bar # same as running `$ASDF_DATA_DIR/plugins/foo/bin/command bar` $ 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/bin/command-help` $ 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/bin/command-bat-man` $ 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/bin/command-bat baz` $ 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, 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. 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 When invoked, if extension commands are have not executable-bit set, they will be
bash scripts and will be sourced having all the functions from `$ASDF_DIR/lib/utils.bash` sourced as bash scripts, having all of the functions from `$ASDF_DIR/lib/utils.bash` available.
available. Also, the `$ASDF_CMD_FILE` resolves to the full path of the file being sourced. 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. 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 A good example of this feature is for plugins like [`haxe`](https://github.com/asdf-community/asdf-haxe)
installing a nodejs version. Authors can provide a handy extension command for this without users which provides the `asdf haxe neko-dylibs-link` to fix an issue where haxe executables expect to find
having to know where exactly is the plugin was installed. 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. 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() { asdf_extension_cmds() {
local plugins_path ext_cmds local plugins_path ext_cmds plugin
plugins_path="$(get_plugin_path)" plugins_path="$(get_plugin_path)"
# use find instead of ls -1 # use find instead of ls -1
# shellcheck disable=SC2012 # 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 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
echo "PLUGIN $plugin" echo "PLUGIN $plugin"
echo "$ext_cmds" | grep " asdf $plugin" echo "$ext_cmds" | grep "$plugin/" | sed "s#^$plugin/# asdf $plugin#" | sort
done done
fi fi
} }

View File

@ -5,21 +5,38 @@ load test_helpers
setup() { setup() {
setup_asdf_dir setup_asdf_dir
install_dummy_plugin install_dummy_plugin
local plugin_path
plugin_path="$(get_plugin_path dummy)"
mkdir -p "$plugin_path/lib/commands"
} }
teardown() { teardown() {
clean_asdf_dir 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" { @test "asdf can execute plugin bin commands" {
plugin_path="$(get_plugin_path dummy)" plugin_path="$(get_plugin_path dummy)"
# this plugin defines a new `asdf dummy foo` command # 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 #!/usr/bin/env bash
echo this is an executable $* echo this is an executable $*
EOF EOF
chmod +x "$plugin_path/bin/command-foo.bash" chmod +x "$plugin_path/lib/commands/command-foo.bash"
expected="this is an executable bar" expected="this is an executable bar"
@ -32,7 +49,7 @@ EOF
plugin_path="$(get_plugin_path dummy)" plugin_path="$(get_plugin_path dummy)"
# this plugin defines a new `asdf dummy foo` command # 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" expected="sourced script has asdf utils $plugin_path bar"
@ -45,11 +62,11 @@ EOF
plugin_path="$(get_plugin_path dummy)" plugin_path="$(get_plugin_path dummy)"
# this plugin defines a new `asdf dummy` command # 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 #!/usr/bin/env bash
echo hello echo hello
EOF EOF
chmod +x "$plugin_path/bin/command.bash" chmod +x "$plugin_path/lib/commands/command.bash"
expected="hello" expected="hello"
@ -62,11 +79,11 @@ EOF
plugin_path="$(get_plugin_path dummy)" plugin_path="$(get_plugin_path dummy)"
# this plugin defines a new `asdf dummy` command # 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 #!/usr/bin/env bash
echo hello $* echo hello $*
EOF EOF
chmod +x "$plugin_path/bin/command.bash" chmod +x "$plugin_path/lib/commands/command.bash"
expected="hello world" expected="hello world"