1require 'rubygems/command'
2require 'rubygems/local_remote_options'
3require 'rubygems/gemcutter_utilities'
4require 'rubygems/package'
5
6class Gem::Commands::PushCommand < Gem::Command
7  include Gem::LocalRemoteOptions
8  include Gem::GemcutterUtilities
9
10  def description # :nodoc:
11    'Push a gem up to RubyGems.org'
12  end
13
14  def arguments # :nodoc:
15    "GEM       built gem to push up"
16  end
17
18  def usage # :nodoc:
19    "#{program_name} GEM"
20  end
21
22  def initialize
23    super 'push', description, :host => self.host
24
25    add_proxy_option
26    add_key_option
27
28    add_option('--host HOST',
29               'Push to another gemcutter-compatible host') do |value, options|
30      options[:host] = value
31    end
32
33    @host = nil
34  end
35
36  def execute
37    @host = options[:host]
38
39    sign_in @host
40
41    send_gem get_one_gem_name
42  end
43
44  def send_gem name
45    args = [:post, "api/v1/gems"]
46
47    latest_rubygems_version = Gem.latest_rubygems_version
48
49    if latest_rubygems_version < Gem.rubygems_version and
50         Gem.rubygems_version.prerelease? and
51         Gem::Version.new('2.0.0.rc.2') != Gem.rubygems_version then
52      alert_error <<-ERROR
53You are using a beta release of RubyGems (#{Gem::VERSION}) which is not
54allowed to push gems.  Please downgrade or upgrade to a release version.
55
56The latest released RubyGems version is #{latest_rubygems_version}
57
58You can upgrade or downgrade to the latest release version with:
59
60  gem update --system=#{latest_rubygems_version}
61
62      ERROR
63      terminate_interaction 1
64    end
65
66    unless @host then
67      if gem_data = Gem::Package.new(name) then
68        @host = gem_data.spec.metadata['default_gem_server']
69      end
70    end
71
72    args << @host if @host
73
74    say "Pushing gem to #{@host || Gem.host}..."
75
76    response = rubygems_api_request(*args) do |request|
77      request.body = Gem.read_binary name
78      request.add_field "Content-Length", request.body.size
79      request.add_field "Content-Type",   "application/octet-stream"
80      request.add_field "Authorization",  api_key
81    end
82
83    with_response response
84  end
85
86end
87
88