patchtest-get-branch 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. #!/usr/bin/env python3
  2. # Get target branch from the corresponding mbox
  3. #
  4. # NOTE: this script was based on patches coming to the openembedded-core
  5. # where target branch is defined inside brackets as subject prefix
  6. # i.e. [master], [rocko], etc.
  7. #
  8. # Copyright (C) 2016 Intel Corporation
  9. #
  10. # SPDX-License-Identifier: GPL-2.0-only
  11. #
  12. import mailbox
  13. import argparse
  14. import re
  15. import git
  16. import sys
  17. re_prefix = re.compile("(\[.*\])", re.DOTALL)
  18. def get_branch(filepath_repo, filepath_mbox, default_branch):
  19. branch = None
  20. # get all remotes branches
  21. gitbranches = git.Git(filepath_repo).branch('-a').splitlines()
  22. # from gitbranches, just get the names
  23. branches = [b.split('/')[-1] for b in gitbranches]
  24. subject = ' '.join(mailbox.mbox(filepath_mbox)[0]['subject'].splitlines())
  25. # we expect that patches will have somewhere between one and three
  26. # consecutive sets of square brackets with tokens inside, e.g.:
  27. # 1. [PATCH]
  28. # 2. [OE-core][PATCH]
  29. # 3. [OE-core][kirkstone][PATCH]
  30. # Some of them may also be part of a series, in which case the PATCH
  31. # token will be formatted like:
  32. # [PATCH 1/4]
  33. # or they will be revisions to previous patches, where it will be:
  34. # [PATCH v2]
  35. # Or they may contain both:
  36. # [PATCH v2 3/4]
  37. # In any case, we want mprefix to contain all of these tokens so
  38. # that we can search for branch names within them.
  39. mprefix = re.findall(r'\[.*?\]', subject)
  40. found_branch = None
  41. if mprefix:
  42. # Iterate over the tokens and compare against the branch list to
  43. # figure out which one the patch is targeting
  44. for token in mprefix:
  45. stripped = token.lower().strip('[]')
  46. if default_branch in stripped:
  47. found_branch = default_branch
  48. break
  49. else:
  50. for branch in branches:
  51. # ignore branches named "core"
  52. if branch != "core" and stripped.rfind(branch) != -1:
  53. found_branch = token.split(' ')[0].strip('[]')
  54. break
  55. # if there's no mprefix content or no known branches were found in
  56. # the tokens, assume the target is master
  57. if found_branch is None:
  58. found_branch = "master"
  59. return (subject, found_branch)
  60. if __name__ == '__main__':
  61. parser = argparse.ArgumentParser()
  62. parser.add_argument('repo', metavar='REPO', help='Main repository')
  63. parser.add_argument('mbox', metavar='MBOX', help='mbox filename')
  64. parser.add_argument('--default-branch', metavar='DEFAULT_BRANCH', default='master', help='Use this branch if no one is found')
  65. parser.add_argument('--separator', '-s', metavar='SEPARATOR', default=' ', help='Char separator for output data')
  66. args = parser.parse_args()
  67. subject, branch = get_branch(args.repo, args.mbox, args.default_branch)
  68. print("branch: %s" % branch)