validate-extensions.py [plain text]
"""\
Check that any files pending commit into a Subversion repository have
suitable file extensions, printing an error and exiting with an
errorful value if any files fail validation. This is intended to be
used as a Subversion pre-commit hook script.
Syntax 1:
validate-extensions.py REPOS_PATH TXN_NAME deny EXT [...]
Ensure that any newly added files do *not* have one of the provided
file extensions.
Syntax 2:
validate-extensions.py REPOS_PATH TXN_NAME allow EXT [...]
Ensure that any newly added files *do* have one of the provided
file extensions. (Extension-less files are disallowed.)
"""
import sys
import os
from svn import repos, fs, core
def validate_added_extensions(repos_path, txn_name, extensions, action):
fs_ptr = repos.fs(repos.open(repos_path))
txn_t = fs.open_txn(fs_ptr, txn_name)
txn_root = fs.txn_root(txn_t)
changes = fs.svn_fs_paths_changed(txn_root)
paths = changes.keys()
for path in paths:
change = changes[path]
if change.change_kind == fs.path_change_delete:
continue
kind = fs.check_path(txn_root, path)
if kind != core.svn_node_file:
continue
if ((change.change_kind == fs.path_change_replace) \
or (change.change_kind == fs.path_change_add)):
copyfrom_rev, copyfrom_path = fs.copied_from(txn_root, path)
if copyfrom_rev == core.SVN_INVALID_REVNUM:
base, ext = os.path.splitext(path)
if ext:
ext = ext[1:].lower()
if ((ext in extensions) and (action == 'deny')) \
or ((ext not in extensions) and (action == 'allow')):
sys.stderr.write("Path '%s' has an extension disallowed by server "
"configuration.\n" % (path))
sys.exit(1)
def usage_and_exit(errmsg=None):
stream = errmsg and sys.stderr or sys.stdout
stream.write(__doc__)
if errmsg:
stream.write("ERROR: " + errmsg + "\n")
sys.exit(errmsg and 1 or 0)
def main():
argc = len(sys.argv)
if argc < 5:
usage_and_exit("Not enough arguments.")
repos_path = sys.argv[1]
txn_name = sys.argv[2]
action = sys.argv[3]
if action not in ("allow", "deny"):
usage_and_exit("Invalid action '%s'. Expected either 'allow' or 'deny'."
% (action))
extensions = [x.lower() for x in sys.argv[4:]]
validate_added_extensions(repos_path, txn_name, extensions, action)
if __name__ == "__main__":
main()