123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- #!/bin/sh
- #
- # Copyright 2024 Odin Kroeger
- #
- # This file is part of SieveManager.
- #
- # SieveManager is free software: you can redistribute it and/or
- # modify it under the terms of the GNU General Public License as
- # published by the Free Software Foundation, either version 3 of
- # the License, or (at your option) any later version.
- #
- # SieveManager is distributed in the hope that it will be useful,
- # but WITHOUT ALL WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public
- # License along with SieveManager. If not, see
- # <https://www.gnu.org/licenses/>.
- #
- set -Cefu
- #
- # Globals
- #
- progname="$(basename "$0")"
- : "${progname:="${0##*/}"}"
- readonly progname
- lockfile=".$progname.lock"
- readonly lockfile
- pylintflags='--disable=W0511'
- readonly pylintflags
- remote="$1"
- readonly remote
- repodir="$(git rev-parse --show-toplevel)"
- readonly repodir
- #
- # Functions
- #
- # Terminate children and clean up before exiting
- atexit() {
- # shellcheck disable=2319
- __atexit_retval="$?"
- trap '' EXIT HUP INT TERM
- set +e
- # shellcheck disable=2046
- kill -s TERM -- $(jobs -p) -$$ 2>/dev/null
- wait
- eval "${atexit-}"
- unset atexit
- return "$__atexit_retval"
- }
- # Catch a signal, clean up, and re-raise the signal
- catch() {
- caught="${1:?}"
- [ "${catch-}" ] || return 0
- atexit
- trap - "$caught"
- kill -s "$caught" "$$"
- }
- # Print a message to stderr and exit the process with a non-zero status
- err() {
- warn "$@"
- exit 1
- }
- # Wait to acquire a lock
- lock() (
- timeout="${1:?}"
- for i in $(seq 0 "$timeout")
- do
- if ( printf '%d\n' "$$" >"$lockfile"; ) >/dev/null 2>&1
- then
- return
- else
- read -r pid <"$lockfile" || :
- if ! [ "$pid" ] || ! kill -0 -- "$pid" >/dev/null 2>&1
- then
- warn "Removing stale $lockfile ..."
- rm -f .pre-push.lock
- elif [ "$i" -lt "$timeout" ]
- then
- sleep 1
- fi
- fi
- done
- warn "Could not acquire $lockfile in $timeout secs"
- return 1
- )
- # Remove the lockfile
- unlock() (
- if [ -e "$lockfile" ]
- then
- read -r pid <"$lockfile"
- if [ "$pid" ] && [ "$pid" -eq "$$" ]
- then rm -f "$lockfile"
- fi
- fi
- )
- # Print a warning to stderr
- warn() {
- printf '%s: %s\n' "$progname" "$*" >&2
- }
- #
- # Init
- #
- # Set up clean-up and signal handling
- trap atexit EXIT
- # shellcheck disable=2064
- for sig in HUP INT TERM
- do trap "catch $sig" "$sig"
- done
- caught=
- # Check that the repodir is set an accessible
- if ! [ "$repodir" ]
- then err "Could not locate repository"
- fi
- cd -P "$repodir" || exit
- # Make sure only one instance of pre-push is running at a time
- atexit="unlock ; ${atexit-}"
- lock 2
- #
- # Main
- #
- # Collect filenames
- sources=
- # shellcheck disable=2034
- while read -r localref localhash remoteref remotehash
- do
- branch="${remoteref##*/}"
- if [ "$(git ls-remote "$remote" "refs/heads/$branch")" ]
- then path="$remote/$branch"
- else path=
- fi
- # Filesnames should not contain whitespace
- # shellcheck disable=2086
- for file in $(git diff --name-only --diff-filter=d $path HEAD)
- do
- case $file in
- (*.py) sources="$sources $file"
- esac
- done
- readonly sources
- done
- # Check code
- if [ "$sources" ]
- then
- if ! git diff -s --exit-code
- then
- catch=
- git stash -q
- atexit="git stash pop -q; ${atexit-}"
- catch=y
- [ "$caught" ] && kill -s "$caught" "$$"
- fi
- # shellcheck disable=1091
- [ -e bin/activate ] && . ./bin/activate
- make "PYLINTFLAGS=$pylintflags" sources="${sources# }" check lint
- fi
|