In Files

  • rubygems/commands/mirror_command.rb

Parent

Methods

Class/Module Index [+]

Quicksearch

Gem::Commands::MirrorCommand

Public Class Methods

new() click to toggle source
 
               # File rubygems/commands/mirror_command.rb, line 9
def initialize
  super 'mirror', 'Mirror a gem repository'
end
            

Public Instance Methods

execute() click to toggle source
 
               # File rubygems/commands/mirror_command.rb, line 27
def execute
  config_file = File.join Gem.user_home, '.gemmirrorrc'

  raise "Config file #{config_file} not found" unless File.exist? config_file

  mirrors = YAML.load_file config_file

  raise "Invalid config file #{config_file}" unless mirrors.respond_to? :each

  mirrors.each do |mir|
    raise "mirror missing 'from' field" unless mir.has_key? 'from'
    raise "mirror missing 'to' field" unless mir.has_key? 'to'

    get_from = mir['from']
    save_to = File.expand_path mir['to']

    raise "Directory not found: #{save_to}" unless File.exist? save_to
    raise "Not a directory: #{save_to}" unless File.directory? save_to

    gems_dir = File.join save_to, "gems"

    if File.exist? gems_dir then
      raise "Not a directory: #{gems_dir}" unless File.directory? gems_dir
    else
      Dir.mkdir gems_dir
    end

    source_index_data = ''

    say "fetching: #{get_from}/Marshal.#{Gem.marshal_version}.Z"

    get_from = URI.parse get_from

    if get_from.scheme.nil? then
      get_from = get_from.to_s
    elsif get_from.scheme == 'file' then
      # check if specified URI contains a drive letter (file:/D:/Temp)
      get_from = get_from.to_s
      get_from = if get_from =~ /^file:.*[a-z]:/ then
                   get_from[6..-1]
                 else
                   get_from[5..-1]
                 end
    end

    open File.join(get_from.to_s, "Marshal.#{Gem.marshal_version}.Z"), "rb" do |y|
      source_index_data = Zlib::Inflate.inflate y.read
      open File.join(save_to, "Marshal.#{Gem.marshal_version}"), "wb" do |out|
        out.write source_index_data
      end
    end

    source_index = Marshal.load source_index_data

    progress = ui.progress_reporter source_index.size,
                                    "Fetching #{source_index.size} gems"
    source_index.each do |fullname, gem|
      gem_file = gem.file_name
      gem_dest = File.join gems_dir, gem_file

      unless File.exist? gem_dest then
        begin
          open "#{get_from}/gems/#{gem_file}", "rb" do |g|
            contents = g.read
            open gem_dest, "wb" do |out|
              out.write contents
            end
          end
        rescue
          old_gf = gem_file
          gem_file = gem_file.downcase
          retry if old_gf != gem_file
          alert_error $!
        end
      end

      progress.updated gem_file
    end

    progress.done
  end
end