/tools/Ruby/lib/ruby/site_ruby/1.8/rubygems/commands/lock_command.rb

http://github.com/agross/netopenspace · Ruby · 110 lines · 83 code · 27 blank · 0 comment · 5 complexity · 282d8fd7a43b1ed7fadad0493a45bd75 MD5 · raw file

  1. require 'rubygems/command'
  2. class Gem::Commands::LockCommand < Gem::Command
  3. def initialize
  4. super 'lock', 'Generate a lockdown list of gems',
  5. :strict => false
  6. add_option '-s', '--[no-]strict',
  7. 'fail if unable to satisfy a dependency' do |strict, options|
  8. options[:strict] = strict
  9. end
  10. end
  11. def arguments # :nodoc:
  12. "GEMNAME name of gem to lock\nVERSION version of gem to lock"
  13. end
  14. def defaults_str # :nodoc:
  15. "--no-strict"
  16. end
  17. def description # :nodoc:
  18. <<-EOF
  19. The lock command will generate a list of +gem+ statements that will lock down
  20. the versions for the gem given in the command line. It will specify exact
  21. versions in the requirements list to ensure that the gems loaded will always
  22. be consistent. A full recursive search of all effected gems will be
  23. generated.
  24. Example:
  25. gemlock rails-1.0.0 > lockdown.rb
  26. will produce in lockdown.rb:
  27. require "rubygems"
  28. gem 'rails', '= 1.0.0'
  29. gem 'rake', '= 0.7.0.1'
  30. gem 'activesupport', '= 1.2.5'
  31. gem 'activerecord', '= 1.13.2'
  32. gem 'actionpack', '= 1.11.2'
  33. gem 'actionmailer', '= 1.1.5'
  34. gem 'actionwebservice', '= 1.0.0'
  35. Just load lockdown.rb from your application to ensure that the current
  36. versions are loaded. Make sure that lockdown.rb is loaded *before* any
  37. other require statements.
  38. Notice that rails 1.0.0 only requires that rake 0.6.2 or better be used.
  39. Rake-0.7.0.1 is the most recent version installed that satisfies that, so we
  40. lock it down to the exact version.
  41. EOF
  42. end
  43. def usage # :nodoc:
  44. "#{program_name} GEMNAME-VERSION [GEMNAME-VERSION ...]"
  45. end
  46. def complain(message)
  47. if options[:strict] then
  48. raise Gem::Exception, message
  49. else
  50. say "# #{message}"
  51. end
  52. end
  53. def execute
  54. say "require 'rubygems'"
  55. locked = {}
  56. pending = options[:args]
  57. until pending.empty? do
  58. full_name = pending.shift
  59. spec = Gem::Specification.load spec_path(full_name)
  60. if spec.nil? then
  61. complain "Could not find gem #{full_name}, try using the full name"
  62. next
  63. end
  64. say "gem '#{spec.name}', '= #{spec.version}'" unless locked[spec.name]
  65. locked[spec.name] = true
  66. spec.runtime_dependencies.each do |dep|
  67. next if locked[dep.name]
  68. candidates = Gem.source_index.search dep
  69. if candidates.empty? then
  70. complain "Unable to satisfy '#{dep}' from currently installed gems"
  71. else
  72. pending << candidates.last.full_name
  73. end
  74. end
  75. end
  76. end
  77. def spec_path(gem_full_name)
  78. gemspecs = Gem.path.map do |path|
  79. File.join path, "specifications", "#{gem_full_name}.gemspec"
  80. end
  81. gemspecs.find { |gemspec| File.exist? gemspec }
  82. end
  83. end