Skip to content

Commit

Permalink
update write and touch methods
Browse files Browse the repository at this point in the history
* allow setting the file open mode.
* Revert previous change to rename perm option mode. This is due to the
naming of the Ruby’s File::open method arguments
  • Loading branch information
yads committed Apr 30, 2018
1 parent cea6f79 commit c8d81fd
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 15 deletions.
42 changes: 29 additions & 13 deletions lib/sugar_utils/file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -105,23 +105,26 @@ def self.read_json(filename, options = {})
# @param [Hash] options
# @option options [String, Integer] :owner
# @option options [String, Integer] :group
# @option options [Integer] :mode
# @option options [Integer] :perm @deprecated
# @option options [Integer] :mode @deprecated
# @option options [Integer] :perm
# @option options [Integer] :mtime
#
# @return [void]
def self.touch(filename, options = {})
owner = options[:owner]
group = options[:group]
mode = options[:mode] || options[:perm]
perm = options[:perm]
touch_options = options.select { |k| %i[mtime].include?(k) }

deprecate_option(:touch, :perm, :mode, 2017, 8) if options.key?(:perm)
if options[:mode].is_a?(Integer)
perm = options[:mode]
deprecate_option(:touch, :mode, :perm, 2018, 7)
end

FileUtils.mkdir_p(::File.dirname(filename))
FileUtils.touch(filename, touch_options)
FileUtils.chown(owner, group, filename)
FileUtils.chmod(mode, filename) if mode
FileUtils.chmod(perm, filename) if perm
end

# @param [String] filename
Expand All @@ -131,8 +134,8 @@ def self.touch(filename, options = {})
# @option options [Boolean] :flush (false)
# @option options [String, Integer] :owner
# @option options [String, Integer] :group
# @option options [Integer] :mode (0o644)
# @option options [Integer] :perm (0o644) @deprecated
# @option options [String] :mode (w+)
# @option options [Integer] :perm (0o644)
#
# @raise [SugarUtils::File::Error]
#
Expand All @@ -141,15 +144,21 @@ def self.write(filename, data, options = {}) # rubocop:disable MethodLength, Abc
flush = options[:flush] || false
owner = options[:owner]
group = options[:group]
mode = options[:mode] || options[:perm] || 0o644
perm = options[:perm] || 0o644
mode = 'w+'

if options[:mode].is_a?(Integer)
perm = options[:mode]

deprecate_option(:touch, :perm, :mode, 2017, 8) if options.key?(:perm)
deprecate_option(:write, :mode, ' with an integer value; use perm instead', 2018, 7)
elsif !options[:mode].nil?
mode = options[:mode]
end

FileUtils.mkdir_p(::File.dirname(filename))
::File.open(filename, ::File::RDWR | ::File::CREAT, mode) do |file|
::File.open(filename, mode, perm) do |file|
flock_exclusive(file, options)

file.truncate(0) # Ensure file is empty before proceeding.
file.puts(data.to_s)

# Flush and fsync to be 100% sure we write this data out now because we
Expand All @@ -162,7 +171,7 @@ def self.write(filename, data, options = {}) # rubocop:disable MethodLength, Abc
end

# Ensure that the permissions are correct if the file already existed.
file.chmod(mode)
file.chmod(perm)
end
FileUtils.chown(owner, group, filename)
rescue Timeout::Error
Expand Down Expand Up @@ -205,7 +214,14 @@ def self.deprecate_option(_method, option_name, option_repl, year, month) # rubo

msg = [
"NOTE: #{target}#{method} option :#{option_name} is deprecated",
option_repl == :none ? ' with no replacement' : "; use :#{option_repl} instead",
case option_repl
when :none
' with no replacement'
when String
option_repl
else
"; use :#{option_repl} instead"
end,
format('. It will be removed on or after %4d-%02d-01.', year, month),
"\n#{target}#{method} called from #{location_of_external_caller}"
]
Expand Down
14 changes: 12 additions & 2 deletions spec/sugar_utils/file_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -171,15 +171,15 @@
end

context 'with deprecated options' do
let(:options) { { perm: 0o600 } }
let(:options) { { mode: 0o600 } }
before { subject }
specify { expect(filename).to have_content(data) }
specify { expect(filename).to have_file_permission(0o100600) }
end

context 'without deprecated options' do
let(:options) do
{ flush: true, owner: 'nobody', group: 'nogroup', mode: 0o600 }
{ flush: true, owner: 'nobody', group: 'nogroup', mode: 'w', perm: 0o600 }
end
before do
expect_any_instance_of(File).to receive(:flush)
Expand All @@ -201,6 +201,16 @@
before { write(filename, 'foobar', 0o777) }
context 'not locked' do
it_behaves_like 'file is written'

context 'with append mode' do
let(:options) { { mode: 'a+' } }
before do
expect(described_class).to receive(:flock_exclusive)
.with(kind_of(File), options)
subject
end
specify { expect(filename).to have_content("foobar#{data}") }
end
end
end
end
Expand Down

0 comments on commit c8d81fd

Please sign in to comment.