diff --git a/docs/faq.rst b/docs/faq.rst index 104235608a..28d08226de 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -90,6 +90,16 @@ The summary is: the mailing list. We know this part of Pigweed is incomplete and will help those who are interested in giving Pigweed a try. +Why doesn't Pigweed allow shell scripting? +------------------------------------------ +Pigweed supports multiple platforms. The native shells on these differ and +additionally "compatible" shells often have sububle differences in behavior. +Pigweed uses Python instead shell wherever practical and changes to Pigweed that +include shell scripting will likely be rejected. Users of Pigweed may use shell +scripts in their own code and we have included support for +`Shellcheck `_ during presubmit checks that is +automatically enabled if ``shellcheck`` found in the path. + What development hosts are supported? ------------------------------------- We support the following platforms: diff --git a/pw_presubmit/py/BUILD.gn b/pw_presubmit/py/BUILD.gn index 235e506dfe..e0e75aecd0 100644 --- a/pw_presubmit/py/BUILD.gn +++ b/pw_presubmit/py/BUILD.gn @@ -34,6 +34,7 @@ pw_python_package("py") { "pw_presubmit/pigweed_presubmit.py", "pw_presubmit/presubmit.py", "pw_presubmit/python_checks.py", + "pw_presubmit/shell_checks.py", "pw_presubmit/tools.py", ] tests = [ diff --git a/pw_presubmit/py/pw_presubmit/pigweed_presubmit.py b/pw_presubmit/py/pw_presubmit/pigweed_presubmit.py index 54a51372bd..d4cbc646a5 100755 --- a/pw_presubmit/py/pw_presubmit/pigweed_presubmit.py +++ b/pw_presubmit/py/pw_presubmit/pigweed_presubmit.py @@ -21,6 +21,7 @@ import os from pathlib import Path import re +import shutil import subprocess import sys from typing import Sequence, IO, Tuple, Optional, Callable, List @@ -50,6 +51,7 @@ PresubmitFailure, Programs, python_checks, + shell_checks, ) from pw_presubmit.install_hook import install_git_hook @@ -815,6 +817,7 @@ def renode_check(ctx: PresubmitContext): cpp_checks.pragma_once, build.bazel_lint, source_is_in_build_files, + shell_checks.shellcheck if shutil.which('shellcheck') else (), ) LINTFORMAT = ( diff --git a/pw_presubmit/py/pw_presubmit/shell_checks.py b/pw_presubmit/py/pw_presubmit/shell_checks.py new file mode 100644 index 0000000000..af50031bc4 --- /dev/null +++ b/pw_presubmit/py/pw_presubmit/shell_checks.py @@ -0,0 +1,35 @@ +# Copyright 2021 The Pigweed Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +"""Shell related checks.""" + +import logging +from pw_presubmit import (Check, PresubmitContext, filter_paths, tools, + PresubmitFailure) + +_LOG = logging.getLogger(__name__) + +_SHELL_EXTENSIONS = ('.sh', '.bash') + + +@filter_paths(endswith=_SHELL_EXTENSIONS) +@Check +def shellcheck(ctx: PresubmitContext) -> None: + """Run shell script static analiyzer on presubmit.""" + + _LOG.warning("The Pigweed project discourages use of shellscripts. " + "https://pigweed.dev/docs/faq.html") + + result = tools.log_run(['shellcheck', *ctx.paths]) + if result.returncode != 0: + raise PresubmitFailure('Shellcheck identifed issues.')