diff options
author | yugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-08-25 15:02:05 +0000 |
---|---|---|
committer | yugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-08-25 15:02:05 +0000 |
commit | 0dc342de848a642ecce8db697b8fecd83a63e117 (patch) | |
tree | 2b7ed4724aff1f86073e4740134bda9c4aac1a39 /trunk/lib/rubygems/commands/unpack_command.rb | |
parent | ef70cf7138ab8034b5b806f466e4b484b24f0f88 (diff) |
added tag v1_9_0_4
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v1_9_0_4@18845 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'trunk/lib/rubygems/commands/unpack_command.rb')
-rw-r--r-- | trunk/lib/rubygems/commands/unpack_command.rb | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/trunk/lib/rubygems/commands/unpack_command.rb b/trunk/lib/rubygems/commands/unpack_command.rb new file mode 100644 index 0000000000..d187f8a9ea --- /dev/null +++ b/trunk/lib/rubygems/commands/unpack_command.rb @@ -0,0 +1,95 @@ +require 'fileutils' +require 'rubygems/command' +require 'rubygems/installer' +require 'rubygems/version_option' + +class Gem::Commands::UnpackCommand < Gem::Command + + include Gem::VersionOption + + def initialize + super 'unpack', 'Unpack an installed gem to the current directory', + :version => Gem::Requirement.default, + :target => Dir.pwd + + add_option('--target', 'target directory for unpacking') do |value, options| + options[:target] = value + end + + add_version_option + end + + def arguments # :nodoc: + "GEMNAME name of gem to unpack" + end + + def defaults_str # :nodoc: + "--version '#{Gem::Requirement.default}'" + end + + def usage # :nodoc: + "#{program_name} GEMNAME" + end + + #-- + # TODO: allow, e.g., 'gem unpack rake-0.3.1'. Find a general solution for + # this, so that it works for uninstall as well. (And check other commands + # at the same time.) + def execute + gemname = get_one_gem_name + path = get_path(gemname, options[:version]) + + if path then + basename = File.basename(path).sub(/\.gem$/, '') + target_dir = File.expand_path File.join(options[:target], basename) + FileUtils.mkdir_p target_dir + Gem::Installer.new(path).unpack target_dir + say "Unpacked gem: '#{target_dir}'" + else + alert_error "Gem '#{gemname}' not installed." + end + end + + # Return the full path to the cached gem file matching the given + # name and version requirement. Returns 'nil' if no match. + # + # Example: + # + # get_path('rake', '> 0.4') # -> '/usr/lib/ruby/gems/1.8/cache/rake-0.4.2.gem' + # get_path('rake', '< 0.1') # -> nil + # get_path('rak') # -> nil (exact name required) + #-- + # TODO: This should be refactored so that it's a general service. I don't + # think any of our existing classes are the right place though. Just maybe + # 'Cache'? + # + # TODO: It just uses Gem.dir for now. What's an easy way to get the list of + # source directories? + def get_path(gemname, version_req) + return gemname if gemname =~ /\.gem$/i + + specs = Gem::source_index.search(/\A#{gemname}\z/, version_req) + + selected = specs.sort_by { |s| s.version }.last + + return nil if selected.nil? + + # We expect to find (basename).gem in the 'cache' directory. + # Furthermore, the name match must be exact (ignoring case). + if gemname =~ /^#{selected.name}$/i + filename = selected.full_name + '.gem' + path = nil + + Gem.path.find do |gem_dir| + path = File.join gem_dir, 'cache', filename + File.exist? path + end + + path + else + nil + end + end + +end + |