blob: 7f0396880745e2b3ffb1f6a5be02b9753025f029 [file] [log] [blame]
Chih-Hung Hsiehadaed142017-02-22 16:14:48 -08001#!/usr/bin/python
2
3"""Parse and check syntax errors of a given OWNERS file."""
4
5import argparse
6import re
7import sys
Chih-Hung Hsiehbee0dec2017-04-05 14:16:49 -07008import urllib
Chih-Hung Hsiehadaed142017-02-22 16:14:48 -08009import urllib2
10
11parser = argparse.ArgumentParser(description='Check OWNERS file syntax')
12parser.add_argument('-v', '--verbose', dest='verbose',
13 action='store_true', default=False,
14 help='Verbose output to debug')
15parser.add_argument('-c', '--check_address', dest='check_address',
16 action='store_true', default=False,
17 help='Check email addresses')
18parser.add_argument(dest='owners', metavar='OWNERS', nargs='+',
19 help='Path to OWNERS file')
20args = parser.parse_args()
21
22gerrit_server = 'https://android-review.googlesource.com'
23checked_addresses = {}
24
25
26def echo(msg):
27 if args.verbose:
28 print msg
29
30
31def find_address(address):
32 if address not in checked_addresses:
Chih-Hung Hsiehc5c443c2018-05-16 11:44:50 -070033 request = (gerrit_server + '/accounts/?n=1&q=email:'
Chih-Hung Hsiehbee0dec2017-04-05 14:16:49 -070034 + urllib.quote(address))
Chih-Hung Hsiehadaed142017-02-22 16:14:48 -080035 echo('Checking email address: ' + address)
36 result = urllib2.urlopen(request).read()
Chih-Hung Hsiehc5c443c2018-05-16 11:44:50 -070037 checked_addresses[address] = result.find('"_account_id":') >= 0
Chih-Hung Hsiehf77c7f72018-08-15 16:07:27 -070038 if checked_addresses[address]:
39 echo('Found email address: ' + address)
Chih-Hung Hsiehadaed142017-02-22 16:14:48 -080040 return checked_addresses[address]
41
42
Chih-Hung Hsiehf77c7f72018-08-15 16:07:27 -070043def check_address(fname, num, address):
44 if find_address(address):
45 return 0
46 print '%s:%d: ERROR: unknown email address: %s' % (fname, num, address)
47 return 1
48
49
Chih-Hung Hsiehadaed142017-02-22 16:14:48 -080050def main():
51 # One regular expression to check all valid lines.
52 noparent = 'set +noparent'
53 email = '([^@ ]+@[^ @]+|\\*)'
Chih-Hung Hsiehf77c7f72018-08-15 16:07:27 -070054 emails = '(%s( *, *%s)*)' % (email, email)
55 directive = '(%s|%s)' % (emails, noparent)
Chih-Hung Hsiehadaed142017-02-22 16:14:48 -080056 glob = '[a-zA-Z0-9_\\.\\-\\*\\?]+'
Chih-Hung Hsiehf77c7f72018-08-15 16:07:27 -070057 globs = '(%s( *, *%s)*)' % (glob, glob)
58 perfile = 'per-file +' + globs + ' *= *' + directive
Chih-Hung Hsieh65129492018-12-07 14:27:17 -080059 include = 'include +([^ :]+ *: *)?[^ ]+'
60 pats = '(|%s|%s|%s|%s)$' % (noparent, email, perfile, include)
Chih-Hung Hsiehadaed142017-02-22 16:14:48 -080061 patterns = re.compile(pats)
Chih-Hung Hsiehf77c7f72018-08-15 16:07:27 -070062 address_pattern = re.compile('([^@ ]+@[^ @]+)')
63 perfile_pattern = re.compile('per-file +.*=(.*)')
Chih-Hung Hsiehadaed142017-02-22 16:14:48 -080064
65 error = 0
66 for fname in args.owners:
67 echo('Checking file: ' + fname)
68 num = 0
69 for line in open(fname, 'r'):
70 num += 1
71 stripped_line = re.sub('#.*$', '', line).strip()
72 if not patterns.match(stripped_line):
Chih-Hung Hsiehf77c7f72018-08-15 16:07:27 -070073 error += 1
74 print '%s:%d: ERROR: unknown line [%s]' % (fname, num, line.strip())
75 elif args.check_address:
76 if perfile_pattern.match(stripped_line):
77 for addr in perfile_pattern.match(stripped_line).group(1).split(','):
78 a = addr.strip()
79 if a and a != '*':
80 error += check_address(fname, num, addr.strip())
81 elif address_pattern.match(stripped_line):
82 error += check_address(fname, num, stripped_line)
Chih-Hung Hsiehadaed142017-02-22 16:14:48 -080083 sys.exit(error)
84
85if __name__ == '__main__':
86 main()