1adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh#!/usr/bin/python 2adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh 3adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh"""Parse and check syntax errors of a given OWNERS file.""" 4adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh 5adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsiehimport argparse 6adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsiehimport re 7adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsiehimport sys 8bee0dec6c4c65787ce340d0610591d879f13da1aChih-Hung Hsiehimport urllib 9adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsiehimport urllib2 10adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh 11adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsiehparser = argparse.ArgumentParser(description='Check OWNERS file syntax') 12adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsiehparser.add_argument('-v', '--verbose', dest='verbose', 13adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh action='store_true', default=False, 14adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh help='Verbose output to debug') 15adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsiehparser.add_argument('-c', '--check_address', dest='check_address', 16adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh action='store_true', default=False, 17adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh help='Check email addresses') 18adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsiehparser.add_argument(dest='owners', metavar='OWNERS', nargs='+', 19adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh help='Path to OWNERS file') 20adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsiehargs = parser.parse_args() 21adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh 22adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsiehgerrit_server = 'https://android-review.googlesource.com' 23adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsiehchecked_addresses = {} 24adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh 25adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh 26adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsiehdef echo(msg): 27adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh if args.verbose: 28adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh print msg 29adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh 30adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh 31adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsiehdef find_address(address): 32adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh if address not in checked_addresses: 33bee0dec6c4c65787ce340d0610591d879f13da1aChih-Hung Hsieh request = (gerrit_server + '/accounts/?n=1&o=ALL_EMAILS&q=email:' 34bee0dec6c4c65787ce340d0610591d879f13da1aChih-Hung Hsieh + urllib.quote(address)) 35adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh echo('Checking email address: ' + address) 36adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh result = urllib2.urlopen(request).read() 372b1efe63cf194e7fa207c0576b5ee76971f9f591Chih-Hung Hsieh checked_addresses[address] = ( 382b1efe63cf194e7fa207c0576b5ee76971f9f591Chih-Hung Hsieh result.find('"email":') >= 0 and result.find('"_account_id":') >= 0) 39adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh return checked_addresses[address] 40adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh 41adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh 42adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsiehdef main(): 43adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh # One regular expression to check all valid lines. 44adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh noparent = 'set +noparent' 45adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh email = '([^@ ]+@[^ @]+|\\*)' 46adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh directive = '(%s|%s)' % (email, noparent) 47adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh glob = '[a-zA-Z0-9_\\.\\-\\*\\?]+' 48adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh perfile = 'per-file +' + glob + ' *= *' + directive 49adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh pats = '(|%s|%s|%s)$' % (noparent, email, perfile) 50adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh patterns = re.compile(pats) 51adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh 52adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh # One pattern to capture email address. 53adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh email_address = '.*(@| |=|^)([^@ =]+@[^ @]+)' 54adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh address_pattern = re.compile(email_address) 55adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh 56adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh error = 0 57adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh for fname in args.owners: 58adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh echo('Checking file: ' + fname) 59adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh num = 0 60adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh for line in open(fname, 'r'): 61adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh num += 1 62adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh stripped_line = re.sub('#.*$', '', line).strip() 63adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh if not patterns.match(stripped_line): 64adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh error = 1 65adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh print('%s:%d: ERROR: unknown line [%s]' 66adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh % (fname, num, line.strip())) 67adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh elif args.check_address and address_pattern.match(stripped_line): 68adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh address = address_pattern.match(stripped_line).group(2) 69adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh if find_address(address): 70adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh echo('Found email address: ' + address) 71adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh else: 72adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh error = 1 73adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh print('%s:%d: ERROR: unknown email address: %s' 74adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh % (fname, num, address)) 75adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh sys.exit(error) 76adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh 77adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsiehif __name__ == '__main__': 78adaed14ff3301dc67fa137b6353c3a8fb4015c27Chih-Hung Hsieh main() 79