Class: Gem::Commands::UpdateCommand

Inherits:
Gem::Command show all
Includes:
InstallUpdateOptions, LocalRemoteOptions, VersionOption
Defined in:
lib/rubygems/commands/update_command.rb

Instance Attribute Summary collapse

Attributes inherited from Gem::Command

#command, #defaults, #options, #program_name, #summary

Instance Method Summary collapse

Methods included from VersionOption

#add_platform_option, #add_prerelease_option, #add_version_option

Methods included from LocalRemoteOptions

#accept_uri_http, #add_bulk_threshold_option, #add_clear_sources_option, #add_local_remote_options, #add_proxy_option, #add_source_option, #add_update_sources_option, #both?, #local?, #remote?

Methods included from InstallUpdateOptions

#add_install_update_options, #install_update_defaults_str

Methods inherited from Gem::Command

add_common_option, #add_extra_args, #add_option, add_specific_extra_args, #begins?, build_args, build_args=, common_options, extra_args, extra_args=, #get_all_gem_names, #get_all_gem_names_and_versions, #get_one_gem_name, #get_one_optional_argument, #handle_options, #handles?, #invoke, #invoke_with_build_args, #merge_options, #remove_option, #show_help, #show_lookup_failure, specific_extra_args, specific_extra_args_hash, #when_invoked

Methods included from UserInteraction

#alert, #alert_error, #alert_warning, #ask, #ask_for_password, #ask_yes_no, #choose_from_list, #say, #terminate_interaction

Methods included from DefaultUserInteraction

ui, #ui, ui=, #ui=, use_ui, #use_ui

Constructor Details

#initializeUpdateCommand

Returns a new instance of UpdateCommand.



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/rubygems/commands/update_command.rb', line 19

def initialize
  super 'update', 'Update installed gems to the latest version',
    :document => %w[rdoc ri],
    :force    => false

  add_install_update_options

  OptionParser.accept Gem::Version do |value|
    Gem::Version.new value

    value
  end

  add_option('--system [VERSION]', Gem::Version,
             'Update the RubyGems system software') do |value, options|
    value = true unless value

    options[:system] = value
  end

  add_local_remote_options
  add_platform_option
  add_prerelease_option "as update targets"

  @updated   = []
  @installer = nil
end

Instance Attribute Details

#installerObject (readonly)

:nodoc:



17
18
19
# File 'lib/rubygems/commands/update_command.rb', line 17

def installer
  @installer
end

Instance Method Details

#argumentsObject

:nodoc:



47
48
49
# File 'lib/rubygems/commands/update_command.rb', line 47

def arguments # :nodoc:
  "GEMNAME       name of gem to update"
end

#check_latest_rubygems(version) ⇒ Object

:nodoc:



68
69
70
71
72
73
74
75
# File 'lib/rubygems/commands/update_command.rb', line 68

def check_latest_rubygems version # :nodoc:
  if Gem.rubygems_version == version then
    say "Latest version currently installed. Aborting."
    terminate_interaction
  end

  options[:user_install] = false
end

#check_update_argumentsObject

:nodoc:



77
78
79
80
81
82
# File 'lib/rubygems/commands/update_command.rb', line 77

def check_update_arguments # :nodoc:
  unless options[:args].empty? then
    alert_error "Gem names are not allowed with the --system option"
    terminate_interaction 1
  end
end

#defaults_strObject

:nodoc:



51
52
53
# File 'lib/rubygems/commands/update_command.rb', line 51

def defaults_str # :nodoc:
  "--document --no-force --install-dir #{Gem.dir}"
end

#descriptionObject

:nodoc:



55
56
57
58
59
60
61
62
# File 'lib/rubygems/commands/update_command.rb', line 55

def description # :nodoc:
  <<-EOF
The update command will update your gems to the latest version.

The update comamnd does not remove the previous version.  Use the cleanup
command to remove old versions.
  EOF
end

#executeObject



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/rubygems/commands/update_command.rb', line 84

def execute
  hig = {}

  if options[:system] then
    update_rubygems
    return
  end

  say "Updating installed gems"

  hig = highest_installed_gems

  gems_to_update = which_to_update hig, options[:args].uniq

  updated = update_gems gems_to_update

  if updated.empty? then
    say "Nothing to update"
  else
    say "Gems updated: #{updated.map { |spec| spec.name }.join ' '}"
  end
end

#fetch_remote_gems(spec) ⇒ Object

:nodoc:



107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/rubygems/commands/update_command.rb', line 107

def fetch_remote_gems spec # :nodoc:
  dependency = Gem::Dependency.new spec.name, "> #{spec.version}"
  dependency.prerelease = options[:prerelease]

  fetcher = Gem::SpecFetcher.fetcher

  spec_tuples, errors = fetcher.search_for_dependency dependency

  error = errors.find { |e| e.respond_to? :exception }

  raise error if error

  spec_tuples
end

#highest_installed_gemsObject

:nodoc:



122
123
124
125
126
127
128
129
130
131
132
# File 'lib/rubygems/commands/update_command.rb', line 122

