Use Utils::Cp to copy files

This replaces `FileUtils.cp` and `system_command! "cp"` with the new
`Utils::Cp` utility where it is expected that the performance
improvement outweighs the cost of the system command invocation.
This commit is contained in:
Daiki Mizukami 2024-05-26 08:46:38 +09:00
parent b905959a99
commit deaac7ce47
No known key found for this signature in database
GPG Key ID: 10478E598B944AA2
12 changed files with 38 additions and 20 deletions

View File

@ -3,6 +3,7 @@
require "cask/artifact/relocated" require "cask/artifact/relocated"
require "cask/quarantine" require "cask/quarantine"
require "utils/cp"
module Cask module Cask
module Artifact module Artifact
@ -108,8 +109,7 @@ module Cask
if target.writable? if target.writable?
source.children.each { |child| FileUtils.move(child, target/child.basename) } source.children.each { |child| FileUtils.move(child, target/child.basename) }
else else
command.run!("/bin/cp", args: ["-pR", *source.children, target], ::Utils::Cp.copy_recursive(source.children, target, sudo: true, command:)
sudo: true)
end end
Quarantine.copy_xattrs(source, target, command:) Quarantine.copy_xattrs(source, target, command:)
source.rmtree source.rmtree
@ -118,7 +118,7 @@ module Cask
else else
# default sudo user isn't necessarily able to write to Homebrew's locations # default sudo user isn't necessarily able to write to Homebrew's locations
# e.g. with runas_default set in the sudoers (5) file. # e.g. with runas_default set in the sudoers (5) file.
command.run!("/bin/cp", args: ["-pR", source, target], sudo: true) ::Utils::Cp.copy_recursive(source, target, sudo: true, command:)
source.rmtree source.rmtree
end end
@ -161,8 +161,8 @@ module Cask
ohai "Backing #{self.class.english_name} '#{target.basename}' up to '#{source}'" ohai "Backing #{self.class.english_name} '#{target.basename}' up to '#{source}'"
source.dirname.mkpath source.dirname.mkpath
# We need to preserve extended attributes between copies. # `Utils::Cp` preserves extended attributes between copies.
command.run!("/bin/cp", args: ["-pR", target, source], sudo: !source.parent.writable?) ::Utils::Cp.copy_recursive(target, source, sudo: !source.parent.writable?, command:)
delete(target, force:, command:, **options) delete(target, force:, command:, **options)
end end

View File

@ -11,6 +11,7 @@ require "keg"
require "formula_versions" require "formula_versions"
require "utils/inreplace" require "utils/inreplace"
require "erb" require "erb"
require "utils/cp"
require "utils/gzip" require "utils/gzip"
require "api" require "api"
require "extend/hash/deep_merge" require "extend/hash/deep_merge"
@ -767,7 +768,7 @@ module Homebrew
all_bottle_hash = { formula_name => all_bottle_formula_hash } all_bottle_hash = { formula_name => all_bottle_formula_hash }
puts "Copying #{filename} to #{all_filename}" if args.verbose? puts "Copying #{filename} to #{all_filename}" if args.verbose?
FileUtils.cp filename.to_s, all_filename.to_s Utils::Cp.copy filename.to_s, all_filename.to_s
puts "Writing #{all_filename.json}" if args.verbose? puts "Writing #{all_filename.json}" if args.verbose?
all_local_json_path = Pathname(all_filename.json) all_local_json_path = Pathname(all_filename.json)

View File

@ -6,6 +6,7 @@ require "resource"
require "metafiles" require "metafiles"
require "extend/file/atomic" require "extend/file/atomic"
require "system_command" require "system_command"
require "utils/cp"
module DiskUsageExtension module DiskUsageExtension
sig { returns(Integer) } sig { returns(Integer) }
@ -226,7 +227,7 @@ class Pathname
else else
dst.dirname.mkpath dst.dirname.mkpath
dst = yield(self, dst) if block_given? dst = yield(self, dst) if block_given?
FileUtils.cp(self, dst) Utils::Cp.copy(self, dst)
end end
end end

View File

@ -350,8 +350,9 @@ RSpec.describe Cask::Artifact::App, :cask do
allow(command).to receive(:run!).with(any_args).and_call_original allow(command).to receive(:run!).with(any_args).and_call_original
expect(command).to receive(:run!) expect(command).to receive(:run!)
.with("/bin/cp", args: ["-pR", source_contents_path, target_path], .with(a_string_ending_with("cp"),
sudo: true) hash_including(args: include(source_contents_path, target_path),
sudo: true))
.and_call_original .and_call_original
expect(FileUtils).not_to receive(:move).with(source_contents_path, an_instance_of(Pathname)) expect(FileUtils).not_to receive(:move).with(source_contents_path, an_instance_of(Pathname))

View File

@ -1,6 +1,8 @@
# typed: true # typed: true
# frozen_string_literal: true # frozen_string_literal: true
require "utils/cp"
module UnpackStrategy module UnpackStrategy
# Strategy for unpacking bzip2 archives. # Strategy for unpacking bzip2 archives.
class Bzip2 class Bzip2
@ -19,7 +21,7 @@ module UnpackStrategy
sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
FileUtils.cp path, unpack_dir/basename, preserve: true Utils::Cp.copy path, unpack_dir/basename
quiet_flags = verbose ? [] : ["-q"] quiet_flags = verbose ? [] : ["-q"]
system_command! "bunzip2", system_command! "bunzip2",
args: [*quiet_flags, unpack_dir/basename], args: [*quiet_flags, unpack_dir/basename],

View File

@ -1,6 +1,8 @@
# typed: true # typed: true
# frozen_string_literal: true # frozen_string_literal: true
require "utils/cp"
module UnpackStrategy module UnpackStrategy
# Strategy for unpacking directories. # Strategy for unpacking directories.
class Directory class Directory
@ -20,9 +22,8 @@ module UnpackStrategy
sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
path.children.each do |child| path.children.each do |child|
system_command! "cp", Utils::Cp.copy_recursive (child.directory? && !child.symlink?) ? "#{child}/." : child,
args: ["-pR", (child.directory? && !child.symlink?) ? "#{child}/." : child, unpack_dir/child.basename,
unpack_dir/child.basename],
verbose: verbose:
end end
end end

View File

@ -1,6 +1,8 @@
# typed: true # typed: true
# frozen_string_literal: true # frozen_string_literal: true
require "utils/cp"
module UnpackStrategy module UnpackStrategy
# Strategy for unpacking gzip archives. # Strategy for unpacking gzip archives.
class Gzip class Gzip
@ -19,7 +21,7 @@ module UnpackStrategy
sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
FileUtils.cp path, unpack_dir/basename, preserve: true Utils::Cp.copy path, unpack_dir/basename
quiet_flags = verbose ? [] : ["-q"] quiet_flags = verbose ? [] : ["-q"]
system_command! "gunzip", system_command! "gunzip",
args: [*quiet_flags, "-N", "--", unpack_dir/basename], args: [*quiet_flags, "-N", "--", unpack_dir/basename],

View File

@ -1,6 +1,8 @@
# typed: true # typed: true
# frozen_string_literal: true # frozen_string_literal: true
require "utils/cp"
module UnpackStrategy module UnpackStrategy
# Strategy for unpacking lzip archives. # Strategy for unpacking lzip archives.
class Lzip class Lzip
@ -23,7 +25,7 @@ module UnpackStrategy
sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
FileUtils.cp path, unpack_dir/basename, preserve: true Utils::Cp.copy path, unpack_dir/basename
quiet_flags = verbose ? [] : ["-q"] quiet_flags = verbose ? [] : ["-q"]
system_command! "lzip", system_command! "lzip",
args: ["-d", *quiet_flags, unpack_dir/basename], args: ["-d", *quiet_flags, unpack_dir/basename],

View File

@ -1,6 +1,8 @@
# typed: true # typed: true
# frozen_string_literal: true # frozen_string_literal: true
require "utils/cp"
module UnpackStrategy module UnpackStrategy
# Strategy for unpacking LZMA archives. # Strategy for unpacking LZMA archives.
class Lzma class Lzma
@ -23,7 +25,7 @@ module UnpackStrategy
sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
FileUtils.cp path, unpack_dir/basename, preserve: true Utils::Cp.copy path, unpack_dir/basename
quiet_flags = verbose ? [] : ["-q"] quiet_flags = verbose ? [] : ["-q"]
system_command! "unlzma", system_command! "unlzma",
args: [*quiet_flags, "--", unpack_dir/basename], args: [*quiet_flags, "--", unpack_dir/basename],

View File

@ -1,6 +1,8 @@
# typed: true # typed: true
# frozen_string_literal: true # frozen_string_literal: true
require "utils/cp"
module UnpackStrategy module UnpackStrategy
# Strategy for unpacking uncompressed files. # Strategy for unpacking uncompressed files.
class Uncompressed class Uncompressed
@ -22,7 +24,7 @@ module UnpackStrategy
sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) }
def extract_to_dir(unpack_dir, basename:, verbose: false) def extract_to_dir(unpack_dir, basename:, verbose: false)
FileUtils.cp path, unpack_dir/basename.sub(/^[\da-f]{64}--/, ""), preserve: true, verbose: Utils::Cp.copy path, unpack_dir/basename.sub(/^[\da-f]{64}--/, ""), verbose:
end end
end end
end end

View File

@ -1,6 +1,8 @@
# typed: true # typed: true
# frozen_string_literal: true # frozen_string_literal: true
require "utils/cp"
module UnpackStrategy module UnpackStrategy
# Strategy for unpacking xz archives. # Strategy for unpacking xz archives.
class Xz class Xz
@ -23,7 +25,7 @@ module UnpackStrategy
sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
FileUtils.cp path, unpack_dir/basename, preserve: true Utils::Cp.copy path, unpack_dir/basename
quiet_flags = verbose ? [] : ["-q"] quiet_flags = verbose ? [] : ["-q"]
system_command! "unxz", system_command! "unxz",
args: [*quiet_flags, "-T0", "--", unpack_dir/basename], args: [*quiet_flags, "-T0", "--", unpack_dir/basename],

View File

@ -1,6 +1,8 @@
# typed: true # typed: true
# frozen_string_literal: true # frozen_string_literal: true
require "utils/cp"
module UnpackStrategy module UnpackStrategy
# Strategy for unpacking zstd archives. # Strategy for unpacking zstd archives.
class Zstd class Zstd
@ -23,7 +25,7 @@ module UnpackStrategy
sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) }
def extract_to_dir(unpack_dir, basename:, verbose:) def extract_to_dir(unpack_dir, basename:, verbose:)
FileUtils.cp path, unpack_dir/basename, preserve: true Utils::Cp.copy path, unpack_dir/basename
quiet_flags = verbose ? [] : ["-q"] quiet_flags = verbose ? [] : ["-q"]
system_command! "unzstd", system_command! "unzstd",
args: [*quiet_flags, "-T0", "--rm", "--", unpack_dir/basename], args: [*quiet_flags, "-T0", "--rm", "--", unpack_dir/basename],