diff --git a/.gitignore b/.gitignore index 7e23174..b6d42d3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -*.gem *.rbc .DS_Store .bundle diff --git a/README.md b/README.md index 802fbd0..1c32665 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,9 @@ Usage Examples # Test fire a webhook. Gems.fire_web_hook 'rails', 'http://example.com' + # Submit a gem to RubyGems.org. + Gems.push File.new 'gemcutter-0.2.1.gem' + # Remove a gem from RubyGems.org's index. # Defaults to the latest version if no version is specified. Gems.yank 'bills', '0.0.1' diff --git a/lib/gems/client.rb b/lib/gems/client.rb index 98ffb17..1a495f4 100644 --- a/lib/gems/client.rb +++ b/lib/gems/client.rb @@ -173,6 +173,16 @@ def fire_web_hook(gem_name, url) post("/api/v1/web_hooks/fire", {:gem_name => gem_name, :url => url}, :raw) end + # Submit a gem to RubyGems.org + # + # @param gem [File] A built gem. + # @return [String] + # @example + # Gems.push(File.new("pkg/gemcutter-0.2.1.gem")) + def push(gem) + post("/api/v1/gems", gem.read, :raw, 'application/octet-stream') + end + # Remove a gem from RubyGems.org's index # # @param gem_name [String] The name of a gem. diff --git a/lib/gems/configuration.rb b/lib/gems/configuration.rb index fa240a3..ad4ce8f 100644 --- a/lib/gems/configuration.rb +++ b/lib/gems/configuration.rb @@ -17,14 +17,15 @@ module Configuration # Set the default response format appended to the path # # @note JSON is preferred over XML because it is more concise and faster to parse. - DEFAULT_FORMAT = :json + DEFAULT_FORMAT = :json.freeze - DEFAULT_HOST = ENV['RUBYGEMS_HOST'] ? ENV['RUBYGEMS_HOST'] : 'https://rubygems.org' + # Set the default API endpoint + DEFAULT_HOST = ENV['RUBYGEMS_HOST'] ? ENV['RUBYGEMS_HOST'].freeze : 'https://rubygems.org'.freeze # Set the default credentials - DEFAULT_KEY = Gem.configuration.rubygems_api_key + DEFAULT_KEY = Gem.configuration.rubygems_api_key.freeze - # Set the default value sent in the 'User-Agent' header + # Set the default 'User-Agent' HTTP header DEFAULT_USER_AGENT = "Gems #{Gems::VERSION}".freeze attr_accessor *VALID_OPTIONS_KEYS diff --git a/lib/gems/connection.rb b/lib/gems/connection.rb index 42ce6c4..45de10f 100644 --- a/lib/gems/connection.rb +++ b/lib/gems/connection.rb @@ -2,7 +2,7 @@ module Gems module Connection - def connection(format=format) + def connection(content_length=nil, content_type=nil, format=foramt) options = { :headers => { :user_agent => user_agent, @@ -11,10 +11,12 @@ def connection(format=format) :url => host, } + options[:headers].merge!({:content_length => content_length}) if content_length + options[:headers].merge!({:content_type => content_type}) if content_type options[:headers].merge!({:authorization => key}) if key connection = Faraday.new(options) do |connection| - connection.use Faraday::Request::UrlEncoded + connection.use Faraday::Request::UrlEncoded unless content_type case format.to_s.downcase when 'json' connection.use Faraday::Response::ParseJson diff --git a/lib/gems/request.rb b/lib/gems/request.rb index 2fc4586..d0aad3c 100644 --- a/lib/gems/request.rb +++ b/lib/gems/request.rb @@ -1,31 +1,37 @@ +require 'rubygems' + module Gems module Request - def delete(path, options={}, format=format) - request(:delete, path, options, format) + def delete(path, options={}, format=format, content_type=nil) + request(:delete, path, options, format, content_type) end - def get(path, options={}, format=format) - request(:get, path, options, format) + def get(path, options={}, format=format, content_type=nil) + request(:get, path, options, format, content_type) end - def post(path, options={}, format=format) - request(:post, path, options, format) + def post(path, options={}, format=format, content_type=nil) + request(:post, path, options, format, content_type) end - def put(path, options={}, format=format) - request(:put, path, options, format) + def put(path, options={}, format=format, content_type=nil) + request(:put, path, options, format, content_type) end private - def request(method, path, options, format) - response = connection(format).send(method) do |request| + def request(method, path, options, format, content_type) + content_length = case content_type + when 'application/octet-stream' + options.size + end + response = connection(content_length, content_type, format).send(method) do |request| case method when :delete, :get request.url(formatted_path(path, format), options) when :post, :put request.path = formatted_path(path, format) - request.body = options unless options.empty? + request.body = options unless options == {} end end response.body diff --git a/spec/fixtures/gems-0.0.8.gem b/spec/fixtures/gems-0.0.8.gem new file mode 100644 index 0000000..1396c82 Binary files /dev/null and b/spec/fixtures/gems-0.0.8.gem differ diff --git a/spec/fixtures/push b/spec/fixtures/push new file mode 100644 index 0000000..7fbf6a6 --- /dev/null +++ b/spec/fixtures/push @@ -0,0 +1 @@ +Successfully registered gem: gems (0.0.8) \ No newline at end of file diff --git a/spec/gems/client_spec.rb b/spec/gems/client_spec.rb index addd62a..633830f 100644 --- a/spec/gems/client_spec.rb +++ b/spec/gems/client_spec.rb @@ -289,6 +289,20 @@ end end + describe ".push" do + before do + stub_post("/api/v1/gems"). + to_return(:body => fixture("push")) + end + + it "should submit a gem to RubyGems.org" do + push = Gems.push(File.new(File.expand_path("../../fixtures/gems-0.0.8.gem", __FILE__), "rb")) + a_post("/api/v1/gems"). + should have_been_made + push.should == "Successfully registered gem: gems (0.0.8)" + end + end + describe ".yank" do context "with no version specified" do before do