mirror of
https://github.com/facebook/sapling.git
synced 2024-10-07 15:27:13 +03:00
91 lines
3.1 KiB
Python
91 lines
3.1 KiB
Python
|
#!/usr/bin/env python
|
||
|
from __future__ import absolute_import, print_function
|
||
|
|
||
|
from glob import glob
|
||
|
|
||
|
import os
|
||
|
import re
|
||
|
import sys
|
||
|
|
||
|
"""
|
||
|
Check if:
|
||
|
- a test is using foreign extensions without proper checks
|
||
|
- a test is using an extension in this repo without absolute path
|
||
|
"""
|
||
|
|
||
|
# whitelisted foreign extensions
|
||
|
foreignexts = set(['remotenames'])
|
||
|
foreignextre = re.compile(r'(%s)' % '|'.join(foreignexts))
|
||
|
|
||
|
# extensions in this repo
|
||
|
repoexts = set(os.path.basename(p).split('.')[0]
|
||
|
for p in glob('hgext3rd/*.py*') if '__' not in p)
|
||
|
repoexts.update(os.path.basename(os.path.dirname(p))
|
||
|
for p in glob('hgext3rd/*/__init__.py'))
|
||
|
repoexts.update(os.path.basename(os.path.dirname(p))
|
||
|
for p in glob('*/__init__.py'))
|
||
|
repoextre = re.compile(r'(%s)' % '|'.join(repoexts))
|
||
|
|
||
|
checkres = [
|
||
|
(re.compile(r'^\s*>\s*%s\s*=\s*$' % foreignextre.pattern),
|
||
|
'use "$ . $TESTDIR/require-ext.sh %(name)s" to skip the test'
|
||
|
' if %(name)s is not available'),
|
||
|
(re.compile(r'^\s*\$.*--config[ =\']*extensions.%s='
|
||
|
% foreignextre.pattern),
|
||
|
'use "$ . $TESTDIR/require-ext.sh %(name)s" to skip the test'
|
||
|
' if %(name)s is not available'),
|
||
|
(re.compile(r'^\s*>\s*%s\s*=\s*$' % repoextre.pattern),
|
||
|
'use full path like $TESTDIR/../hgext3rd/%(name)s.py for extension '
|
||
|
'in this repo'),
|
||
|
(re.compile(r'^\s*\$.*--config[ =\']*extensions.%s=[ \'"]'
|
||
|
% repoextre.pattern),
|
||
|
'use full path like $TESTDIR/../hgext3rd/%(name)s.py for extension '
|
||
|
'in this repo'),
|
||
|
]
|
||
|
|
||
|
requirere = re.compile(r'require-ext\.sh (.*)$')
|
||
|
|
||
|
def checkfile(path):
|
||
|
errors = []
|
||
|
with open(path) as f:
|
||
|
required = set()
|
||
|
for i, line in enumerate(f):
|
||
|
msg = None
|
||
|
m = requirere.search(line)
|
||
|
if m:
|
||
|
requiredexts = set(m.group(1).split())
|
||
|
unknownexts = requiredexts - foreignexts
|
||
|
for e in unknownexts:
|
||
|
if e in repoexts:
|
||
|
msg = 'do not require non-foreign extension %s'
|
||
|
else:
|
||
|
# change foreignexts if this error is a false postive
|
||
|
msg = 'do not require non-whitelisted extension %s'
|
||
|
errors.append((path, i + 1, line[:-1], msg % e))
|
||
|
required.update(requiredexts)
|
||
|
for regex, msg in checkres:
|
||
|
m = regex.search(line)
|
||
|
if not m:
|
||
|
continue
|
||
|
name = m.group(1)
|
||
|
if name in required:
|
||
|
continue
|
||
|
# line[:-1] is to remove the last "\n"
|
||
|
errors.append((path, i + 1, line[:-1], msg % {'name': name}))
|
||
|
# only one error per extension per file
|
||
|
required.add(name)
|
||
|
return errors
|
||
|
|
||
|
def checkfiles(paths):
|
||
|
errors = []
|
||
|
for path in sys.argv[1:]:
|
||
|
errors += checkfile(path)
|
||
|
return sorted(set(errors))
|
||
|
|
||
|
def printerrors(errors):
|
||
|
# same format with check-code.py
|
||
|
for fname, lineno, line, msg in errors:
|
||
|
print('%s:%d:\n > %s\n %s' % (fname, lineno, line, msg))
|
||
|
|
||
|
printerrors(checkfiles(sys.argv[1:]))
|