• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python
2
3"""Parse and check syntax errors of a given OWNERS file."""
4
5import argparse
6import re
7import sys
8import urllib
9import 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:
33    request = (gerrit_server + '/accounts/?n=1&o=ALL_EMAILS&q=email:'
34               + urllib.quote(address))
35    echo('Checking email address: ' + address)
36    result = urllib2.urlopen(request).read()
37    expected = '"email": "' + address + '"'
38    checked_addresses[address] = (result.find(expected) >= 0)
39  return checked_addresses[address]
40
41
42def main():
43  # One regular expression to check all valid lines.
44  noparent = 'set +noparent'
45  email = '([^@ ]+@[^ @]+|\\*)'
46  directive = '(%s|%s)' % (email, noparent)
47  glob = '[a-zA-Z0-9_\\.\\-\\*\\?]+'
48  perfile = 'per-file +' + glob + ' *= *' + directive
49  pats = '(|%s|%s|%s)$' % (noparent, email, perfile)
50  patterns = re.compile(pats)
51
52  # One pattern to capture email address.
53  email_address = '.*(@| |=|^)([^@ =]+@[^ @]+)'
54  address_pattern = re.compile(email_address)
55
56  error = 0
57  for fname in args.owners:
58    echo('Checking file: ' + fname)
59    num = 0
60    for line in open(fname, 'r'):
61      num += 1
62      stripped_line = re.sub('#.*$', '', line).strip()
63      if not patterns.match(stripped_line):
64        error = 1
65        print('%s:%d: ERROR: unknown line [%s]'
66              % (fname, num, line.strip()))
67      elif args.check_address and address_pattern.match(stripped_line):
68        address = address_pattern.match(stripped_line).group(2)
69        if find_address(address):
70          echo('Found email address: ' + address)
71        else:
72          error = 1
73          print('%s:%d: ERROR: unknown email address: %s'
74                % (fname, num, address))
75  sys.exit(error)
76
77if __name__ == '__main__':
78  main()
79