Commit a9afb687 authored by Georg Brandl's avatar Georg Brandl

#9095, #8912, #8999: add support in patchcheck for Mercurial checkouts, C file...

#9095, #8912, #8999: add support in patchcheck for Mercurial checkouts, C file reindenting, and docs whitespace fixing.
parent 50de5f56
import re
import sys
import shutil
import os.path import os.path
import subprocess import subprocess
import sys
import reindent import reindent
import untabify
def n_files_str(count): def n_files_str(count):
...@@ -29,17 +32,26 @@ def status(message, modal=False, info=None): ...@@ -29,17 +32,26 @@ def status(message, modal=False, info=None):
@status("Getting the list of files that have been added/changed", @status("Getting the list of files that have been added/changed",
info=lambda x: n_files_str(len(x))) info=lambda x: n_files_str(len(x)))
def changed_files(): def changed_files():
"""Run ``svn status`` and return a set of files that have been """Get the list of changed or added files from the VCS."""
changed/added. if os.path.isdir('.hg'):
""" vcs = 'hg'
cmd = 'svn status --quiet --non-interactive --ignore-externals' cmd = 'hg status --added --modified --no-status'
svn_st = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) elif os.path.isdir('.svn'):
svn_st.wait() vcs = 'svn'
output = (x.decode().rstrip().rsplit(None, 1)[-1] cmd = 'svn status --quiet --non-interactive --ignore-externals'
for x in svn_st.stdout if x[0] in b'AM') else:
return set(path for path in output if os.path.isfile(path)) sys.exit('need a checkout to get modified files')
st = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
st.wait()
if vcs == 'hg':
return [x.decode().rstrip() for x in st.stdout]
else:
output = (x.decode().rstrip().rsplit(None, 1)[-1]
for x in st.stdout if x[0] in b'AM')
return set(path for path in output if os.path.isfile(path))
def report_modified_files(file_paths): def report_modified_files(file_paths):
...@@ -64,6 +76,39 @@ def normalize_whitespace(file_paths): ...@@ -64,6 +76,39 @@ def normalize_whitespace(file_paths):
return fixed return fixed
@status("Fixing C file whitespace", info=report_modified_files)
def normalize_c_whitespace(file_paths):
"""Report if any C files """
fixed = []
for path in file_paths:
with open(path, 'r') as f:
if '\t' not in f.read():
continue
untabify.process(path, 8, verbose=False)
fixed.append(path)
return fixed
ws_re = re.compile(br'\s+(\r?\n)$')
@status("Fixing docs whitespace", info=report_modified_files)
def normalize_docs_whitespace(file_paths):
fixed = []
for path in file_paths:
try:
with open(path, 'rb') as f:
lines = f.readlines()
new_lines = [ws_re.sub(br'\1', line) for line in lines]
if new_lines != lines:
shutil.copyfile(path, path + '.bak')
with open(path, 'wb') as f:
f.writelines(new_lines)
fixed.append(path)
except Exception as err:
print('Cannot fix %s: %s' % (path, err))
return fixed
@status("Docs modified", modal=True) @status("Docs modified", modal=True)
def docs_modified(file_paths): def docs_modified(file_paths):
"""Report if any file in the Doc directory has been changed.""" """Report if any file in the Doc directory has been changed."""
...@@ -86,12 +131,16 @@ def main(): ...@@ -86,12 +131,16 @@ def main():
file_paths = changed_files() file_paths = changed_files()
python_files = [fn for fn in file_paths if fn.endswith('.py')] python_files = [fn for fn in file_paths if fn.endswith('.py')]
c_files = [fn for fn in file_paths if fn.endswith(('.c', '.h'))] c_files = [fn for fn in file_paths if fn.endswith(('.c', '.h'))]
docs = [fn for fn in file_paths if fn.startswith('Doc')] doc_files = [fn for fn in file_paths if fn.startswith('Doc')]
special_files = {'Misc/ACKS', 'Misc/NEWS'} & set(file_paths) special_files = {'Misc/ACKS', 'Misc/NEWS'} & set(file_paths)
# PEP 8 whitespace rules enforcement. # PEP 8 whitespace rules enforcement.
normalize_whitespace(python_files) normalize_whitespace(python_files)
# C rules enforcement.
normalize_c_whitespace(c_files)
# Doc whitespace enforcement.
normalize_docs_whitespace(doc_files)
# Docs updated. # Docs updated.
docs_modified(docs) docs_modified(doc_files)
# Misc/ACKS changed. # Misc/ACKS changed.
credit_given(special_files) credit_given(special_files)
# Misc/NEWS changed. # Misc/NEWS changed.
......
...@@ -3,27 +3,12 @@ ...@@ -3,27 +3,12 @@
# Make a reST file compliant to our pre-commit hook. # Make a reST file compliant to our pre-commit hook.
# Currently just remove trailing whitespace. # Currently just remove trailing whitespace.
import sys
import sys, re, shutil import patchcheck
ws_re = re.compile(br'\s+(\r?\n)$')
def main(argv=sys.argv): def main(argv=sys.argv):
rv = 0 patchcheck.normalize_docs_whitespace(argv[1:])
for filename in argv[1:]:
try:
with open(filename, 'rb') as f:
lines = f.readlines()
new_lines = [ws_re.sub(br'\1', line) for line in lines]
if new_lines != lines:
print('Fixing %s...' % filename)
shutil.copyfile(filename, filename + '.bak')
with open(filename, 'wb') as f:
f.writelines(new_lines)
except Exception as err:
print('Cannot fix %s: %s' % (filename, err))
rv = 1
return rv
if __name__ == '__main__': if __name__ == '__main__':
sys.exit(main()) sys.exit(main())
...@@ -25,7 +25,7 @@ def main(): ...@@ -25,7 +25,7 @@ def main():
process(filename, tabsize) process(filename, tabsize)
def process(filename, tabsize): def process(filename, tabsize, verbose=True):
try: try:
with open(filename) as f: with open(filename) as f:
text = f.read() text = f.read()
...@@ -46,7 +46,8 @@ def process(filename, tabsize): ...@@ -46,7 +46,8 @@ def process(filename, tabsize):
pass pass
with open(filename, "w") as f: with open(filename, "w") as f:
f.write(newtext) f.write(newtext)
print(filename) if verbose:
print(filename)
if __name__ == '__main__': if __name__ == '__main__':
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment