lib/rubygems/commands/webhook_command.rb
require 'rubygems/local_remote_options'
require 'rubygems/gemcutter_utilities'
require 'rubygems/command'
class Gem::Commands::WebhookCommand < Gem::Command
include Gem::LocalRemoteOptions
include Gem::GemcutterUtilities
def description
<<-EOF
Webhooks can be created for either specific gems or all gems. In both cases
you'll get a POST request of the gem in JSON format at the URL you specify in
the command. You can also use this command to test fire a webhook for any gem.
EOF
end
def arguments
"GEM_NAME name of gem to register webhook for, or omit to list hooks."
end
def usage
"#{program_name} [GEM_NAME]"
end
def initialize
super 'webhook', "Register a webhook that will be called any time a gem is updated on Gemcutter."
option_text = "The URL of the webhook to"
add_option('-a', '--add URL', "#{option_text} add") do |value, options|
options[:send] = 'add'
options[:url] = value
end
add_option('-r', '--remove URL', "#{option_text} remove") do |value, options|
options[:send] = 'remove'
options[:url] = value
end
add_option('-f', '--fire URL', "#{option_text} testfire") do |value, options|
options[:send] = 'fire'
options[:url] = value
end
add_option('-g', '--global', "Apply hook globally") do |value, options|
options[:global] = true
end
add_proxy_option
end
def execute
sign_in
if options[:url]
name = options[:global] ? '*' : get_one_gem_name
send("#{options[:send]}_webhook", name, options[:url])
else
list_webhooks
end
end
def add_webhook(name, url)
say "Adding webhook..."
make_webhook_request(:post, name, url)
end
def remove_webhook(name, url)
say "Removing webhook..."
make_webhook_request(:delete, name, url, "api/v1/web_hooks/remove")
end
def fire_webhook(name, url)
say "Test firing webhook..."
make_webhook_request(:post, name, url, "api/v1/web_hooks/fire")
end
def list_webhooks
resp = rubygems_api_request(:get, "api/v1/web_hooks.yaml") do |request|
request.add_field("Authorization", Gem.configuration.rubygems_api_key)
end
with_response(resp) do |response|
begin
groups = YAML.load(response.body)
if groups.size.zero?
say "You haven't added any webhooks yet."
else
groups.each do |group, hooks|
if options[:global]
next if group != "all gems"
elsif options[:args] && options[:args].first
next if group != options[:args].first
end
say "#{group}:"
hooks.each do |hook|
say "- #{hook['url']}"
end
end
end
rescue Exception => error
say "There was a problem parsing the data:"
say error.to_s
terminate_interaction
end
end
end
def make_webhook_request(method, name, url, api = "api/v1/web_hooks")
response = rubygems_api_request(method, api) do |request|
request.set_form_data("gem_name" => name, "url" => url)
request.add_field("Authorization", Gem.configuration.rubygems_api_key)
end
with_response(response)
end
end