diff --git a/Gemfile b/Gemfile index a451b21..0186b4f 100644 --- a/Gemfile +++ b/Gemfile @@ -20,6 +20,7 @@ group :test do gem "rspec", "~> 3.13.0" gem "rubocop", "~> 1.90.0" gem "rubocop-performance", "~> 1.27.0" + gem "ruby-lsp", "~> 0.26.11" gem "simplecov", "~> 1.0.0" gem "simplecov-console", "~> 0.9.1" end diff --git a/allure-ruby-commons/lib/allure_ruby_commons/file_writer.rb b/allure-ruby-commons/lib/allure_ruby_commons/file_writer.rb index 6316db9..eadb816 100644 --- a/allure-ruby-commons/lib/allure_ruby_commons/file_writer.rb +++ b/allure-ruby-commons/lib/allure_ruby_commons/file_writer.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require "tempfile" + module Allure # Allure result file writer class FileWriter @@ -83,12 +85,30 @@ def output_dir end def write(name, source) - filename = File.join(output_dir, name) - File.write(filename, source) + atomic_write(name) { |temp_file| temp_file.write(source) } end def copy(from, to) - FileUtils.cp(from, File.join(output_dir, to)) + atomic_write(to) { |temp_file| IO.copy_stream(from, temp_file) } + end + + def atomic_write(name) + filename = File.join(output_dir, name) + target_mode = begin + File.stat(filename).mode + rescue Errno::ENOENT + 0o644 + end + + Tempfile.create("#{name}.tmp", output_dir) do |temp_file| + temp_file.binmode + + yield temp_file + + temp_file.chmod(target_mode) + temp_file.close + File.rename(temp_file.path, filename) + end end end end