1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
ruby--ruby/lib/rubygems/commands/lock_command.rb
hsbt 5335ce0e06 Merge master branch from rubygems/rubygems upstream.
* Enable Style/MethodDefParentheses in Rubocop
    https://github.com/rubygems/rubygems/pull/2478
  * Enable Style/MultilineIfThen in Rubocop
    https://github.com/rubygems/rubygems/pull/2479
  * Fix required_ruby_version with prereleases and improve error message
    https://github.com/rubygems/rubygems/pull/2344
  * Fix bundler rubygems binstub not properly looking for bundler
    https://github.com/rubygems/rubygems/pull/2426

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65904 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-21 10:20:47 +00:00

110 lines
2.7 KiB
Ruby

# frozen_string_literal: true
require 'rubygems/command'
class Gem::Commands::LockCommand < Gem::Command
def initialize
super 'lock', 'Generate a lockdown list of gems',
:strict => false
add_option '-s', '--[no-]strict',
'fail if unable to satisfy a dependency' do |strict, options|
options[:strict] = strict
end
end
def arguments # :nodoc:
"GEMNAME name of gem to lock\nVERSION version of gem to lock"
end
def defaults_str # :nodoc:
"--no-strict"
end
def description # :nodoc:
<<-EOF
The lock command will generate a list of +gem+ statements that will lock down
the versions for the gem given in the command line. It will specify exact
versions in the requirements list to ensure that the gems loaded will always
be consistent. A full recursive search of all effected gems will be
generated.
Example:
gem lock rails-1.0.0 > lockdown.rb
will produce in lockdown.rb:
require "rubygems"
gem 'rails', '= 1.0.0'
gem 'rake', '= 0.7.0.1'
gem 'activesupport', '= 1.2.5'
gem 'activerecord', '= 1.13.2'
gem 'actionpack', '= 1.11.2'
gem 'actionmailer', '= 1.1.5'
gem 'actionwebservice', '= 1.0.0'
Just load lockdown.rb from your application to ensure that the current
versions are loaded. Make sure that lockdown.rb is loaded *before* any
other require statements.
Notice that rails 1.0.0 only requires that rake 0.6.2 or better be used.
Rake-0.7.0.1 is the most recent version installed that satisfies that, so we
lock it down to the exact version.
EOF
end
def usage # :nodoc:
"#{program_name} GEMNAME-VERSION [GEMNAME-VERSION ...]"
end
def complain(message)
if options[:strict]
raise Gem::Exception, message
else
say "# #{message}"
end
end
def execute
say "require 'rubygems'"
locked = {}
pending = options[:args]
until pending.empty? do
full_name = pending.shift
spec = Gem::Specification.load spec_path(full_name)
if spec.nil?
complain "Could not find gem #{full_name}, try using the full name"
next
end
say "gem '#{spec.name}', '= #{spec.version}'" unless locked[spec.name]
locked[spec.name] = true
spec.runtime_dependencies.each do |dep|
next if locked[dep.name]
candidates = dep.matching_specs
if candidates.empty?
complain "Unable to satisfy '#{dep}' from currently installed gems"
else
pending << candidates.last.full_name
end
end
end
end
def spec_path(gem_full_name)
gemspecs = Gem.path.map { |path|
File.join path, "specifications", "#{gem_full_name}.gemspec"
}
gemspecs.find { |path| File.exist? path }
end
end