class Object
Constants
- CI_TEST_ARGS
- ERROR_DISTANCE
- GERGICH_GIT_PATH
- GERGICH_REVIEW_LABEL
- GERGICH_USER
- GergichError
- MASTER_BOUNCER_REVIEW_LABEL
- PROJECT
- WARN_DISTANCE
TODO: time-based thresholds
Public Instance Methods
error(text)
click to toggle source
# File lib/gergich/cli.rb, line 24 def error(text) $stderr.puts "\e[31mError:\e[0m #{text}" $stderr.puts usage exit 1 end
help_command(commands)
click to toggle source
# File lib/gergich/cli.rb, line 30 def help_command(commands) { action: ->(subcommand = "help") { subcommand_info = commands[subcommand] if !subcommand_info error "Unrecognized command `#{subcommand}`" elsif (help_text = subcommand_info[:help]) info help_text.respond_to?(:call) ? help_text.call : help_text else error "No help available for `#{subcommand}`" end }, help: -> { indentation = commands.keys.map(&:size).max commands_help = commands .to_a .sort_by(&:first) .map { |key, data| "#{key.ljust(indentation)} - #{data[:summary]}" if data[:summary] } .compact usage(commands_help.join("\n")) } } end
info(text)
click to toggle source
# File lib/gergich/cli.rb, line 9 def info(text) puts text exit end
maybe_bounce_commit!(commit)
click to toggle source
# File lib/gergich/cli/master_bouncer.rb, line 27 def maybe_bounce_commit!(commit) draft = Gergich::Draft.new(commit) draft.reset! distance = Gergich.git("rev-list origin/master ^#{commit.ref} --count").to_i detail = "#{distance} commits behind master" score = 0 message = nil if distance > ERROR_DISTANCE score = -2 message = "This commit is probably not safe to merge (#{detail}). You'll " \ "need to rebase it to ensure all the tests still pass." elsif distance > WARN_DISTANCE score = -1 message = "This commit may not be safe to merge (#{detail}). Please " \ "rebase to make sure all the tests still pass." end review = Gergich::Review.new(commit, draft) current_score = review.current_score puts "#{detail}, " + (score == current_score ? "score still #{score}" : "changing score from #{current_score} to #{score}") # since we run on a daily cron, we might be checking the same patchset # many times, so bail if nothing has changed return if score == current_score draft.add_label MASTER_BOUNCER_REVIEW_LABEL, score draft.add_message message if message # otherwise we always publish ... even in the score=0 case it's # important, as we might be undoing a previous negative score. # similarly, over time the same patchset will become more out of date, # so we allow_repost (so to speak) so we can add increasingly negative # reviews review.publish!(allow_repost: true) end
potentially_mergeable_changes()
click to toggle source
# File lib/gergich/cli/master_bouncer.rb, line 16 def potentially_mergeable_changes url = "/changes/?q=status:open+" \ "p:#{PROJECT}+" \ "label:Verified=1+" \ "is:mergeable+" \ "branch:master" \ "&o=CURRENT_REVISION" changes = Gergich::API.get(url) changes.reject { |c| c["subject"] =~ /\Awip($|\W)/i } end
run_app(commands)
click to toggle source
# File lib/gergich/cli.rb, line 68 def run_app(commands) commands["help"] = help_command(commands) command = ARGV.shift || "help" if commands[command] begin action = commands[command][:action] run_command(action) rescue GergichError error $ERROR_INFO.message rescue StandardError error "Unhandled exception: #{$ERROR_INFO}\n#{$ERROR_INFO.backtrace.join("\n")}" end else error "Unrecognized command `#{command}`" end end
run_ci_test!(all_commands)
click to toggle source
# File lib/gergich/cli/gergich.rb, line 25 def run_ci_test!(all_commands) ENV["GERGICH_CHANGE_NAME"] = "0" commands_to_test = all_commands - %w[citest reset publish status] commands_to_test << "status" # put it at the end, so we maximize the stuff it tests commands = commands_to_test.map { |command| [command, CI_TEST_ARGS[command] || []] } commands.concat(all_commands.map { |command| ["help", [command]] }) # after running our test commands, reset and publish frd: commands << ["reset"] # Note that while gergich should always be able to vote on these labels, he may be used to # vone on other branches depending on project usage and project-specific permissions commands << ["label", ["Lint-Review", 1]] commands << ["label", ["Code-Review", 1]] # Not all projects have Lint-Review commands << ["message", ["\`gergich citest\` checks out :thumbsup: :mj:"]] commands << ["publish"] commands.each do |command, args = []| arglist = args.map { |arg| Shellwords.escape(arg.to_s) } output = `bundle exec gergich #{command} #{arglist.join(" ")} 2>&1` unless $CHILD_STATUS.success? error "`gergich citest` failed on step `#{command}`:\n\n#{output.gsub(/^/, ' ')}\n" end end end
run_command(action)
click to toggle source
# File lib/gergich/cli.rb, line 56 def run_command(action) params = action.parameters params.each_with_index do |(type, name), i| error "No <#{name}> specified" if i >= ARGV.size && type == :req end if ARGV.size > params.size extra_args = ARGV[params.size, ARGV.size].map { |a| "`#{Shellwords.escape(a)}`" } error "Extra arg(s) #{extra_args.join(' ')}" end action.call(*ARGV) end
script_name()
click to toggle source
# File lib/gergich/cli.rb, line 14 def script_name $PROGRAM_NAME.sub(%r{.*/}, "") end
usage(content = nil)
click to toggle source
# File lib/gergich/cli.rb, line 18 def usage(content = nil) "Usage: #{script_name} <command> [<args>...]\n" + (content ? "\n#{content}\n\n" : "") + "Tip: run `#{script_name} help <command>` for more info" end