Skip to content

Commit

Permalink
Merge pull request #669 from asdf-vm/tb/keep-source
Browse files Browse the repository at this point in the history
Keep Source
  • Loading branch information
Stratus3D committed May 14, 2020
2 parents a907935 + 410f414 commit a7252e6
Show file tree
Hide file tree
Showing 15 changed files with 253 additions and 3 deletions.
1 change: 1 addition & 0 deletions docs/core-configuration.md
Expand Up @@ -42,6 +42,7 @@ legacy_version_file = yes

- `legacy_version_file` - defaults to `no`. If set to yes it will cause plugins that support this feature to read the version files used by other version managers (e.g. `.ruby-version` in the case of Ruby's `rbenv`).
- `use_release_candidates` - defaults to `no`. If set to yes it will cause the `asdf update` command to upgrade to the latest release candidate release instead of the latest semantic version.
- `always_keep_download` - defaults to `no`. If set to `yes` it will cause `asdf install` always keep the source code or binary it downloads. If set to `no` the source code or binary downloaded by `asdf install` will be deleted after successful installation.

## Environment Variables

Expand Down
20 changes: 19 additions & 1 deletion docs/plugins-create.md
Expand Up @@ -5,17 +5,25 @@ A plugin is a git repo, with a couple executable scripts, to support versioning
## Required Scripts

- `bin/list-all` - lists all installable versions
- `bin/download` - download source code or binary for the specified version
- `bin/install` - installs the specified version

## Environment Variables

All scripts except `bin/list-all` will have access to the following env vars to act upon:

- `ASDF_INSTALL_TYPE` - `version` or `ref`
- `ASDF_INSTALL_VERSION` - if `ASDF_INSTALL_TYPE` is `version` then this will be the version number. Else it will be the git ref that is passed. Might point to a tag/commit/branch on the repo.
- `ASDF_INSTALL_PATH` - the dir where the it _has been_ installed (or _should_ be installed in case of the `bin/install` script)

These additional environment variables the `bin/install` script will also have accesss to:
These additional environment variables will be available to the `bin/install` script:

- `ASDF_CONCURRENCY` - the number of cores to use when compiling the source code. Useful for setting `make -j`.
- `ASDF_DOWNLOAD_PATH` - the path to where the source code or binary was downloaded by the `bin/download` script.

These additional environment variables will be available to the `bin/download` script:

- `ASDF_DOWNLOAD_PATH` - the path to where the source code or binary should be downloaded.

#### bin/list-all

Expand All @@ -29,6 +37,16 @@ Note that the newest version should be listed last so it appears closer to the u

If versions are being pulled from releases page on a website it's recommended to not sort the versions if at all possible. Often the versions are already in the correct order or, in reverse order, in which case something like `tac` should suffice. If you must sort versions manually you cannot rely on `sort -V` since it is not supported on OSX. An alternate sort function [like this is a better choice](https://github.com/vic/asdf-idris/blob/master/bin/list-all#L6).

#### bin/download

This script must download the source or binary, in the path contained in the `ASDF_DOWNLOAD_PATH` environment variable. If the downloaded source or binary is compressed, only the uncompressed source code or binary may be placed in the `ASDF_DOWNLOAD_PATH` directory.

The script must exit with a status of `0` when the download is successful. If the download fails the script must exit with any non-zero exit status.

If possible the script should only place files in the `ASDF_DOWNLOAD_PATH`. If the download fails no files should be placed in the directory.

If this script is not present asdf will assume that the `bin/install` script is present and will download and install the version. asdf only works without this script to support legacy plugins. All plugins must include this script, and eventually support for legacy plugins will be removed.

#### bin/install

This script should install the version, in the path mentioned in `ASDF_INSTALL_PATH`.
Expand Down
54 changes: 52 additions & 2 deletions lib/commands/command-install.bash
Expand Up @@ -15,14 +15,15 @@ handle_cancel() {
install_command() {
local plugin_name=$1
local full_version=$2
local extra_args="${*:3}"

if [ "$plugin_name" = "" ] && [ "$full_version" = "" ]; then
install_local_tool_versions
install_local_tool_versions "$extra_args"
elif [[ $# -eq 1 ]]; then
display_error "You must specify a name and a version to install"
exit 1
else
install_tool_version "$plugin_name" "$full_version"
install_tool_version "$plugin_name" "$full_version" "$extra_args"
fi
}

Expand Down Expand Up @@ -80,10 +81,25 @@ install_local_tool_versions() {
install_tool_version() {
local plugin_name=$1
local full_version=$2
local flags=$3
local keep_download
local plugin_path

plugin_path=$(get_plugin_path "$plugin_name")
check_if_plugin_exists "$plugin_name"

for flag in $flags; do
case "$flag" in
"--keep-download")
keep_download=true
shift
;;
*)
shift
;;
esac
done

if [ "$full_version" = "system" ]; then
return
fi
Expand All @@ -106,17 +122,44 @@ install_tool_version() {

local install_path
install_path=$(get_install_path "$plugin_name" "$install_type" "$version")
local download_path
download_path=$(get_download_path "$plugin_name" "$install_type" "$version")
local concurrency
concurrency=$(get_concurrency)
trap 'handle_cancel $install_path' INT

if [ -d "$install_path" ]; then
echo "$plugin_name $full_version is already installed"
else

if [ -f "${plugin_path}/bin/download" ]; then
# Not a legacy plugin
# Run the download script
(
# shellcheck disable=SC2030
export ASDF_INSTALL_TYPE=$install_type
# shellcheck disable=SC2030
export ASDF_INSTALL_VERSION=$version
# shellcheck disable=SC2030
export ASDF_INSTALL_PATH=$install_path
# shellcheck disable=SC2030
export ASDF_DOWNLOAD_PATH=$download_path
mkdir "$download_path"
asdf_run_hook "pre_asdf_download_${plugin_name}" "$full_version"
bash "${plugin_path}"/bin/download
)
fi

(
# shellcheck disable=SC2031
export ASDF_INSTALL_TYPE=$install_type
# shellcheck disable=SC2031
export ASDF_INSTALL_VERSION=$version
# shellcheck disable=SC2031
export ASDF_INSTALL_PATH=$install_path
# shellcheck disable=SC2031
export ASDF_DOWNLOAD_PATH=$download_path
# shellcheck disable=SC2031
export ASDF_CONCURRENCY=$concurrency
mkdir "$install_path"
asdf_run_hook "pre_asdf_install_${plugin_name}" "$full_version"
Expand All @@ -125,7 +168,14 @@ install_tool_version() {

local exit_code=$?
if [ $exit_code -eq 0 ]; then
# Remove download directory if --keep-download flag or always_keep_download config setting are not set
always_keep_download=$(get_asdf_config_value "always_keep_download")
if [ ! "$keep_download" = "true" ] && [ ! "$always_keep_download" = "yes" ] && [ -d "$download_path" ]; then
rm -r "$download_path"
fi

asdf reshim "$plugin_name" "$full_version"

asdf_run_hook "post_asdf_install_${plugin_name}" "$full_version"
else
handle_failure "$install_path"
Expand Down
1 change: 1 addition & 0 deletions lib/commands/command-plugin-remove.bash
Expand Up @@ -19,6 +19,7 @@ plugin_remove_command() {

rm -rf "$plugin_path"
rm -rf "$(asdf_data_dir)/installs/${plugin_name}"
rm -rf "$(asdf_data_dir)/downloads/${plugin_name}"

grep -l "asdf-plugin: ${plugin_name}" "$(asdf_data_dir)"/shims/* 2>/dev/null | xargs rm -f

Expand Down
19 changes: 19 additions & 0 deletions lib/utils.bash
Expand Up @@ -67,6 +67,25 @@ get_install_path() {
fi
}

get_download_path() {
local plugin=$1
local install_type=$2
local version=$3

local download_dir
download_dir="$(asdf_data_dir)/downloads"

mkdir -p "${download_dir}/${plugin}"

if [ "$install_type" = "version" ]; then
echo "${download_dir}/${plugin}/${version}"
elif [ "$install_type" = "path" ]; then
return
else
echo "${download_dir}/${plugin}/${install_type}-${version}"
fi
}

list_installed_versions() {
local plugin_name=$1
local plugin_path
Expand Down
12 changes: 12 additions & 0 deletions test/fixtures/dummy_legacy_plugin/bin/get-version-from-legacy-file
@@ -0,0 +1,12 @@
#!/usr/bin/env bash

get_legacy_version() {
current_directory=$1
version_file="$current_directory/.dummy-version"

if [ -f "$version_file" ]; then
cat "$version_file"
fi
}

get_legacy_version "$1"
17 changes: 17 additions & 0 deletions test/fixtures/dummy_legacy_plugin/bin/install
@@ -0,0 +1,17 @@
#!/usr/bin/env bash

mkdir -p "$ASDF_INSTALL_PATH"
env >"$ASDF_INSTALL_PATH/env"
echo "$ASDF_INSTALL_VERSION" >"$ASDF_INSTALL_PATH/version"

# create the dummy executable
mkdir -p "$ASDF_INSTALL_PATH/bin"
cat <<EOF >"$ASDF_INSTALL_PATH/bin/dummy"
echo This is Dummy ${ASDF_INSTALL_VERSION}! \$2 \$1
EOF
chmod +x "$ASDF_INSTALL_PATH/bin/dummy"
mkdir -p "$ASDF_INSTALL_PATH/bin/subdir"
cat <<EOF >"$ASDF_INSTALL_PATH/bin/subdir/other_bin"
echo This is Other Bin ${ASDF_INSTALL_VERSION}! \$2 \$1
EOF
chmod +x "$ASDF_INSTALL_PATH/bin/subdir/other_bin"
4 changes: 4 additions & 0 deletions test/fixtures/dummy_legacy_plugin/bin/list-all
@@ -0,0 +1,4 @@
#!/usr/bin/env bash

versions_list=(1.0 1.1 2.0)
echo "${versions_list[@]}"
3 changes: 3 additions & 0 deletions test/fixtures/dummy_legacy_plugin/bin/list-legacy-filenames
@@ -0,0 +1,3 @@
#!/usr/bin/env bash

echo ".dummy-version .dummyrc"
4 changes: 4 additions & 0 deletions test/fixtures/dummy_legacy_plugin/bin/parse-legacy-file
@@ -0,0 +1,4 @@
#!/usr/bin/env bash

# shellcheck disable=SC2020
tr <"$1" -d "dummy-"
3 changes: 3 additions & 0 deletions test/fixtures/dummy_plugin/bin/download
@@ -0,0 +1,3 @@
#!/usr/bin/env bash

exit 0
38 changes: 38 additions & 0 deletions test/install_command.bats
Expand Up @@ -4,6 +4,7 @@ load test_helpers

setup() {
setup_asdf_dir
install_dummy_legacy_plugin
install_dummy_plugin

PROJECT_DIR=$HOME/project
Expand All @@ -20,6 +21,12 @@ teardown() {
[ $(cat $ASDF_DIR/installs/dummy/1.1/version) = "1.1" ]
}

@test "install_command installs the correct version for plugins without download script" {
run asdf install legacy-dummy 1.1
[ "$status" -eq 0 ]
[ $(cat $ASDF_DIR/installs/legacy-dummy/1.1/version) = "1.1" ]
}

@test "install_command without arguments installs even if the user is terrible and does not use newlines" {
cd $PROJECT_DIR
echo -n 'dummy 1.2' > ".tool-versions"
Expand Down Expand Up @@ -56,6 +63,14 @@ teardown() {
[ "$status" -eq 0 ]
}

@test "install_command should create a shim with asdf-plugin metadata for plugins without download script" {
run asdf install legacy-dummy 1.0
[ "$status" -eq 0 ]
[ -f $ASDF_DIR/installs/legacy-dummy/1.0/env ]
run grep "asdf-plugin: legacy-dummy 1.0" $ASDF_DIR/shims/dummy
[ "$status" -eq 0 ]
}

@test "install_command on two versions should create a shim with asdf-plugin metadata" {
run asdf install dummy 1.1
[ "$status" -eq 0 ]
Expand Down Expand Up @@ -200,3 +215,26 @@ EOM
[ "$status" -eq 0 ]
[ $(cat $ASDF_DIR/installs/dummy/1.1/version) = "1.1" ]
}

@test "install_command deletes the download directory" {
run asdf install dummy 1.1
[ "$status" -eq 0 ]
[ ! -d $ASDF_DIR/downloads/dummy/1.1 ]
[ $(cat $ASDF_DIR/installs/dummy/1.1/version) = "1.1" ]
}

@test "install_command keeps the download directory when --keep-download flag is provided" {
run asdf install dummy 1.1 --keep-download
[ "$status" -eq 0 ]
[ -d $ASDF_DIR/downloads/dummy/1.1 ]
[ $(cat $ASDF_DIR/installs/dummy/1.1/version) = "1.1" ]
}

@test "install_command keeps the download directory when always_keep_download setting is true" {
echo 'always_keep_download = yes' > $HOME/.asdfrc
run asdf install dummy 1.1
echo $output
[ "$status" -eq 0 ]
[ -d $ASDF_DIR/downloads/dummy/1.1 ]
[ $(cat $ASDF_DIR/installs/dummy/1.1/version) = "1.1" ]
}
29 changes: 29 additions & 0 deletions test/plugin_remove_command.bats
@@ -0,0 +1,29 @@
#!/usr/bin/env bats

load test_helpers

setup() {
setup_asdf_dir
install_dummy_plugin
}

teardown() {
clean_asdf_dir
}

@test "plugin_remove command removes the plugin directory" {
run asdf install dummy 1.0
[ "$status" -eq 0 ]
[ -d "$ASDF_DIR/downloads/dummy" ]


run asdf plugin-remove "dummy"
[ "$status" -eq 0 ]
[ ! -d "$ASDF_DIR/downloads/dummy" ]
}

@test "plugin_remove command fails if the plugin doesn't exist" {
run asdf plugin-remove "does-not-exist"
[ "$status" -eq 1 ]
echo "$output" | grep "No such plugin: does-not-exist"
}
10 changes: 10 additions & 0 deletions test/test_helpers.bash
Expand Up @@ -27,6 +27,12 @@ install_mock_plugin() {
cp -r "$BATS_TEST_DIRNAME/fixtures/dummy_plugin" "$location/plugins/$plugin_name"
}

install_mock_legacy_plugin() {
local plugin_name=$1
local location="${2:-$ASDF_DIR}"
cp -r "$BATS_TEST_DIRNAME/fixtures/dummy_legacy_plugin" "$location/plugins/$plugin_name"
}

install_mock_plugin_repo() {
local plugin_name=$1
local location="${BASE_DIR}/repo-${plugin_name}"
Expand All @@ -49,6 +55,10 @@ install_dummy_plugin() {
install_mock_plugin "dummy"
}

install_dummy_legacy_plugin() {
install_mock_legacy_plugin "legacy-dummy"
}

install_dummy_version() {
install_mock_plugin_version "dummy" "$1"
}
Expand Down

0 comments on commit a7252e6

Please sign in to comment.