Skip to content

Commit

Permalink
Added a python helper for check_header.sh in git pre-commit script.
Browse files Browse the repository at this point in the history
On my box this speeds up the header check from 5 seconds to a little over 1 second.

```
 build-support/bin/check_header.sh        | 46 ++--------------------------------------------
 build-support/bin/check_header_helper.py | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+), 44 deletions(-)
```

Testing Done:
```
~/Src/Pants zundel/cheader * git commit -a
Checking packages
Checking imports
Checking headers
ERROR: All .py files other than __init__.py should start with the following header:

# coding=utf-8
# Copyright YYYY Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from __future__ import (absolute_import, division, generators, nested_scopes, print_function,
                        unicode_literals, with_statement)

---
The following 1 file(s) do not conform:
  src/grody.py
```

Bugs closed: 1250

Reviewed at https://rbcommons.com/s/twitter/r/1910/
  • Loading branch information
ericzundel committed Mar 13, 2015
1 parent 29ebcf0 commit fa44550
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 44 deletions.
46 changes: 2 additions & 44 deletions build-support/bin/check_header.sh
Original file line number Diff line number Diff line change
@@ -1,50 +1,8 @@
#!/usr/bin/env bash

set -euo pipefail
IFS=$'\n\t'
set -e

REPO_ROOT="$(git rev-parse --show-toplevel)"
cd ${REPO_ROOT}

expected_header=$(cat <<EOF
# coding=utf-8
# Copyright YYYY Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).
from __future__ import (absolute_import, division, generators, nested_scopes, print_function,
unicode_literals, with_statement)
EOF
)

py_files=$(find src tests pants-plugins examples contrib -name '*.py' -not -name __init__.py)
known_bad_headers=$(cat <<EOF
tests/python/pants_test/tasks/false.py
tests/python/pants_test/tasks/true.py
EOF
)

bad_files=""
for file in $py_files
do
if echo "$known_bad_headers" | grep -Fx "$file" >> /dev/null
then
#known bad file, skip
continue
fi
header=$(head -7 "$file"|sed -e 's/20[0-9][0-9]/YYYY/' -e 's/ / /g')
if [[ "$header" != "$expected_header" ]]
then
bad_files="${bad_files}"$'\n'"${file}"
fi
done

if [[ "x$bad_files" != "x" ]]
then
echo "ERROR: All .py files other than __init__.py should start with the following header"
echo "$expected_header"
echo "---"
echo "The following files don't:"
echo "$bad_files"
exit 1
fi
build-support/bin/check_header_helper.py src tests pants-plugins examples contrib
71 changes: 71 additions & 0 deletions build-support/bin/check_header_helper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/usr/bin/env python2.7
#
# Helper for check_headers.sh to check .py files in the repo to see if they start with the
# appropriate headers.
#
# usage: check_header_helper.py dir1 [ dir2 [ ... ] ]

import os
import re
import sys


EXPECTED_HEADER="""# coding=utf-8
# Copyright YYYY Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).
from __future__ import (absolute_import, division, generators, nested_scopes, print_function,
unicode_literals, with_statement)
"""


def check_header(filename):
"""Returns True if header check passes."""
try:
with open(filename, 'r') as pyfile:
buf = ""
for lineno in range(1,8):
line = pyfile.readline()
# Skip shebang line
if lineno == 1 and line.startswith('#!'):
line = pyfile.readline()
# Don't care much about the actual year, just that its there
if line.startswith("# Copyright"):
year = line[12:-4]
if not re.match(r'20\d\d', year):
return False
line = "# Copyright YYYY" + line[16:]
buf += line
return buf == EXPECTED_HEADER
except IOError:
return False

def check_dir(directory):
"""Returns list of files that fail the check."""
failed_files = []
for root, dirs, files in os.walk(directory):
for f in files:
if f.endswith('.py') and os.path.basename(f) != '__init__.py':
filename = os.path.join(root, f)
if not check_header(filename):
failed_files.append(filename)
return failed_files


def main():
dirs = sys.argv
failed_files = []
for directory in dirs:
failed_files.extend(check_dir(directory))
if failed_files:
print 'ERROR: All .py files other than __init__.py should start with the following header:'
print
print EXPECTED_HEADER
print '---'
print 'The following {} file(s) do not conform:'.format(len(failed_files))
print ' {}'.format('\n '.join(failed_files))
sys.exit(1)

if __name__ == '__main__':
main()

0 comments on commit fa44550

Please sign in to comment.