From 859023a86714d2882a213db6963587c6b6bc1751 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 25 Nov 2015 17:25:30 +0100 Subject: [PATCH 1/2] update helper to active_support 4.2.4 --- lib/filewatch/helper.rb | 56 ++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/lib/filewatch/helper.rb b/lib/filewatch/helper.rb index 21c54b7..d585c98 100644 --- a/lib/filewatch/helper.rb +++ b/lib/filewatch/helper.rb @@ -1,5 +1,5 @@ -# code downloaded from Ruby on Rails 4.2.1 -# https://raw.githubusercontent.com/rails/rails/v4.2.1/activesupport/lib/active_support/core_ext/file/atomic.rb +# code downloaded from Ruby on Rails 4.2.4 +# https://raw.githubusercontent.com/rails/rails/v4.2.4/activesupport/lib/active_support/core_ext/file/atomic.rb require 'fileutils' class File @@ -16,7 +16,14 @@ class File # File.atomic_write('/data/something.important', '/data/tmp') do |file| # file.write('hello') # end - def self.atomic_write(file_name) + def self.atomic_write(file_name, temp_dir = Dir.tmpdir) + require 'tempfile' unless defined?(Tempfile) + require 'fileutils' unless defined?(FileUtils) + + temp_file = Tempfile.new(basename(file_name), temp_dir) + temp_file.binmode + yield temp_file + temp_file.close if File.exist?(file_name) # Get original file permissions @@ -27,42 +34,35 @@ def self.atomic_write(file_name) old_stat = probe_stat_in(dirname(file_name)) end - mode = old_stat ? old_stat.mode : nil - - # Create temporary file with identical permissions - temp_file = File.new(rand_filename(file_name), "w", mode) - temp_file.binmode - return_val = yield temp_file - temp_file.close - # Overwrite original file with temp file - File.rename(temp_file.path, file_name) + FileUtils.mv(temp_file.path, file_name) - # Unable to get permissions of the original file => return - return return_val if old_stat.nil? - - # Set correct uid/gid on new file - chown(old_stat.uid, old_stat.gid, file_name) if old_stat - - return_val + # Set correct permissions on new file + begin + chown(old_stat.uid, old_stat.gid, file_name) + # This operation will affect filesystem ACL's + chmod(old_stat.mode, file_name) + rescue Errno::EPERM, Errno::EACCES + # Changing file ownership failed, moving on. + end end # Private utility method. def self.probe_stat_in(dir) #:nodoc: - basename = rand_filename(".permissions_check") + basename = [ + '.permissions_check', + Thread.current.object_id, + Process.pid, + rand(1000000) + ].join('.') + file_name = join(dir, basename) FileUtils.touch(file_name) stat(file_name) - rescue - # ... ensure - FileUtils.rm_f(file_name) if File.exist?(file_name) + FileUtils.rm_f(file_name) if file_name end - - def self.rand_filename(prefix) - [ prefix, Thread.current.object_id, Process.pid, rand(1000000) ].join('.') - end - + def self.device?(file_name) chardev?(file_name) || blockdev?(file_name) end From fa033c32d2fca0edbda8640100c67b5fff17407f Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 7 Jan 2016 13:44:11 +0100 Subject: [PATCH 2/2] Namespace monkey-patches to File to avoid conflicts --- lib/filewatch/helper.rb | 114 ++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 56 deletions(-) diff --git a/lib/filewatch/helper.rb b/lib/filewatch/helper.rb index d585c98..fc691fb 100644 --- a/lib/filewatch/helper.rb +++ b/lib/filewatch/helper.rb @@ -2,68 +2,70 @@ # https://raw.githubusercontent.com/rails/rails/v4.2.4/activesupport/lib/active_support/core_ext/file/atomic.rb require 'fileutils' -class File - # Write to a file atomically. Useful for situations where you don't - # want other processes or threads to see half-written files. - # - # File.atomic_write('important.file') do |file| - # file.write('hello') - # end - # - # If your temp directory is not on the same filesystem as the file you're - # trying to write, you can provide a different temporary directory. - # - # File.atomic_write('/data/something.important', '/data/tmp') do |file| - # file.write('hello') - # end - def self.atomic_write(file_name, temp_dir = Dir.tmpdir) - require 'tempfile' unless defined?(Tempfile) - require 'fileutils' unless defined?(FileUtils) +module FileWatch + class File < ::File + # Write to a file atomically. Useful for situations where you don't + # want other processes or threads to see half-written files. + # + # File.atomic_write('important.file') do |file| + # file.write('hello') + # end + # + # If your temp directory is not on the same filesystem as the file you're + # trying to write, you can provide a different temporary directory. + # + # File.atomic_write('/data/something.important', '/data/tmp') do |file| + # file.write('hello') + # end + def self.atomic_write(file_name, temp_dir = Dir.tmpdir) + require 'tempfile' unless defined?(Tempfile) + require 'fileutils' unless defined?(FileUtils) - temp_file = Tempfile.new(basename(file_name), temp_dir) - temp_file.binmode - yield temp_file - temp_file.close + temp_file = Tempfile.new(basename(file_name), temp_dir) + temp_file.binmode + yield temp_file + temp_file.close - if File.exist?(file_name) - # Get original file permissions - old_stat = stat(file_name) - else - # If not possible, probe which are the default permissions in the - # destination directory. - old_stat = probe_stat_in(dirname(file_name)) - end + if File.exist?(file_name) + # Get original file permissions + old_stat = stat(file_name) + else + # If not possible, probe which are the default permissions in the + # destination directory. + old_stat = probe_stat_in(dirname(file_name)) + end - # Overwrite original file with temp file - FileUtils.mv(temp_file.path, file_name) + # Overwrite original file with temp file + FileUtils.mv(temp_file.path, file_name) - # Set correct permissions on new file - begin - chown(old_stat.uid, old_stat.gid, file_name) - # This operation will affect filesystem ACL's - chmod(old_stat.mode, file_name) - rescue Errno::EPERM, Errno::EACCES - # Changing file ownership failed, moving on. + # Set correct permissions on new file + begin + chown(old_stat.uid, old_stat.gid, file_name) + # This operation will affect filesystem ACL's + chmod(old_stat.mode, file_name) + rescue Errno::EPERM, Errno::EACCES + # Changing file ownership failed, moving on. + end end - end - # Private utility method. - def self.probe_stat_in(dir) #:nodoc: - basename = [ - '.permissions_check', - Thread.current.object_id, - Process.pid, - rand(1000000) - ].join('.') + # Private utility method. + def self.probe_stat_in(dir) #:nodoc: + basename = [ + '.permissions_check', + Thread.current.object_id, + Process.pid, + rand(1000000) + ].join('.') - file_name = join(dir, basename) - FileUtils.touch(file_name) - stat(file_name) - ensure - FileUtils.rm_f(file_name) if file_name - end - - def self.device?(file_name) - chardev?(file_name) || blockdev?(file_name) + file_name = join(dir, basename) + FileUtils.touch(file_name) + stat(file_name) + ensure + FileUtils.rm_f(file_name) if file_name + end + + def self.device?(file_name) + chardev?(file_name) || blockdev?(file_name) + end end end