Skip to content

Commit

Permalink
Add ShellCheck feature (#3)
Browse files Browse the repository at this point in the history
Most useful for… this project!
  • Loading branch information
jgarber623-cargosense authored Feb 29, 2024
2 parents 40a439e + c960555 commit f2cc875
Show file tree
Hide file tree
Showing 9 changed files with 218 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ jobs:
matrix:
features:
- actionlint
- postgresql-client
- shellcheck
baseImage:
- debian:latest
- ubuntu:latest
Expand All @@ -29,6 +31,8 @@ jobs:
matrix:
features:
- actionlint
- postgresql-client
- shellcheck
continue-on-error: true
steps:
- uses: actions/checkout@v4
Expand Down
9 changes: 9 additions & 0 deletions .shellcheckrc
Original file line number Diff line number Diff line change
@@ -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
24 changes: 24 additions & 0 deletions src/shellcheck/README.md
Original file line number Diff line number Diff line change
@@ -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.
25 changes: 25 additions & 0 deletions src/shellcheck/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -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"
]
}
53 changes: 53 additions & 0 deletions src/shellcheck/install.sh
Original file line number Diff line number Diff line change
@@ -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
19 changes: 19 additions & 0 deletions test/shellcheck/scenarios.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
}
}
18 changes: 18 additions & 0 deletions test/shellcheck/shellcheck-install-path.sh
Original file line number Diff line number Diff line change
@@ -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 <LABEL> <cmd> [args...]
check "which shellcheck" bash -c "which shellcheck | grep /usr/bin/shellcheck"

# Report result
# If any of the checks above exited with a non-zero exit code, the test will fail.
reportResults
18 changes: 18 additions & 0 deletions test/shellcheck/shellcheck-version.sh
Original file line number Diff line number Diff line change
@@ -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 <LABEL> <cmd> [args...]
check "version" bash -c "shellcheck --version | grep 0.8.0"

# Report result
# If any of the checks above exited with a non-zero exit code, the test will fail.
reportResults
48 changes: 48 additions & 0 deletions test/shellcheck/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env bash

# This test file will be executed against an auto-generated devcontainer.json that
# includes the 'shellcheck' Feature with no options.
#
# For more information, see: https://github.com/devcontainers/cli/blob/main/docs/features/test.md
#
# Eg:
# {
# "image": "<..some-base-image...>",
# "features": {
# "shellcheck": {}
# },
# "remoteUser": "root"
# }
#
# Thus, the value of all options will fall back to the default value in the
# Feature's 'devcontainer-feature.json'.
#
# These scripts are run as 'root' by default. Although that can be changed
# with the '--remote-user' flag.
#
# This test can be run with the following command:
#
# devcontainer features test \
# --features shellcheck \
# --remote-user root \
# --skip-scenarios \
# --base-image mcr.microsoft.com/devcontainers/base:ubuntu \
# /path/to/this/repo

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 <LABEL> <cmd> [args...]
check "version" shellcheck --version
check "which shellcheck" bash -c "which shellcheck | grep /usr/bin/shellcheck"

# Report result
# If any of the checks above exited with a non-zero exit code, the test will fail.
reportResults

0 comments on commit f2cc875

Please sign in to comment.