In Files

  • rubygems/commands/unpack_command.rb

Class/Module Index [+]

Quicksearch

Gem::Commands::UnpackCommand

Public Class Methods

new() click to toggle source
 
               # File rubygems/commands/unpack_command.rb, line 10
def initialize
  require 'fileutils'

  super 'unpack', 'Unpack an installed gem to the current directory',
        :version => Gem::Requirement.default,
        :target  => Dir.pwd

  add_option('--target=DIR',
             'target directory for unpacking') do |value, options|
    options[:target] = value
  end

  add_option('--spec', 'unpack the gem specification') do |value, options|
    options[:spec] = true
  end

  add_version_option
end
            

Public Instance Methods

description() click to toggle source
 
               # File rubygems/commands/unpack_command.rb, line 37
  def description
    <<-EOF
The unpack command allows you to examine the contents of a gem or modify
them to help diagnose a bug.

You can add the contents of the unpacked gem to the load path using the
RUBYLIB environment variable or -I:

  $ gem unpack my_gem
  Unpacked gem: '.../my_gem-1.0'
  [edit my_gem-1.0/lib/my_gem.rb]
  $ ruby -Imy_gem-1.0/lib -S other_program

You can repackage an unpacked gem using the build command.  See the build
command help for an example.
    EOF
  end
            
execute() click to toggle source
 
               # File rubygems/commands/unpack_command.rb, line 64
def execute
  get_all_gem_names.each do |name|
    dependency = Gem::Dependency.new name, options[:version]
    path = get_path dependency

    unless path then
      alert_error "Gem '#{name}' not installed nor fetchable."
      next
    end

    if @options[:spec] then
      spec, metadata = get_metadata path

      if metadata.nil? then
        alert_error "--spec is unsupported on '#{name}' (old format gem)"
        next
      end

      spec_file = File.basename spec.spec_file

      open spec_file, 'w' do |io|
        io.write metadata
      end
    else
      basename = File.basename path, '.gem'
      target_dir = File.expand_path basename, options[:target]

      package = Gem::Package.new path
      package.extract_files target_dir

      say "Unpacked gem: '#{target_dir}'"
    end
  end
end
            
find_in_cache(filename) click to toggle source

Find cached filename in Gem.path. Returns nil if the file cannot be found.

 
               # File rubygems/commands/unpack_command.rb, line 106
def find_in_cache(filename)
  Gem.path.each do |path|
    this_path = File.join(path, "cache", filename)
    return this_path if File.exist? this_path
  end

  return nil
end
            
get_metadata(path) click to toggle source

Extracts the Gem::Specification and raw metadata from the .gem file at path.

 
               # File rubygems/commands/unpack_command.rb, line 160
def get_metadata path
  format = Gem::Package.new path
  spec = format.spec

  metadata = nil

  open path, Gem.binary_mode do |io|
    tar = Gem::Package::TarReader.new io
    tar.each_entry do |entry|
      case entry.full_name
      when 'metadata' then
        metadata = entry.read
      when 'metadata.gz' then
        metadata = Gem.gunzip entry.read
      end
    end
  end

  return spec, metadata
end
            
get_path(dependency) click to toggle source

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)
 
               # File rubygems/commands/unpack_command.rb, line 132
def get_path dependency
  return dependency.name if dependency.name =~ /\.gem$/

  specs = dependency.matching_specs

  selected = specs.max_by { |s| s.version }

  return Gem::RemoteFetcher.fetcher.download_to_cache(dependency) unless
    selected

  return unless dependency.name =~ /^#{selected.name}$/

  # We expect to find (basename).gem in the 'cache' directory.  Furthermore,
  # the name match must be exact (ignoring case).

  path = find_in_cache File.basename selected.cache_file

  return Gem::RemoteFetcher.fetcher.download_to_cache(dependency) unless path

  path
end
            

Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.

If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.

If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.

If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.

blog comments powered by Disqus