Skip to content

Commit

Permalink
feat: faster list-all, move single-command functions out of lib/utils…
Browse files Browse the repository at this point in the history
….bash

speedup from asdf-vm/asdf-plugin-template#58
  • Loading branch information
MetricMike committed Apr 24, 2023
1 parent e1a842c commit 9082ae6
Show file tree
Hide file tree
Showing 4 changed files with 239 additions and 200 deletions.
64 changes: 63 additions & 1 deletion bin/download
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,72 @@ current_script_path=${BASH_SOURCE[0]}
plugin_dir=$(dirname "$(dirname "${current_script_path}")")

# shellcheck source=../lib/utils.bash
source "${plugin_dir}/lib/utils.bash"
. "${plugin_dir}/lib/utils.bash"

TOOL_NAME="awscli"
CURL_OPTS=(-fsSL)

mkdir -p "${ASDF_DOWNLOAD_PATH}"

download_source() {
local version download_path major_version os_distribution
version="$1"
download_path="$2"
major_version="${version:0:1}"

if [[ "${major_version}" = "2" ]]; then
source_url="https://awscli.amazonaws.com/awscli-${version}.tar.gz"
filename="awscli.tar.gz"
source_file="${download_path}/${filename}"
curl "${CURL_OPTS[@]}" -o "${source_file}" -C - "${source_url}" || fail "Could not download ${source_url}"
tar -xzf "${source_file}" -C "${download_path}" --strip-components=1 || fail "Could not extract ${source_file}"
rm "${source_file}"
else
fail "asdf-${TOOL_NAME} does not support downloading from source for major version v${major_version}"
fi
}

download_release() {
local version download_path major_version os_distribution os_arch
version="$1"
download_path="$2"
major_version="${version:0:1}"

if [[ "${major_version}" = "1" ]]; then
release_url="https://s3.amazonaws.com/aws-cli/awscli-bundle-${version}.zip"
filename="awscli-bundle.zip"
elif [[ "${major_version}" = "2" ]]; then
os_distribution="$(uname -s)"
os_arch="$(uname -m)"

if [[ "${os_distribution}" = "Linux" ]]; then
if [[ "${os_arch}" = "x86_64" || "${os_arch}" = "aarch64" ]]; then
release_url="https://awscli.amazonaws.com/awscli-exe-linux-${os_arch}-${version}.zip"
filename="awscliv2.zip"
else
fail "asdf-${TOOL_NAME} does not support ${os_arch} on ${os_distribution}"
fi
elif [[ "${os_distribution}" = "Darwin" ]]; then
release_url="https://awscli.amazonaws.com/AWSCLIV2-${version}.pkg"
filename="AWSCLIV2.pkg"
# elif [[ "${os_distribution}" = "Windows_NT" ]]; then
# release_url="https://awscli.amazonaws.com/AWSCLIV2-${version}.msi"
# filename="AWSCLIV2.msi"
else
fail "asdf-${TOOL_NAME} does not support OS distribution ${os_distribution}"
fi
else
fail "asdf-${TOOL_NAME} does not support major version v${version}"
fi

release_file="${download_path}/${filename}"
curl "${CURL_OPTS[@]}" -o "${release_file}" "${release_url}" || fail "Could not download ${release_url}"
if [[ "${release_file: -3}" = "zip" ]]; then
unzip -oq "${release_file}" -d "${download_path}"
rm "${release_file}"
fi
}

if [ "${ASDF_INSTALL_TYPE}" = "version" ]; then
download_release "${ASDF_INSTALL_VERSION}" "${ASDF_DOWNLOAD_PATH}"
elif [ "${ASDF_INSTALL_TYPE}" = "ref" ]; then
Expand Down
122 changes: 121 additions & 1 deletion bin/install
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,127 @@ current_script_path=${BASH_SOURCE[0]}
plugin_dir=$(dirname "$(dirname "${current_script_path}")")

