Skip to content

Commit 70b2d62

Browse files
authored
Merge pull request #4 from smithy-lang/update-asdf
refactor: use .zip instead of tarball
2 parents 4f3078b + 20c707e commit 70b2d62

3 files changed

Lines changed: 250 additions & 8 deletions

File tree

lib/compare_semver

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
#!/bin/bash
2+
3+
set -euo pipefail
4+
5+
# Validate a semver string, exit if invalid.
6+
# Arguments:
7+
# $1: semver string to validate
8+
validate_semver() {
9+
10+
# Regex for a semver digit
11+
D='0|[1-9][0-9]*'
12+
# Regex for a semver pre-release word
13+
PW='[0-9]*[a-zA-Z-][0-9a-zA-Z-]*'
14+
# Regex for a semver build-metadata word
15+
MW='[0-9a-zA-Z-]+'
16+
17+
# Regex pattern to match a semver string with numeric version identifiers, pre-release identifiers, and build metadata
18+
semver_pattern="^($D)\.($D)\.($D)(-(($D|$PW)(\.($D|$PW))*))?(\+($MW(\.$MW)*))?$"
19+
20+
if ! [[ $1 =~ $semver_pattern ]]; then
21+
echo "$0: Invalid semver string: $1" >&2
22+
echo "$0: Expected format 'x.y.z' or 'x.y.z-pre-release'."
23+
exit 1
24+
fi
25+
}
26+
27+
# Function to compare two component strings.
28+
# Arguments:
29+
# $1: First component string
30+
# $2: Second component string
31+
# Output:
32+
# -1 if the first component has lower precedence
33+
# 1 if the first component has higher precedence
34+
compare_components() {
35+
if (($1 > $2)); then
36+
echo 1 && exit 0
37+
elif (($1 < $2)); then
38+
echo -1 && exit 0
39+
fi
40+
}
41+
42+
# Function to compare pre-release identifiers.
43+
# Arguments:
44+
# $1: First pre-release identifier
45+
# $2: Second pre-release identifier
46+
# Output:
47+
# -1 if the first pre-release identifier has lower precedence
48+
# 0 if both identifiers are equal
49+
# 1 if the first pre-release identifier has higher precedence
50+
compare_prerelease() {
51+
# If both pre-release identifiers are empty, they are considered equal
52+
if [ -z "$1" ] && [ -z "$2" ]; then
53+
echo 0 && exit 0
54+
fi
55+
56+
# If one of the pre-release identifiers is empty, the one with the non-empty identifier has lower precedence
57+
if [ -z "$1" ]; then
58+
echo 1 && exit 0
59+
elif [ -z "$2" ]; then
60+
echo -1 && exit 0
61+
fi
62+
63+
# Split pre-release identifiers into individual parts
64+
IFS='.' read -r -a parts1 <<<"$1"
65+
IFS='.' read -r -a parts2 <<<"$2"
66+
67+
# Compare each part of the pre-release identifiers
68+
for ((i = 0; i < ${#parts1[@]} || i < ${#parts2[@]}; i++)); do
69+
part1="${parts1[i]:=""}"
70+
part2="${parts2[i]:=""}"
71+
72+
# If one part is missing, it has lower precedence
73+
if [ -z "$part1" ]; then
74+
echo -1 && exit 0
75+
elif [ -z "$part2" ]; then
76+
echo 1 && exit 0
77+
fi
78+
79+
# If parts are numeric, compare numerically
80+
if [[ "$part1" =~ ^[0-9]+$ ]] && [[ "$part2" =~ ^[0-9]+$ ]]; then
81+
compare_components "$part1" "$part2"
82+
fi
83+
84+
# Lexicographically compare non-numeric parts
85+
[[ "$part1" < "$part2" ]] && echo -1 && exit 0
86+
[[ "$part1" > "$part2" ]] && echo 1 && exit 0
87+
done
88+
89+
# Versions are equal
90+
echo 0
91+
}
92+
93+
# Function to compare two semver strings.
94+
# Arguments:
95+
# $1: First semver string
96+
# $2: Second semver string
97+
# Output:
98+
# -1 if the first version is less than the second version
99+
# 0 if the versions are equal
100+
# 1 if the first version is greater than the second version
101+
compare_semver() {
102+
# Validate the semver strings
103+
validate_semver "$1"
104+
validate_semver "$2"
105+
106+
# Remove build metadata if present
107+
semver1=$(cut -d+ -f1 <<<"$1")
108+
semver2=$(cut -d+ -f1 <<<"$2")
109+
110+
# Extract major, minor, patch, and pre-release versions from the input strings
111+
major1=$(cut -d. -f1 <<<"$semver1")
112+
minor1=$(cut -d. -f2 <<<"$semver1")
113+
patch1=$(cut -d. -f3 -s <<<"$semver1" | cut -d- -f1)
114+
prerelease1=$(cut -d- -f2- -s <<<"$semver1")
115+
116+
major2=$(cut -d. -f1 <<<"$semver2")
117+
minor2=$(cut -d. -f2 <<<"$semver2")
118+
patch2=$(cut -d. -f3 -s <<<"$semver2" | cut -d- -f1)
119+
prerelease2=$(cut -d- -f2- -s <<<"$semver2")
120+
121+
# Compare each component of the versions
122+
compare_components "$major1" "$major2"
123+
compare_components "$minor1" "$minor2"
124+
compare_components "$patch1" "$patch2"
125+
126+
# Check if one version has a pre-release identifier while the other does not
127+
if [ -n "$prerelease1" ] && [ -z "$prerelease2" ]; then
128+
echo -1 && exit 0
129+
elif [ -z "$prerelease1" ] && [ -n "$prerelease2" ]; then
130+
echo 1 && exit 0
131+
fi
132+
133+
# Compare pre-release identifiers if they exist
134+
if [ -n "$prerelease1" ] && [ -n "$prerelease2" ]; then
135+
compare_prerelease "$prerelease1" "$prerelease2" && exit 0
136+
fi
137+
138+
# Versions are equal
139+
echo 0
140+
}
141+
142+
compare_semver "$1" "$2"

lib/test_compare_semver

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/bin/bash
2+
3+
test_cases=(
4+
# Versions are equal
5+
"1.0.0 1.0.0 0"
6+
"1.1.0 1.1.0 0"
7+
"1.0.1 1.0.1 0"
8+
"1.0.0-alpha 1.0.0-alpha 0"
9+
"1.0.0-alpha.beta 1.0.0-alpha.beta 0"
10+
"1.0.0-abc123.1.1.1 1.0.0-abc123.1.1.1 0"
11+
12+
# First version is less than second version
13+
"1.0.0 2.0.0 -1"
14+
"1.0.0 1.1.0 -1"
15+
"1.0.0 1.0.1 -1"
16+
"1.0.0-alpha 1.0.0 -1"
17+
18+
# First version is greater than second version
19+
"2.0.0 1.0.0 1"
20+
"1.1.0 1.0.0 1"
21+
"1.0.1 1.0.0 1"
22+
"1.0.0 1.0.0-alpha 1"
23+
"1.0.0-alpha.1 1.0.0-alpha 1"
24+
25+
# Pre-release versions comparison
26+
"1.0.0-alpha 1.0.0-alpha.beta -1"
27+
"1.0.0-alpha.beta 1.0.0-beta -1"
28+
"1.0.0-alpha.beta 1.0.0-beta.2 -1"
29+
"1.0.0-alpha.beta 1.0.0-beta.11 -1"
30+
"1.0.0-alpha.beta 1.0.0-rc.1 -1"
31+
"1.0.0-alpha.beta 1.0.0 -1"
32+
"1.0.0-beta 1.0.0-beta.2 -1"
33+
"1.0.0-beta 1.0.0-beta.11 -1"
34+
"1.0.0-beta 1.0.0-rc.1 -1"
35+
"1.0.0-beta 1.0.0 -1"
36+
"1.0.0-beta.2 1.0.0-beta.11 -1"
37+
"1.0.0-beta.2 1.0.0-rc.1 -1"
38+
"1.0.0-beta.2 1.0.0 -1"
39+
"1.0.0-beta.11 1.0.0-rc.1 -1"
40+
"1.0.0-rc.1 1.0.0-rc.2 -1"
41+
"1.0.0-rc.1 1.0.0 -1"
42+
43+
# Versions with build metadata
44+
"1.0.0 1.0.0+build.1 0"
45+
"1.0.0 1.0.0+build.2 0"
46+
"1.0.0-alpha 1.0.0-alpha+build.1 0"
47+
"1.0.0-alpha+build.1 1.0.0-alpha+build.2 0"
48+
"1.0.0-alpha+build.1 1.0.0+build.1 -1"
49+
"1.0.0+early 1.0.1+late -1"
50+
"1.0.0+early 1.1.0+late -1"
51+
"1.0.0+early 2.0.0+late -1"
52+
)
53+
54+
LIB="$(dirname "$(readlink -f "$0")")"
55+
56+
# Run test cases
57+
for test_case in "${test_cases[@]}"; do
58+
versions=()
59+
read -ra versions <<<"$test_case"
60+
result=$("$LIB/compare_semver" "${versions[0]}" "${versions[1]}")
61+
expected="${versions[2]}"
62+
if [ "$result" -eq "$expected" ]; then
63+
echo "OK: ${versions[0]} compared to ${versions[1]} :: Result - $result"
64+
else
65+
echo "FAIL: ${versions[0]} compared to ${versions[1]} :: Expected - $expected, Actual - $result"
66+
fi
67+
done

lib/utils.bash

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ REPO="smithy-lang/smithy"
66
GH_REPO="https://github.com/$REPO"
77
GH_REPO_API="https://api.github.com/repos/$REPO"
88
TOOL_NAME="smithy"
9+
LIB="$(dirname "$(dirname "$(readlink -f "$0")")")/lib"
910

1011
fail() {
11-
echo -e "asdf-$TOOL_NAME: $*"
12+
printf '%s\n' "asdf-$TOOL_NAME: $*" >&2
1213
exit 1
1314
}
1415

@@ -44,6 +45,11 @@ get_platform() {
4445
# get architecture, output it, quit if unsupported
4546
get_arch() {
4647
arch="$(uname -m)"
48+
if [[ "$arch" =~ "arm64" ]]; then
49+
# uname may return arm64 for arm-based machines, they're synonymous
50+
arch="aarch64"
51+
fi
52+
4753
if [[ ! $(check_arch "$arch") ]]; then
4854
fail "unsupported architecture ($arch)"
4955
fi
@@ -59,7 +65,7 @@ check_arch() {
5965
}
6066

6167
# get the url for the artifact to download, based on
62-
# the system (1st arg) and the version (2nd arg)
68+
# the system (1st arg), the version (2nd arg), and the file extensions (3rd arg)
6369
get_artifact_url() {
6470
check jq
6571
if [ "$#" -gt 1 ]; then
@@ -70,7 +76,7 @@ get_artifact_url() {
7076
else
7177
tag=$2
7278
fi
73-
echo "$GH_REPO/releases/download/$tag/smithy-cli-$1.tar.gz"
79+
echo "$GH_REPO/releases/download/$tag/smithy-cli-$1.$3"
7480
else
7581
fail "platform or version were not specified."
7682
fi
@@ -86,12 +92,37 @@ download_release() {
8692

8793
if [ "$type" = "version" ]; then
8894
echo "* Downloading $TOOL_NAME release ($version)..."
89-
url=$(get_artifact_url "$(get_platform)-$(get_arch)" "$version")
90-
if [ "$url" ]; then
91-
curl "${curl_opts[@]}" "$url" | tar xzf - -C "$path" ||
92-
fail "Request to '$url' returned bad response ($?)."
95+
platform=$(get_platform)
96+
arch=$(get_arch)
97+
# Based on the version, install from tar or zip
98+
# versions earlier than 1.47.0 must install from tarball
99+
vercmp="$(. "$LIB"/compare_semver "$version" "1.47.0")"
100+
if [ "$vercmp" = "-1" ]; then
101+
# version is less than 1.47.0, use tar
102+
url=$(get_artifact_url "$(get_platform)-$(get_arch)" "$version" "tar.gz")
103+
if [ "$url" ]; then
104+
echo "Retrieving release at $url..."
105+
curl "${curl_opts[@]}" "$url" | tar xzf - -C "$path" ||
106+
fail "Request to '$url' returned bad response ($?)."
107+
else
108+
fail "Could not form url."
109+
fi
93110
else
94-
fail "Could not form url."
111+
# version is greater than or equal to 1.47.0, use zip
112+
url=$(get_artifact_url "$platform-$arch" "$version" "zip")
113+
if [ "$url" ]; then
114+
mkdir -p "$path"
115+
echo "Retrieving release at $url..."
116+
tmp_download_dir=$(mktemp -d -t asdf_extract_XXXXXXX)
117+
cd "$tmp_download_dir"
118+
curl "${curl_opts[@]}" -o smithy.zip "$url" || fail "Request to '$url' returned bad response ($?)."
119+
unzip -oq smithy.zip
120+
mv smithy-cli-"$platform"-"$arch"/* "$path"
121+
rm -rf smithy-cli-"$platform"-"$arch" smithy.zip
122+
cd -
123+
else
124+
fail "Could not form url."
125+
fi
95126
fi
96127
else
97128
fail "Download by '$type' is not supported."
@@ -117,6 +148,8 @@ install_version() {
117148

118149
(
119150
mkdir -p "$path"
151+
# zips don't maintain permissions, so we need to add x perms to the right files
152+
chmod +x "$download_path"/bin/* "$download_path"/lib/jspawnhelper
120153
cp -r "$download_path"/* "$path"
121154

122155
# assert smithy exists and runs

0 commit comments

Comments
 (0)