diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e934ae8..a73003e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,6 +13,8 @@ jobs: matrix: features: - actionlint + - postgresql-client + - shellcheck baseImage: - debian:latest - ubuntu:latest @@ -29,6 +31,8 @@ jobs: matrix: features: - actionlint + - postgresql-client + - shellcheck continue-on-error: true steps: - uses: actions/checkout@v4 diff --git a/.shellcheckrc b/.shellcheckrc new file mode 100644 index 0000000..c0cc574 --- /dev/null +++ b/.shellcheckrc @@ -0,0 +1,9 @@ +# Enable all optional checks +enable=all + +# Follow source statements even when the file is not specified as input +external-sources=true + +# Disable check-extra-masked-returns +# https://www.shellcheck.net/wiki/SC2312 +disable=SC2312 diff --git a/src/shellcheck/README.md b/src/shellcheck/README.md new file mode 100644 index 0000000..d5dce07 --- /dev/null +++ b/src/shellcheck/README.md @@ -0,0 +1,24 @@ +# shellcheck + +Install [ShellCheck](https://www.shellcheck.net), a static analysis tool for shell scripts. + +## Usage + +```json +"features": { + "ghcr.io/CargoSense/devcontainer-features/shellcheck:1": {} +} +``` + +## Options + +| Option ID | Description | Type | Default Value | +|:--------------|:---------------------------------------------|:-------|:-----------------| +| `version` | The ShellCheck version to install. | string | `os-provided` | +| `installPath` | The path where ShellCheck will be installed. | string | `/usr/local/bin` | + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu and Linux distributions using the [apt](https://wiki.debian.org/AptCLI) management tool. + +`bash` is required to execute the `install.sh` script. diff --git a/src/shellcheck/devcontainer-feature.json b/src/shellcheck/devcontainer-feature.json new file mode 100644 index 0000000..204cc50 --- /dev/null +++ b/src/shellcheck/devcontainer-feature.json @@ -0,0 +1,25 @@ +{ + "name": "ShellCheck", + "id": "shellcheck", + "version": "1.0.0", + "description": "Install ShellCheck, a static analysis tool for shell scripts.", + "options": { + "version": { + "type": "string", + "proposals": [ + "latest", + "os-provided" + ], + "default": "os-provided", + "description": "Select or enter a ShellCheck version." + }, + "installPath": { + "type": "string", + "default": "/usr/local/bin", + "description": "The path where ShellCheck will be installed." + } + }, + "installsAfter": [ + "ghcr.io/devcontainers/features/common-utils" + ] + } diff --git a/src/shellcheck/install.sh b/src/shellcheck/install.sh new file mode 100755 index 0000000..93ebe4e --- /dev/null +++ b/src/shellcheck/install.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env sh + +set -e + +SHELLCHECK_VERSION="${VERSION:-"os-provided"}" +INSTALL_PATH="${INSTALLPATH:-"/usr/local/bin"}" + +if [ "$(id -u)" -ne 0 ]; then + printf 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' + exit 1 +fi + + +if [ "${SHELLCHECK_VERSION}" = "os-provided" ]; then + apt update --yes + apt install --no-install-recommends --yes shellcheck + + exit 0 +fi + +curl_installed="" + +if ! type curl >/dev/null 2>&1; then + apt update --yes + apt install --no-install-recommends --yes curl ca-certificates xz-utils + + curl_installed="true" +fi + +if [ "${SHELLCHECK_VERSION}" = "latest" ]; then + SHELLCHECK_VERSION="$(curl -s --head https://github.com/koalaman/shellcheck/releases/latest | sed -nr 's/location:.*\/v(.+)/\1/ip' | tr -d '\r')" +fi + +machine="$(uname -m)" +case "${machine}" in + aarch64) arch="aarch64" ;; + arm*) arch="armv6" ;; + x86_64) arch="x86_64" ;; + *) + echo "Could not determine arch from machine hardware name '${machine}'" >&2 + exit 1 + ;; +esac + +# https://github.com/koalaman/shellcheck/releases/download/v0.9.0/shellcheck-v0.9.0.linux.aarch64.tar.xz +file="shellcheck-v${SHELLCHECK_VERSION}.linux.${arch}.tar.xz" +url="https://github.com/koalaman/shellcheck/releases/download/v${SHELLCHECK_VERSION}/${file}" + +curl -sSL "${url}" | tar --strip-components=1 -Jxvf - -C "${INSTALL_PATH}" "shellcheck-v${SHELLCHECK_VERSION}/shellcheck" + +if [ -n "${curl_installed}" ]; then + apt purge curl xz-utils --autoremove --yes +fi diff --git a/test/shellcheck/scenarios.json b/test/shellcheck/scenarios.json new file mode 100644 index 0000000..e64f3c9 --- /dev/null +++ b/test/shellcheck/scenarios.json @@ -0,0 +1,19 @@ +{ + "shellcheck-version": { + "image": "debian:latest", + "features": { + "shellcheck": { + "version": "0.8.0" + } + } + }, + + "shellcheck-install-path": { + "image": "debian:latest", + "features": { + "shellcheck": { + "installPath": "/usr/bin" + } + } + } +} diff --git a/test/shellcheck/shellcheck-install-path.sh b/test/shellcheck/shellcheck-install-path.sh new file mode 100755 index 0000000..e515248 --- /dev/null +++ b/test/shellcheck/shellcheck-install-path.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +set -e + +# Optional: Import test library bundled with the devcontainer CLI +# See https://github.com/devcontainers/cli/blob/HEAD/docs/features/test.md#dev-container-features-test-lib +# Provides the 'check' and 'reportResults' commands. +# shellcheck source=/dev/null +source dev-container-features-test-lib + +# Feature-specific tests +# The 'check' command comes from the dev-container-features-test-lib. Syntax is... +# check