PHP 8.2.31
Preview: unpack_command.rb Size: 4.06 KB
//proc/thread-self/root/opt/alt/ruby20/lib64/ruby/2.0.0/rubygems/commands/unpack_command.rb

require 'rubygems/command'
require 'rubygems/installer'
require 'rubygems/version_option'
require 'rubygems/remote_fetcher'

class Gem::Commands::UnpackCommand < Gem::Command

  include Gem::VersionOption

  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

  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
    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 cached filename in Gem.path. Returns nil if the file cannot be found.
  #
  #--
  # TODO: see comments in get_path() about general service.

  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

  ##
  # 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 dependency
    return dependency.name if dependency.name =~ /\.gem$/i

    specs = dependency.matching_specs

    selected = specs.sort_by { |s| s.version }.last # HACK: hunt last down

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

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

    # 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

  ##
  # Extracts the Gem::Specification and raw metadata from the .gem file at
  # +path+.
  #--
  # TODO move to Gem::Package as #raw_spec or something

  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

end

Directory Contents

Dirs: 0 × Files: 31

Name Size Perms Modified Actions
859 B lrw-r--r-- 2012-11-29 06:52:18
Edit Download
6.41 KB lrw-r--r-- 2013-06-21 16:16:31
Edit Download
2.01 KB lrw-r--r-- 2012-12-23 00:35:09
Edit Download
3.85 KB lrw-r--r-- 2013-01-04 22:58:15
Edit Download
3.12 KB lrw-r--r-- 2012-11-30 00:23:15
Edit Download
3.89 KB lrw-r--r-- 2012-11-29 06:52:18
Edit Download
4.16 KB lrw-r--r-- 2012-11-29 06:52:18
Edit Download
1.49 KB lrw-r--r-- 2013-09-15 14:23:26
Edit Download
2.52 KB lrw-r--r-- 2012-11-29 06:52:18
Edit Download
4.56 KB lrw-r--r-- 2013-07-22 16:33:18
Edit Download
5.45 KB lrw-r--r-- 2012-12-06 05:26:46
Edit Download
696 B lrw-r--r-- 2013-07-22 16:33:18
Edit Download
2.67 KB lrw-r--r-- 2012-11-29 06:52:18
Edit Download
395 B lrw-r--r-- 2012-11-29 06:52:18
Edit Download
866 B lrw-r--r-- 2012-11-29 06:52:18
Edit Download
1.84 KB lrw-r--r-- 2013-07-22 16:33:18
Edit Download
3.66 KB lrw-r--r-- 2013-08-16 15:35:06
Edit Download
2.02 KB lrw-r--r-- 2013-07-22 16:33:18
Edit Download
8.03 KB lrw-r--r-- 2013-07-25 15:42:22
Edit Download
2.31 KB lrw-r--r-- 2012-12-14 05:09:37
Edit Download
616 B lrw-r--r-- 2013-07-25 15:42:22
Edit Download
2.35 KB lrw-r--r-- 2012-11-29 06:52:18
Edit Download
12.94 KB lrw-r--r-- 2013-07-22 16:33:18
Edit Download
3.62 KB lrw-r--r-- 2013-03-17 14:18:23
Edit Download
2.93 KB lrw-r--r-- 2013-07-22 16:33:18
Edit Download
704 B lrw-r--r-- 2011-07-27 01:40:07
Edit Download
3.07 KB lrw-r--r-- 2012-12-06 05:26:46
Edit Download
4.06 KB lrw-r--r-- 2012-11-29 06:52:18
Edit Download
5.80 KB lrw-r--r-- 2013-07-22 16:33:18
Edit Download
1.87 KB lrw-r--r-- 2011-07-27 01:40:07
Edit Download
2.40 KB lrw-r--r-- 2012-11-29 08:10:23
Edit Download

If ZipArchive is unavailable, a .tar will be created (no compression).