2017-02-23 08:14:48 +08:00
|
|
|
#!/usr/bin/python
|
|
|
|
|
|
|
|
"""Parse and check syntax errors of a given OWNERS file."""
|
|
|
|
|
|
|
|
import argparse
|
|
|
|
import re
|
|
|
|
import sys
|
2017-04-06 05:16:49 +08:00
|
|
|
import urllib
|
2017-02-23 08:14:48 +08:00
|
|
|
import urllib2
|
|
|
|
|
|
|
|
parser = argparse.ArgumentParser(description='Check OWNERS file syntax')
|
|
|
|
parser.add_argument('-v', '--verbose', dest='verbose',
|
|
|
|
action='store_true', default=False,
|
|
|
|
help='Verbose output to debug')
|
|
|
|
parser.add_argument('-c', '--check_address', dest='check_address',
|
|
|
|
action='store_true', default=False,
|
|
|
|
help='Check email addresses')
|
|
|
|
parser.add_argument(dest='owners', metavar='OWNERS', nargs='+',
|
|
|
|
help='Path to OWNERS file')
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
|
|
gerrit_server = 'https://android-review.googlesource.com'
|
|
|
|
checked_addresses = {}
|
|
|
|
|
|
|
|
|
|
|
|
def echo(msg):
|
|
|
|
if args.verbose:
|
|
|
|
print msg
|
|
|
|
|
|
|
|
|
|
|
|
def find_address(address):
|
|
|
|
if address not in checked_addresses:
|
2018-05-17 02:44:50 +08:00
|
|
|
request = (gerrit_server + '/accounts/?n=1&q=email:'
|
2017-04-06 05:16:49 +08:00
|
|
|
+ urllib.quote(address))
|
2017-02-23 08:14:48 +08:00
|
|
|
echo('Checking email address: ' + address)
|
|
|
|
result = urllib2.urlopen(request).read()
|
2018-05-17 02:44:50 +08:00
|
|
|
checked_addresses[address] = result.find('"_account_id":') >= 0
|
2018-08-16 07:07:27 +08:00
|
|
|
if checked_addresses[address]:
|
|
|
|
echo('Found email address: ' + address)
|
2017-02-23 08:14:48 +08:00
|
|
|
return checked_addresses[address]
|
|
|
|
|
|
|
|
|
2018-08-16 07:07:27 +08:00
|
|
|
def check_address(fname, num, address):
|
|
|
|
if find_address(address):
|
|
|
|
return 0
|
|
|
|
print '%s:%d: ERROR: unknown email address: %s' % (fname, num, address)
|
|
|
|
return 1
|
|
|
|
|
|
|
|
|
2017-02-23 08:14:48 +08:00
|
|
|
def main():
|
|
|
|
# One regular expression to check all valid lines.
|
|
|
|
noparent = 'set +noparent'
|
|
|
|
email = '([^@ ]+@[^ @]+|\\*)'
|
2018-08-16 07:07:27 +08:00
|
|
|
emails = '(%s( *, *%s)*)' % (email, email)
|
|
|
|
directive = '(%s|%s)' % (emails, noparent)
|
2017-02-23 08:14:48 +08:00
|
|
|
glob = '[a-zA-Z0-9_\\.\\-\\*\\?]+'
|
2018-08-16 07:07:27 +08:00
|
|
|
globs = '(%s( *, *%s)*)' % (glob, glob)
|
|
|
|
perfile = 'per-file +' + globs + ' *= *' + directive
|
2018-12-08 06:27:17 +08:00
|
|
|
include = 'include +([^ :]+ *: *)?[^ ]+'
|
|
|
|
pats = '(|%s|%s|%s|%s)$' % (noparent, email, perfile, include)
|
2017-02-23 08:14:48 +08:00
|
|
|
patterns = re.compile(pats)
|
2018-08-16 07:07:27 +08:00
|
|
|
address_pattern = re.compile('([^@ ]+@[^ @]+)')
|
|
|
|
perfile_pattern = re.compile('per-file +.*=(.*)')
|
2017-02-23 08:14:48 +08:00
|
|
|
|
|
|
|
error = 0
|
|
|
|
for fname in args.owners:
|
|
|
|
echo('Checking file: ' + fname)
|
|
|
|
num = 0
|
|
|
|
for line in open(fname, 'r'):
|
|
|
|
num += 1
|
|
|
|
stripped_line = re.sub('#.*$', '', line).strip()
|
|
|
|
if not patterns.match(stripped_line):
|
2018-08-16 07:07:27 +08:00
|
|
|
error += 1
|
|
|
|
print '%s:%d: ERROR: unknown line [%s]' % (fname, num, line.strip())
|
|
|
|
elif args.check_address:
|
|
|
|
if perfile_pattern.match(stripped_line):
|
|
|
|
for addr in perfile_pattern.match(stripped_line).group(1).split(','):
|
|
|
|
a = addr.strip()
|
|
|
|
if a and a != '*':
|
|
|
|
error += check_address(fname, num, addr.strip())
|
|
|
|
elif address_pattern.match(stripped_line):
|
|
|
|
error += check_address(fname, num, stripped_line)
|
2017-02-23 08:14:48 +08:00
|
|
|
sys.exit(error)
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|