Module: Atomos

Defined in:
lib/atomos.rb,
lib/atomos/version.rb

Constant Summary collapse

VERSION =
File.read(File.expand_path('../../../VERSION', __FILE__))

Class Method Summary collapse

Class Method Details

.atomic_write(dest, contents = nil, tmpdir: nil, &block) ⇒ Object

rubocop:disable Metrics/MethodLength



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/atomos.rb', line 9

def atomic_write(dest, contents = nil, tmpdir: nil, &block)
  unless contents.nil? ^ block.nil?
    raise ArgumentError, 'must provide either contents or a block'
  end

  tmpdir = Atomos.default_tmpdir_for_file(dest, tmpdir)

  require 'tempfile'
  Tempfile.open(".atomos.#{File.basename(dest)}", tmpdir) do |tmpfile|
    if contents
      tmpfile << contents
    else
      retval = yield tmpfile
    end

    tmpfile.close

    File.rename(tmpfile.path, dest)

    retval
  end
end

.default_tmpdir_for_file(dest, tmpdir) ⇒ Object

rubocop:enable Metrics/MethodLength



33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/atomos.rb', line 33

def self.default_tmpdir_for_file(dest, tmpdir)
  tmpdir ||= begin
    require 'tmpdir'
    Dir.tmpdir
  end

  # Ensure the destination is on the same device as tmpdir
  if File.stat(tmpdir).dev != File.stat(File.dirname(dest)).dev
    # If not, use the directory of the destination as the tmpdir.
    tmpdir = File.dirname(dest)
  end

  tmpdir
end