| 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: spec_file = File.basename spec.spec_file
65:
66: open spec_file, 'w' do |io|
67: io.write metadata
68: end
69: else
70: basename = File.basename path, '.gem'
71: target_dir = File.expand_path basename, options[:target]
72: FileUtils.mkdir_p target_dir
73: Gem::Installer.new(path, :unpack => true).unpack target_dir
74: say "Unpacked gem: '#{target_dir}'"
75: end
76: end
77: end
Find cached filename in Gem.path. Returns nil if the file cannot be found.
# File lib/rubygems/commands/unpack_command.rb, line 86
86: def find_in_cache(filename)
87: Gem.path.each do |path|
88: this_path = File.join(path, "cache", filename)
89: return this_path if File.exist? this_path
90: end
91:
92: return nil
93: end
Extracts the Gem::Specification and raw metadata from the .gem file at path.
# File lib/rubygems/commands/unpack_command.rb, line 138
138: def get_metadata path
139: format = Gem::Format.from_file_by_path path
140: spec = format.spec
141:
142: metadata = nil
143:
144: open path, Gem.binary_mode do |io|
145: tar = Gem::Package::TarReader.new io
146: tar.each_entry do |entry|
147: case entry.full_name
148: when 'metadata' then
149: metadata = entry.read
150: when 'metadata.gz' then
151: metadata = Gem.gunzip entry.read
152: end
153: end
154: end
155:
156: return spec, metadata
157: 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 112
112: def get_path dependency
113: return dependency.name if dependency.name =~ /\.gem$/i
114:
115: specs = dependency.matching_specs
116:
117: selected = specs.sort_by { |s| s.version }.last # HACK: hunt last down
118:
119: return Gem::RemoteFetcher.fetcher.download_to_cache(dependency) unless
120: selected
121:
122: return unless dependency.name =~ /^#{selected.name}$/i
123:
124: # We expect to find (basename).gem in the 'cache' directory. Furthermore,
125: # the name match must be exact (ignoring case).
126:
127: path = find_in_cache File.basename selected.cache_file
128:
129: return Gem::RemoteFetcher.fetcher.download_to_cache(dependency) unless path
130:
131: path
132: end