From d6f921a18c32568469189ed17f344c24a7eaf1c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boris=20Bu=CC=88gling?= Date: Mon, 29 Aug 2016 16:56:22 +0200 Subject: [PATCH 1/3] Perform DevToolsCore writing in a subprocess --- lib/xcodeproj/plist/ffi.rb | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/lib/xcodeproj/plist/ffi.rb b/lib/xcodeproj/plist/ffi.rb index 6d6af76f3..7d9ea8448 100644 --- a/lib/xcodeproj/plist/ffi.rb +++ b/lib/xcodeproj/plist/ffi.rb @@ -36,9 +36,10 @@ def attempt_to_load! def write_to_path(hash, path) raise ThreadError, 'Can only write plists from the main thread.' unless Thread.current == Thread.main - if DevToolsCore.load_xcode_frameworks && path.end_with?('pbxproj') - ruby_hash_write_xcode(hash, path) - else + path = File.expand_path(path) + success = ruby_hash_write_xcode(hash, path) + + unless success CoreFoundation.RubyHashPropertyListWrite(hash, path) fix_encoding(path) end @@ -96,7 +97,27 @@ def fix_encoding(filename) # The path of the file. # def ruby_hash_write_xcode(hash, path) - path = File.expand_path(path) + return false unless path.end_with?('pbxproj') + + reader, writer = IO.pipe + + Process.fork do + success = false + if DevToolsCore.load_xcode_frameworks + success = ruby_hash_write_devtoolscore(hash, path) + end + writer.write(success) + end + Process.waitall + + writer.close + result = reader.read + reader.close + + result == 'true' + end + + def ruby_hash_write_devtoolscore(hash, path) success = true begin @@ -111,7 +132,7 @@ def ruby_hash_write_xcode(hash, path) success = false end - CoreFoundation.RubyHashPropertyListWrite(hash, path) unless success + success end end end From a27b13d612a2a964580cb1b523079dd61928eb29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boris=20Bu=CC=88gling?= Date: Mon, 29 Aug 2016 16:57:26 +0200 Subject: [PATCH 2/3] More verbose output for DevToolsCore failures --- lib/xcodeproj/plist/ffi/dev_tools_core.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/xcodeproj/plist/ffi/dev_tools_core.rb b/lib/xcodeproj/plist/ffi/dev_tools_core.rb index 53151310d..3740aa37b 100644 --- a/lib/xcodeproj/plist/ffi/dev_tools_core.rb +++ b/lib/xcodeproj/plist/ffi/dev_tools_core.rb @@ -5,13 +5,13 @@ module Plist module FFI module DevToolsCore def self.silence_stderr - begin - orig_stderr = $stderr.clone - $stderr.reopen File.new('/dev/null', 'w') + #begin + # orig_stderr = $stderr.clone + # $stderr.reopen File.new('/dev/null', 'w') retval = yield - ensure - $stderr.reopen orig_stderr - end + #ensure + # $stderr.reopen orig_stderr + #end retval end From 177a325052fe6257ffa35971d53849c3e37aa25d Mon Sep 17 00:00:00 2001 From: Samuel Giddins Date: Thu, 1 Sep 2016 17:08:53 -0400 Subject: [PATCH 3/3] [FFI] Avoid forking when creating a subprocess --- lib/xcodeproj/plist/ffi.rb | 29 ++++++++++------------- lib/xcodeproj/plist/ffi/dev_tools_core.rb | 13 ++++------ spec/project_spec.rb | 2 +- 3 files changed, 18 insertions(+), 26 deletions(-) diff --git a/lib/xcodeproj/plist/ffi.rb b/lib/xcodeproj/plist/ffi.rb index 7d9ea8448..f39e4fad5 100644 --- a/lib/xcodeproj/plist/ffi.rb +++ b/lib/xcodeproj/plist/ffi.rb @@ -98,23 +98,18 @@ def fix_encoding(filename) # def ruby_hash_write_xcode(hash, path) return false unless path.end_with?('pbxproj') - - reader, writer = IO.pipe - - Process.fork do - success = false - if DevToolsCore.load_xcode_frameworks - success = ruby_hash_write_devtoolscore(hash, path) - end - writer.write(success) - end - Process.waitall - - writer.close - result = reader.read - reader.close - - result == 'true' + require 'open3' + _output, status = Open3.capture2e(Gem.ruby, '-e', <<-RUBY, path, :stdin_data => Marshal.dump(hash)) + $LOAD_PATH.replace #{$LOAD_PATH} + path = ARGV.first + hash = Marshal.load(STDIN) + require "xcodeproj" + require "xcodeproj/plist/ffi" + ffi = Xcodeproj::Plist::FFI + success = ffi::DevToolsCore.load_xcode_frameworks && ffi.send(:ruby_hash_write_devtoolscore, hash, path) + exit(success ? 0 : 1) + RUBY + status.success? end def ruby_hash_write_devtoolscore(hash, path) diff --git a/lib/xcodeproj/plist/ffi/dev_tools_core.rb b/lib/xcodeproj/plist/ffi/dev_tools_core.rb index 3740aa37b..5e9afd4da 100644 --- a/lib/xcodeproj/plist/ffi/dev_tools_core.rb +++ b/lib/xcodeproj/plist/ffi/dev_tools_core.rb @@ -5,14 +5,11 @@ module Plist module FFI module DevToolsCore def self.silence_stderr - #begin - # orig_stderr = $stderr.clone - # $stderr.reopen File.new('/dev/null', 'w') - retval = yield - #ensure - # $stderr.reopen orig_stderr - #end - retval + orig_stderr = $stderr.clone + $stderr.reopen File.new('/dev/null', 'w') + yield + ensure + $stderr.reopen orig_stderr end # rubocop:disable Style/MethodName diff --git a/spec/project_spec.rb b/spec/project_spec.rb index 0b9f47f19..6115d5065 100644 --- a/spec/project_spec.rb +++ b/spec/project_spec.rb @@ -208,7 +208,7 @@ module ProjectSpecs end it 'escapes non ASCII characters in the project' do - Plist::FFI::DevToolsCore.stubs(:load_xcode_frameworks).returns(nil) + Plist::FFI.stubs(:ruby_hash_write_xcode).returns(false) file_ref = @project.new_file('わくわく') file_ref.name = 'わくわく'