1""" 2Verify that the MoinMoin source files conform (mostly) to PEP8 coding style. 3 4Additionally, we check that the files have no crlf (Windows style) line endings. 5 6@copyright: 2006 by Armin Rigo (originally only testing for tab chars), 7 2007 adapted and extended (calling the PEP8 checker for most stuff) by MoinMoin:ThomasWaldmann. 8@license: MIT licensed 9""" 10 11import os, re, time, stat 12 13import pep8 14 15from MoinMoin.conftest import moindir 16 17ROOT = str(moindir) 18 19EXCLUDE = [ 20 '/contrib/DesktopEdition/setup_py2exe.py', # has crlf 21 '/contrib/TWikiDrawPlugin', # 3rd party java stuff 22 '/contrib/flup-server', # 3rd party WSGI adapters 23 '/MoinMoin/support', # 3rd party libs or non-broken stdlib stuff 24 '/MoinMoin/web/static/htdocs', # this is our dist static stuff 25 '/tests/wiki', # this is our test wiki 26 '/wiki/data/pages', # wiki pages, there may be .py attachments 27] 28 29TRAILING_SPACES = 'nochange' # 'nochange' or 'fix' 30 # use 'fix' with extreme caution and in a separate changeset! 31FIX_TS_RE = re.compile(r' +$', re.M) # 'fix' mode: everything matching the trailing space re will be removed 32 33try: 34 import xattr 35 if not hasattr(xattr, "xattr"): # there seem to be multiple modules with that name 36 raise ImportError 37 def mark_file_ok(path, mtime): 38 x = xattr.xattr(path) 39 try: 40 x.set('user.moin-pep8-tested-mtime', '%d' % mtime) 41 except IOError: 42 # probably not supported 43 mark_file_ok = lambda path, mtime: None 44 45 def should_check_file(path, mtime): 46 x = xattr.xattr(path) 47 try: 48 mt = x.get('user.moin-pep8-tested-mtime') 49 mt = long(mt) 50 return mtime > mt 51 except IOError: 52 # probably not supported 53 should_check_file = lambda path, mtime: True 54 return True 55except ImportError: 56 def mark_file_ok(path, mtime): 57 pass 58 def should_check_file(path, mtime): 59 return True 60 61RECENTLY = time.time() - 7 * 24*60*60 # we only check stuff touched recently. 62#RECENTLY = 0 # check everything! 63 64# After doing a fresh clone, this procedure is recommended: 65# 1. Run the tests once to see if everything is OK (as cloning updates the mtime, 66# it will test every file). 67# 2. Before starting to make new changes, use "touch" to change all timestamps 68# to a time before <RECENTLY>. 69# 3. Regularly run the tests, they will run much faster now. 70 71def pep8_error_count(path): 72 # process_options initializes some data structures and MUST be called before each Checker().check_all() 73 pep8.process_options(['pep8', '--ignore=E202,E221,E222,E241,E301,E302,E401,E501,E701,W391,W601,W602', '--show-source', 'dummy_path']) 74 error_count = pep8.Checker(path).check_all() 75 return error_count 76 77def check_py_file(reldir, path, mtime): 78 if TRAILING_SPACES == 'fix': 79 f = file(path, 'rb') 80 data = f.read() 81 f.close() 82 fixed = FIX_TS_RE.sub('', data) 83 84 # Don't write files if there's no need for that, 85 # as altering timestamps can be annoying with some tools. 86 if fixed == data: 87 return 88 89 f = file(path, 'wb') 90 f.write(fixed) 91 f.close() 92 # Please read and follow PEP8 - rerun this test until it does not fail any more, 93 # any type of error is only reported ONCE (even if there are multiple). 94 error_count = pep8_error_count(path) 95 assert error_count == 0 96 mark_file_ok(path, mtime) 97 98def test_sourcecode(): 99 def walk(reldir): 100 if reldir in EXCLUDE: 101 #print "Skippping %r..." % reldir 102 return 103 if reldir: 104 path = os.path.join(ROOT, *reldir.split('/')) 105 else: 106 path = ROOT 107 st = os.stat(path) 108 mode = st.st_mode 109 if stat.S_ISREG(mode): # is a regular file 110 if (path.lower().endswith('.py') and st.st_mtime >= RECENTLY and 111 should_check_file(path, st.st_mtime)): 112 yield check_py_file, reldir, path, st.st_mtime 113 elif stat.S_ISDIR(mode): # is a directory 114 for entry in os.listdir(path): 115 if not entry.startswith('.'): 116 for _ in walk('%s/%s' % (reldir, entry)): 117 yield _ 118 119 global EXCLUDE 120 EXCLUDE = dict([(path, True) for path in EXCLUDE]) # dict lookup is faster 121 for _ in walk(''): 122 yield _ 123 124