def highest_installed_gems # :nodoc:
  hig = {} # highest installed gems

  Gem::Specification.each do |spec|
    if hig[spec.name].nil? or hig[spec.name].version < spec.version then
      hig[spec.name] = spec
    end
  end

  hig
end

#highest_remote_version(spec) ⇒ Object

:nodoc:



134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/rubygems/commands/update_command.rb', line 134

def highest_remote_version spec # :nodoc:
  spec_tuples = fetch_remote_gems spec

  matching_gems = spec_tuples.select do |g,_|
    g.name == spec.name and g.match_platform?
  end

  highest_remote_gem = matching_gems.max_by { |g,_| g.version }

  highest_remote_gem ||= [Gem::NameTuple.null]

  highest_remote_gem.first.version
end

#install_rubygems(version) ⇒ Object

:nodoc:



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/rubygems/commands/update_command.rb', line 148

def install_rubygems version # :nodoc:
  args = update_rubygems_arguments

  update_dir = File.join Gem.dir, 'gems', "rubygems-update-#{version}"

  Dir.chdir update_dir do
    say "Installing RubyGems #{version}"

    # Make sure old rubygems isn't loaded
    old = ENV["RUBYOPT"]
    ENV.delete("RUBYOPT") if old
    installed = system Gem.ruby, 'setup.rb', *args
    say "RubyGems system software updated" if installed
    ENV["RUBYOPT"] = old if old
  end
end

#rubygems_target_versionObject



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/rubygems/commands/update_command.rb', line 165

def rubygems_target_version
  version = options[:system]
  update_latest = version == true

  if update_latest then
    version     = Gem::Version.new     Gem::VERSION
    requirement = Gem::Requirement.new ">= #{Gem::VERSION}"
  else
    version     = Gem::Version.new     version
    requirement = Gem::Requirement.new version
  end

  rubygems_update         = Gem::Specification.new
  rubygems_update.name    = 'rubygems-update'
  rubygems_update.version = version

  hig = {
    'rubygems-update' => rubygems_update
  }

  gems_to_update = which_to_update hig, options[:args], :system
  _, up_ver   = gems_to_update.first

  target = if update_latest then
             up_ver
           else
             version
           end

  return target, requirement
end

#update_gem(name, version = Gem::Requirement.default) ⇒ Object



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/rubygems/commands/update_command.rb', line 197

def update_gem name, version = Gem::Requirement.default
  return if @updated.any? { |spec| spec.name == name }

  @installer ||= Gem::DependencyInstaller.new options

  success = false

  say "Updating #{name}"
  begin
    @installer.install name, Gem::Requirement.new(version)
    success = true
  rescue Gem::InstallError => e
    alert_error "Error installing #{name}:\n\t#{e.message}"
    success = false
  end

  @installer.installed_gems.each do |spec|
    @updated << spec
  end
end

#update_gems(gems_to_update) ⇒ Object



218
219
220
221
222
223
224
# File 'lib/rubygems/commands/update_command.rb', line 218

def update_gems gems_to_update
  gems_to_update.uniq.sort.each do |(name, version)|
    update_gem name, version
  end

  @updated
end

#update_rubygemsObject

Update RubyGems software to the latest version.



229
230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/rubygems/commands/update_command.rb', line 229

def update_rubygems
  check_update_arguments

  version, requirement = rubygems_target_version

  check_latest_rubygems version

  update_gem 'rubygems-update', version

  installed_gems = Gem::Specification.find_all_by_name 'rubygems-update', requirement
  version        = installed_gems.last.version

  install_rubygems version
end

#update_rubygems_argumentsObject

:nodoc:



244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/rubygems/commands/update_command.rb', line 244

def update_rubygems_arguments # :nodoc:
  args = []
  args << '--prefix' << Gem.prefix if Gem.prefix
  # TODO use --document for >= 1.9 , --no-rdoc --no-ri < 1.9
  args << '--no-rdoc' unless options[:document].include? 'rdoc'
  args << '--no-ri'   unless options[:document].include? 'ri'
  args << '--no-format-executable' if options[:no_format_executable]
  args << '--previous-version' << Gem::VERSION if
    options[:system] == true or
      Gem::Version.new(options[:system]) >= Gem::Version.new(2)
  args
end

#usageObject

:nodoc:



64
65
66
# File 'lib/rubygems/commands/update_command.rb', line 64

def usage # :nodoc:
  "#{program_name} GEMNAME [GEMNAME ...]"
end

#which_to_update(highest_installed_gems, gem_names, system = false) ⇒ Object



257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
# File 'lib/rubygems/commands/update_command.rb', line 257

def which_to_update highest_installed_gems, gem_names, system = false
  result = []

  highest_installed_gems.each do |l_name, l_spec|
    next if not gem_names.empty? and
            gem_names.all? { |name| /#{name}/ !~ l_spec.name }

    highest_remote_ver = highest_remote_version l_spec

    if system or (l_spec.version < highest_remote_ver) then
      result << [l_spec.name, [l_spec.version, highest_remote_ver].max]
    end
  end

  result
end