blob: f037321059e6a9df0b07e636b8e264e7059c4d96 [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
Orion Hodsone4216682022-04-04 13:22:38 +01008import urllib.request, urllib.parse, urllib.error
9import urllib.request, urllib.error, urllib.parse
Chih-Hung Hsiehadaed142017-02-22 16:14:48 -080010
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:
Orion Hodsone4216682022-04-04 13:22:38 +010028 print(msg)
Chih-Hung Hsiehadaed142017-02-22 16:14:48 -080029
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:'
Orion Hodsone4216682022-04-04 13:22:38 +010034 + urllib.parse.quote(address))
Chih-Hung Hsiehadaed142017-02-22 16:14:48 -080035 echo('Checking email address: ' + address)
Orion Hodsone4216682022-04-04 13:22:38 +010036 result = urllib.request.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
Orion Hodsone4216682022-04-04 13:22:38 +010046 print('%s:%d: ERROR: unknown email address: %s' % (fname, num, address))
Chih-Hung Hsiehf77c7f72018-08-15 16:07:27 -070047 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)
Chih-Hung Hsiehcc477292019-03-04 15:13:20 -080055 file_directive = 'file: *([^ :]+ *: *)?[^ ]+'
56 directive = '(%s|%s|%s)' % (emails, noparent, file_directive)
Chih-Hung Hsiehadaed142017-02-22 16:14:48 -080057 glob = '[a-zA-Z0-9_\\.\\-\\*\\?]+'
Chih-Hung Hsiehf77c7f72018-08-15 16:07:27 -070058 globs = '(%s( *, *%s)*)' % (glob, glob)
59 perfile = 'per-file +' + globs + ' *= *' + directive
Chih-Hung Hsieh65129492018-12-07 14:27:17 -080060 include = 'include +([^ :]+ *: *)?[^ ]+'
Chih-Hung Hsiehcc477292019-03-04 15:13:20 -080061 pats = '(|%s|%s|%s|%s|%s)$' % (noparent, email, perfile, include, file_directive)
Chih-Hung Hsiehadaed142017-02-22 16:14:48 -080062 patterns = re.compile(pats)
Chih-Hung Hsiehf77c7f72018-08-15 16:07:27 -070063 address_pattern = re.compile('([^@ ]+@[^ @]+)')
64 perfile_pattern = re.compile('per-file +.*=(.*)')
Chih-Hung Hsiehadaed142017-02-22 16:14:48 -080065
66 error = 0
67 for fname in args.owners:
68 echo('Checking file: ' + fname)
69 num = 0
70 for line in open(fname, 'r'):
71 num += 1
72 stripped_line = re.sub('#.*$', '', line).strip()
73 if not patterns.match(stripped_line):
Chih-Hung Hsiehf77c7f72018-08-15 16:07:27 -070074 error += 1
Orion Hodsone4216682022-04-04 13:22:38 +010075 print('%s:%d: ERROR: unknown line [%s]' % (fname, num, line.strip()))
Chih-Hung Hsiehf77c7f72018-08-15 16:07:27 -070076 elif args.check_address:
77 if perfile_pattern.match(stripped_line):
78 for addr in perfile_pattern.match(stripped_line).group(1).split(','):
79 a = addr.strip()
80 if a and a != '*':
81 error += check_address(fname, num, addr.strip())
82 elif address_pattern.match(stripped_line):
83 error += check_address(fname, num, stripped_line)
Chih-Hung Hsiehadaed142017-02-22 16:14:48 -080084 sys.exit(error)
85
86if __name__ == '__main__':
87 main()