class Fuel::CLI::Gerrit

Public Instance Methods

abandon() click to toggle source
# File lib/fuel/cli/gerrit.rb, line 88
def abandon
  change_id = fetch_change_id_or_fail
  params = options['message'] ? { body: { message: options['message'] }.to_json } : {}
  result = self.class.post(changes_endpoint(change_id, 'abandon'), params).parsed_response
end
alias(email, alias_name = nil) click to toggle source
# File lib/fuel/cli/gerrit.rb, line 61
def alias(email, alias_name = nil)
  if alias_name
    Config.set('gerrit', 'aliases', alias_name, email)
  else
    aliases = Config.get('gerrit', 'aliases') || {}
    aliases_found = aliases.map { |k, v| v == email ? k : nil }.compact
    if aliases_found.empty?
      say "No aliases created for #{email}", :yellow
    else
      say "Aliases for #{email}: #{aliases_found.join("; ")}"
    end
  end
end
auth(user) click to toggle source
# File lib/fuel/cli/gerrit.rb, line 76
def auth(user)
  set_credentials(user, ['gerrit', 'user'], ['gerrit', 'password'])
end
checkout(email_or_alias) click to toggle source
# File lib/fuel/cli/gerrit.rb, line 114
def checkout(email_or_alias)
  email = to_email(email_or_alias)
  say "Group aliases are not supported", :red and return if email.is_a?(Array)
  result = self.class.get(changes_endpoint(nil, "?q=status:open+owner:#{email}&n=1&o=CURRENT_REVISION&o=DOWNLOAD_COMMANDS")).parsed_response
  say "No open changes found for #{email_or_alias}", :yellow and return if result.empty?
  current_rev = result[0]['current_revision']
  command = result[0]['revisions'][current_rev]['fetch']['ssh']['commands']['Checkout']
  `#{command}`
end
comments(file) click to toggle source
# File lib/fuel/cli/gerrit.rb, line 143
def comments(file)
  comments, lines = comments_for_file(file)
  extra_lines = 0
  comments.each do |c|
    line = c['line'] + extra_lines
    comment_lines = format_comment(c)
    lines.insert(line, *comment_lines)
    extra_lines += comment_lines.size
  end
  exec("printf #{lines.join('\n').inspect} | less -F -X -R")
end
cr(vote) click to toggle source
# File lib/fuel/cli/gerrit.rb, line 132
def cr(vote)
  submit_review('Code-Review', vote)
end
gerrit_change_url() click to toggle source
# File lib/fuel/cli/gerrit.rb, line 189
def gerrit_change_url
  change_id = fetch_change_id_or_fail
  result = self.class.get(changes_endpoint(change_id)).parsed_response
  "#{gerrit_url}/#{result['_number']}"
end
open() click to toggle source
# File lib/fuel/cli/gerrit.rb, line 41
def open
  `open #{gerrit_change_url}`
end
qa(vote) click to toggle source
# File lib/fuel/cli/gerrit.rb, line 126
def qa(vote)
  submit_review('QA-Test-Passed', vote)
end
rebase() click to toggle source
# File lib/fuel/cli/gerrit.rb, line 103
def rebase
  change_id = fetch_change_id_or_fail
  result = self.class.post(changes_endpoint(change_id, "rebase"))
  if result.response.code == "409"
    say "Rebase failed, conflicts found", :red
  else
    say "Rebased successfully", :green
  end
end
respond(file) click to toggle source
# File lib/fuel/cli/gerrit.rb, line 156
def respond(file)
  comments, lines, change_id, revision_id = comments_for_file(file)
  commented_on = {}
  comments_for_lines = comments.inject({}) do |h, c|
    h[c['line']] ||= []
    h[c['line']] << c
    h
  end
  comments_to_post = comments_for_lines.map do |line, cc|
    next if cc.all? { |c| c['author']['username'] == gerrit_user }
    system 'tput smcup'

    line_in_array = line - 1
    first_line = [0, line_in_array - 4].max
    if first_line == line_in_array
      say "Line #{line}:", :bold
    else
      say "Lines #{first_line + 1}-#{line}:", :bold
    end
    say lines[first_line..line_in_array].join("\n")
    cc.each do |c|
      say format_comment(c).join("\n")
    end
    reply = ask "Reply on this line (press enter to skip):"
    system 'tput rmcup'
    next if reply.strip.empty?
    { line: line, message: reply }
  end.compact
  say 'No comments to respond to!', :green and return if comments_to_post.empty?
  result = self.class.post(revisions_endpoint(change_id, revision_id, 'review'), body: { comments: { file => comments_to_post } }.to_json).parsed_response
