4
require 'rubygems/command'
5
require 'rubygems/gem_open_uri'
7
class Gem::Commands::MirrorCommand < Gem::Command
10
super 'mirror', 'Mirror a gem repository'
13
def description # :nodoc:
15
The mirror command uses the ~/.gemmirrorrc config file to mirror remote gem
16
repositories to a local path. The config file is a YAML document that looks
20
- from: http://gems.example.com # source repository URI
21
to: /path/to/mirror # destination directory
23
Multiple sources and destinations may be specified.
28
config_file = File.join Gem.user_home, '.gemmirrorrc'
30
raise "Config file #{config_file} not found" unless File.exist? config_file
32
mirrors = YAML.load_file config_file
34
raise "Invalid config file #{config_file}" unless mirrors.respond_to? :each
37
raise "mirror missing 'from' field" unless mir.has_key? 'from'
38
raise "mirror missing 'to' field" unless mir.has_key? 'to'
40
get_from = mir['from']
41
save_to = File.expand_path mir['to']
43
raise "Directory not found: #{save_to}" unless File.exist? save_to
44
raise "Not a directory: #{save_to}" unless File.directory? save_to
46
gems_dir = File.join save_to, "gems"
48
if File.exist? gems_dir then
49
raise "Not a directory: #{gems_dir}" unless File.directory? gems_dir
56
say "fetching: #{get_from}/Marshal.#{Gem.marshal_version}.Z"
58
get_from = URI.parse get_from
60
if get_from.scheme.nil? then
61
get_from = get_from.to_s
62
elsif get_from.scheme == 'file' then
63
# check if specified URI contains a drive letter (file:/D:/Temp)
64
get_from = get_from.to_s
65
get_from = if get_from =~ /^file:.*[a-z]:/i then
72
open File.join(get_from.to_s, "Marshal.#{Gem.marshal_version}.Z"), "rb" do |y|
73
sourceindex_data = Zlib::Inflate.inflate y.read
74
open File.join(save_to, "Marshal.#{Gem.marshal_version}"), "wb" do |out|
75
out.write sourceindex_data
79
sourceindex = Marshal.load(sourceindex_data)
81
progress = ui.progress_reporter sourceindex.size,
82
"Fetching #{sourceindex.size} gems"
83
sourceindex.each do |fullname, gem|
84
gem_file = "#{fullname}.gem"
85
gem_dest = File.join gems_dir, gem_file
87
unless File.exist? gem_dest then
89
open "#{get_from}/gems/#{gem_file}", "rb" do |g|
91
open gem_dest, "wb" do |out|
97
gem_file = gem_file.downcase
98
retry if old_gf != gem_file
103
progress.updated gem_file