class Gem::Commands::LockCommand

def arguments # :nodoc:

:nodoc:
def arguments # :nodoc:
  "GEMNAME       name of gem to lock\nVERSION       version of gem to lock"
end

def complain(message)

def complain(message)
  if options[:strict] then
    raise Gem::Exception, message
  else
    say "# #{message}"
  end
end

def defaults_str # :nodoc:

:nodoc:
def defaults_str # :nodoc:
  "--no-strict"
end

def description # :nodoc:

:nodoc:
def description # :nodoc:
  <<-EOF
e lock command will generate a list of +gem+ statements that will lock down
e versions for the gem given in the command line.  It will specify exact
rsions in the requirements list to ensure that the gems loaded will always
 consistent.  A full recursive search of all effected gems will be
nerated.
ample:
gem lock rails-1.0.0 > lockdown.rb
ll 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'
st load lockdown.rb from your application to ensure that the current
rsions are loaded.  Make sure that lockdown.rb is loaded *before* any
her require statements.
tice that rails 1.0.0 only requires that rake 0.6.2 or better be used.
ke-0.7.0.1 is the most recent version installed that satisfies that, so we
ck it down to the exact version.
  EOF
end

def execute

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? then
      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? then
        complain "Unable to satisfy '#{dep}' from currently installed gems"
      else
        pending << candidates.last.full_name
      end
    end
  end
end

def initialize

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 spec_path(gem_full_name)

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

def usage # :nodoc:

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