From 456d8e36ca76b36b848453a63b54ffeb214bce7e Mon Sep 17 00:00:00 2001 From: James Hegedus Date: Tue, 2 Mar 2021 17:37:05 +1100 Subject: [PATCH] fix: to latest commit on default branch for each plugin (#800) --- help.txt | 7 +- lib/commands/command-plugin-update.bash | 19 +++--- test/plugin_update_command.bats | 85 +++++++++++++++++++------ test/test_helpers.bash | 2 +- 4 files changed, 82 insertions(+), 31 deletions(-) diff --git a/help.txt b/help.txt index cb2acce4..3812e05b 100644 --- a/help.txt +++ b/help.txt @@ -7,9 +7,10 @@ asdf plugin list [--urls] [--refs] List installed plugins. Optionally show asdf plugin list all List plugins registered on asdf-plugins repository with URLs asdf plugin remove Remove plugin and package versions -asdf plugin update [] Update a plugin to latest commit or a - particular git-ref -asdf plugin update --all Update all plugins +asdf plugin update [] Update a plugin to latest commit on + default branch or a particular git-ref +asdf plugin update --all Update all plugins to latest commit on + default branch MANAGE PACKAGES diff --git a/lib/commands/command-plugin-update.bash b/lib/commands/command-plugin-update.bash index bea52f01..0f80b832 100644 --- a/lib/commands/command-plugin-update.bash +++ b/lib/commands/command-plugin-update.bash @@ -2,18 +2,17 @@ plugin_update_command() { if [ "$#" -lt 1 ]; then - display_error "usage: asdf plugin-update { | --all} [git-ref]" + display_error "usage: asdf plugin-update { [git-ref] | --all}" exit 1 fi local plugin_name="$1" - local gitref="${2:-master}" + local gitref="${2}" + if [ "$plugin_name" = "--all" ]; then if [ -d "$(asdf_data_dir)"/plugins ]; then - while IFS= read -r -d '' dir; do - local plugin_name - plugin_name=$(basename "$dir") - update_plugin "$plugin_name" "$dir" "$gitref" & + while IFS= read -r dir; do + update_plugin "$(basename "$dir")" "$dir" "$gitref" & done < <(find "$(asdf_data_dir)"/plugins -mindepth 1 -maxdepth 1 -type d) wait fi @@ -28,11 +27,13 @@ plugin_update_command() { update_plugin() { local plugin_name=$1 local plugin_path=$2 - local gitref=$3 + plugin_remote_default_branch=$(git --git-dir "$plugin_path/.git" --work-tree "$plugin_path" ls-remote --symref origin HEAD | awk -F'[[:space:]]*' 'NR == 1 {sub(/refs\/heads\//, "", $2); print $2}') + local gitref=${3:-${plugin_remote_default_branch}} logfile=$(mktemp) { - printf "Updating %s...\\n" "$plugin_name" - (cd "$plugin_path" && git fetch -p -u origin "$gitref:$gitref" && git checkout -f "$gitref") + printf "Updating %s to %s\\n" "$plugin_name" "$gitref" + git --git-dir "$plugin_path/.git" --work-tree "$plugin_path" fetch --prune --update-head-ok origin "$gitref:$gitref" + git --git-dir "$plugin_path/.git" --work-tree "$plugin_path" -c advice.detachedHead=false checkout --force "$gitref" } >"$logfile" 2>&1 cat "$logfile" rm "$logfile" diff --git a/test/plugin_update_command.bats b/test/plugin_update_command.bats index 6195b951..24d79a61 100644 --- a/test/plugin_update_command.bats +++ b/test/plugin_update_command.bats @@ -3,32 +3,81 @@ load test_helpers setup() { - BASE_DIR=$(mktemp -dt asdf.XXXX) - HOME=$BASE_DIR/home - ASDF_DIR=$HOME/.asdf - git clone -o local "$(dirname "$BATS_TEST_DIRNAME")" "$ASDF_DIR" - git --git-dir "$ASDF_DIR/.git" remote add origin https://github.com/asdf-vm/asdf.git - mkdir -p "$ASDF_DIR/plugins" - ASDF_BIN="$ASDF_DIR/bin" - - # shellcheck disable=SC2031 - PATH=$ASDF_BIN:$ASDF_DIR/shims:$PATH - install_dummy_plugin - - PROJECT_DIR=$HOME/project - mkdir $PROJECT_DIR + setup_asdf_dir + install_mock_plugin_repo "dummy" + run asdf plugin-add "dummy" "${BASE_DIR}/repo-dummy" } teardown() { clean_asdf_dir } -@test "asdf plugin-update should pull latest master branch for plugin" { +@test "asdf plugin-update should pull latest default branch (refs/remotes/origin/HEAD) for plugin" { run asdf plugin-update dummy + repo_head="$(git --git-dir "$ASDF_DIR/plugins/dummy/.git" --work-tree "$ASDF_DIR/plugins/dummy" rev-parse --abbrev-ref HEAD)" [ "$status" -eq 0 ] - [[ "$output" =~ "Updating dummy..."* ]] - cd $ASDF_DIR/plugins/dummy - [ $(git rev-parse --abbrev-ref HEAD) = "master" ] + [[ "$output" =~ "Updating dummy to master"* ]] + [ "$repo_head" = "master" ] +} + +@test "asdf plugin-update should pull latest default branch (refs/remotes/origin/HEAD) for plugin even if default branch changes" { + install_mock_plugin_repo "dummy-remote" + remote_dir="$BASE_DIR/repo-dummy-remote" + # set HEAD to refs/head/main in dummy-remote + git -C "${remote_dir}" checkout -b main + # track & fetch remote repo (dummy-remote) in plugin (dummy) + git --git-dir "$ASDF_DIR/plugins/dummy/.git" --work-tree "$ASDF_DIR/plugins/dummy" remote remove origin + git --git-dir "$ASDF_DIR/plugins/dummy/.git" --work-tree "$ASDF_DIR/plugins/dummy" remote add origin "$remote_dir" + git --git-dir "$ASDF_DIR/plugins/dummy/.git" --work-tree "$ASDF_DIR/plugins/dummy" fetch origin + + run asdf plugin-update dummy + repo_head="$(git --git-dir "$ASDF_DIR/plugins/dummy/.git" --work-tree "$ASDF_DIR/plugins/dummy" rev-parse --abbrev-ref HEAD)" + + [ "$status" -eq 0 ] + [[ "$output" =~ "Updating dummy to main"* ]] + [ "$repo_head" = "main" ] +} + +@test "asdf plugin-update should pull latest default branch (refs/remotes/origin/HEAD) for plugin even if the default branch contains a forward slash" { + install_mock_plugin_repo "dummy-remote" + remote_dir="$BASE_DIR/repo-dummy-remote" + # set HEAD to refs/head/my/default in dummy-remote + git -C "${remote_dir}" checkout -b my/default + # track & fetch remote repo (dummy-remote) in plugin (dummy) + git --git-dir "$ASDF_DIR/plugins/dummy/.git" --work-tree "$ASDF_DIR/plugins/dummy" remote remove origin + git --git-dir "$ASDF_DIR/plugins/dummy/.git" --work-tree "$ASDF_DIR/plugins/dummy" remote add origin "$remote_dir" + git --git-dir "$ASDF_DIR/plugins/dummy/.git" --work-tree "$ASDF_DIR/plugins/dummy" fetch origin + + run asdf plugin-update dummy + repo_head="$(git --git-dir "$ASDF_DIR/plugins/dummy/.git" --work-tree "$ASDF_DIR/plugins/dummy" rev-parse --abbrev-ref HEAD)" + + [ "$status" -eq 0 ] + [[ "$output" =~ "Updating dummy to my/default"* ]] + [ "$repo_head" = "my/default" ] +} + +@test "asdf plugin-update should pull latest default branch (refs/remotes/origin/HEAD) for plugin even if already set to specific ref" { + # set plugin to specific sha + current_sha="$(git --git-dir "${BASE_DIR}/repo-dummy/.git" --work-tree "$BASE_DIR/repo-dummy" rev-parse HEAD)" + run asdf plugin-update dummy "${current_sha}" + + # setup mock plugin remote + install_mock_plugin_repo "dummy-remote" + remote_dir="$BASE_DIR/repo-dummy-remote" + # set HEAD to refs/head/main in dummy-remote + git -C "${remote_dir}" checkout -b main + # track & fetch remote repo (dummy-remote) in plugin (dummy) + git --git-dir "$ASDF_DIR/plugins/dummy/.git" --work-tree "$ASDF_DIR/plugins/dummy" remote remove origin + git --git-dir "$ASDF_DIR/plugins/dummy/.git" --work-tree "$ASDF_DIR/plugins/dummy" remote add origin "$remote_dir" + git --git-dir "$ASDF_DIR/plugins/dummy/.git" --work-tree "$ASDF_DIR/plugins/dummy" fetch origin + + # update plugin to the default branch + run asdf plugin-update dummy + repo_head="$(git --git-dir "$ASDF_DIR/plugins/dummy/.git" --work-tree "$ASDF_DIR/plugins/dummy" rev-parse --abbrev-ref HEAD)" + + [ "$status" -eq 0 ] + [[ "$output" =~ "Updating dummy to main"* ]] + [ "$repo_head" = "main" ] } @test "asdf plugin-update should not remove plugin versions" { diff --git a/test/test_helpers.bash b/test/test_helpers.bash index de6d40a0..0e0fb4f2 100644 --- a/test/test_helpers.bash +++ b/test/test_helpers.bash @@ -41,7 +41,7 @@ install_mock_plugin_repo() { git -C "${location}" config user.name "Test" git -C "${location}" config user.email "test@example.com" git -C "${location}" add -A - git -C "${location}" commit -q -m 'asdf dummy plugin' + git -C "${location}" commit -q -m "asdf ${plugin_name} plugin" } install_mock_plugin_version() {