#!/bin/bash # author: Stefan Klinger # Database & Information Systems (DBIS) Group # Uni Konstanz # license: GNU Affero General Public License # file LICENSE, or set -u -e -C; shopt -s nullglob; # Redirect all output to stderr exec 1>&2; # Enforce C-locale to get character classes right export LC_ALL=C; # Set the PATH. PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'; # Set defined working directory. cd '/tmp'; # Get command line arguments. repo="$1"; txn="$2"; shift "$#"; # Kill stdin (lock tokens) cat >/dev/null; # Provide frontend to look at current repo and txn. function svnlook { cmd="${1}"; shift command svnlook "${cmd}" -t "${txn}" "${repo}" "$@"; } # Authors matching this regex are exempt from some tests. privilegedUsers=''; # Files matching this regex are exempt from some tests. privilegedPaths=''; # Maximum size of committed files maxFileSize="65535"; # file suffixes that are forbidden badSuffixes='mp3|ogg|mpeg|mp4|avi|png|jpeg|jpg|tiff'; # media files badSuffixes+='|pdf|od[tspgcfim]|xlsx?|pptx?|docx?|svgz?'; # office files badSuffixes+='|log|aux|out'; # LaTeX intermediates badSuffixes+='|i|o|s'; # C compiled badSuffixes+='|class'; # Java compiled badSuffixes+='|hi|o|dyn_hi|dyn_o'; # Haskell compiled badSuffixes+='|zip|rar|gz|bz2|xz|tgz'; # Compressed files # the only allowed characters in file names allowedChars='a-zA-Z0-9_+./-'; # read configuration conf="${repo}/hooks/pre-commit.config"; test -r "$conf" && source "$conf"; # is the author privileged? privileged=false; author="$(svnlook author)" && grep -Exq "${privilegedUsers}" <<< "${author}" && privileged=true; echo ' ##### Sanity check reports'; function bad { "$bad" || echo $'\n'"${path}"; bad=true; echo $'\t'"$@"; } # if the commit shall fail fail=false; while read path; do # Whether this file is bad. bad=false; grep -Exq -v "[${allowedChars}]*" <<< "${path}" && bad "Only use [${allowedChars}] in filenames. No spaces, no umlauts!" # privileged users are exempt from all following tests. "$bad" && fail=true; "$privileged" && continue; # privileged paths are exempt from all following tests. grep -Exq "${privilegedPaths}" <<< "${path}" && continue; # remaining tests only affect files, not directories grep -Eq '/$' <<< "${path}" && continue; # Limit size of individual files. # Not available with old SVN: size="$(svnlook filesize "$path")"; if size="$(svnlook cat "$path" | wc -c)"; then test "$size" -gt "${maxFileSize}" && bad "File is too big, $((size / 1024))kB."; else bad "Cannot determine file size"; fi; # Do not allow certain file types, indicated by suffix. grep -Eqi "\.(${badSuffixes})$" <<< "${path}" && bad "Files with this suffix are not allowed." # Set failure flag for this commit. "$bad" && fail=true; # from svnlook get those changes that are not about deleting files done < <(svnlook changed | sed -rn 's#^[^D].\s+(.*)$#\1#p'); if "$fail"; then cat <<'EOF' Add source code instead of executables, and LaTeX code instead of PDF-files. Add data generating scripts instead of generated data. Use links to online resources instead of adding downloaded files. Some files are not accepted, like "office" documents, images, temporary files generated by LaTeX, or compiled files. To remove them from the commit, use `svn revert `. Some characters (notably spaces and umlauts) must not appear in filenames. To rename added files, use `svn mv `. COMMIT ABORTED EOF exit 1; fi; exit 0;