# shellcheck source=../lib/utils.bash
source "${plugin_dir}/lib/utils.bash"
. "${plugin_dir}/lib/utils.bash"

TOOL_NAME="awscli"
TOOL_TEST="aws --version"

install_source() {
local version download_path install_path major_version os_distribution make_concurrency tool_cmd
version="$1"
download_path="$2"
install_path="$3"
make_concurrency="$4"
major_version="${version:0:1}"
tool_cmd="$(echo "${TOOL_TEST}" | cut -d' ' -f1)"

(
if [[ "${major_version}" = "2" ]]; then
os_distribution="$(uname -s)"

if [[ "${os_distribution}" = "Linux" || "${os_distribution}" = "Darwin" ]]; then
pushd "${download_path}"
./configure --prefix="${install_path}" --with-download-deps --with-install-type=portable-exe
make --jobs "${make_concurrency}"
make install
popd
else
fail "asdf-${TOOL_NAME} does not support installing from source for OS distribution ${os_distribution}"
fi
else
fail "asdf-${TOOL_NAME} does not support installing from source for major version v${major_version}"
fi

test -x "${install_path}/bin/${tool_cmd}" || fail "Expected ${install_path}/bin/${tool_cmd} to be executable."
echo "asdf-${TOOL_NAME} ${version} installation was successful!"
) || (
rm -rf "${install_path}"
fail "An error ocurred while installing awscli ${version}."
)
}

install_release() {
local version download_path install_path major_version os_distribution os_arch
version="$1"
download_path="$2"
install_path="$3"
major_version="${version:0:1}"

(
if [[ "${major_version}" = "1" ]]; then
install_v1_bundled_installer "${download_path}" "${install_path}"
elif [[ "${major_version}" = "2" ]]; then
os_distribution="$(uname -s)"
os_arch="$(uname -m)"

if [[ "${os_distribution}" = "Linux" ]]; then
if [[ "${os_arch}" = "x86_64" || "${os_arch}" = "aarch64" ]]; then
install_v2_linux_bundled_installer "${download_path}" "${install_path}"
else
fail "asdf-${TOOL_NAME} does not support ${os_arch} on ${os_distribution}"
fi
elif [[ "${os_distribution}" = "Darwin" ]]; then
install_v2_macos_bundled_installer "${download_path}" "${install_path}"
elif [[ "${os_distribution}" = "Windows_NT" ]]; then
install_v2_windows_bundled_installer "${download_path}" "${install_path}"
else
fail "asdf-${TOOL_NAME} does not support OS distribution ${os_distribution}"
fi
else
fail "asdf-${TOOL_NAME} does not support major version v${major_version}"
fi

local tool_cmd
tool_cmd="$(echo "${TOOL_TEST}" | cut -d' ' -f1)"
test -x "${install_path}/bin/${tool_cmd}" || fail "Expected ${install_path}/bin/${tool_cmd} to be executable."
echo "asdf-${TOOL_NAME} ${version} installation was successful!"
) || (
rm -rf "${install_path}"
fail "An error ocurred while installing awscli ${version}."
)
}

install_v1_bundled_installer() {
local download_path install_path
download_path="$1"
install_path="$2"
# requires python 3.7+ https://docs.aws.amazon.com/cli/v1/userguide/cli-chap-install.html#cli-chap-install-python
"${download_path}"/awscli-bundle/install --install-dir "${install_path}"
}

install_v2_linux_bundled_installer() {
local download_path install_path
download_path="$1"
install_path="$2"
# requires glibc, groff, less
"${download_path}"/aws/install --install-dir "${install_path}" --bin-dir "${install_path}/bin"
}

