2020-11-13 12:26:36 +01:00

57 lines
1.5 KiB
Ruby

# typed: true
# frozen_string_literal: true
require "system_command"
module UnpackStrategy
# Strategy for unpacking tar archives.
class Tar
extend T::Sig
include UnpackStrategy
extend SystemCommand::Mixin
using Magic
sig { returns(T::Array[String]) }
def self.extensions
[
".tar",
".tbz", ".tbz2", ".tar.bz2",
".tgz", ".tar.gz",
".tlzma", ".tar.lzma",
".txz", ".tar.xz"
]
end
def self.can_extract?(path)
return true if path.magic_number.match?(/\A.{257}ustar/n)
return false unless [Bzip2, Gzip, Lzip, Xz].any? { |s| s.can_extract?(path) }
# Check if `tar` can list the contents, then it can also extract it.
stdout, _, status = system_command("tar", args: ["tf", path], print_stderr: false)
status.success? && !stdout.empty?
end
private
sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) }
def extract_to_dir(unpack_dir, basename:, verbose:)
Dir.mktmpdir do |tmpdir|
tar_path = path
if DependencyCollector.tar_needs_xz_dependency? && Xz.can_extract?(path)
tmpdir = Pathname(tmpdir)
Xz.new(path).extract(to: tmpdir, verbose: verbose)
tar_path = tmpdir.children.first
end
system_command! "tar",
args: ["xof", tar_path, "-C", unpack_dir],
verbose: verbose
end
end
end
end