mirror of
https://github.com/servo/servo.git
synced 2025-06-10 09:33:13 +00:00
Auto merge of #12736 - aneeshusa:prohibit-backticks-in-shell-scripts, r=Wafflespeanut
Add more shell script lints <!-- Please describe your changes on the following line: --> 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. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [ ] These changes fix #__ (github issue number if applicable). <!-- Either: --> - [x] There are tests for these changes OR - [ ] These changes do not require tests because _____ <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/12736) <!-- Reviewable:end -->
This commit is contained in:
commit
aa900b91aa
10 changed files with 63 additions and 35 deletions
|
@ -9,7 +9,7 @@ set -o nounset
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
TARGET_DIR="${OUT_DIR}/../../.."
|
TARGET_DIR="${OUT_DIR}/../../.."
|
||||||
arm-linux-androideabi-gcc "$@" \
|
arm-linux-androideabi-gcc "${@}" \
|
||||||
"${LDFLAGS-}" -lc -shared \
|
"${LDFLAGS-}" -lc -shared \
|
||||||
-o "${TARGET_DIR}/libservo.so"
|
-o "${TARGET_DIR}/libservo.so"
|
||||||
touch "${TARGET_DIR}/servo"
|
touch "${TARGET_DIR}/servo"
|
||||||
|
|
|
@ -9,5 +9,5 @@ set -o nounset
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
diff="$(git diff -- */*/Cargo.lock)"
|
diff="$(git diff -- */*/Cargo.lock)"
|
||||||
echo "$diff"
|
echo "${diff}"
|
||||||
[[ ! $diff ]]
|
[[ -z "${diff}" ]]
|
||||||
|
|
|
@ -17,5 +17,5 @@ set -o pipefail
|
||||||
./mach test-wpt --manifest-update --binary= SKIP_TESTS > /dev/null
|
./mach test-wpt --manifest-update --binary= SKIP_TESTS > /dev/null
|
||||||
|
|
||||||
diff="$(git diff -- tests/*/MANIFEST.json)"
|
diff="$(git diff -- tests/*/MANIFEST.json)"
|
||||||
echo "$diff"
|
echo "${diff}"
|
||||||
[[ ! $diff ]]
|
[[ -z "${diff}" ]]
|
||||||
|
|
|
@ -12,7 +12,7 @@ set -o errexit
|
||||||
set -o nounset
|
set -o nounset
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
cd "$(dirname $0)/../.."
|
cd "$(dirname ${0})/../.."
|
||||||
|
|
||||||
./mach doc
|
./mach doc
|
||||||
# etc/doc.servo.org/index.html overwrites $(mach rust-root)/doc/index.html
|
# etc/doc.servo.org/index.html overwrites $(mach rust-root)/doc/index.html
|
||||||
|
|
|
@ -27,7 +27,7 @@ upload() {
|
||||||
|
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
if [[ "$#" != 1 ]]; then
|
if [[ "${#}" != 1 ]]; then
|
||||||
usage >&2
|
usage >&2
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
@ -58,4 +58,4 @@ main() {
|
||||||
upload "${platform}" ${package} "${extension}"
|
upload "${platform}" ${package} "${extension}"
|
||||||
}
|
}
|
||||||
|
|
||||||
main "$@"
|
main "${@}"
|
||||||
|
|
|
@ -8,28 +8,28 @@ set -o errexit
|
||||||
set -o nounset
|
set -o nounset
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
if [ $# -eq 0 ]; then
|
if [[ ${#} -eq 0 ]]; then
|
||||||
echo "Usage: $0 /path/to/gecko/objdir [other-regen.py-flags]"
|
echo "Usage: ${0} /path/to/gecko/objdir [other-regen.py-flags]"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check for rust-bindgen
|
# Check for rust-bindgen
|
||||||
if [ ! -d rust-bindgen ]; then
|
if [[ ! -d rust-bindgen ]]; then
|
||||||
echo "rust-bindgen not found. Run setup_bindgen.sh first."
|
echo "rust-bindgen not found. Run setup_bindgen.sh first."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check for /usr/include
|
# Check for /usr/include
|
||||||
if [ ! -d /usr/include ]; then
|
if [[ ! -d /usr/include ]]; then
|
||||||
echo "/usr/include doesn't exist." \
|
echo "/usr/include doesn't exist." \
|
||||||
"Mac users may need to run xcode-select --install."
|
"Mac users may need to run xcode-select --install."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$(uname)" == "Linux" ]; then
|
if [[ "$(uname)" == "Linux" ]]; then
|
||||||
LIBCLANG_PATH=/usr/lib/llvm-3.8/lib;
|
LIBCLANG_PATH=/usr/lib/llvm-3.8/lib
|
||||||
else
|
else
|
||||||
LIBCLANG_PATH=`brew --prefix llvm38`/lib/llvm-3.8/lib;
|
LIBCLANG_PATH="$(brew --prefix llvm38)/lib/llvm-3.8/lib"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
./regen.py --target all "$@"
|
./regen.py --target all "${@}"
|
||||||
|
|
|
@ -9,33 +9,33 @@ set -o nounset
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
# Run in the tools directory.
|
# Run in the tools directory.
|
||||||
cd "$(dirname $0)"
|
cd "$(dirname ${0})"
|
||||||
|
|
||||||
# Setup and build bindgen.
|
# Setup and build bindgen.
|
||||||
if [ "$(uname)" == "Linux" ]; then
|
if [[ "$(uname)" == "Linux" ]]; then
|
||||||
export LIBCLANG_PATH=/usr/lib/llvm-3.8/lib;
|
export LIBCLANG_PATH=/usr/lib/llvm-3.8/lib
|
||||||
else
|
else
|
||||||
export LIBCLANG_PATH=`brew --prefix llvm38`/lib/llvm-3.8/lib;
|
export LIBCLANG_PATH="$(brew --prefix llvm38)/lib/llvm-3.8/lib"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Make sure we have llvm38.
|
# Make sure we have llvm38.
|
||||||
if [ ! -x "$(command -v clang-3.8)" ]; then
|
if [[ ! -x "$(command -v clang-3.8)" ]]; then
|
||||||
echo "llmv38 must be installed." \
|
echo "llmv38 must be installed." \
|
||||||
"Mac users should |brew install llvm38|, Linux varies by distro."
|
"Mac users should |brew install llvm38|, Linux varies by distro."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export LD_LIBRARY_PATH=$LIBCLANG_PATH
|
export LD_LIBRARY_PATH="${LIBCLANG_PATH}"
|
||||||
export DYLD_LIBRARY_PATH=$LIBCLANG_PATH
|
export DYLD_LIBRARY_PATH="${LIBCLANG_PATH}"
|
||||||
|
|
||||||
# Check for multirust
|
# Check for multirust
|
||||||
if [ ! -x "$(command -v multirust)" ]; then
|
if [[ ! -x "$(command -v multirust)" ]]; then
|
||||||
echo "multirust must be installed."
|
echo "multirust must be installed."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Don't try to clone twice.
|
# Don't try to clone twice.
|
||||||
if [ ! -d rust-bindgen ]; then
|
if [[ ! -d rust-bindgen ]]; then
|
||||||
git clone https://github.com/servo/rust-bindgen.git
|
git clone https://github.com/servo/rust-bindgen.git
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -318,19 +318,23 @@ def check_shell(file_name, lines):
|
||||||
shebang = "#!/usr/bin/env bash"
|
shebang = "#!/usr/bin/env bash"
|
||||||
required_options = {"set -o errexit", "set -o nounset", "set -o pipefail"}
|
required_options = {"set -o errexit", "set -o nounset", "set -o pipefail"}
|
||||||
|
|
||||||
|
did_shebang_check = False
|
||||||
|
|
||||||
if len(lines) == 0:
|
if len(lines) == 0:
|
||||||
yield (0, 'script is an empty file')
|
yield (0, 'script is an empty file')
|
||||||
else:
|
return
|
||||||
if lines[0].rstrip() != shebang:
|
|
||||||
yield (1, 'script does not have shebang "{}"'.format(shebang))
|
|
||||||
|
|
||||||
for idx in range(1, len(lines)):
|
if lines[0].rstrip() != shebang:
|
||||||
stripped = lines[idx].rstrip()
|
yield (1, 'script does not have shebang "{}"'.format(shebang))
|
||||||
|
|
||||||
# Comments or blank lines are ignored. (Trailing whitespace is caught with a separate linter.)
|
for idx in range(1, len(lines)):
|
||||||
if lines[idx].startswith("#") or stripped == "":
|
stripped = lines[idx].rstrip()
|
||||||
continue
|
# Comments or blank lines are ignored. (Trailing whitespace is caught with a separate linter.)
|
||||||
elif stripped in required_options:
|
if lines[idx].startswith("#") or stripped == "":
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not did_shebang_check:
|
||||||
|
if stripped in required_options:
|
||||||
required_options.remove(stripped)
|
required_options.remove(stripped)
|
||||||
else:
|
else:
|
||||||
# The first non-comment, non-whitespace, non-option line is the first "real" line of the script.
|
# The first non-comment, non-whitespace, non-option line is the first "real" line of the script.
|
||||||
|
@ -338,7 +342,20 @@ def check_shell(file_name, lines):
|
||||||
if len(required_options) != 0:
|
if len(required_options) != 0:
|
||||||
formatted = ['"{}"'.format(opt) for opt in required_options]
|
formatted = ['"{}"'.format(opt) for opt in required_options]
|
||||||
yield (idx + 1, "script is missing options {}".format(", ".join(formatted)))
|
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")
|
||||||
|
|
||||||
|
if " [ " in stripped or stripped.startswith("[ "):
|
||||||
|
yield (idx + 1, "script should use `[[` instead of `[` for conditional testing")
|
||||||
|
|
||||||
|
for dollar in re.finditer('\$', stripped):
|
||||||
|
next_idx = dollar.end()
|
||||||
|
if next_idx < len(stripped):
|
||||||
|
next_char = stripped[next_idx]
|
||||||
|
if not (next_char == '{' or next_char == '('):
|
||||||
|
yield(idx + 1, "variable substitutions should use the full \"${VAR}\" form")
|
||||||
|
|
||||||
|
|
||||||
def check_rust(file_name, lines):
|
def check_rust(file_name, lines):
|
||||||
|
|
|
@ -4,4 +4,11 @@
|
||||||
|
|
||||||
set -o nounset
|
set -o nounset
|
||||||
|
|
||||||
|
# Talking about some `concept in backticks` # shouldn't trigger
|
||||||
echo "hello world"
|
echo "hello world"
|
||||||
|
some_var=`echo "command substitution"`
|
||||||
|
another_var="$some_var"
|
||||||
|
if [ -z "${some_var}" ]; then
|
||||||
|
echo "should have used [["
|
||||||
|
fi
|
||||||
|
[ -z "${another_var}" ]
|
||||||
|
|
|
@ -52,6 +52,10 @@ class CheckTidiness(unittest.TestCase):
|
||||||
errors = tidy.collect_errors_for_files(iterFile('shell_tidy.sh'), [], [tidy.check_shell], print_text=False)
|
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 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 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.assertEqual('variable substitutions should use the full \"${VAR}\" form', errors.next()[2])
|
||||||
|
self.assertEqual('script should use `[[` instead of `[` for conditional testing', errors.next()[2])
|
||||||
|
self.assertEqual('script should use `[[` instead of `[` for conditional testing', errors.next()[2])
|
||||||
self.assertNoMoreErrors(errors)
|
self.assertNoMoreErrors(errors)
|
||||||
|
|
||||||
def test_rust(self):
|
def test_rust(self):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue