chore(installation): Refactor installation script

- Run the script through `shellcheck` and apply the suggested changes,
  bar one regarding the use of `ls`.
- Add more descriptive comments.
- Refactor and simplify code.
This commit is contained in:
Jonah Kruschke 2020-08-03 22:51:02 -04:00
parent c4853ee6bb
commit 5aa2173f5f

View file

@ -1,142 +1,123 @@
#!/usr/bin/env bash #!/usr/bin/env bash
echo "Let's get you set up with Rustlings!" # Compare two version strings, v1 and v2, passed as arguments (e.g 1.31 and
# 1.33.0). Returns 1 if v1 > v2, 0 if v1 == v2, 2 if v1 < v2.
echo "Checking requirements..." compare_versions() {
if [ -x "$(command -v git)" ] [ "$1" == "$2" ] && return 0
then declare -a v1=() v2=()
echo "SUCCESS: Git is installed" mapfile -d . -t v1 < <(echo "$1")
else mapfile -d . -t v2 < <(echo "$1")
echo "ERROR: Git does not seem to be installed." declare -ir max_len=$(( ${#v1[@]} > ${#v2[@]} ? ${#v1[@]} : ${#v2[@]} ))
echo "Please download Git using your package manager or over https://git-scm.com/!" for i in $(seq 0 "$max_len")
exit 1
fi
if [ -x "$(command -v rustc)" ]
then
echo "SUCCESS: Rust is installed"
else
echo "ERROR: Rust does not seem to be installed."
echo "Please download Rust using https://rustup.rs!"
exit 1
fi
if [ -x "$(command -v cargo)" ]
then
echo "SUCCESS: Cargo is installed"
else
echo "ERROR: Cargo does not seem to be installed."
echo "Please download Rust and Cargo using https://rustup.rs!"
exit 1
fi
# Look up python installations, starting with 3 with a fallback of 2
if [ -x "$(command -v python3)" ]
then
PY="$(command -v python3)"
elif [ -x "$(command -v python)" ]
then
PY="$(command -v python)"
elif [ -x "$(command -v python2)" ]
then
PY="$(command -v python2)"
else
echo "ERROR: No working python installation was found"
echo "Please install python and add it to the PATH variable"
exit 1
fi
# Function that compares two versions strings v1 and v2 given in arguments (e.g 1.31 and 1.33.0).
# Returns 1 if v1 > v2, 0 if v1 == v2, 2 if v1 < v2.
function vercomp() {
if [[ $1 == $2 ]]
then
return 0
fi
v1=( ${1//./ } )
v2=( ${2//./ } )
len1=${#v1[@]}
len2=${#v2[@]}
max_len=$len1
if [[ $max_len -lt $len2 ]]
then
max_len=$len2
fi
for i in `seq 0 $max_len`
do do
# Fill empty fields with zeros in v1 # Fill empty fields with zeros.
if [ -z "${v1[$i]}" ] [ -z "${v1[$i]}" ] && v1["$i"]=0
then [ -z "${v2[$i]}" ] && v2["$i"]=0
v1[$i]=0 # Compare the fields.
fi [ ${v1[$i]} -gt ${v2[$i]} ] && return 1
# And in v2 [ ${v1[$i]} -lt ${v2[$i]} ] && return 2
if [ -z "${v2[$i]}" ]
then
v2[$i]=0
fi
if [ ${v1[$i]} -gt ${v2[$i]} ]
then
return 1
fi
if [ ${v1[$i]} -lt ${v2[$i]} ]
then
return 2
fi
done done
return 0 return 0
} }
# Return 0 if the argument passed represents a valid command on the machine,
# 1 otherwise.
verify_dependency() {
declare -r package="$1"
if [ -x "$(command -v "$package")" ]
then
echo "SUCCESS: $package is installed"
return 0
else
echo "ERROR: $package does not seem to be installed." >&2
return 1
fi
}
declare Clippy Py RustVersion Version
declare -r CargoBin="${CARGO_HOME:-$HOME/.cargo}/bin"
declare -r Path=${1:-rustlings/}
declare -r MinRustVersion=1.31
echo "Let's get you set up with Rustlings!"
# Verify that the required dependencies are installed.
echo "Checking requirements..."
for dep in git rustc cargo curl
do
verify_dependency "$dep" || exit 1
done
# Look up Python installations; start with 3 and fallback to 2 if required.
if [ -x "$(command -v python3)" ]
then
Py="$(command -v python3)"
elif [ -x "$(command -v python)" ]
then
Py="$(command -v python)"
elif [ -x "$(command -v python2)" ]
then
Py="$(command -v python2)"
else
echo ERROR: No working python installation was found. >&2
echo Please install python and add it to the PATH variable. >&2
exit 1
fi
# Ensure the installed Rust compiler is sufficiently up-to-date.
RustVersion=$(rustc --version | cut -d " " -f 2) RustVersion=$(rustc --version | cut -d " " -f 2)
MinRustVersion=1.31 compare_versions "$RustVersion" "$MinRustVersion"
vercomp $RustVersion $MinRustVersion
if [ $? -eq 2 ] if [ $? -eq 2 ]
then then
echo "ERROR: Rust version is too old: $RustVersion - needs at least $MinRustVersion" echo ERROR: Rust version is too old: "$RustVersion" - needs at least \
echo "Please update Rust with 'rustup update'" "$MinRustVersion" >&2
echo Please update Rust with \`rustup update\`. >&2
exit 1 exit 1
else else
echo "SUCCESS: Rust is up to date" echo "SUCCESS: Rust is up to date"
fi fi
Path=${1:-rustlings/} # Clone the Git repository.
echo "Cloning Rustlings at $Path..." echo "Cloning Rustlings into $Path..."
git clone -q https://github.com/rust-lang/rustlings $Path git clone -q https://github.com/rust-lang/rustlings "$Path"
cd "$Path" || exit 1
cd $Path # Determine which version of Rustlings to install.
Version=$(curl -s \
Version=$(curl -s https://api.github.com/repos/rust-lang/rustlings/releases/latest | ${PY} -c "import json,sys;obj=json.load(sys.stdin);print(obj['tag_name']);") https://api.github.com/repos/rust-lang/rustlings/releases/latest \
CargoBin="${CARGO_HOME:-$HOME/.cargo}/bin" | "$Py" -c \
"import json,sys;obj=json.load(sys.stdin);print(obj['tag_name']);")
if [[ -z ${Version} ]] if [ -z "$Version" ]
then then
echo "The latest tag version could not be fetched remotely." echo The latest tag version could not be fetched remotely.
echo "Using the local git repository..." echo Using the local git repository...
Version=$(ls -tr .git/refs/tags/ | tail -1) Version=$(ls -t .git/refs/tags/ | head --lines=1)
if [[ -z ${Version} ]] if [ -z "$Version" ]
then then
echo "No valid tag version found" echo No valid tag version found
echo "Rustlings will be installed using the main branch" echo Rustlings will be installed using the main branch
Version="main" Version="main"
else else
Version="tags/${Version}" Version="tags/$Version"
fi fi
else else
Version="tags/${Version}" Version="tags/$Version"
fi fi
# Install the selected version of Rustlings.
echo "Checking out version $Version..." echo "Checking out version $Version..."
git checkout -q ${Version} git checkout -q "$Version"
echo "Installing the 'rustlings' executable..." echo "Installing the 'rustlings' executable..."
cargo install --force --path . cargo install --force --path .
# Verify that the Rustlings installation was successful.
if ! [ -x "$(command -v rustlings)" ] if ! [ -x "$(command -v rustlings)" ]
then then
echo "WARNING: Please check that you have '$CargoBin' in your PATH environment variable!" echo WARNING: Please ensure "'$CargoBin'" is in your PATH environment \
variable!
fi fi
# Checking whether Clippy is installed. # Ensure Clippy is installed (due to a bug in Cargo, this must be done with
# Due to a bug in Cargo, this must be done with Rustup: https://github.com/rust-lang/rustup/issues/1514 # Rustup: https://github.com/rust-lang/rustup/issues/1514).
Clippy=$(rustup component list | grep "clippy" | grep "installed") Clippy=$(rustup component list | grep "clippy" | grep "installed")
if [ -z "$Clippy" ] if [ -z "$Clippy" ]
then then