Skip to content

Update to active_support 4.2.4 #68

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 60 additions & 58 deletions lib/filewatch/helper.rb
Original file line number Diff line number Diff line change
@@ -1,69 +1,71 @@
# 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
# 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)
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)

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

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
temp_file = Tempfile.new(basename(file_name), temp_dir)
temp_file.binmode
yield temp_file
temp_file.close

# Overwrite original file with temp file
File.rename(temp_file.path, file_name)
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

# Unable to get permissions of the original file => return
return return_val if old_stat.nil?
# Overwrite original file with temp file
FileUtils.mv(temp_file.path, file_name)

# Set correct uid/gid on new file
chown(old_stat.uid, old_stat.gid, file_name) if old_stat

return_val
end
# 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")
file_name = join(dir, basename)
FileUtils.touch(file_name)
stat(file_name)
rescue
# ...
ensure
FileUtils.rm_f(file_name) if File.exist?(file_name)
end
# Private utility method.
def self.probe_stat_in(dir) #:nodoc:
basename = [
'.permissions_check',
Thread.current.object_id,
Process.pid,
rand(1000000)
].join('.')

def self.rand_filename(prefix)
[ prefix, Thread.current.object_id, Process.pid, rand(1000000) ].join('.')
end
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)
def self.device?(file_name)
chardev?(file_name) || blockdev?(file_name)
end
end
end