2024-07-11 19:57:12 +01:00
|
|
|
# typed: strict
|
2019-04-19 15:38:03 +09:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2018-07-23 20:59:21 +02:00
|
|
|
module UnpackStrategy
|
2020-08-09 06:09:05 +02:00
|
|
|
# Strategy for unpacking directories.
|
2018-07-23 20:59:21 +02:00
|
|
|
class Directory
|
|
|
|
include UnpackStrategy
|
|
|
|
|
2024-07-05 22:29:41 -07:00
|
|
|
sig { override.returns(T::Array[String]) }
|
2018-07-30 09:49:59 +02:00
|
|
|
def self.extensions
|
|
|
|
[]
|
|
|
|
end
|
|
|
|
|
2024-07-11 19:57:12 +01:00
|
|
|
sig { override.params(path: Pathname).returns(T::Boolean) }
|
2018-07-29 10:04:51 +02:00
|
|
|
def self.can_extract?(path)
|
2018-07-23 20:59:21 +02:00
|
|
|
path.directory?
|
|
|
|
end
|
|
|
|
|
2024-10-05 17:19:53 -04:00
|
|
|
sig {
|
|
|
|
params(
|
|
|
|
path: T.any(String, Pathname),
|
|
|
|
ref_type: T.nilable(Symbol),
|
|
|
|
ref: T.nilable(String),
|
|
|
|
merge_xattrs: T::Boolean,
|
|
|
|
move: T::Boolean,
|
|
|
|
).void
|
|
|
|
}
|
|
|
|
def initialize(path, ref_type: nil, ref: nil, merge_xattrs: false, move: false)
|
|
|
|
super(path, ref_type:, ref:, merge_xattrs:)
|
|
|
|
@move = move
|
|
|
|
end
|
|
|
|
|
2018-07-23 20:59:21 +02:00
|
|
|
private
|
|
|
|
|
2024-07-11 11:05:42 +01:00
|
|
|
sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).void }
|
2018-07-23 20:59:21 +02:00
|
|
|
def extract_to_dir(unpack_dir, basename:, verbose:)
|
2024-10-05 17:19:53 -04:00
|
|
|
move_to_dir(unpack_dir, verbose:) if @move
|
2024-10-03 15:50:23 -04:00
|
|
|
path_children = path.children
|
|
|
|
return if path_children.empty?
|
|
|
|
|
2024-10-05 17:19:53 -04:00
|
|
|
system_command!("cp", args: ["-pR", *path_children, unpack_dir], verbose:)
|
|
|
|
end
|
|
|
|
|
|
|
|
# Move all files from source `path` to target `unpack_dir`. Any existing
|
|
|
|
# subdirectories are not modified and only the contents are moved.
|
|
|
|
#
|
|
|
|
# @raise [RuntimeError] on unsupported `mv` operation, e.g. overwriting a file with a directory
|
|
|
|
sig { params(unpack_dir: Pathname, verbose: T::Boolean).void }
|
|
|
|
def move_to_dir(unpack_dir, verbose:)
|
|
|
|
path.find do |src|
|
|
|
|
next if src == path
|
|
|
|
|
|
|
|
dst = unpack_dir/src.relative_path_from(path)
|
|
|
|
if dst.exist?
|
|
|
|
dst_real_dir = dst.directory? && !dst.symlink?
|
|
|
|
src_real_dir = src.directory? && !src.symlink?
|
|
|
|
# Avoid moving a directory over an existing non-directory and vice versa.
|
|
|
|
# This outputs the same error message as GNU mv which is more readable than macOS mv.
|
|
|
|
raise "mv: cannot overwrite non-directory '#{dst}' with directory '#{src}'" if src_real_dir && !dst_real_dir
|
|
|
|
raise "mv: cannot overwrite directory '#{dst}' with non-directory '#{src}'" if !src_real_dir && dst_real_dir
|
|
|
|
# Defer writing over existing directories. Handle this later on to copy attributes
|
|
|
|
next if dst_real_dir
|
|
|
|
|
|
|
|
FileUtils.rm(dst, verbose:)
|
|
|
|
end
|
|
|
|
|
|
|
|
FileUtils.mv(src, dst, verbose:)
|
|
|
|
Find.prune
|
2018-07-23 20:59:21 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|