bugzilla-close-candidate.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #!/usr/bin/env python3
  2. # The script is used for finding PRs that have a GIT revision that
  3. # mentiones the PR and are not closed. It's done by iterating all
  4. # comments of a PR and finding GIT commit entries.
  5. """
  6. Sample output of the script:
  7. Bugzilla URL page size: 50
  8. HINT: bugs with following comment are ignored: Can the bug be marked as resolved?
  9. Bug URL GIT commits known-to-fail known-to-work Bug summary
  10. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88129 master Two blockage insns are emited in the function epilogue
  11. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88122 master [9 Regression] g++ ICE: internal compiler error: Segmentation fault
  12. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88084 master basic_string_view::copy doesn't use Traits::copy
  13. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88083 master ICE in find_constant_pool_ref_1, at config/s390/s390.c:8231
  14. ...
  15. Bugzilla lists:
  16. https://gcc.gnu.org/bugzilla/buglist.cgi?bug_id=88129,88122,88084,88083,88074,88073,88071,88070,88051,88018,87985,87955,87926,87917,87913,87898,87895,87874,87871,87855,87853,87826,87824,87819,87818,87799,87793,87789,87788,87787,87754,87725,87674,87665,87649,87647,87645,87625,87611,87610,87598,87593,87582,87566,87556,87547,87544,87541,87537,87528
  17. https://gcc.gnu.org/bugzilla/buglist.cgi?bug_id=87486
  18. """
  19. import argparse
  20. import json
  21. import requests
  22. base_url = 'https://gcc.gnu.org/bugzilla/rest.cgi/'
  23. statuses = ['UNCONFIRMED', 'ASSIGNED', 'SUSPENDED', 'NEW', 'WAITING', 'REOPENED']
  24. regex = '(.*\[)([0-9\./]*)( [rR]egression])(.*)'
  25. closure_question = 'Can the bug be marked as resolved?'
  26. start_page = 20
  27. url_page_size = 50
  28. def get_branches_by_comments(comments):
  29. versions = set()
  30. for c in comments:
  31. text = c['text']
  32. lines = text.split('\n')
  33. if 'URL: https://gcc.gnu.org/viewcvs' in text:
  34. version = 'master'
  35. for line in lines:
  36. if 'branches/gcc-' in line:
  37. parts = line.strip().split('/')
  38. parts = parts[1].split('-')
  39. assert len(parts) == 3
  40. version = parts[1]
  41. break
  42. versions.add(version)
  43. else:
  44. for line in lines:
  45. if line.startswith('The ') and 'branch has been updated' in line:
  46. version = 'master'
  47. name = line.strip().split(' ')[1]
  48. if '/' in name:
  49. name = name.split('/')[1]
  50. assert '-' in name
  51. version = name.split('-')[1]
  52. versions.add(version)
  53. break
  54. return versions
  55. def get_bugs(query):
  56. u = base_url + 'bug'
  57. r = requests.get(u, params = query)
  58. return r.json()['bugs']
  59. def search():
  60. chunk = 1000
  61. ids = []
  62. print('%-30s%-30s%-40s%-40s%-60s' % ('Bug URL', 'GIT commits', 'known-to-fail', 'known-to-work', 'Bug summary'))
  63. for i in range(start_page, 0, -1):
  64. # print('offset: %d' % (i * chunk), flush = True)
  65. bugs = get_bugs({'bug_status': statuses, 'limit': chunk, 'offset': i * chunk})
  66. for b in sorted(bugs, key = lambda x: x['id'], reverse = True):
  67. id = b['id']
  68. fail = b['cf_known_to_fail']
  69. work = b['cf_known_to_work']
  70. u = base_url + 'bug/' + str(id) + '/comment'
  71. r = requests.get(u).json()
  72. keys = list(r['bugs'].keys())
  73. assert len(keys) == 1
  74. comments = r['bugs'][keys[0]]['comments']
  75. skip = False
  76. for c in comments:
  77. if closure_question in c['text']:
  78. skip = True
  79. break
  80. if skip:
  81. continue
  82. branches = sorted(list(get_branches_by_comments(comments)),
  83. key=lambda b: 999 if b is 'master' else int(b))
  84. if branches:
  85. branches_str = ','.join(branches)
  86. print('%-30s%-30s%-40s%-40s%-60s' % ('https://gcc.gnu.org/PR%d' % id, branches_str, fail, work, b['summary']), flush=True)
  87. ids.append(id)
  88. # print all URL lists
  89. print('\nBugzilla lists:')
  90. while len(ids) > 0:
  91. print('https://gcc.gnu.org/bugzilla/buglist.cgi?bug_id=%s' % ','.join([str(x) for x in ids[:url_page_size]]))
  92. ids = ids[url_page_size:]
  93. print('Bugzilla URL page size: %d' % url_page_size)
  94. print('HINT: bugs with following comment are ignored: %s\n' % closure_question)
  95. parser = argparse.ArgumentParser(description='')
  96. args = parser.parse_args()
  97. search()