From a26bed6586119324f81a1595c46930ef8713b88b Mon Sep 17 00:00:00 2001 From: Victor Hugo Borja Date: Sun, 15 Mar 2020 11:45:09 -0600 Subject: [PATCH] Make sure extension commands are properly displayed by `asdf help` --- CHANGELOG.md | 11 +++++++++++ bin/asdf | 2 +- docs/plugins-create.md | 26 ++++++++++++------------- lib/commands/command-help.bash | 9 +++++---- test/plugin_extension_command.bats | 31 +++++++++++++++++++++++------- 5 files changed, 54 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bccad2b0..f11c3f11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/bin/asdf b/bin/asdf index 8f69384f..efc2c7f1 100755 --- a/bin/asdf +++ b/bin/asdf @@ -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" diff --git a/docs/plugins-create.md b/docs/plugins-create.md index 5e85b0d7..4610691e 100644 --- a/docs/plugins-create.md +++ b/docs/plugins-create.md @@ -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. diff --git a/lib/commands/command-help.bash b/lib/commands/command-help.bash index a464d4c9..fcb8d483 100644 --- a/lib/commands/command-help.bash +++ b/lib/commands/command-help.bash @@ -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 } diff --git a/test/plugin_extension_command.bats b/test/plugin_extension_command.bats index 77743f80..5d3dff71 100644 --- a/test/plugin_extension_command.bats +++ b/test/plugin_extension_command.bats @@ -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"