patchtest-get-branch 2.8 KB

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