Properly handle special characters in file names.

This commit is contained in:
Markus Reiter 2017-10-11 15:32:39 +02:00
parent 56458f03fc
commit 04363b25a3
3 changed files with 26 additions and 18 deletions

View File

@ -94,6 +94,9 @@ Performance/Caller:
Style/Alias:
EnforcedStyle: prefer_alias
Style/AsciiComments:
Enabled: false
Style/AutoResourceCleanup:
Enabled: true

View File

@ -88,7 +88,7 @@ module Hbc
bomfile.close
Tempfile.open(["", ".list"]) do |filelist|
filelist.write(bom_filelist_from_path(mount))
filelist.puts(bom_filelist_from_path(mount))
filelist.close
@command.run!("/usr/bin/mkbom", args: ["-s", "-i", filelist.path, "--", bomfile.path])
@ -98,16 +98,17 @@ module Hbc
end
def bom_filelist_from_path(mount)
Dir.chdir(mount) do
Dir.glob("**/*", File::FNM_DOTMATCH).map do |path|
next if skip_path?(Pathname(path))
(path == ".") ? path : path.prepend("./")
end.compact.join("\n").concat("\n")
end
# We need to use `find` here instead of Ruby in order to properly handle
# file names containing special characters, such as “e” + “´” vs. “é”.
@command.run("/usr/bin/find", args: [".", "-print0"], chdir: mount, print_stderr: false).stdout
.split("\0")
.reject { |path| skip_path?(mount, path) }
.join("\n")
end
def skip_path?(path)
dmg_metadata?(path) || system_dir_symlink?(path)
def skip_path?(mount, path)
path = Pathname(path.sub(%r{^\./}, ""))
dmg_metadata?(path) || system_dir_symlink?(mount, path)
end
# unnecessary DMG metadata
@ -130,9 +131,10 @@ module Hbc
DMG_METADATA_FILES.include?(relative_root.basename.to_s)
end
def system_dir_symlink?(path)
def system_dir_symlink?(mount, path)
full_path = Pathname(mount).join(path)
# symlinks to system directories (commonly to /Applications)
path.symlink? && MacOS.system_dir?(path.readlink)
full_path.symlink? && MacOS.system_dir?(full_path.readlink)
end
def mounts_from_plist(plist)

View File

@ -10,12 +10,12 @@ module Hbc
class SystemCommand
attr_reader :command
def self.run(executable, options = {})
new(executable, options).run!
def self.run(executable, **options)
new(executable, **options).run!
end
def self.run!(command, options = {})
run(command, options.merge(must_succeed: true))
def self.run!(command, **options)
run(command, **options.merge(must_succeed: true))
end
def run!
@ -37,7 +37,7 @@ module Hbc
result
end
def initialize(executable, options)
def initialize(executable, **options)
@executable = executable
@options = options
process_options!
@ -49,7 +49,7 @@ module Hbc
def process_options!
options.extend(HashValidator)
.assert_valid_keys :input, :print_stdout, :print_stderr, :args, :must_succeed, :sudo
.assert_valid_keys :input, :print_stdout, :print_stderr, :args, :must_succeed, :sudo, :chdir
sudo_prefix = %w[/usr/bin/sudo -E --]
sudo_prefix = sudo_prefix.insert(1, "-A") unless ENV["SUDO_ASKPASS"].nil?
@command = [executable]
@ -76,8 +76,11 @@ module Hbc
end
def each_output_line(&b)
opts = {}
opts[:chdir] = options[:chdir] if options[:chdir]
raw_stdin, raw_stdout, raw_stderr, raw_wait_thr =
Open3.popen3(*expanded_command)
Open3.popen3(*expanded_command, **opts)
write_input_to(raw_stdin)
raw_stdin.close_write