diff --git a/docs/testing/linters.md b/docs/testing/linters.md index 8b7aab283a..931ef3d5f3 100644 --- a/docs/testing/linters.md +++ b/docs/testing/linters.md @@ -210,10 +210,19 @@ its CSS; see our [configuration](https://github.com/zulip/zulip/blob/master/.stylelintrc) for the rules we currently enforce. +#### Shell scripts + +Zulip uses [shellcheck](https://github.com/koalaman/shellcheck) to +lint our shell scripts. We recommend the +[shellcheck gallery of bad code][shellcheck-bad-code] as a resource on +how to not write bad shell. + +[shellcheck-bad-code]: https://github.com/koalaman/shellcheck/blob/master/README.md#user-content-gallery-of-bad-code + #### Markdown, shell scripts, JSON fixtures -We mostly validate miscellaneous source files like `.sh`, `.json`, and `.md` files for -whitespace issues. +We mostly validate miscellaneous source files like `.json`, and `.md` +files for whitespace issues. ## Philosophy diff --git a/scripts/lib/install-shellcheck b/scripts/lib/install-shellcheck new file mode 100755 index 0000000000..8ad7c338cf --- /dev/null +++ b/scripts/lib/install-shellcheck @@ -0,0 +1,14 @@ +#!/bin/bash +set -eu + +version=0.5.0 + +if ! out="$(shellcheck --version 2>/dev/null)" || [[ "$out" != *" +version: $version +"* ]]; then + tmpdir="$(mktemp -d)" + trap 'rm -r "$tmpdir"' EXIT + cd "$tmpdir" + wget -nv "https://storage.googleapis.com/shellcheck/shellcheck-v$version.linux.x86_64.tar.xz" + tar -xJf "shellcheck-v$version.linux.x86_64.tar.xz" --no-same-owner --strip-components=1 -C /usr/local/bin "shellcheck-v$version/shellcheck" +fi diff --git a/tools/lib/provision.py b/tools/lib/provision.py index b1e89f939d..101c8f2c87 100755 --- a/tools/lib/provision.py +++ b/tools/lib/provision.py @@ -260,6 +260,9 @@ def main(options): print(WARNING + "`yarn install` failed; retrying..." + ENDC) setup_node_modules() + # Install shellcheck. + run(["sudo", "scripts/lib/install-shellcheck"]) + # Import tools/setup_venv.py instead of running it so that we get an # activated virtualenv for the rest of the provisioning process. from tools.setup import setup_venvs diff --git a/tools/lint b/tools/lint index 0c6a1630bc..8328d861e6 100755 --- a/tools/lint +++ b/tools/lint @@ -97,6 +97,7 @@ def run(): linter_config.external_linter('templates', ['tools/check-templates'], ['handlebars', 'html']) linter_config.external_linter('urls', ['tools/check-urls'], ['py']) linter_config.external_linter('swagger', ['node', 'tools/check-swagger'], ['yaml']) + linter_config.external_linter('shellcheck', ['shellcheck', '-x'], ['sh']) # Disabled check for imperative mood until it is stabilized if not args.no_gitlint: diff --git a/tools/linter_lib/exclude.py b/tools/linter_lib/exclude.py index b51e5510c3..a2c341f4e3 100644 --- a/tools/linter_lib/exclude.py +++ b/tools/linter_lib/exclude.py @@ -8,6 +8,8 @@ EXCLUDED_FILES = [ "puppet/apt/manifests/release.pp", "puppet/apt/manifests/unattended_upgrades.pp", "puppet/stdlib/tests/file_line.pp", + "puppet/zulip/files/nagios_plugins/zulip_nagios_server/check_website_response.sh", + "scripts/lib/third", "static/third", # Transifex syncs translation.json files without trailing # newlines; there's nothing other than trailing newlines we'd be diff --git a/version.py b/version.py index 9aca420317..c6b531f157 100644 --- a/version.py +++ b/version.py @@ -8,4 +8,4 @@ ZULIP_VERSION = "1.9.0-rc2+git" # Typically, adding a dependency only requires a minor version bump, and # removing a dependency requires a major version bump. -PROVISION_VERSION = '26.9' +PROVISION_VERSION = '26.10'