style: make style hook work with pre-qrefresh and update to use new code
clean up the code a little bit while we're at it. I recommend that everyone adds the pre-qrefresh hook below since it will make qref run the style hook and not just commit/qpush [extensions] style = <m5 path>/util/style.py [hooks] pretxncommit.style = python:style.check_whitespace pre-qrefresh.style = python:style.check_whitespace
This commit is contained in:
parent
04f5bb34ce
commit
fe6574ecc0
3 changed files with 122 additions and 61 deletions
|
@ -165,6 +165,7 @@ style = %s/util/style.py
|
||||||
|
|
||||||
[hooks]
|
[hooks]
|
||||||
pretxncommit.style = python:style.check_whitespace
|
pretxncommit.style = python:style.check_whitespace
|
||||||
|
pre-qrefresh.style = python:style.check_whitespace
|
||||||
""" % (main.root)
|
""" % (main.root)
|
||||||
|
|
||||||
mercurial_bin_not_found = """
|
mercurial_bin_not_found = """
|
||||||
|
|
89
util/file_types.py
Normal file
89
util/file_types.py
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
# lanuage type for each file extension
|
||||||
|
lang_types = {
|
||||||
|
'.c' : "C",
|
||||||
|
'.h' : "C",
|
||||||
|
'.cc' : "C++",
|
||||||
|
'.hh' : "C++",
|
||||||
|
'.cxx' : "C++",
|
||||||
|
'.hxx' : "C++",
|
||||||
|
'.cpp' : "C++",
|
||||||
|
'.hpp' : "C++",
|
||||||
|
'.C' : "C++",
|
||||||
|
'.H' : "C++",
|
||||||
|
'.i' : "swig",
|
||||||
|
'.py' : "python",
|
||||||
|
'.pl' : "perl",
|
||||||
|
'.pm' : "perl",
|
||||||
|
'.s' : "asm",
|
||||||
|
'.S' : "asm",
|
||||||
|
'.l' : "lex",
|
||||||
|
'.ll' : "lex",
|
||||||
|
'.y' : "yacc",
|
||||||
|
'.yy' : "yacc",
|
||||||
|
'.isa' : "isa",
|
||||||
|
'.sh' : "shell",
|
||||||
|
'.slicc' : "slicc",
|
||||||
|
'.sm' : "slicc",
|
||||||
|
'.awk' : "awk",
|
||||||
|
'.el' : "lisp",
|
||||||
|
'.txt' : "text",
|
||||||
|
'.tex' : "tex",
|
||||||
|
}
|
||||||
|
|
||||||
|
# languages based on file prefix
|
||||||
|
lang_prefixes = (
|
||||||
|
('SCons', 'scons'),
|
||||||
|
('Make', 'make'),
|
||||||
|
('make', 'make'),
|
||||||
|
('Doxyfile', 'doxygen'),
|
||||||
|
)
|
||||||
|
|
||||||
|
# languages based on #! line of first file
|
||||||
|
hash_bang = (
|
||||||
|
('python', 'python'),
|
||||||
|
('perl', 'perl'),
|
||||||
|
('sh', 'shell'),
|
||||||
|
)
|
||||||
|
|
||||||
|
# the list of all languages that we detect
|
||||||
|
all_languages = frozenset(lang_types.itervalues())
|
||||||
|
all_languages |= frozenset(lang for start,lang in lang_prefixes)
|
||||||
|
all_languages |= frozenset(lang for start,lang in hash_bang)
|
||||||
|
|
||||||
|
def lang_type(filename, firstline=None, openok=True):
|
||||||
|
'''identify the language of a given filename and potentially the
|
||||||
|
firstline of the file. If the firstline of the file is not
|
||||||
|
provided and openok is True, open the file and read the first line
|
||||||
|
if necessary'''
|
||||||
|
|
||||||
|
basename = os.path.basename(filename)
|
||||||
|
name,extension = os.path.splitext(basename)
|
||||||
|
|
||||||
|
# first try to detect language based on file extension
|
||||||
|
try:
|
||||||
|
return lang_types[extension]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# now try to detect language based on file prefix
|
||||||
|
for start,lang in lang_prefixes:
|
||||||
|
if basename.startswith(start):
|
||||||
|
return start
|
||||||
|
|
||||||
|
# if a first line was not provided but the file is ok to open,
|
||||||
|
# grab the first line of the file.
|
||||||
|
if firstline is None and openok:
|
||||||
|
handle = file(filename, 'r')
|
||||||
|
firstline = handle.readline()
|
||||||
|
handle.close()
|
||||||
|
|
||||||
|
# try to detect language based on #! in first line
|
||||||
|
if firstline and firstline.startswith('#!'):
|
||||||
|
for string,lang in hash_bang:
|
||||||
|
if firstline.find(string) > 0:
|
||||||
|
return lang
|
||||||
|
|
||||||
|
# sorry, we couldn't detect the language
|
||||||
|
return None
|
|
@ -32,47 +32,17 @@ import re
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
sys.path.insert(0, os.path.dirname(__file__))
|
||||||
|
|
||||||
|
from file_types import lang_type
|
||||||
|
|
||||||
lead = re.compile(r'^([ \t]+)')
|
lead = re.compile(r'^([ \t]+)')
|
||||||
trail = re.compile(r'([ \t]+)$')
|
trail = re.compile(r'([ \t]+)$')
|
||||||
any_control = re.compile(r'\b(if|while|for)[ \t]*[(]')
|
any_control = re.compile(r'\b(if|while|for)[ \t]*[(]')
|
||||||
good_control = re.compile(r'\b(if|while|for) [(]')
|
good_control = re.compile(r'\b(if|while|for) [(]')
|
||||||
|
|
||||||
lang_types = { 'c' : "C",
|
whitespace_types = set(('C', 'C++', 'swig', 'python', 'asm', 'isa', 'scons'))
|
||||||
'h' : "C",
|
format_types = set(('C', 'C++'))
|
||||||
'cc' : "C++",
|
|
||||||
'hh' : "C++",
|
|
||||||
'cxx' : "C++",
|
|
||||||
'hxx' : "C++",
|
|
||||||
'cpp' : "C++",
|
|
||||||
'hpp' : "C++",
|
|
||||||
'C' : "C++",
|
|
||||||
'H' : "C++",
|
|
||||||
'i' : "swig",
|
|
||||||
'py' : "python",
|
|
||||||
's' : "asm",
|
|
||||||
'S' : "asm",
|
|
||||||
'isa' : "isa" }
|
|
||||||
def file_type(filename):
|
|
||||||
extension = filename.split('.')
|
|
||||||
extension = len(extension) > 1 and extension[-1]
|
|
||||||
return lang_types.get(extension, None)
|
|
||||||
|
|
||||||
whitespace_types = ('C', 'C++', 'swig', 'python', 'asm', 'isa')
|
|
||||||
def whitespace_file(filename):
|
|
||||||
if file_type(filename) in whitespace_types:
|
|
||||||
return True
|
|
||||||
|
|
||||||
if filename.startswith("SCons"):
|
|
||||||
return True
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
format_types = ( 'C', 'C++' )
|
|
||||||
def format_file(filename):
|
|
||||||
if file_type(filename) in format_types:
|
|
||||||
return True
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def checkwhite_line(line):
|
def checkwhite_line(line):
|
||||||
match = lead.search(line)
|
match = lead.search(line)
|
||||||
|
@ -86,7 +56,7 @@ def checkwhite_line(line):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def checkwhite(filename):
|
def checkwhite(filename):
|
||||||
if not whitespace_file(filename):
|
if lang_type(filename) not in whitespace_types:
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -116,7 +86,7 @@ def fixwhite_line(line, tabsize):
|
||||||
return line.rstrip() + '\n'
|
return line.rstrip() + '\n'
|
||||||
|
|
||||||
def fixwhite(filename, tabsize, fixonly=None):
|
def fixwhite(filename, tabsize, fixonly=None):
|
||||||
if not whitespace_file(filename):
|
if lang_type(filename) not in whitespace_types:
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -174,7 +144,7 @@ class ValidationStats(object):
|
||||||
self.trailwhite or self.badcontrol or self.cret
|
self.trailwhite or self.badcontrol or self.cret
|
||||||
|
|
||||||
def validate(filename, stats, verbose, exit_code):
|
def validate(filename, stats, verbose, exit_code):
|
||||||
if not format_file(filename):
|
if lang_type(filename) not in format_types:
|
||||||
return
|
return
|
||||||
|
|
||||||
def msg(lineno, line, message):
|
def msg(lineno, line, message):
|
||||||
|
@ -186,13 +156,6 @@ def validate(filename, stats, verbose, exit_code):
|
||||||
if exit_code is not None:
|
if exit_code is not None:
|
||||||
sys.exit(exit_code)
|
sys.exit(exit_code)
|
||||||
|
|
||||||
cpp = filename.endswith('.cc') or filename.endswith('.hh')
|
|
||||||
py = filename.endswith('.py')
|
|
||||||
|
|
||||||
if py + cpp != 1:
|
|
||||||
raise AttributeError, \
|
|
||||||
"I don't know how to deal with the file %s" % filename
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
f = file(filename, 'r')
|
f = file(filename, 'r')
|
||||||
except OSError:
|
except OSError:
|
||||||
|
@ -314,7 +277,7 @@ def do_check_whitespace(ui, repo, *files, **args):
|
||||||
if skip(fname):
|
if skip(fname):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if not whitespace_file(fname):
|
if lang_type(fname) not in whitespace_types:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
fctx = wctx.filectx(fname)
|
fctx = wctx.filectx(fname)
|
||||||
|
@ -348,19 +311,7 @@ def do_check_whitespace(ui, repo, *files, **args):
|
||||||
if prompt(fname, fixonly):
|
if prompt(fname, fixonly):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def check_whitespace(ui, repo, hooktype, node, parent1, parent2, **kwargs):
|
def do_check_format(ui, repo, **args):
|
||||||
if hooktype != 'pretxncommit':
|
|
||||||
raise AttributeError, \
|
|
||||||
"This hook is only meant for pretxncommit, not %s" % hooktype
|
|
||||||
|
|
||||||
args = { 'tabsize' : 8 }
|
|
||||||
return do_check_whitespace(ui, repo, **args)
|
|
||||||
|
|
||||||
def check_format(ui, repo, hooktype, node, parent1, parent2, **kwargs):
|
|
||||||
if hooktype != 'pretxncommit':
|
|
||||||
raise AttributeError, \
|
|
||||||
"This hook is only meant for pretxncommit, not %s" % hooktype
|
|
||||||
|
|
||||||
modified, added, removed, deleted, unknown, ignore, clean = repo.status()
|
modified, added, removed, deleted, unknown, ignore, clean = repo.status()
|
||||||
|
|
||||||
verbose = 0
|
verbose = 0
|
||||||
|
@ -381,6 +332,21 @@ def check_format(ui, repo, hooktype, node, parent1, parent2, **kwargs):
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def check_hook(hooktype):
|
||||||
|
if hooktype not in ('pretxncommit', 'pre-qrefresh'):
|
||||||
|
raise AttributeError, \
|
||||||
|
"This hook is not meant for %s" % hooktype
|
||||||
|
|
||||||
|
def check_whitespace(ui, repo, hooktype, **kwargs):
|
||||||
|
check_hook(hooktype)
|
||||||
|
args = { 'tabsize' : 8 }
|
||||||
|
return do_check_whitespace(ui, repo, **args)
|
||||||
|
|
||||||
|
def check_format(ui, repo, hooktype, **kwargs):
|
||||||
|
check_hook(hooktype)
|
||||||
|
args = {}
|
||||||
|
return do_check_format(ui, repo, **args)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from mercurial.i18n import _
|
from mercurial.i18n import _
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -392,8 +358,13 @@ cmdtable = {
|
||||||
( do_check_whitespace,
|
( do_check_whitespace,
|
||||||
[ ('a', 'auto', False, _("automatically fix whitespace")),
|
[ ('a', 'auto', False, _("automatically fix whitespace")),
|
||||||
('t', 'tabsize', 8, _("Number of spaces TAB indents")) ],
|
('t', 'tabsize', 8, _("Number of spaces TAB indents")) ],
|
||||||
_('hg m5check [-t <tabsize>] [FILE]...')),
|
_('hg m5style [-a] [-t <tabsize>] [FILE]...')),
|
||||||
|
'^m5format' :
|
||||||
|
( do_check_format,
|
||||||
|
[ ],
|
||||||
|
_('hg m5format [FILE]...')),
|
||||||
}
|
}
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import getopt
|
import getopt
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue