Utils::Cp: Use cp from macOS

This commit is contained in:
Daiki Mizukami 2024-05-27 18:00:12 +09:00
parent b8af1c546e
commit 942906b74a
No known key found for this signature in database
GPG Key ID: 10478E598B944AA2

View File

@ -41,6 +41,8 @@ module Utils
sig { returns(T.any(String, Pathname)) } sig { returns(T.any(String, Pathname)) }
def executable def executable
case type case type
when :macos
Pathname("/bin/cp")
when :coreutils when :coreutils
GCP GCP
when :uutils when :uutils
@ -50,23 +52,26 @@ module Utils
end end
end end
MACOS_FLAGS = [
# Perform a lightweight copy-on-write clone if applicable.
"-c",
].freeze
GNU_FLAGS = [ GNU_FLAGS = [
# Unlike BSD cp, `gcp -p` doesn't guarantee to preserve extended attributes, including # Unlike BSD cp, `gcp -p` doesn't guarantee to preserve extended attributes, including
# quarantine information on macOS. # quarantine information on macOS.
"--preserve=all", "--preserve=all",
"--no-preserve=links", "--no-preserve=links",
# Perform a lightweight copy-on-write clone if applicable. # Equivalent to `-c` on macOS.
"--reflink=auto", "--reflink=auto",
].freeze ].freeze
# On macOS, the `cp` utility has the `-c` option, which is equivalent to
# `gcp --reflink=always`, but we are not using that because it would fail if the `clonefile`
# syscall isn't applicable (the underlying filesystem doesn't support the feature or the
# source and the target are on different filesystems).
GENERIC_FLAGS = [].freeze GENERIC_FLAGS = [].freeze
sig { returns(T::Array[String]) } sig { returns(T::Array[String]) }
def extra_flags def extra_flags
if type case type
when :macos
MACOS_FLAGS
when :coreutils, :uutils
GNU_FLAGS GNU_FLAGS
else else
GENERIC_FLAGS GENERIC_FLAGS
@ -77,6 +82,12 @@ module Utils
def type def type
return @type if defined?(@type) return @type if defined?(@type)
# The `cp` command on some older macOS versions also had the `-c` option, but before Sonoma,
# the command would fail if the `clonefile` syscall isn't applicable (the underlying
# filesystem doesn't support the feature or the source and the target are on different
# filesystems).
return @type = :macos if MacOS.version >= :sonoma
{ {
coreutils: "coreutils", coreutils: "coreutils",
uutils: "uutils-coreutils", uutils: "uutils-coreutils",