class MxxRu::Externals::ArchiveAsExternals

Implementation of externals represented as downloadable archive (like tar.gz, zip, rar or 7z).

Attributes

archive_name[R]

Public Class Methods

new(name) { |self| ... } click to toggle source
# File lib/mxx_ru/externals.rb, line 653
def initialize(name)
  defaults(name)
  @unpacker_options = []

  yield self if block_given?

  parse_uri
  detect_archive_type

  Registry::handle_external(@name, self)
end

Public Instance Methods

define_rules(old_or_new) click to toggle source
# File lib/mxx_ru/externals.rb, line 695
def define_rules(old_or_new)
  define(old_or_new) do |tmp_dir|
    # Temporary directory must be removed in a case of any error.
    successful = false
    begin
      mkdir(tmp_dir, fileop_options) if !Dir.exists?(tmp_dir)

      cd tmp_dir do
        download_archive
        unpack_archive
      end

      successful = true
    ensure
      rm_dir_if_exists(tmp_dir) unless successful
    end
  end
end
make_hash() click to toggle source
# File lib/mxx_ru/externals.rb, line 685
def make_hash
  all_downloader_options.merge( basics_to_map ).merge!(
    { :md5 => @md5,
      :sha1 => @sha1,
      :sha256 => @sha256,
      :sha512 => @sha512,
      :unpacker_options => @unpacker_options
    } )
end
md5(v) click to toggle source
# File lib/mxx_ru/externals.rb, line 665
def md5(v)
  @md5 = v
end
sha1(v) click to toggle source
# File lib/mxx_ru/externals.rb, line 669
def sha1(v)
  @sha1 = v
end
sha256(v) click to toggle source
# File lib/mxx_ru/externals.rb, line 673
def sha256(v)
  @sha256 = v
end
sha512(v) click to toggle source
# File lib/mxx_ru/externals.rb, line 677
def sha512(v)
  @sha512 = v
end
unpacker_option(v) click to toggle source
# File lib/mxx_ru/externals.rb, line 681
def unpacker_option(v)
  @unpacker_options.push(v)
end

Private Instance Methods

check_digest_if_necessary(digest_id, expected) click to toggle source
# File lib/mxx_ru/externals.rb, line 782
def check_digest_if_necessary(digest_id, expected)
  return unless expected

  digest_klass = Digest(digest_id)
  puts "#{archive_name} checking #{digest_id} checksum..." if @verbose
  chsum = digest_klass.file(archive_name).hexdigest
  if chsum != expected
    raise "#{archive_name}: #{digest_id} checksum missmatch. " +
      "actual: #{chsum}, expected: #{expected}"
  end
end
detect_archive_type() click to toggle source
# File lib/mxx_ru/externals.rb, line 731
def detect_archive_type
  ext = @@archive_extensions.keys.find {|k| @archive_name.end_with?(k)}
  raise "#{name} unable to detect archive type for " +
      "#{@archive_name}" unless ext

  @archive_type = @@archive_extensions[ext]
end
download_archive() click to toggle source
# File lib/mxx_ru/externals.rb, line 739
def download_archive
  if 'file' == uri_scheme
    download_archive_via_cp
  else
    download_archive_from_web
  end
  check_digest_if_necessary(:MD5, @md5)
  check_digest_if_necessary(:SHA1, @sha1)
  check_digest_if_necessary(:SHA256, @sha256)
  check_digest_if_necessary(:SHA512, @sha512)
end
download_archive_from_web() click to toggle source
# File lib/mxx_ru/externals.rb, line 751
def download_archive_from_web
  web_downloader = Impl::WebDownloader.instance.make_downloader(self)
  sh *(web_downloader.make_download_sh_args(@url, archive_name))
end
download_archive_via_cp() click to toggle source
# File lib/mxx_ru/externals.rb, line 756
def download_archive_via_cp
  # On Windows path can look like '/d:/...'.
  # The leading slash must be removed.
  path = uri_path.gsub(/^(\/)(\w:)(.+)$/, '\2\3')
  cp(path, archive_name, fileop_options)
end
make_unpacker_args() click to toggle source
# File lib/mxx_ru/externals.rb, line 794
def make_unpacker_args
  handler = @@archive_handlers[@archive_type]
  self.instance_eval &handler
end
parse_uri() click to toggle source
# File lib/mxx_ru/externals.rb, line 715
def parse_uri
  @parsed_uri = URI::split(@url)
  @archive_name = File.split(uri_path).last
end
unpack_archive() click to toggle source
# File lib/mxx_ru/externals.rb, line 763
def unpack_archive
  sh(*make_unpacker_args)
  rm(archive_name, fileop_options)
  names = Dir['*']
  if 1 == names.size and Dir.exists?(names.first)
    # This is the only folder in the distributive.
    # Move all its contents one level up.
    cd names.first do
      # Files like '.gitignore' won't be found without FNM_DOTMATCH.
      # But in that case '.' and '..' will be found too.
      Dir.glob('*', File::FNM_DOTMATCH).each do |n|
        mv(n, '..', fileop_options) if n != '.' && n != '..'
      end
    end
    # This single directory no more needed.
    rm_r(names.first, fileop_options)
  end
end
uri_path() click to toggle source
# File lib/mxx_ru/externals.rb, line 724
def uri_path
  @parsed_uri[5] # See doc for URI::split for description
                 # of items in result vector.
end
uri_scheme() click to toggle source
# File lib/mxx_ru/externals.rb, line 720
def uri_scheme
  @parsed_uri[0]
end