Module: Flexr::ArtifactWriter
- Defined in:
- lib/flexr/artifact_writer.rb
Class Method Summary collapse
- .atomic_replace(path, content) ⇒ Object
- .default_generated_path(source_path) ⇒ Object
- .ensure_distinct!(source_path, output_path) ⇒ Object
- .sync_directory(directory) ⇒ Object
- .write!(path, content, source_path: nil) ⇒ Object
Class Method Details
.atomic_replace(path, content) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/flexr/artifact_writer.rb', line 32 def atomic_replace(path, content) = File.(path) directory = File.dirname() basename = File.basename() mode = File.exist?() ? File.stat().mode & 0o7777 : 0o666 & ~File.umask temporary_path = nil Tempfile.create([".#{basename}.", ".tmp"], directory, binmode: true) do |temporary| temporary_path = temporary.path temporary.write(content) temporary.flush temporary.fsync temporary.chmod(mode) temporary.close File.rename(temporary_path, ) temporary_path = nil end sync_directory(directory) ensure File.unlink(temporary_path) if temporary_path && File.exist?(temporary_path) end |
.default_generated_path(source_path) ⇒ Object
9 10 11 12 13 14 |
# File 'lib/flexr/artifact_writer.rb', line 9 def default_generated_path(source_path) return source_path.sub(/\.flexr\.rb\z/, ".rb") if source_path.end_with?(".flexr.rb") return source_path.sub(/\.rb\z/, ".generated.rb") if source_path.end_with?(".rb") "#{source_path}.generated.rb" end |
.ensure_distinct!(source_path, output_path) ⇒ Object
24 25 26 27 28 29 30 |
# File 'lib/flexr/artifact_writer.rb', line 24 def ensure_distinct!(source_path, output_path) same_path = File.(source_path) == File.(output_path) same_file = File.exist?(source_path) && File.exist?(output_path) && File.identical?(source_path, output_path) return unless same_path || same_file raise ArgumentError, "refusing to overwrite input file: #{source_path}" end |
.sync_directory(directory) ⇒ Object
54 55 56 57 58 59 |
# File 'lib/flexr/artifact_writer.rb', line 54 def sync_directory(directory) File.open(directory, File::RDONLY, &:fsync) rescue SystemCallError, IOError # Some supported filesystems do not allow fsync on directories. The file # itself has already been synced before the atomic rename. end |
.write!(path, content, source_path: nil) ⇒ Object
16 17 18 19 20 21 22 |
# File 'lib/flexr/artifact_writer.rb', line 16 def write!(path, content, source_path: nil) ensure_distinct!(source_path, path) if source_path return :unchanged if File.file?(path) && File.binread(path) == content.b atomic_replace(path, content) :written end |