end
restore() click to toggle source
# File lib/fuel/cli/gerrit.rb, line 96
def restore
  change_id = fetch_change_id_or_fail
  params = options['message'] ? { body: { message: options['message'] }.to_json } : {}
  result = self.class.post(changes_endpoint(change_id, 'restore'), params).parsed_response
end
review_add(*emails_or_aliases) click to toggle source
# File lib/fuel/cli/gerrit.rb, line 46
def review_add(*emails_or_aliases)
  change_id = fetch_change_id_or_fail
  emails_or_aliases.each do |value|
    emails = Array(to_email(value))
    if emails.empty?
      say "No email found for alias #{value}; reviewer not added", :yellow
      next
    end
    emails.each do |email|
      result = self.class.post(reviewers_endpoint(change_id), body: { reviewer: email }.to_json).parsed_response
    end
  end
end
status() click to toggle source
# File lib/fuel/cli/gerrit.rb, line 18
def status
  change_id = fetch_change_id_or_fail

  result = self.class.get(changes_endpoint(change_id, "?o=CURRENT_REVISION")).parsed_response
  current_rev = result['current_revision']

  say result["subject"], :bold
  table = [["Owner", result["owner"]["name"]]]
  table << ["Updated", format_time(result["updated"])]
  table << ["Status", result["status"]]
  table << ["Ref", gerrit_ref(result)]
  print_table table

  result = fetch_comments(change_id, current_rev)
  print_comments_info(result)
  puts
  result = self.class.get(reviewers_endpoint(change_id)).parsed_response
  table = result.map { |row| format_row(row) }
  table.unshift(["Reviewer", "CR", "QA", "V"])
  print_table table
end
submit() click to toggle source
# File lib/fuel/cli/gerrit.rb, line 81
def submit
  change_id = fetch_change_id_or_fail
  result = self.class.post(changes_endpoint(change_id, 'submit'), body: { wait_for_merge: true }.to_json)
end
verified(vote) click to toggle source
# File lib/fuel/cli/gerrit.rb, line 138
def verified(vote)
  submit_review('Verified', vote)
end

Private Instance Methods

comments_for_file(file) click to toggle source
# File lib/fuel/cli/gerrit.rb, line 290
def comments_for_file(file)
  change_id = fetch_change_id_or_fail
  result = self.class.get(changes_endpoint(change_id, "detail?o=CURRENT_REVISION&o=CURRENT_FILES")).parsed_response
  current_rev = result['current_revision']

  content = self.class.get(revisions_endpoint(change_id, current_rev, "files/#{CGI::escape(file)}/content")).parsed_response
  content = Base64::decode64(content)
  lines = content.split("\n")
  comments = fetch_comments(change_id, current_rev)[file]
  comments.sort_by! { |c| [c['line'], Time.parse(c['updated'])] }
  [comments, lines, change_id, current_rev]
end
cross() click to toggle source
# File lib/fuel/cli/gerrit.rb, line 262
def cross
  set_color(" " + [10008].pack("U*"), :red)
end
emails_for_alias(alias_name) click to toggle source
# File lib/fuel/cli/gerrit.rb, line 230
def emails_for_alias(alias_name)
  aliases = Config.get('gerrit', 'aliases', alias_name)
end
fetch_comments(change_id, revision_id) click to toggle source
# File lib/fuel/cli/gerrit.rb, line 286
def fetch_comments(change_id, revision_id)
  return self.class.get(revisions_endpoint(change_id, revision_id, 'comments')).parsed_response