# The official AWS CLI directions suggest using installer and a choices.xml
# but I was unable to find a deterministic way to make that work
# so copypasta
install_v2_macos_bundled_installer() {
local download_path install_path
download_path="$1"
install_path="$2"
# requires rosetta on M1 macs

mkdir -p "${install_path}/bin"
pkgutil --expand-full "${download_path}/AWSCLIV2.pkg" "${download_path}/tmp-awscliv2"
cp -a "${download_path}/tmp-awscliv2/aws-cli.pkg/Payload/aws-cli/" "${install_path}"
ln -snf "${install_path}/aws" "${install_path}/bin/aws"
ln -snf "${install_path}/aws_completer" "${install_path}/bin/aws_completer"
rm -rf "${download_path}/tmp-awscliv2"
}

install_v2_windows_bundled_installer() {
local download_path install_path
download_path="$1"
install_path="$2"

# requires curl, msiexec
msiexec.exe /i "${download_path}/AWSCLIV2.msi" "INSTALLDIR=${ASDF_INSTALL_PATH}" MSIINSTALLPERUSER=1
}

# Preserve compatibilty with older ASDF versions
# https://github.com/asdf-vm/asdf/pull/669#issuecomment-600330467
Expand Down
57 changes: 55 additions & 2 deletions bin/list-all
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,59 @@ current_script_path=${BASH_SOURCE[0]}
plugin_dir=$(dirname "$(dirname "${current_script_path}")")

# shellcheck source=../lib/utils.bash
source "${plugin_dir}/lib/utils.bash"
. "${plugin_dir}/lib/utils.bash"

list_all_versions | sort_versions | xargs echo
GIT_REMINDER_FILE="${ASDF_INSTALL_PATH}/.upgradegit"
GH_REPO="https://github.com/aws/aws-cli"
GIT_VERSION=$(git --version)
GIT_VERSION="${GIT_VERSION##* }"

git_supports_sort() {
awk '{ split($0,a,"."); if ((a[1] < 2) || (a[2] < 18)) { print "1" } else { print "0" } }' <<<"$1"
}

if [ "$(git_supports_sort "${GIT_VERSION}")" -eq 0 ]; then
rm -f "${GIT_REMINDER_FILE}"
GIT_SUPPORTS_SORT=0
else
GIT_SUPPORTS_SORT=1
if [ ! -f "${GIT_REMINDER_FILE}" ]; then
printf "consider upgrading git to a version >= 2.18.0 for faster asdf - you have v%s\n" "${GIT_VERSION}"
touch "${GIT_REMINDER_FILE}"
fi
fi

# NOTE: This is a fallback for if the user's installed version of git doesn't support sorting.
sort_versions() {
sed 'h; s/[+-]/./g; s/.p\([[:digit:]]\)/.z\1/; s/$/.z/; G; s/\n/ /' |
LC_ALL=C sort -t. -k 1,1 -k 2,2n -k 3,3n -k 4,4n -k 5,5n | awk '{print $2}'
}

list_github_tags() {
git ls-remote --tags --refs "${GH_REPO}" |
grep -o 'refs/tags/.*' | cut -d/ -f3- |
sed 's/^v//'
}

list_remote_tags() {
if [ "${GIT_SUPPORTS_SORT}" -eq 0 ]; then
git -c 'versionsort.suffix=a' -c 'versionsort.suffix=b' \
-c 'versionsort.suffix=r' -c 'versionsort.suffix=p' \
-c 'versionsort.suffix=-' -c 'versionsort.suffix=_' \
ls-remote --exit-code --tags --refs --sort="version:refname" "${REPO}" |
awk -F'[/v]' '$NF ~ /^[0-9]+.*/ { print $NF }' || fail "no releases found"
else
git ls-remote --exit-code --tags --refs "${REPO}" |
awk -F'[/v]' '$NF ~ /^[0-9]+.*/ { print $NF }' || fail "no releases found"
fi
}

list_all_versions() {
if [ "${GIT_SUPPORTS_SORT}" -eq 0 ]; then
list_remote_tags
else
list_remote_tags | sort_versions
fi
}

list_all_versions | xargs echo
Loading

0 comments on commit 9082ae6

Please sign in to comment.