From 79ef9b4efc307aa0aebfbeb5b0c120a3ad525399 Mon Sep 17 00:00:00 2001 From: Aneesh Agrawal Date: Thu, 4 Aug 2016 15:16:04 -0400 Subject: [PATCH] Add lint for backticks in shell scripts The "$(some_command arg1 arg2)" form is preferred to the `some_command arg1 arg2` form because it nests unambiguously. Add a lint for this to tidy. --- ports/geckolib/gecko_bindings/tools/regen.sh | 4 +-- .../gecko_bindings/tools/setup_bindgen.sh | 4 +-- python/tidy/servo_tidy/tidy.py | 27 ++++++++++++------- python/tidy/servo_tidy_tests/shell_tidy.sh | 2 ++ python/tidy/servo_tidy_tests/test_tidy.py | 1 + 5 files changed, 24 insertions(+), 14 deletions(-) diff --git a/ports/geckolib/gecko_bindings/tools/regen.sh b/ports/geckolib/gecko_bindings/tools/regen.sh index 2d02bebdb34..21b998141c9 100755 --- a/ports/geckolib/gecko_bindings/tools/regen.sh +++ b/ports/geckolib/gecko_bindings/tools/regen.sh @@ -27,9 +27,9 @@ if [ ! -d /usr/include ]; then fi if [ "$(uname)" == "Linux" ]; then - LIBCLANG_PATH=/usr/lib/llvm-3.8/lib; + LIBCLANG_PATH=/usr/lib/llvm-3.8/lib else - LIBCLANG_PATH=`brew --prefix llvm38`/lib/llvm-3.8/lib; + LIBCLANG_PATH="$(brew --prefix llvm38)/lib/llvm-3.8/lib" fi ./regen.py --target all "$@" diff --git a/ports/geckolib/gecko_bindings/tools/setup_bindgen.sh b/ports/geckolib/gecko_bindings/tools/setup_bindgen.sh index d42bfc9adb4..31a81111b6d 100755 --- a/ports/geckolib/gecko_bindings/tools/setup_bindgen.sh +++ b/ports/geckolib/gecko_bindings/tools/setup_bindgen.sh @@ -13,9 +13,9 @@ cd "$(dirname $0)" # Setup and build bindgen. if [ "$(uname)" == "Linux" ]; then - export LIBCLANG_PATH=/usr/lib/llvm-3.8/lib; + export LIBCLANG_PATH=/usr/lib/llvm-3.8/lib else - export LIBCLANG_PATH=`brew --prefix llvm38`/lib/llvm-3.8/lib; + export LIBCLANG_PATH="$(brew --prefix llvm38)/lib/llvm-3.8/lib" fi # Make sure we have llvm38. diff --git a/python/tidy/servo_tidy/tidy.py b/python/tidy/servo_tidy/tidy.py index 34eea7f882a..d47aa0137a0 100644 --- a/python/tidy/servo_tidy/tidy.py +++ b/python/tidy/servo_tidy/tidy.py @@ -318,19 +318,23 @@ def check_shell(file_name, lines): shebang = "#!/usr/bin/env bash" required_options = {"set -o errexit", "set -o nounset", "set -o pipefail"} + did_shebang_check = False + if len(lines) == 0: yield (0, 'script is an empty file') - else: - if lines[0].rstrip() != shebang: - yield (1, 'script does not have shebang "{}"'.format(shebang)) + return - for idx in range(1, len(lines)): - stripped = lines[idx].rstrip() + if lines[0].rstrip() != shebang: + yield (1, 'script does not have shebang "{}"'.format(shebang)) - # Comments or blank lines are ignored. (Trailing whitespace is caught with a separate linter.) - if lines[idx].startswith("#") or stripped == "": - continue - elif stripped in required_options: + for idx in range(1, len(lines)): + stripped = lines[idx].rstrip() + # Comments or blank lines are ignored. (Trailing whitespace is caught with a separate linter.) + if lines[idx].startswith("#") or stripped == "": + continue + + if not did_shebang_check: + if stripped in required_options: required_options.remove(stripped) else: # The first non-comment, non-whitespace, non-option line is the first "real" line of the script. @@ -338,7 +342,10 @@ def check_shell(file_name, lines): if len(required_options) != 0: formatted = ['"{}"'.format(opt) for opt in required_options] yield (idx + 1, "script is missing options {}".format(", ".join(formatted))) - break + did_shebang_check = True + + if "`" in stripped: + yield (idx + 1, "script should not use backticks for command substitution") def check_rust(file_name, lines): diff --git a/python/tidy/servo_tidy_tests/shell_tidy.sh b/python/tidy/servo_tidy_tests/shell_tidy.sh index fbf0e784755..ff8e5fc7240 100644 --- a/python/tidy/servo_tidy_tests/shell_tidy.sh +++ b/python/tidy/servo_tidy_tests/shell_tidy.sh @@ -4,4 +4,6 @@ set -o nounset +# Talking about some `concept in backticks` # shouldn't trigger echo "hello world" +some_var=`echo "command substitution"` diff --git a/python/tidy/servo_tidy_tests/test_tidy.py b/python/tidy/servo_tidy_tests/test_tidy.py index b08e6057541..58e8f6e5fd3 100644 --- a/python/tidy/servo_tidy_tests/test_tidy.py +++ b/python/tidy/servo_tidy_tests/test_tidy.py @@ -52,6 +52,7 @@ class CheckTidiness(unittest.TestCase): errors = tidy.collect_errors_for_files(iterFile('shell_tidy.sh'), [], [tidy.check_shell], print_text=False) self.assertEqual('script does not have shebang "#!/usr/bin/env bash"', errors.next()[2]) self.assertEqual('script is missing options "set -o errexit", "set -o pipefail"', errors.next()[2]) + self.assertEqual('script should not use backticks for command substitution', errors.next()[2]) self.assertNoMoreErrors(errors) def test_rust(self):