end
format_comment(c) click to toggle source
# File lib/fuel/cli/gerrit.rb, line 198
def format_comment(c)
  msg = c['message'].gsub("\n\n", "\n")
  date = format_time(c['updated'])
  author = set_color(c['author']['name'], :yellow)
  prefix = "[#{date}] #{author}: "
  comment_lines = msg.split("\n")
  comment_lines[0].prepend prefix
  comment_lines[1..-1].each do |cline|
    cline.prepend " " * prefix.size
  end
  comment_lines
end
format_review(cell) click to toggle source
# File lib/fuel/cli/gerrit.rb, line 244
def format_review(cell)
  characters = { "0" => " ", "-1" => set_color("-1", :red), "+1" => set_color("+1", :green), "+2" => tick, "-2" => cross }
  characters[(cell || "").strip]
end
format_row(row) click to toggle source
# File lib/fuel/cli/gerrit.rb, line 234
def format_row(row)
  result = [row["name"]]
  approvals = row["approvals"]

  result << format_review(approvals && approvals["Code-Review"])
  result << format_verified(approvals && approvals["QA-Test-Passed"])
  result << format_verified(approvals && approvals["Verified"])
  result
end
format_time(time) click to toggle source
# File lib/fuel/cli/gerrit.rb, line 254
def format_time(time)
  Time.parse(time + " UTC").getlocal.strftime("%b %-d %l:%M %p")
end
format_verified(cell) click to toggle source
# File lib/fuel/cli/gerrit.rb, line 249
def format_verified(cell)
  characters = { "0" => " ", "-1" => cross, "+1" => tick }
  characters[(cell || "").strip]
end
gerrit_user() click to toggle source
# File lib/fuel/cli/gerrit.rb, line 303
def gerrit_user
  Config.get('gerrit', 'user')
end
is_email?(value) click to toggle source
# File lib/fuel/cli/gerrit.rb, line 226
def is_email?(value)
  !!value.index('@')
end
plural(n, singular) click to toggle source
# File lib/fuel/cli/gerrit.rb, line 320
def plural(n, singular)
  if n == 1
    "1 #{singular}"
  else
    "#{n} #{singular}s"
  end
end
print_comments_info(data) click to toggle source
reviewers_endpoint(change_id) click to toggle source
# File lib/fuel/cli/gerrit.rb, line 273
def reviewers_endpoint(change_id)
  changes_endpoint(change_id, "reviewers")
end
revisions_endpoint(change_id, revision_id = nil, path = nil) click to toggle source
# File lib/fuel/cli/gerrit.rb, line 266
def revisions_endpoint(change_id, revision_id = nil, path = nil)
  url = "#{changes_endpoint(change_id)}revisions/"
  url += "#{revision_id}/" if revision_id
  url += path if path
  url
end
run_editor() click to toggle source
# File lib/fuel/cli/gerrit.rb, line 277
def run_editor
  path = File.expand_path('~/.fuel/MSG')
  FileUtils.touch(path)
  system((ENV['EDITOR'] || 'vi') + ' ' + path)
  content = File.read(path)
  FileUtils.rm(path)
  content
end
submit_review(label, vote) click to toggle source
# File lib/fuel/cli/gerrit.rb, line 211
def submit_review(label, vote)
  change_id = fetch_change_id_or_fail
  result = self.class.get(changes_endpoint(change_id, "?o=CURRENT_REVISION")).parsed_response
  current_rev = result['current_revision']
  body = { labels: { label => vote.to_i } }
  message = options['message'] || run_editor.gsub("\n", "\n\n")

  body[:message] = message
  result = self.class.post(revisions_endpoint(change_id, current_rev, 'review'), body: body.to_json).parsed_response
end
tick() click to toggle source
# File lib/fuel/cli/gerrit.rb, line 258
def tick
  set_color(" " + [10003].pack("U*"), :green)
end
to_email(value) click to toggle source
# File lib/fuel/cli/gerrit.rb, line 222
def to_email(value)
  is_email?(value) ? value : emails_for_alias(value)
end