Aaron Massey | e4d9222 | 2020-07-13 17:41:29 +0000 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | # -*- coding: utf-8 -*- |
| 3 | # Copyright 2020 The Chromium OS Authors. All rights reserved. |
| 4 | # Use of this source code is governed by a BSD-style license that can be |
| 5 | # found in the LICENSE file. |
| 6 | |
Aaron Massey | 40b5d42 | 2020-08-11 17:29:21 +0000 | [diff] [blame^] | 7 | """This is a utility script for parsing the repo manifest used by gerrit.el""" |
Aaron Massey | e4d9222 | 2020-07-13 17:41:29 +0000 | [diff] [blame] | 8 | |
| 9 | import xml.parsers.expat as xml |
| 10 | import sys |
| 11 | import argparse |
| 12 | import pathlib |
Aaron Massey | 40b5d42 | 2020-08-11 17:29:21 +0000 | [diff] [blame^] | 13 | import subprocess |
Aaron Massey | e4d9222 | 2020-07-13 17:41:29 +0000 | [diff] [blame] | 14 | |
Aaron Massey | 40b5d42 | 2020-08-11 17:29:21 +0000 | [diff] [blame^] | 15 | def parse_manifest_projects_to_lisp_alist(repo_root_path): |
| 16 | """Parse repo manifest to Lisp alist. |
Aaron Massey | e4d9222 | 2020-07-13 17:41:29 +0000 | [diff] [blame] | 17 | |
| 18 | Any project without a dest-branch attribute is skipped. |
| 19 | |
| 20 | Args: |
Aaron Massey | 40b5d42 | 2020-08-11 17:29:21 +0000 | [diff] [blame^] | 21 | repo_root_path: The path to a repo root. |
Aaron Massey | e4d9222 | 2020-07-13 17:41:29 +0000 | [diff] [blame] | 22 | |
| 23 | Returns: |
| 24 | Lisp readable alist with elements of the form ((name . dest-branch) . path) |
| 25 | |
| 26 | Raises: |
Aaron Massey | 40b5d42 | 2020-08-11 17:29:21 +0000 | [diff] [blame^] | 27 | CalledProcessError: The repo tool threw an error getting the manifest. |
Aaron Massey | e4d9222 | 2020-07-13 17:41:29 +0000 | [diff] [blame] | 28 | ExpatError: An error occured when attempting to parse. |
| 29 | """ |
| 30 | |
| 31 | assoc_list_entries = [] |
| 32 | |
| 33 | def _project_elem_handler(name, attrs): |
| 34 | """XML element handler collecting project elements to form a Lisp alist. |
| 35 | |
| 36 | Args: |
| 37 | name: The name of the handled xml element. |
| 38 | attrs: A dictionary of the handled xml element's attributes. |
| 39 | """ |
| 40 | if name == 'project': |
Aaron Massey | e4d9222 | 2020-07-13 17:41:29 +0000 | [diff] [blame] | 41 | project_name = attrs['name'] |
Aaron Massey | 0a50912 | 2020-08-10 21:46:43 +0000 | [diff] [blame] | 42 | project_path = attrs.get('path', project_name) |
| 43 | dest_branch = attrs.get('dest-branch') |
Aaron Massey | e4d9222 | 2020-07-13 17:41:29 +0000 | [diff] [blame] | 44 | if not dest_branch: |
| 45 | # We skip anything without a dest-branch |
| 46 | return |
| 47 | # We don't want the refs/heads/ prefix of dest-branch |
| 48 | dest_branch = dest_branch.replace('refs/heads/', '') |
| 49 | |
| 50 | key = '("{}" . "{}")'.format(project_name, dest_branch) |
| 51 | value = '"{}"'.format(project_path) |
| 52 | |
| 53 | assoc_list_entries.append('({} . {})'.format(key, value)) |
| 54 | |
| 55 | p = xml.ParserCreate() |
| 56 | p.StartElementHandler = _project_elem_handler |
Aaron Massey | 40b5d42 | 2020-08-11 17:29:21 +0000 | [diff] [blame^] | 57 | |
| 58 | repo_cmd = ['repo', '--no-pager', 'manifest'] |
| 59 | repo_cmd_result = subprocess.run(repo_cmd, |
| 60 | cwd=repo_root_path.expanduser().resolve(), |
| 61 | capture_output=True, |
| 62 | check=True) |
| 63 | p.Parse(repo_cmd_result.stdout) |
| 64 | return '({})'.format(''.join(assoc_list_entries)) |
Aaron Massey | e4d9222 | 2020-07-13 17:41:29 +0000 | [diff] [blame] | 65 | |
| 66 | |
| 67 | def main(argv): |
| 68 | """main.""" |
| 69 | arg_parser = argparse.ArgumentParser() |
Aaron Massey | 40b5d42 | 2020-08-11 17:29:21 +0000 | [diff] [blame^] | 70 | arg_parser.add_argument('repo_root_path', |
Aaron Massey | e4d9222 | 2020-07-13 17:41:29 +0000 | [diff] [blame] | 71 | type=pathlib.Path, |
Aaron Massey | 40b5d42 | 2020-08-11 17:29:21 +0000 | [diff] [blame^] | 72 | help='System path to repo root.') |
Aaron Massey | e4d9222 | 2020-07-13 17:41:29 +0000 | [diff] [blame] | 73 | args = arg_parser.parse_args(argv) |
| 74 | |
| 75 | try: |
Aaron Massey | 40b5d42 | 2020-08-11 17:29:21 +0000 | [diff] [blame^] | 76 | print(parse_manifest_projects_to_lisp_alist(args.repo_root_path)) |
Aaron Massey | e4d9222 | 2020-07-13 17:41:29 +0000 | [diff] [blame] | 77 | return 0 |
| 78 | |
| 79 | except xml.ExpatError as err: |
| 80 | print('XML Parsing Error:', err) |
| 81 | return 1 |
| 82 | |
| 83 | |
| 84 | if __name__ == '__main__': |
| 85 | sys.exit(main(sys.argv[1:])) |