From 6804e6133347eca8156ae4b11a976aeaf74466c0 Mon Sep 17 00:00:00 2001 From: per1234 Date: Tue, 15 Dec 2020 19:39:26 -0800 Subject: [PATCH 1/9] Initial commit of installation script Source: https://github.com/arduino/arduino-cli/blob/6a177ebf56f2e28c501b26ae47aee596e47dc0e6/install.sh --- install.sh | 220 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100755 install.sh diff --git a/install.sh b/install.sh new file mode 100755 index 000000000..296f7bdbb --- /dev/null +++ b/install.sh @@ -0,0 +1,220 @@ +#!/bin/sh + +# The original version of this script is licensed under the MIT license. +# See https://github.com/Masterminds/glide/blob/master/LICENSE for more details +# and copyright notice. + +# +# Usage: +# +# To install the latest version of the CLI: +# ./install.sh +# +# To pin a specific release of the CLI: +# ./install.sh 0.9.0 +# + +PROJECT_NAME="arduino-cli" + +# BINDIR represents the local bin location, defaults to ./bin. +LBINDIR="" +DEFAULT_BINDIR="$PWD/bin" + +fail() { + echo "$1" + exit 1 +} + +initDestination() { + if [ -n "$BINDIR" ]; then + if [ ! -d "$BINDIR" ]; then + fail "$BINDIR "'($BINDIR)'" folder not found. Please create it before continuing." + fi + LBINDIR="$BINDIR" + else + if [ ! -d "$DEFAULT_BINDIR" ]; then + mkdir "$DEFAULT_BINDIR" + fi + LBINDIR="$DEFAULT_BINDIR" + fi + echo "Installing in $LBINDIR" +} + +initArch() { + ARCH=$(uname -m) + case $ARCH in + armv5*) ARCH="armv5";; + armv6*) ARCH="ARMv6";; + armv7*) ARCH="ARMv7";; + aarch64) ARCH="ARM64";; + x86) ARCH="32bit";; + x86_64) ARCH="64bit";; + i686) ARCH="32bit";; + i386) ARCH="32bit";; + esac + echo "ARCH=$ARCH" +} + +initOS() { + OS=$(uname -s) + case "$OS" in + Linux*) OS='Linux' ;; + Darwin*) OS='macOS' ;; + MINGW*) OS='Windows';; + MSYS*) OS='Windows';; + esac + echo "OS=$OS" +} + +initDownloadTool() { + if type "curl" > /dev/null; then + DOWNLOAD_TOOL="curl" + elif type "wget" > /dev/null; then + DOWNLOAD_TOOL="wget" + else + fail "You need curl or wget as download tool. Please install it first before continuing" + fi + echo "Using $DOWNLOAD_TOOL as download tool" +} + +checkLatestVersion() { + # Use the GitHub releases webpage to find the latest version for this project + # so we don't get rate-limited. + local tag + local regex="[0-9][A-Za-z0-9\.-]*" + local latest_url="https://github.com/arduino/arduino-cli/releases/latest" + if [ "$DOWNLOAD_TOOL" = "curl" ]; then + tag=$(curl -SsL $latest_url | grep -o "Release $regex · arduino/arduino-cli" | grep -o "$regex") + elif [ "$DOWNLOAD_TOOL" = "wget" ]; then + tag=$(wget -q -O - $latest_url | grep -o "<title>Release $regex · arduino/arduino-cli" | grep -o "$regex") + fi + if [ "x$tag" = "x" ]; then + echo "Cannot determine latest tag." + exit 1 + fi + eval "$1='$tag'" +} + +get() { + local url="$2" + local body + local httpStatusCode + echo "Getting $url" + if [ "$DOWNLOAD_TOOL" = "curl" ]; then + httpResponse=$(curl -sL --write-out HTTPSTATUS:%{http_code} "$url") + httpStatusCode=$(echo $httpResponse | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') + body=$(echo "$httpResponse" | sed -e 's/HTTPSTATUS\:.*//g') + elif [ "$DOWNLOAD_TOOL" = "wget" ]; then + tmpFile=$(mktemp) + body=$(wget --server-response --content-on-error -q -O - "$url" 2> $tmpFile || true) + httpStatusCode=$(cat $tmpFile | awk '/^ HTTP/{print $2}') + fi + if [ "$httpStatusCode" != 200 ]; then + echo "Request failed with HTTP status code $httpStatusCode" + fail "Body: $body" + fi + eval "$1='$body'" +} + +getFile() { + local url="$1" + local filePath="$2" + if [ "$DOWNLOAD_TOOL" = "curl" ]; then + httpStatusCode=$(curl -s -w '%{http_code}' -L "$url" -o "$filePath") + elif [ "$DOWNLOAD_TOOL" = "wget" ]; then + body=$(wget --server-response --content-on-error -q -O "$filePath" "$url") + httpStatusCode=$(cat $tmpFile | awk '/^ HTTP/{print $2}') + fi + echo "$httpStatusCode" +} + +downloadFile() { + if [ -z $1 ]; then + checkLatestVersion TAG + else + TAG=$1 + fi + echo "TAG=$TAG" + # arduino-cli_0.4.0-rc1_Linux_64bit.[tar.gz, zip] + if [ "$OS" = "Windows" ]; then + CLI_DIST="arduino-cli_${TAG}_${OS}_${ARCH}.zip" + else + CLI_DIST="arduino-cli_${TAG}_${OS}_${ARCH}.tar.gz" + fi + echo "CLI_DIST=$CLI_DIST" + DOWNLOAD_URL="https://downloads.arduino.cc/arduino-cli/$CLI_DIST" + CLI_TMP_FILE="/tmp/$CLI_DIST" + echo "Downloading $DOWNLOAD_URL" + httpStatusCode=$(getFile "$DOWNLOAD_URL" "$CLI_TMP_FILE") + if [ "$httpStatusCode" -ne 200 ]; then + echo "Did not find a release for your system: $OS $ARCH" + echo "Trying to find a release using the GitHub API." + LATEST_RELEASE_URL="https://api.github.com/repos/arduino/$PROJECT_NAME/releases/tags/$TAG" + echo "LATEST_RELEASE_URL=$LATEST_RELEASE_URL" + get LATEST_RELEASE_JSON $LATEST_RELEASE_URL + # || true forces this command to not catch error if grep does not find anything + DOWNLOAD_URL=$(echo "$LATEST_RELEASE_JSON" | grep 'browser_' | cut -d\" -f4 | grep "$CLI_DIST") || true + if [ -z "$DOWNLOAD_URL" ]; then + echo "Sorry, we dont have a dist for your system: $OS $ARCH" + fail "You can request one here: https://github.com/Arduino/$PROJECT_NAME/issues" + else + echo "Downloading $DOWNLOAD_URL" + getFile "$DOWNLOAD_URL" "$CLI_TMP_FILE" + fi + fi +} + +installFile() { + CLI_TMP="/tmp/$PROJECT_NAME" + mkdir -p "$CLI_TMP" + if [ "$OS" = "Windows" ]; then + unzip -d "$CLI_TMP" "$CLI_TMP_FILE" + else + tar xf "$CLI_TMP_FILE" -C "$CLI_TMP" + fi + CLI_TMP_BIN="$CLI_TMP/$PROJECT_NAME" + cp "$CLI_TMP_BIN" "$LBINDIR" + rm -rf $CLI_TMP + rm -f $CLI_TMP_FILE +} + +bye() { + result=$? + if [ "$result" != "0" ]; then + echo "Failed to install $PROJECT_NAME" + fi + exit $result +} + +testVersion() { + set +e + CLI="$(which $PROJECT_NAME)" + if [ "$?" = "1" ]; then + echo "$PROJECT_NAME not found. You might want to add "$LBINDIR" to your "'$PATH' + else + # Convert to resolved, absolute paths before comparison + CLI_REALPATH="$(cd -- "$(dirname -- "$CLI")" && pwd -P)" + LBINDIR_REALPATH="$(cd -- "$LBINDIR" && pwd -P)" + if [ "$CLI_REALPATH" != "$LBINDIR_REALPATH" ]; then + echo "An existing $PROJECT_NAME was found at $CLI. Please prepend "$LBINDIR" to your "'$PATH'" or remove the existing one." + fi + fi + + set -e + CLI_VERSION=$($LBINDIR/$PROJECT_NAME version) + echo "$CLI_VERSION installed successfully in $LBINDIR" +} + + +# Execution + +#Stop execution on any error +trap "bye" EXIT +initDestination +set -e +initArch +initOS +initDownloadTool +downloadFile $1 +installFile +testVersion From 0cc39bb9e422f6bcdb3b04da053f8c49db2b6bcd Mon Sep 17 00:00:00 2001 From: per1234 <accounts@perglass.com> Date: Tue, 15 Dec 2020 19:44:22 -0800 Subject: [PATCH 2/9] Add link to source of install script It may be useful to check the ongoing development work on the source script. Previously, it was difficult to find that script because it's hosted in a different repository from the one the licensing comment provides. --- install.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/install.sh b/install.sh index 296f7bdbb..87640f91d 100755 --- a/install.sh +++ b/install.sh @@ -1,8 +1,7 @@ #!/bin/sh -# The original version of this script is licensed under the MIT license. -# See https://github.com/Masterminds/glide/blob/master/LICENSE for more details -# and copyright notice. +# The original version of this script (https://github.com/Masterminds/glide.sh/blob/master/get) is licensed under the +# MIT license. See https://github.com/Masterminds/glide/blob/master/LICENSE for more details and copyright notice. # # Usage: From e3fac4b83a167448bc1b1eca26be574f7a55167a Mon Sep 17 00:00:00 2001 From: per1234 <accounts@perglass.com> Date: Tue, 15 Dec 2020 19:53:23 -0800 Subject: [PATCH 3/9] Replace references to Arduino CLI in installation script --- install.sh | 63 +++++++++++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/install.sh b/install.sh index 87640f91d..f71c3dde1 100755 --- a/install.sh +++ b/install.sh @@ -6,14 +6,15 @@ # # Usage: # -# To install the latest version of the CLI: +# To install the latest version of arduino-lint: # ./install.sh # -# To pin a specific release of the CLI: +# To pin a specific release of arduino-lint: # ./install.sh 0.9.0 # -PROJECT_NAME="arduino-cli" +PROJECT_OWNER="arduino" +PROJECT_NAME="arduino-lint" # BINDIR represents the local bin location, defaults to ./bin. LBINDIR="" @@ -81,11 +82,11 @@ checkLatestVersion() { # so we don't get rate-limited. local tag local regex="[0-9][A-Za-z0-9\.-]*" - local latest_url="https://github.com/arduino/arduino-cli/releases/latest" + local latest_url="https://github.com/${PROJECT_OWNER}/${PROJECT_NAME}/releases/latest" if [ "$DOWNLOAD_TOOL" = "curl" ]; then - tag=$(curl -SsL $latest_url | grep -o "<title>Release $regex · arduino/arduino-cli" | grep -o "$regex") + tag=$(curl -SsL $latest_url | grep -o "<title>Release $regex · ${PROJECT_OWNER}/${PROJECT_NAME}" | grep -o "$regex") elif [ "$DOWNLOAD_TOOL" = "wget" ]; then - tag=$(wget -q -O - $latest_url | grep -o "<title>Release $regex · arduino/arduino-cli" | grep -o "$regex") + tag=$(wget -q -O - $latest_url | grep -o "<title>Release $regex · ${PROJECT_OWNER}/${PROJECT_NAME}" | grep -o "$regex") fi if [ "x$tag" = "x" ]; then echo "Cannot determine latest tag." @@ -133,48 +134,46 @@ downloadFile() { else TAG=$1 fi - echo "TAG=$TAG" - # arduino-cli_0.4.0-rc1_Linux_64bit.[tar.gz, zip] + # arduino-lint_0.4.0-rc1_Linux_64bit.[tar.gz, zip] if [ "$OS" = "Windows" ]; then - CLI_DIST="arduino-cli_${TAG}_${OS}_${ARCH}.zip" + ARDUINO_LINT_DIST="${PROJECT_NAME}_${TAG}_${OS}_${ARCH}.zip" else - CLI_DIST="arduino-cli_${TAG}_${OS}_${ARCH}.tar.gz" + ARDUINO_LINT_DIST="${PROJECT_NAME}_${TAG}_${OS}_${ARCH}.tar.gz" fi - echo "CLI_DIST=$CLI_DIST" - DOWNLOAD_URL="https://downloads.arduino.cc/arduino-cli/$CLI_DIST" - CLI_TMP_FILE="/tmp/$CLI_DIST" + DOWNLOAD_URL="https://downloads.arduino.cc/${PROJECT_NAME}/${ARDUINO_LINT_DIST}" + ARDUINO_LINT_TMP_FILE="/tmp/$ARDUINO_LINT_DIST" echo "Downloading $DOWNLOAD_URL" - httpStatusCode=$(getFile "$DOWNLOAD_URL" "$CLI_TMP_FILE") + httpStatusCode=$(getFile "$DOWNLOAD_URL" "$ARDUINO_LINT_TMP_FILE") if [ "$httpStatusCode" -ne 200 ]; then echo "Did not find a release for your system: $OS $ARCH" echo "Trying to find a release using the GitHub API." - LATEST_RELEASE_URL="https://api.github.com/repos/arduino/$PROJECT_NAME/releases/tags/$TAG" + LATEST_RELEASE_URL="https://api.github.com/repos/${PROJECT_OWNER}/$PROJECT_NAME/releases/tags/$TAG" echo "LATEST_RELEASE_URL=$LATEST_RELEASE_URL" get LATEST_RELEASE_JSON $LATEST_RELEASE_URL # || true forces this command to not catch error if grep does not find anything - DOWNLOAD_URL=$(echo "$LATEST_RELEASE_JSON" | grep 'browser_' | cut -d\" -f4 | grep "$CLI_DIST") || true + DOWNLOAD_URL=$(echo "$LATEST_RELEASE_JSON" | grep 'browser_' | cut -d\" -f4 | grep "$ARDUINO_LINT_DIST") || true if [ -z "$DOWNLOAD_URL" ]; then echo "Sorry, we dont have a dist for your system: $OS $ARCH" - fail "You can request one here: https://github.com/Arduino/$PROJECT_NAME/issues" + fail "You can request one here: https://github.com/${PROJECT_OWNER}/$PROJECT_NAME/issues" else echo "Downloading $DOWNLOAD_URL" - getFile "$DOWNLOAD_URL" "$CLI_TMP_FILE" + getFile "$DOWNLOAD_URL" "$ARDUINO_LINT_TMP_FILE" fi fi } installFile() { - CLI_TMP="/tmp/$PROJECT_NAME" - mkdir -p "$CLI_TMP" + ARDUINO_LINT_TMP="/tmp/$PROJECT_NAME" + mkdir -p "$ARDUINO_LINT_TMP" if [ "$OS" = "Windows" ]; then - unzip -d "$CLI_TMP" "$CLI_TMP_FILE" + unzip -d "$ARDUINO_LINT_TMP" "$ARDUINO_LINT_TMP_FILE" else - tar xf "$CLI_TMP_FILE" -C "$CLI_TMP" + tar xf "$ARDUINO_LINT_TMP_FILE" -C "$ARDUINO_LINT_TMP" fi - CLI_TMP_BIN="$CLI_TMP/$PROJECT_NAME" - cp "$CLI_TMP_BIN" "$LBINDIR" - rm -rf $CLI_TMP - rm -f $CLI_TMP_FILE + ARDUINO_LINT_TMP_BIN="$ARDUINO_LINT_TMP/$PROJECT_NAME" + cp "$ARDUINO_LINT_TMP_BIN" "$LBINDIR" + rm -rf $ARDUINO_LINT_TMP + rm -f $ARDUINO_LINT_TMP_FILE } bye() { @@ -187,21 +186,21 @@ bye() { testVersion() { set +e - CLI="$(which $PROJECT_NAME)" + ARDUINO_LINT="$(which $PROJECT_NAME)" if [ "$?" = "1" ]; then echo "$PROJECT_NAME not found. You might want to add "$LBINDIR" to your "'$PATH' else # Convert to resolved, absolute paths before comparison - CLI_REALPATH="$(cd -- "$(dirname -- "$CLI")" && pwd -P)" + ARDUINO_LINT_REALPATH="$(cd -- "$(dirname -- "$ARDUINO_LINT")" && pwd -P)" LBINDIR_REALPATH="$(cd -- "$LBINDIR" && pwd -P)" - if [ "$CLI_REALPATH" != "$LBINDIR_REALPATH" ]; then - echo "An existing $PROJECT_NAME was found at $CLI. Please prepend "$LBINDIR" to your "'$PATH'" or remove the existing one." + if [ "$ARDUINO_LINT_REALPATH" != "$LBINDIR_REALPATH" ]; then + echo "An existing $PROJECT_NAME was found at $ARDUINO_LINT. Please prepend "$LBINDIR" to your "'$PATH'" or remove the existing one." fi fi set -e - CLI_VERSION=$($LBINDIR/$PROJECT_NAME version) - echo "$CLI_VERSION installed successfully in $LBINDIR" + ARDUINO_LINT_VERSION=$($LBINDIR/$PROJECT_NAME version) + echo "$ARDUINO_LINT_VERSION installed successfully in $LBINDIR" } From ad7f0b1ecd3b54ec118625d07ba5e2351a54f52a Mon Sep 17 00:00:00 2001 From: per1234 <accounts@perglass.com> Date: Tue, 15 Dec 2020 19:56:22 -0800 Subject: [PATCH 4/9] Format installation script Using the default configuration of shfmt. --- .github/workflows/check-formatting.yml | 6 +++++ Taskfile.yml | 11 +++++++++ install.sh | 33 +++++++++++++------------- 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/.github/workflows/check-formatting.yml b/.github/workflows/check-formatting.yml index 92e1de761..b7c3cb06c 100644 --- a/.github/workflows/check-formatting.yml +++ b/.github/workflows/check-formatting.yml @@ -39,6 +39,12 @@ jobs: - name: Check Go code formatting run: task go:check-formatting + - name: Check shell script formatting + # https://github.com/mvdan/sh + run: | + docker run --volume "$GITHUB_WORKSPACE/libraries/spell-check":/mnt --workdir /mnt mvdan/shfmt:latest -w . + git diff --color --exit-code + - name: Check documentation formatting run: task docs:check-formatting diff --git a/Taskfile.yml b/Taskfile.yml index 3ac4d6585..c44021f6b 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -203,6 +203,17 @@ tasks: cmds: - npx {{ .PRETTIER }} --write "**/*.md" + shell:check-formatting: + desc: Format shell scripts + cmds: + # https://github.com/mvdan/sh#shfmt + - shfmt -d . + + shell:format: + desc: Format shell scripts + cmds: + - shfmt -l -w . + config:check: desc: Lint and check formatting of configuration files cmds: diff --git a/install.sh b/install.sh index f71c3dde1..9d70c74d1 100755 --- a/install.sh +++ b/install.sh @@ -33,7 +33,7 @@ initDestination() { LBINDIR="$BINDIR" else if [ ! -d "$DEFAULT_BINDIR" ]; then - mkdir "$DEFAULT_BINDIR" + mkdir "$DEFAULT_BINDIR" fi LBINDIR="$DEFAULT_BINDIR" fi @@ -43,14 +43,14 @@ initDestination() { initArch() { ARCH=$(uname -m) case $ARCH in - armv5*) ARCH="armv5";; - armv6*) ARCH="ARMv6";; - armv7*) ARCH="ARMv7";; - aarch64) ARCH="ARM64";; - x86) ARCH="32bit";; - x86_64) ARCH="64bit";; - i686) ARCH="32bit";; - i386) ARCH="32bit";; + armv5*) ARCH="armv5" ;; + armv6*) ARCH="ARMv6" ;; + armv7*) ARCH="ARMv7" ;; + aarch64) ARCH="ARM64" ;; + x86) ARCH="32bit" ;; + x86_64) ARCH="64bit" ;; + i686) ARCH="32bit" ;; + i386) ARCH="32bit" ;; esac echo "ARCH=$ARCH" } @@ -58,18 +58,18 @@ initArch() { initOS() { OS=$(uname -s) case "$OS" in - Linux*) OS='Linux' ;; - Darwin*) OS='macOS' ;; - MINGW*) OS='Windows';; - MSYS*) OS='Windows';; + Linux*) OS='Linux' ;; + Darwin*) OS='macOS' ;; + MINGW*) OS='Windows' ;; + MSYS*) OS='Windows' ;; esac echo "OS=$OS" } initDownloadTool() { - if type "curl" > /dev/null; then + if type "curl" >/dev/null; then DOWNLOAD_TOOL="curl" - elif type "wget" > /dev/null; then + elif type "wget" >/dev/null; then DOWNLOAD_TOOL="wget" else fail "You need curl or wget as download tool. Please install it first before continuing" @@ -106,7 +106,7 @@ get() { body=$(echo "$httpResponse" | sed -e 's/HTTPSTATUS\:.*//g') elif [ "$DOWNLOAD_TOOL" = "wget" ]; then tmpFile=$(mktemp) - body=$(wget --server-response --content-on-error -q -O - "$url" 2> $tmpFile || true) + body=$(wget --server-response --content-on-error -q -O - "$url" 2>$tmpFile || true) httpStatusCode=$(cat $tmpFile | awk '/^ HTTP/{print $2}') fi if [ "$httpStatusCode" != 200 ]; then @@ -203,7 +203,6 @@ testVersion() { echo "$ARDUINO_LINT_VERSION installed successfully in $LBINDIR" } - # Execution #Stop execution on any error From df1398a79130dd02c0e13c493464f216b579a11b Mon Sep 17 00:00:00 2001 From: per1234 <accounts@perglass.com> Date: Sun, 20 Dec 2020 02:36:50 -0800 Subject: [PATCH 5/9] Remove bashisms from install script Unfortunately, `local` is Bash-specific. The script's shebang (#!/bin/sh) indicates POSIX compliance was intended, so the use of `local` is not appropriate. I used the function name as a prefix "namespace" for the previously local variables in the attempt to achieve somewhat of the same effect in a POSIX-compliant manner. --- install.sh | 61 ++++++++++++++++++++++++++---------------------------- 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/install.sh b/install.sh index 9d70c74d1..f825000b3 100755 --- a/install.sh +++ b/install.sh @@ -67,9 +67,9 @@ initOS() { } initDownloadTool() { - if type "curl" >/dev/null; then + if command -v "curl" >/dev/null 2>&1; then DOWNLOAD_TOOL="curl" - elif type "wget" >/dev/null; then + elif command -v "wget" >/dev/null 2>&1; then DOWNLOAD_TOOL="wget" else fail "You need curl or wget as download tool. Please install it first before continuing" @@ -80,52 +80,49 @@ initDownloadTool() { checkLatestVersion() { # Use the GitHub releases webpage to find the latest version for this project # so we don't get rate-limited. - local tag - local regex="[0-9][A-Za-z0-9\.-]*" - local latest_url="https://github.com/${PROJECT_OWNER}/${PROJECT_NAME}/releases/latest" + CHECKLATESTVERSION_REGEX="[0-9][A-Za-z0-9\.-]*" + CHECKLATESTVERSION_LATEST_URL="https://github.com/${PROJECT_OWNER}/${PROJECT_NAME}/releases/latest" if [ "$DOWNLOAD_TOOL" = "curl" ]; then - tag=$(curl -SsL $latest_url | grep -o "<title>Release $regex · ${PROJECT_OWNER}/${PROJECT_NAME}" | grep -o "$regex") + CHECKLATESTVERSION_TAG=$(curl -SsL $CHECKLATESTVERSION_LATEST_URL | grep -o "<title>Release $CHECKLATESTVERSION_REGEX · ${PROJECT_OWNER}/${PROJECT_NAME}" | grep -o "$CHECKLATESTVERSION_REGEX") elif [ "$DOWNLOAD_TOOL" = "wget" ]; then - tag=$(wget -q -O - $latest_url | grep -o "<title>Release $regex · ${PROJECT_OWNER}/${PROJECT_NAME}" | grep -o "$regex") + CHECKLATESTVERSION_TAG=$(wget -q -O - $CHECKLATESTVERSION_LATEST_URL | grep -o "<title>Release $CHECKLATESTVERSION_REGEX · ${PROJECT_OWNER}/${PROJECT_NAME}" | grep -o "$CHECKLATESTVERSION_REGEX") fi - if [ "x$tag" = "x" ]; then + if [ "x$CHECKLATESTVERSION_TAG" = "x" ]; then echo "Cannot determine latest tag." exit 1 fi - eval "$1='$tag'" + eval "$1='$CHECKLATESTVERSION_TAG'" } get() { - local url="$2" - local body - local httpStatusCode - echo "Getting $url" + GET_URL="$2" + echo "Getting $GET_URL" if [ "$DOWNLOAD_TOOL" = "curl" ]; then - httpResponse=$(curl -sL --write-out HTTPSTATUS:%{http_code} "$url") - httpStatusCode=$(echo $httpResponse | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') - body=$(echo "$httpResponse" | sed -e 's/HTTPSTATUS\:.*//g') + GET_HTTP_RESPONSE=$(curl -sL --write-out 'HTTPSTATUS:%{http_code}' "$GET_URL") + GET_HTTP_STATUS_CODE=$(echo $GET_HTTP_RESPONSE | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') + GET_BODY=$(echo "$GET_HTTP_RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g') elif [ "$DOWNLOAD_TOOL" = "wget" ]; then - tmpFile=$(mktemp) - body=$(wget --server-response --content-on-error -q -O - "$url" 2>$tmpFile || true) - httpStatusCode=$(cat $tmpFile | awk '/^ HTTP/{print $2}') + TMP_FILE=$(mktemp) + GET_BODY=$(wget --server-response --content-on-error -q -O - "$GET_URL" 2>$TMP_FILE || true) + GET_HTTP_STATUS_CODE=$(cat $TMP_FILE | awk '/^ HTTP/{print $2}') fi - if [ "$httpStatusCode" != 200 ]; then - echo "Request failed with HTTP status code $httpStatusCode" - fail "Body: $body" + if [ "$GET_HTTP_STATUS_CODE" != 200 ]; then + echo "Request failed with HTTP status code $GET_HTTP_STATUS_CODE" + fail "Body: $GET_BODY" fi - eval "$1='$body'" + eval "$1='$GET_BODY'" } getFile() { - local url="$1" - local filePath="$2" + GETFILE_URL="$1" + GETFILE_FILE_PATH="$2" if [ "$DOWNLOAD_TOOL" = "curl" ]; then - httpStatusCode=$(curl -s -w '%{http_code}' -L "$url" -o "$filePath") + GETFILE_HTTP_STATUS_CODE=$(curl -s -w '%{http_code}' -L "$GETFILE_URL" -o "$GETFILE_FILE_PATH") elif [ "$DOWNLOAD_TOOL" = "wget" ]; then - body=$(wget --server-response --content-on-error -q -O "$filePath" "$url") - httpStatusCode=$(cat $tmpFile | awk '/^ HTTP/{print $2}') + GETFILE_BODY=$(wget --server-response --content-on-error -q -O "$GETFILE_FILE_PATH" "$GETFILE_URL") + GETFILE_HTTP_STATUS_CODE=$(cat $TMP_FILE | awk '/^ HTTP/{print $2}') fi - echo "$httpStatusCode" + echo "$GETFILE_HTTP_STATUS_CODE" } downloadFile() { @@ -177,11 +174,11 @@ installFile() { } bye() { - result=$? - if [ "$result" != "0" ]; then + BYE_RESULT=$? + if [ "$BYE_RESULT" != "0" ]; then echo "Failed to install $PROJECT_NAME" fi - exit $result + exit $BYE_RESULT } testVersion() { From a85d1d62475f278d19ba6db11542d80427636d66 Mon Sep 17 00:00:00 2001 From: per1234 <accounts@perglass.com> Date: Sun, 20 Dec 2020 02:50:55 -0800 Subject: [PATCH 6/9] Bring install script into ShellCheck compliance ShellCheck is a static analysis tool for shell scripts. --- .github/workflows/lint-shell.yml | 28 +++++++++++++++++++ Taskfile.yml | 8 ++++++ install.sh | 47 ++++++++++++++++++-------------- 3 files changed, 62 insertions(+), 21 deletions(-) create mode 100644 .github/workflows/lint-shell.yml diff --git a/.github/workflows/lint-shell.yml b/.github/workflows/lint-shell.yml new file mode 100644 index 000000000..4ed990c40 --- /dev/null +++ b/.github/workflows/lint-shell.yml @@ -0,0 +1,28 @@ +name: Lint shell scripts + +on: + push: + paths: + - ".github/workflows/lint-shell.yml" + - "**.sh" + pull_request: + paths: + - ".github/workflows/lint-shell.yml" + - "**.sh" + +jobs: + lint: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Install Taskfile + uses: arduino/actions/setup-taskfile@master + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Lint shell scripts + run: task shell:lint diff --git a/Taskfile.yml b/Taskfile.yml index c44021f6b..84e4a9562 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -203,6 +203,14 @@ tasks: cmds: - npx {{ .PRETTIER }} --write "**/*.md" + shell:lint: + desc: Lint shell scripts + cmds: + # https://github.com/koalaman/shellcheck + - | + shopt -s globstar # Needed to check all scripts recursively. + shellcheck ./**/*.sh + shell:check-formatting: desc: Format shell scripts cmds: diff --git a/install.sh b/install.sh index f825000b3..8eadefa07 100755 --- a/install.sh +++ b/install.sh @@ -17,7 +17,7 @@ PROJECT_OWNER="arduino" PROJECT_NAME="arduino-lint" # BINDIR represents the local bin location, defaults to ./bin. -LBINDIR="" +EFFECTIVE_BINDIR="" DEFAULT_BINDIR="$PWD/bin" fail() { @@ -28,16 +28,18 @@ fail() { initDestination() { if [ -n "$BINDIR" ]; then if [ ! -d "$BINDIR" ]; then + # The second instance of $BINDIR is intentionally a literal in this message. + # shellcheck disable=SC2016 fail "$BINDIR "'($BINDIR)'" folder not found. Please create it before continuing." fi - LBINDIR="$BINDIR" + EFFECTIVE_BINDIR="$BINDIR" else if [ ! -d "$DEFAULT_BINDIR" ]; then mkdir "$DEFAULT_BINDIR" fi - LBINDIR="$DEFAULT_BINDIR" + EFFECTIVE_BINDIR="$DEFAULT_BINDIR" fi - echo "Installing in $LBINDIR" + echo "Installing in $EFFECTIVE_BINDIR" } initArch() { @@ -99,12 +101,12 @@ get() { echo "Getting $GET_URL" if [ "$DOWNLOAD_TOOL" = "curl" ]; then GET_HTTP_RESPONSE=$(curl -sL --write-out 'HTTPSTATUS:%{http_code}' "$GET_URL") - GET_HTTP_STATUS_CODE=$(echo $GET_HTTP_RESPONSE | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') + GET_HTTP_STATUS_CODE=$(echo "$GET_HTTP_RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') GET_BODY=$(echo "$GET_HTTP_RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g') elif [ "$DOWNLOAD_TOOL" = "wget" ]; then TMP_FILE=$(mktemp) - GET_BODY=$(wget --server-response --content-on-error -q -O - "$GET_URL" 2>$TMP_FILE || true) - GET_HTTP_STATUS_CODE=$(cat $TMP_FILE | awk '/^ HTTP/{print $2}') + GET_BODY=$(wget --server-response --content-on-error -q -O - "$GET_URL" 2>"$TMP_FILE" || true) + GET_HTTP_STATUS_CODE=$(awk '/^ HTTP/{print $2}' "$TMP_FILE") fi if [ "$GET_HTTP_STATUS_CODE" != 200 ]; then echo "Request failed with HTTP status code $GET_HTTP_STATUS_CODE" @@ -119,14 +121,14 @@ getFile() { if [ "$DOWNLOAD_TOOL" = "curl" ]; then GETFILE_HTTP_STATUS_CODE=$(curl -s -w '%{http_code}' -L "$GETFILE_URL" -o "$GETFILE_FILE_PATH") elif [ "$DOWNLOAD_TOOL" = "wget" ]; then - GETFILE_BODY=$(wget --server-response --content-on-error -q -O "$GETFILE_FILE_PATH" "$GETFILE_URL") - GETFILE_HTTP_STATUS_CODE=$(cat $TMP_FILE | awk '/^ HTTP/{print $2}') + wget --server-response --content-on-error -q -O "$GETFILE_FILE_PATH" "$GETFILE_URL" + GETFILE_HTTP_STATUS_CODE=$(awk '/^ HTTP/{print $2}' "$TMP_FILE") fi echo "$GETFILE_HTTP_STATUS_CODE" } downloadFile() { - if [ -z $1 ]; then + if [ -z "$1" ]; then checkLatestVersion TAG else TAG=$1 @@ -146,7 +148,7 @@ downloadFile() { echo "Trying to find a release using the GitHub API." LATEST_RELEASE_URL="https://api.github.com/repos/${PROJECT_OWNER}/$PROJECT_NAME/releases/tags/$TAG" echo "LATEST_RELEASE_URL=$LATEST_RELEASE_URL" - get LATEST_RELEASE_JSON $LATEST_RELEASE_URL + get LATEST_RELEASE_JSON "$LATEST_RELEASE_URL" # || true forces this command to not catch error if grep does not find anything DOWNLOAD_URL=$(echo "$LATEST_RELEASE_JSON" | grep 'browser_' | cut -d\" -f4 | grep "$ARDUINO_LINT_DIST") || true if [ -z "$DOWNLOAD_URL" ]; then @@ -168,9 +170,9 @@ installFile() { tar xf "$ARDUINO_LINT_TMP_FILE" -C "$ARDUINO_LINT_TMP" fi ARDUINO_LINT_TMP_BIN="$ARDUINO_LINT_TMP/$PROJECT_NAME" - cp "$ARDUINO_LINT_TMP_BIN" "$LBINDIR" - rm -rf $ARDUINO_LINT_TMP - rm -f $ARDUINO_LINT_TMP_FILE + cp "$ARDUINO_LINT_TMP_BIN" "$EFFECTIVE_BINDIR" + rm -rf "$ARDUINO_LINT_TMP" + rm -f "$ARDUINO_LINT_TMP_FILE" } bye() { @@ -185,19 +187,22 @@ testVersion() { set +e ARDUINO_LINT="$(which $PROJECT_NAME)" if [ "$?" = "1" ]; then - echo "$PROJECT_NAME not found. You might want to add "$LBINDIR" to your "'$PATH' + # $PATH is intentionally a literal in this message. + # shellcheck disable=SC2016 + echo "$PROJECT_NAME not found. You might want to add \"$EFFECTIVE_BINDIR\" to your "'$PATH' else # Convert to resolved, absolute paths before comparison ARDUINO_LINT_REALPATH="$(cd -- "$(dirname -- "$ARDUINO_LINT")" && pwd -P)" - LBINDIR_REALPATH="$(cd -- "$LBINDIR" && pwd -P)" - if [ "$ARDUINO_LINT_REALPATH" != "$LBINDIR_REALPATH" ]; then - echo "An existing $PROJECT_NAME was found at $ARDUINO_LINT. Please prepend "$LBINDIR" to your "'$PATH'" or remove the existing one." + EFFECTIVE_BINDIR_REALPATH="$(cd -- "$EFFECTIVE_BINDIR" && pwd -P)" + if [ "$ARDUINO_LINT_REALPATH" != "$EFFECTIVE_BINDIR_REALPATH" ]; then + # shellcheck disable=SC2016 + echo "An existing $PROJECT_NAME was found at $ARDUINO_LINT. Please prepend \"$EFFECTIVE_BINDIR\" to your "'$PATH'" or remove the existing one." fi fi set -e - ARDUINO_LINT_VERSION=$($LBINDIR/$PROJECT_NAME version) - echo "$ARDUINO_LINT_VERSION installed successfully in $LBINDIR" + ARDUINO_LINT_VERSION="$("$EFFECTIVE_BINDIR/$PROJECT_NAME" version)" + echo "$ARDUINO_LINT_VERSION installed successfully in $EFFECTIVE_BINDIR" } # Execution @@ -209,6 +214,6 @@ set -e initArch initOS initDownloadTool -downloadFile $1 +downloadFile "$1" installFile testVersion From 9e98c0ef8b0d5f712814892c5cce1dd6ed125e58 Mon Sep 17 00:00:00 2001 From: per1234 <accounts@perglass.com> Date: Sun, 20 Dec 2020 05:07:40 -0800 Subject: [PATCH 7/9] Add installation instructions --- docs/index.md | 4 +++ docs/installation.md | 61 ++++++++++++++++++++++++++++++++++++++++++++ mkdocs.yml | 1 + 3 files changed, 66 insertions(+) create mode 100644 docs/installation.md diff --git a/docs/index.md b/docs/index.md index 90d5719a4..314d8bbff 100644 --- a/docs/index.md +++ b/docs/index.md @@ -5,6 +5,10 @@ Its focus is on the structure, metadata, and configuration of Arduino projects, [specification](https://arduino.github.io/arduino-cli/latest/library-specification) compliance, Library Manager submission [requirements](https://github.com/arduino/Arduino/wiki/Library-Manager-FAQ), and best practices. +## Installation + +See the [installation instructions](installation.md). + ## Getting started Once installed, you only need to open a terminal at your project folder and run the command: diff --git a/docs/installation.md b/docs/installation.md new file mode 100644 index 000000000..a25be9f97 --- /dev/null +++ b/docs/installation.md @@ -0,0 +1,61 @@ +## Use the install script + +The script requires `sh`, which is always available on Linux and macOS. `sh` is not available by default on Windows. The +script can be run on Windows by installing [Git for Windows](https://gitforwindows.org/), then running it from Git Bash. + +This script will install the latest version of arduino-lint to `$PWD/bin`: + +``` +curl -fsSL https://raw.githubusercontent.com/arduino/arduino-lint/main/install.sh | sh +``` + +If you want to target a different directory, for example `~/local/bin`, set the `BINDIR` environment variable like this: + +``` +curl -fsSL https://raw.githubusercontent.com/arduino/arduino-lint/main/install.sh | BINDIR=~/local/bin sh +``` + +If you would like to use the `arduino-lint` command from any location, install arduino-lint to a directory already in +your `PATH` or add the arduino-lint installation path to your `PATH` environment variable. + +If you want to download a specific arduino-lint version, for example `0.9.0`, pass the version number as a parameter +like this: + +``` +curl -fsSL https://raw.githubusercontent.com/arduino/arduino-lint/main/install.sh | sh -s 0.9.0 +``` + +### Download + +Pre-built binaries for all the supported platforms are available for download from the links below. + +If you would like to use the `arduino-lint` command from any location, extract the downloaded file to a directory +already in your `PATH` or add the arduino-lint installation path to your `PATH` environment variable. + +#### Latest release + +| Platform | | | +| --------- | -------------------- | -------------------- | +| Linux | [32 bit][linux32] | [64 bit][linux64] | +| Linux ARM | [32 bit][linuxarm32] | [64 bit][linuxarm64] | +| Windows | [32 bit][windows32] | [64 bit][windows64] | +| macOS | | [64 bit][macos] | + +[linux64]: https://downloads.arduino.cc/arduino-lint/arduino-lint_latest_Linux_64bit.tar.gz +[linux32]: https://downloads.arduino.cc/arduino-lint/arduino-lint_latest_Linux_32bit.tar.gz +[linuxarm64]: https://downloads.arduino.cc/arduino-lint/arduino-lint_latest_Linux_ARM64.tar.gz +[linuxarm32]: https://downloads.arduino.cc/arduino-lint/arduino-lint_latest_Linux_ARMv7.tar.gz +[windows64]: https://downloads.arduino.cc/arduino-lint/arduino-lint_latest_Windows_64bit.zip +[windows32]: https://downloads.arduino.cc/arduino-lint/arduino-lint_latest_Windows_32bit.zip +[macos]: https://downloads.arduino.cc/arduino-lint/arduino-lint_latest_macOS_64bit.tar.gz + +#### Previous versions + +These are available from the "Assets" sections on the [releases page](https://github.com/arduino/arduino-lint/releases). + +`https://downloads.arduino.cc/arduino-lint/nightly/nightly-<DATE>-checksums.txt` + +### Build from source + +If you’re familiar with Golang or if you want to contribute to the project, you will probably build arduino-lint locally +with your Go toolchain. See the ["How to contribute"](CONTRIBUTING.md#building-the-source-code) page for instructions. diff --git a/mkdocs.yml b/mkdocs.yml index a1784f8e0..8c2cbd726 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -46,6 +46,7 @@ markdown_extensions: # Navigation nav: - Documentation Home: index.md + - installation.md - Command reference: commands/arduino-lint.md - CONTRIBUTING.md From 72ecf03e5efbe7c0c0aabc1ef494994c9a636469 Mon Sep 17 00:00:00 2001 From: per1234 <accounts@perglass.com> Date: Sun, 20 Dec 2020 12:23:41 -0800 Subject: [PATCH 8/9] Move installation script to etc subfolder I would prefer to avoid cluttering up the root of the repository too much. The reason is that when people visit the repository on GitHub, they must scroll down past the root directory listing before getting to the readme. Some files and folders must be in the root, but there are some others (e.g., gon.config.hcl) that can be moved to a subfolder, so this move can be part of a larger campaign. --- docs/installation.md | 6 +++--- install.sh => etc/install.sh | 0 2 files changed, 3 insertions(+), 3 deletions(-) rename install.sh => etc/install.sh (100%) diff --git a/docs/installation.md b/docs/installation.md index a25be9f97..50de6bb8c 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -6,13 +6,13 @@ script can be run on Windows by installing [Git for Windows](https://gitforwindo This script will install the latest version of arduino-lint to `$PWD/bin`: ``` -curl -fsSL https://raw.githubusercontent.com/arduino/arduino-lint/main/install.sh | sh +curl -fsSL https://raw.githubusercontent.com/arduino/arduino-lint/main/etc/install.sh | sh ``` If you want to target a different directory, for example `~/local/bin`, set the `BINDIR` environment variable like this: ``` -curl -fsSL https://raw.githubusercontent.com/arduino/arduino-lint/main/install.sh | BINDIR=~/local/bin sh +curl -fsSL https://raw.githubusercontent.com/arduino/arduino-lint/main/etc/install.sh | BINDIR=~/local/bin sh ``` If you would like to use the `arduino-lint` command from any location, install arduino-lint to a directory already in @@ -22,7 +22,7 @@ If you want to download a specific arduino-lint version, for example `0.9.0`, pa like this: ``` -curl -fsSL https://raw.githubusercontent.com/arduino/arduino-lint/main/install.sh | sh -s 0.9.0 +curl -fsSL https://raw.githubusercontent.com/arduino/arduino-lint/main/etc/install.sh | sh -s 0.9.0 ``` ### Download diff --git a/install.sh b/etc/install.sh similarity index 100% rename from install.sh rename to etc/install.sh From ca03ece598747e4ec8454b15861bd9b9fe436a3f Mon Sep 17 00:00:00 2001 From: per1234 <accounts@perglass.com> Date: Sun, 20 Dec 2020 17:40:41 -0800 Subject: [PATCH 9/9] Use correct command to get version arduino-lint uses the --version flag. --- etc/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/install.sh b/etc/install.sh index 8eadefa07..c3bd00f79 100755 --- a/etc/install.sh +++ b/etc/install.sh @@ -201,7 +201,7 @@ testVersion() { fi set -e - ARDUINO_LINT_VERSION="$("$EFFECTIVE_BINDIR/$PROJECT_NAME" version)" + ARDUINO_LINT_VERSION="$("$EFFECTIVE_BINDIR/$PROJECT_NAME" --version)" echo "$ARDUINO_LINT_VERSION installed successfully in $EFFECTIVE_BINDIR" }