| Class | Gem::Commands::UnpackCommand |
| In: |
lib/rubygems/commands/unpack_command.rb
|
| Parent: | Gem::Command |
# File lib/rubygems/commands/unpack_command.rb, line 10
10: def initialize
11: require 'fileutils'
12:
13: super 'unpack', 'Unpack an installed gem to the current directory',
14: :version => Gem::Requirement.default,
15: :target => Dir.pwd
16:
17: add_option('--target=DIR',
18: 'target directory for unpacking') do |value, options|
19: options[:target] = value
20: end
21:
22: add_option('--spec', 'unpack the gem specification') do |value, options|
23: options[:spec] = true
24: end
25:
26: add_version_option
27: end
# File lib/rubygems/commands/unpack_command.rb, line 46
46: def execute
47: get_all_gem_names.each do |name|
48: dependency = Gem::Dependency.new name, options[:version]
49: path = get_path dependency
50:
51: unless path then
52: alert_error "Gem '#{name}' not installed nor fetchable."
53: next
54: end
55:
56: if @options[:spec] then
57: spec, metadata = get_metadata path
58:
59: if metadata.nil? then
60: alert_error "--spec is unsupported on '#{name}' (old format gem)"
61: next
62: end
63:
64: open spec.spec_name, 'w' do |io|
65: io.write metadata
66: end
67: else
68: basename = File.basename path, '.gem'
69: target_dir = File.expand_path basename, options[:target]
70: FileUtils.mkdir_p target_dir
71: Gem::Installer.new(path, :unpack => true).unpack target_dir
72: say "Unpacked gem: '#{target_dir}'"
73: end
74: end
75: end
Find cached filename in Gem.path. Returns nil if the file cannot be found.
# File lib/rubygems/commands/unpack_command.rb, line 84
84: def find_in_cache(filename)
85: Gem.path.each do |path|
86: this_path = Gem.cache_gem(filename, path)
87: return this_path if File.exist? this_path
88: end
89:
90: return nil
91: end
Extracts the Gem::Specification and raw metadata from the .gem file at path.
# File lib/rubygems/commands/unpack_command.rb, line 136
136: def get_metadata path
137: format = Gem::Format.from_file_by_path path
138: spec = format.spec
139:
140: metadata = nil
141:
142: open path, Gem.binary_mode do |io|
143: tar = Gem::Package::TarReader.new io
144: tar.each_entry do |entry|
145: case entry.full_name
146: when 'metadata' then
147: metadata = entry.read
148: when 'metadata.gz' then
149: metadata = Gem.gunzip entry.read
150: end
151: end
152: end
153:
154: return spec, metadata
155: 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)
# File lib/rubygems/commands/unpack_command.rb, line 110
110: def get_path dependency
111: return dependency.name if dependency.name =~ /\.gem$/i
112:
113: specs = Gem.source_index.search dependency
114:
115: selected = specs.sort_by { |s| s.version }.last
116:
117: return Gem::RemoteFetcher.fetcher.download_to_cache(dependency) unless
118: selected
119:
120: return unless dependency.name =~ /^#{selected.name}$/i
121:
122: # We expect to find (basename).gem in the 'cache' directory. Furthermore,
123: # the name match must be exact (ignoring case).
124:
125: path = find_in_cache selected.file_name
126:
127: return Gem::RemoteFetcher.fetcher.download_to_cache(dependency) unless path
128:
129: path
130: end