I am trying to make a small shell script function where basically it should return me only the two latest versions of a github repository (not counting the latest). Here is my code:
get_release() {
curl --silent \
-H "Accept: application/vnd.github.v3 json" \
https://api.github.com/repos/user/repo/releases |
grep '"tag_name":' |
sed -E 's/.*"([^"] )".*/\1/'
}
#str="1.1.1 2.2.2 3.3.3 4.4.4 5.5.5 6.6.6 7.7.7 8.8.8 9.9.9"
str=($get_release)
#VERSION=$(get_release)
IFS=', ' read -r -a array <<< "$str"
LASTVERSION=${array[-2]}
PENULTIMATEVERSION=${array[-3]}
echo "${LASTVERSION}"
echo "${PENULTIMATEVERSION}"
But I'm getting this when I try to run:
t.sh: line 17: array: bad array subscript
t.sh: line 18: array: bad array subscript
Note: the commented str variable is just a simulation of an array, with it working normally, but when trying to use the get_release function, I get this error.
CodePudding user response:
As a working example which is compatible with all bash releases from 3.2 forward:
get_releases() {
local user=$1 repo=$2
curl --silent \
-H "Accept: application/vnd.github.v3 json" \
"https://api.github.com/repos/$user/$repo/releases" |
jq -r '.[].tag_name'
}
IFS=$'\n' read -r -d '' -a releases < <(get_releases juji-io datalevin && printf '\0')
echo "Newest release: ${releases[0]}"
echo "Oldest release: ${releases[${#releases[@]}-1]}"
echo "Second oldest: ${releases[${#releases[@]}-2]}"
...which as of present date correctly emits (for the juji-io/datalevin
project used in the example above):
Newest release: 0.6.6
Oldest release: 0.5.13
Second oldest: 0.5.14
CodePudding user response:
As per @Philippe's comments ($get_release)
will not call your function, but $(get_release)
will.
As per @Charles Duffy comments, I have updated how we compute the latest indexes.
Here's the amended code snippet:
get_release() {
curl --silent \
-H "Accept: application/vnd.github.v3 json" \
https://api.github.com/repos/user/repo/releases |
grep '"tag_name":' |
sed -E 's/.*"([^"] )".*/\1/'
}
# str=($get_release) # Warning: this does not call get_release
# str='1.1.1 2.2.2 3.3.3 4.4.4 5.5.5 6.6.6 7.7.7 8.8.8 9.9.9'
str=$(get_release)
IFS=', ' read -r -a array <<< "$str"
n=${#array[@]}
LASTVERSION=${array[$((n-1))]}
PENULTIMATEVERSION=${array[$((n-2))]}
echo "${LASTVERSION}" # 9.9.9
echo "${PENULTIMATEVERSION}" # 8.8.8
Another solution is we can use regex to solve this problem, i.e.
# str=($get_release) # Warning: this does not call get_release
# str='1.1.1 2.2.2 3.3.3 4.4.4 5.5.5 6.6.6 7.7.7 8.8.8 9.9.9'
str=$(get_release)
LASTVERSION=$(perl -ne 'print if s/.* (\d \.\d \.\d )/\1/' <<< $str)
PENULTIMATEVERSION=$(perl -ne 'print if s/.* (\d \.\d \.\d ) \d \.\d \.\d /\1/' <<< $str)
echo "${LASTVERSION}" # 9.9.9
echo "${PENULTIMATEVERSION}" # 8.8.8