relnotes.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #!/usr/bin/python
  2. # Run this command as:
  3. #
  4. # jira.sh -s https://issues.apache.org/jira -u $user -p $pw \
  5. # -a getIssueList --search \
  6. # "project in (HADOOP,HDFS,MAPREDUCE) and fixVersion = '$vers' and resolution = Fixed" \
  7. # | ./relnotes.py > $vers.html
  8. import csv
  9. import re
  10. import subprocess
  11. import sys
  12. namePattern = re.compile(r' \([0-9]+\)')
  13. htmlSpecialPattern = re.compile(r'[&<>\'"\n]')
  14. quotes = {'<' : '&lt;', '>': '&gt;', '"': '&quot;', "'": '&apos;',
  15. '&': '&amp;', '\n': '<br>'}
  16. def clean(str):
  17. return re.sub(namePattern, "", str)
  18. def formatComponents(str):
  19. str = re.sub(namePattern, '', str).replace("'", "")
  20. if str != "":
  21. return "(" + str + ")"
  22. else:
  23. return ""
  24. def quoteHtmlChar(m):
  25. return quotes[m.group(0)]
  26. def quoteHtml(str):
  27. return re.sub(htmlSpecialPattern, quoteHtmlChar, str)
  28. def readReleaseNote(id, default):
  29. cmd = ['jira.sh', '-s', 'https://issues.apache.org/jira', '-u', user,
  30. '-p', password, '-a', 'getFieldValue', '--issue', id, '--field',
  31. 'Release Note']
  32. proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=sys.stderr)
  33. lines = proc.stdout.readlines()
  34. # throw away first line
  35. if len(lines) < 2 or len(lines[1]) < 2:
  36. return default
  37. else:
  38. return "\n".join(lines[1:])[1:-2]
  39. user = sys.argv[1]
  40. password = sys.argv[2]
  41. vers = sys.argv[3]
  42. cmd = ['jira.sh', '-s', 'https://issues.apache.org/jira', '-u', user, '-p',
  43. password, '-a', 'getIssueList', '--search',
  44. "project in (HADOOP,HDFS,MAPREDUCE) and fixVersion = '" + vers +
  45. "' and resolution = Fixed"]
  46. proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=sys.stderr)
  47. reader = csv.reader(proc.stdout, skipinitialspace=True)
  48. # throw away number of issues
  49. reader.next()
  50. # read the columns
  51. columns = reader.next()
  52. key = columns.index('Key')
  53. type = columns.index('Type')
  54. priority = columns.index('Priority')
  55. assignee = columns.index('Assignee')
  56. reporter = columns.index('Reporter')
  57. summary = columns.index('Summary')
  58. description = columns.index('Description')
  59. components = columns.index('Components')
  60. print "<html><body><ul>"
  61. for row in reader:
  62. row_descr = readReleaseNote(row[key], row[description])
  63. print \
  64. '<li> <a href="https://issues.apache.org/jira/browse/%s">%s</a>.\n' \
  65. ' %s %s reported by %s and fixed by %s %s<br>\n' \
  66. ' <b>%s</b><br>\n' \
  67. ' <blockquote>%s</blockquote></li>\n' \
  68. % (row[key], row[key], clean(row[priority]), clean(row[type]).lower(),
  69. row[reporter], row[assignee], formatComponents(row[components]),
  70. quoteHtml(row[summary]), quoteHtml(row_descr))
  71. print "</ul>\n</body></html>"