#!/bin/bash
set -e
RED = '\033[0;31m'
GREEN = '\033[0;32m'
UNDERLINE = '\033[4m'
BOLD = '\033[1m'
NC = '\033[0m'
DIR = " $( cd " $( dirname " ${ BASH_SOURCE [0] } " ) " >/dev/null && pwd ) "
cd $DIR /../
FAILED = 0
IGNORED_FILES = "uv\.lock|docs\/CARS.md"
IGNORED_DIRS = "^third_party.*|^msgq.*|^msgq_repo.*|^opendbc.*|^opendbc_repo.*|^cereal.*|^panda.*|^rednose.*|^rednose_repo.*|^tinygrad.*|^tinygrad_repo.*|^teleoprtc.*|^teleoprtc_repo.*"
function run( ) {
shopt -s extglob
case $1 in
$SKIP | $RUN ) return 0 ; ;
esac
echo -en " $1 "
for ( ( i = 0; i<$(( 50 - ${# 1 } )) ; i++) ) ; do
echo -n "."
done
shift 1;
CMD = " $@ "
set +e
log = " $(( eval " $CMD " ) 2 >& 1 ) "
if [ [ $? -eq 0 ] ] ; then
echo -e " [ ${ GREEN } ✔ ${ NC } ] "
else
echo -e " [ ${ RED } ✗ ${ NC } ] "
echo " $log "
FAILED = 1
fi
set -e
}
function run_tests( ) {
ALL_FILES = $1
PYTHON_FILES = $2
run "ruff" ruff check $PYTHON_FILES --quiet
run "lint-imports" lint-imports
run "check_added_large_files" python3 -m pre_commit_hooks.check_added_large_files --enforce-all $ALL_FILES --maxkb= 120
run "check_shebang_scripts_are_executable" python3 -m pre_commit_hooks.check_shebang_scripts_are_executable $ALL_FILES
if [ [ -z " $FAST " ] ] ; then
run "mypy" mypy $PYTHON_FILES
run "codespell" codespell $ALL_FILES
fi
return $FAILED
}
function help( ) {
echo "A fast linter"
echo ""
echo -e " ${ BOLD } ${ UNDERLINE } Usage: ${ NC } op lint [TESTS] [OPTIONS] "
echo ""
echo -e " ${ BOLD } ${ UNDERLINE } Tests: ${ NC } "
echo -e " ${ BOLD } ruff ${ NC } "
echo -e " ${ BOLD } mypy ${ NC } "
echo -e " ${ BOLD } lint-imports ${ NC } "
echo -e " ${ BOLD } codespell ${ NC } "
echo -e " ${ BOLD } check_added_large_files ${ NC } "
echo -e " ${ BOLD } check_shebang_scripts_are_executable ${ NC } "
echo ""
echo -e " ${ BOLD } ${ UNDERLINE } Options: ${ NC } "
echo -e " ${ BOLD } -f, --fast ${ NC } "
echo " Skip slow tests"
echo -e " ${ BOLD } -s, --skip ${ NC } "
echo " Specify tests to skip separated by spaces"
echo ""
echo -e " ${ BOLD } ${ UNDERLINE } Examples: ${ NC } "
echo " op lint mypy ruff"
echo " Only run the mypy and ruff tests"
echo ""
echo " op lint --skip mypy ruff"
echo " Skip the mypy and ruff tests"
echo ""
echo " op lint"
echo " Run all the tests"
}
SKIP = ""
RUN = ""
while [ [ $# -gt 0 ] ] ; do
case $1 in
-f | --fast ) shift 1; FAST = "1" ; ;
-s | --skip ) shift 1; SKIP = " " ; ;
-h | --help | -help | --h ) help; exit 0 ; ;
* ) if [ [ -n $SKIP ] ] ; then SKIP += " $1 " ; else RUN += " $1 " ; fi ; shift 1 ; ;
esac
done
RUN = $( [ -z " $RUN " ] && echo "" || echo " !( $( echo $RUN | sed 's/ /|/g' ) ) " )
SKIP = " @( $( echo $SKIP | sed 's/ /|/g' ) ) "
GIT_FILES = " $( git ls-files | sed -E " s/ $IGNORED_FILES | $IGNORED_DIRS //g " ) "
ALL_FILES = ""
for f in $GIT_FILES ; do
if [ [ -f $f ] ] ; then
ALL_FILES += " $f " $'\n'
fi
done
PYTHON_FILES = $( echo " $ALL_FILES " | grep --color= never '.py$' || true )
run_tests " $ALL_FILES " " $PYTHON_FILES "