#!/bin/sh # # Copyright (c) 2017, United States Government, as represented by the # Administrator of the National Aeronautics and Space Administration. # # All rights reserved. # # The Astrobee platform is 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 # # http://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. py_changed=$(git diff --diff-filter=d --cached --name-only | grep -v '\.launch\.py$' | grep -v '\.test\.py$' | grep '\.py$') # If py_changed is empty exit success if [ -z "${py_changed}" ]; then echo "==================================================" echo " No Python files changed, no checks needed." exit 0 fi failed_lint=false command -v black > /dev/null 2>&1 ans=$? if [ "$ans" -ne "0" ]; then echo "'black' was not found. To install, check https://github.com/psf/black." echo "Note that black requires Python 3.6.2+ to run." exit 0 fi command -v isort > /dev/null 2>&1 ans=$? if [ "$ans" -ne "0" ]; then echo "'isort' was not found. To install, check https://github.com/PyCQA/isort." exit 0 fi echo "==================================================" # Change black's default files to exclude: # - Remove 'build' folder. We have a Python script in a 'build' folder. # - Add '*.launch.py'. Black's styling doesn't work well for ROS2 # Python launch files. The ROS2 examples use a more compact # style that is much easier to read. # default_black_exclude="/(\.direnv|\.eggs|\.git|\.hg|\.mypy_cache|\.nox|\.tox|\.venv|venv|\.svn|_build|buck-out|build|dist)/" black_exclude="(/(\.direnv|\.eggs|\.git|\.hg|\.mypy_cache|\.nox|\.tox|\.venv|venv|\.svn|_build|buck-out|dist)/|\.launch\.py\$)" # This check the files but they will not be commited if `black . --include ${py_changed} --check --quiet`; then echo "Linter checks using 'black' passed." else echo " Analysing python code style with 'black'." if $(black . --include ${files_black} --exclude "$black_exclude" --check --quiet); then echo "Linter checks using 'black' passed." else echo "Errors detected with 'black'. Fixing them. Try to add and commit your files again." black . --include ${py_changed} failed_lint=true fi fi echo "==================================================" echo " Analysing python code style with 'isort'." # We're running isort recursively on the top-level folder (not # limiting it to the changed files) in order to match how it is # invoked in the CI workflow. This is because isort determines what # imports are treated as first party, and therefore should be grouped # separately, in part based on what files it is asked to process. We # definitely don't want to have any disagreement where this pre-commit # hook wants things grouped one way but the CI workflow says that's # wrong. Note that our intention is for isort to treat all imports # found in the astrobee repo as first party, and we specify that using # the src_paths setting in the .isort.cfg file. But we should still # run isort consistently in both places to avoid disagreement, which # could happen for example if the .isort.cfg src_paths list gets out # of date. if $(isort . --extend-skip cmake --profile black --diff --check-only --quiet >/dev/null); then echo "Linter checks using 'isort' passed." else echo "Errors detected with 'isort'. Fixing them. Try to add and commit your files again." isort . --extend-skip cmake --profile black >/dev/null failed_lint=true fi # Cancel commit if linter failed # The user should add manually the corrected files if ${failed_lint}; then exit 1 fi