| #!/usr/bin/env python |
| # Copyright (c) 2017 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Parses OWNERS recursively and generates a machine readable component mapping. |
| |
| OWNERS files are expected to contain a well-formatted pair of tags as shown |
| below. A presubmit check exists that validates this. |
| |
| This script finds lines in the OWNERS files such as: |
| `# TEAM: team@chromium.org` and |
| `# COMPONENT: Tools>Test>Findit` |
| and dumps this information into a json file. |
| |
| Refer to crbug.com/667952 |
| """ |
| |
| import json |
| import optparse |
| import os |
| import sys |
| |
| from owners_file_tags import aggregate_components_from_owners |
| |
| |
| _DEFAULT_SRC_LOCATION = os.path.join( |
| os.path.dirname(__file__), os.pardir, os.pardir) |
| |
| _README = """ |
| This file is generated by src/tools/checkteamtags/extract_components.py |
| by parsing the contents of OWNERS files throughout the chromium source code and |
| extracting `# TEAM:` and `# COMPONENT:` tags. |
| |
| Manual edits of this file will be overwritten by an automated process. |
| """.splitlines() |
| |
| |
| def write_results(filename, data): |
| """Write data to the named file, or the default location.""" |
| if not filename: |
| filename = 'component_map.json' |
| with open(filename, 'w') as f: |
| f.write(data) |
| |
| |
| def main(argv): |
| usage = """Usage: python %prog [options] [<root_dir>] |
| root_dir specifies the topmost directory to traverse looking for OWNERS |
| files, defaults to two levels up from this file's directory. |
| i.e. where src/ is expected to be. |
| |
| Examples: |
| python %prog |
| python %prog /b/build/src |
| python %prog -v /b/build/src |
| python %prog -w /b/build/src |
| python %prog -o ~/components.json /b/build/src |
| """ |
| parser = optparse.OptionParser(usage=usage) |
| parser.add_option('-w', '--write', action='store_true', |
| help='If no errors occur, write the mappings to disk.') |
| parser.add_option('-v', '--verbose', action='store_true', |
| help='Print warnings.') |
| parser.add_option('-f', '--force_print', action='store_true', |
| help='Print the mappings despite errors.') |
| parser.add_option('-o', '--output_file', help='Specify file to write the ' |
| 'mappings to instead of the default: <CWD>/' |
| 'component_map.json (implies -w)') |
| options, args = parser.parse_args(argv[1:]) |
| if args: |
| root = args[0] |
| else: |
| root = _DEFAULT_SRC_LOCATION |
| |
| mappings, warnings, errors = aggregate_components_from_owners(root) |
| if options.verbose: |
| for w in warnings: |
| print w |
| |
| for e in errors: |
| print e |
| |
| mappings['AAA-README']= _README |
| mapping_file_contents = json.dumps(mappings, sort_keys=True, indent=2) |
| if options.write or options.output_file: |
| if errors: |
| print 'Not writing to file due to errors' |
| if options.force_print: |
| print mapping_file_contents |
| else: |
| write_results(options.output_file, mapping_file_contents) |
| else: |
| print mapping_file_contents |
| |
| return len(errors) |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main(sys.argv)) |