Module: Woods::AtomicFile

Defined in:
lib/woods/atomic_file.rb

Overview

Crash-safe file writes via a temp file + atomic rename.

Extracted from the pattern in IndexArtifact (whose own atomic_write is private and instance-level) so any component that writes many files — e.g. the Obsidian exporter writing a vault of notes — can reuse it. If the process dies mid-write, the destination file is either the old content or the new content, never a torn partial.

Examples:

Woods::AtomicFile.write("tmp/woods/obsidian_vault/models/User.md", note_body)

Class Method Summary collapse

Class Method Details

.write(path, content) ⇒ void

This method returns an undefined value.

Atomically write content to path, creating parent directories.

Parameters:

  • path (String, Pathname)

    destination path

  • content (String)

    file content



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/woods/atomic_file.rb', line 25

def write(path, content)
  path = path.to_s
  FileUtils.mkdir_p(File.dirname(path))
  tmp = Tempfile.new('.woods-', File.dirname(path))
  # Binary mode so the content's bytes (e.g. UTF-8) are written verbatim
  # regardless of the process's default external encoding.
  tmp.binmode
  tmp.write(content)
  tmp.flush
  tmp.fsync
  tmp.close
  File.rename(tmp.path, path)
rescue StandardError
  tmp&.close
  tmp&.unlink
  raise
end