PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/tools/bitbucket_pullrequests

https://bitbucket.org/pwkalana9/gazebo_3.1_actor_animation_fix
Ruby | 235 lines | 192 code | 23 blank | 20 comment | 20 complexity | 64345cbe0464edef5e62c70f3c763946 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause, LGPL-2.1, LGPL-3.0
  1. #!/usr/bin/env ruby
  2. #/ Usage: <progname> [options]...
  3. #/ Get info on pull requests from gazebo's bitbucket repository
  4. # based on http://www.alphadevx.com/a/88-Writing-a-REST-Client-in-Ruby
  5. # to install dependencies on Ubuntu (tested with Precise, Quantal, and Raring):
  6. #sudo apt-get install rubygems ruby-rest-client ruby-json
  7. require 'rubygems'
  8. require 'rest_client'
  9. require 'json'
  10. require 'optparse'
  11. require 'date'
  12. $stderr.sync = true
  13. class BitbucketPullRequests
  14. # Pull request summary
  15. class Summary
  16. attr_reader :id
  17. attr_reader :source
  18. attr_reader :destination
  19. attr_reader :branch
  20. attr_reader :createdOn
  21. attr_reader :title
  22. def initialize(jsonHash, options)
  23. @options = options
  24. @id = jsonHash["id"]
  25. @source = " "*12
  26. @destination = " "*12
  27. @branch = ""
  28. @title = ""
  29. source = jsonHash["source"]["commit"]
  30. destination = jsonHash["destination"]["commit"]
  31. branch = jsonHash["source"]["branch"]
  32. title = jsonHash["title"]
  33. @source = source["hash"] if !source.nil?
  34. @destination = destination["hash"] if !destination.nil?
  35. @branch = branch["name"] if !branch.nil?
  36. @title = title if !title.nil?
  37. @createdOn = jsonHash["created_on"]
  38. end
  39. def to_s
  40. title = ""
  41. title += "\n" + @title + "\n" if @options["title"]
  42. title +
  43. @id.to_s.rjust(5, ' ') + " " +
  44. DateTime.parse(@createdOn).strftime("%Y-%m-%d") + " " +
  45. @source + " " +
  46. @destination + " " +
  47. @branch + "\n"
  48. end
  49. def date_and_string
  50. [@createdOn, self.to_s]
  51. end
  52. end
  53. # constructor
  54. def initialize(options)
  55. @url_pullrequests = 'https://bitbucket.org/api/2.0/repositories/osrf/gazebo/pullrequests'
  56. @options = options
  57. end
  58. # helpers for RestClient.get calls
  59. def getUrl(url)
  60. puts url if @options["show-url"]
  61. RestClient.get(url)
  62. end
  63. def getJson(url)
  64. json = JSON.parse(getUrl(url).body)
  65. if @options["verbose"]
  66. puts JSON.pretty_generate(json)
  67. end
  68. json
  69. end
  70. # summary of open pull requests
  71. def listPullRequests()
  72. jsonHash = getJson(@url_pullrequests + "/?state=OPEN")
  73. output = ""
  74. # Hash of pull requests.
  75. pullrequests = {}
  76. jsonHash["values"].each { |pr|
  77. date, str = Summary.new(pr, @options).date_and_string
  78. pullrequests[date] = str
  79. }
  80. while jsonHash.has_key? "next"
  81. jsonHash = getJson(jsonHash["next"])
  82. jsonHash["values"].each { |pr|
  83. date, str = Summary.new(pr, @options).date_and_string
  84. pullrequests[date] = str
  85. }
  86. end
  87. # Generate output sorted by creation time
  88. pullrequests.keys.sort.each { |k| output += pullrequests[k] }
  89. return output
  90. end
  91. # summary of one pull request
  92. def getPullRequestSummary(id)
  93. jsonHash = getJson(@url_pullrequests + "/" + id.to_s)
  94. return Summary.new(jsonHash, @options)
  95. end
  96. # diff of pull request
  97. def getPullRequestDiff(id)
  98. response = getUrl(@url_pullrequests + "/" + id.to_s + "/diff")
  99. puts response if @options["verbose"]
  100. return response
  101. end
  102. # list of files changed by pull request
  103. def getPullRequestFiles(id)
  104. files = []
  105. diff = getPullRequestDiff(id)
  106. diff.lines.map(&:chomp).each do |line|
  107. if line.start_with? '+++ b/'
  108. line["+++ b/"] = ""
  109. files << line
  110. end
  111. end
  112. return files
  113. end
  114. # get ids for open pull requests
  115. def getOpenPullRequests()
  116. jsonHash = getJson(@url_pullrequests + "/?state=OPEN")
  117. ids = []
  118. jsonHash["values"].each { |pr| ids << pr["id"].to_i }
  119. while jsonHash.has_key? "next"
  120. jsonHash = getJson(jsonHash["next"])
  121. jsonHash["values"].each { |pr| ids << pr["id"].to_i }
  122. end
  123. return ids
  124. end
  125. # check changed files in pull request by id
  126. def checkPullRequest(id, fork=true)
  127. summary = getPullRequestSummary(id)
  128. puts "checking pull request #{id}, branch #{summary.branch}"
  129. files = getPullRequestFiles(id)
  130. files_list = ""
  131. files.each { |f| files_list += " " + f }
  132. hg_root = `hg root`.chomp
  133. `hg log -r #{summary.destination} 2>&1`
  134. if $? != 0
  135. puts "Unknown revision #{summary.destination}, try: hg pull"
  136. return
  137. end
  138. `hg log -r #{summary.source} 2>&1`
  139. if $? != 0
  140. puts "Unknown revision #{summary.source}, try: hg pull " +
  141. "(it could also be a fork)"
  142. return
  143. end
  144. ancestor=`hg log -r "ancestor(#{summary.source},#{summary.destination})" | head -1 | sed -e 's@.*:@@'`.chomp
  145. if ancestor != summary.destination
  146. puts "Need to merge branch #{summary.branch} with #{summary.destination}"
  147. end
  148. if fork
  149. # this will allow real-time console output
  150. exec "echo #{files_list} | sh #{hg_root}/tools/code_check.sh --quick #{summary.source}"
  151. else
  152. puts `echo #{files_list} | sh "#{hg_root}"/tools/code_check.sh --quick #{summary.source}`
  153. end
  154. end
  155. end
  156. # default options
  157. options = {}
  158. options["list"] = false
  159. options["summary"] = nil
  160. options["check"] = false
  161. options["check_id"] = nil
  162. options["diff"] = nil
  163. options["files"] = nil
  164. options["show-url"] = false
  165. options["title"] = false
  166. options["verbose"] = false
  167. opt_parser = OptionParser.new do |o|
  168. o.on("-l", "--list",
  169. "List open pull requests with fields:\n" + " "*37 +
  170. "[id] [source] [dest] [branch]") { |o| options["list"] = o }
  171. o.on("-c", "--check [id]", Integer,
  172. "") { |o| options["check_id"] = o; options["check"] = true }
  173. o.on("-d", "--diff [id]", Integer,
  174. "Show diff from pull request") { |o| options["diff"] = o }
  175. o.on("-f", "--files [id]", Integer,
  176. "Show changed files in a pull request") { |o| options["files"] = o }
  177. o.on("-s", "--summary [id]", Integer,
  178. "Summarize a pull request with fields:\n" + " "*37 +
  179. "[id] [source] [dest] [branch]") { |o| options["summary"] = o }
  180. o.on("-t", "--title",
  181. "Show pull request title with --list, --summary") { |o| options["title"] = o }
  182. o.on("-u", "--show-url",
  183. "Show urls accessed") { |o| options["show-url"] = o }
  184. o.on("-v", "--verbose",
  185. "Verbose output") { |o| options["verbose"] = o }
  186. o.on("-h", "--help", "Display this help message") do
  187. puts opt_parser
  188. exit
  189. end
  190. end
  191. opt_parser.parse!
  192. client = BitbucketPullRequests.new(options)
  193. if options["list"]
  194. puts client.listPullRequests()
  195. elsif !options["summary"].nil?
  196. puts client.getPullRequestSummary(options["summary"])
  197. elsif !options["diff"].nil?
  198. puts client.getPullRequestDiff(options["diff"])
  199. elsif !options["files"].nil?
  200. puts client.getPullRequestFiles(options["files"])
  201. elsif options["check"]
  202. if options["check_id"].nil?
  203. # check all open pull requests
  204. client.getOpenPullRequests().each { |id|
  205. client.checkPullRequest(id, false)
  206. }
  207. else
  208. client.checkPullRequest(options["check_id"])
  209. end
  210. else
  211. puts opt_parser
  212. end