From e1333f5671b5b435f01b5d402f0d47a7fe2b55d5 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Sat, 24 Feb 2024 08:01:29 +1300 Subject: [PATCH] feat: add option to have `gsub_file` error if file contents don't change --- lib/thor/actions/file_manipulation.rb | 10 ++++++++-- spec/actions/file_manipulation_spec.rb | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/lib/thor/actions/file_manipulation.rb b/lib/thor/actions/file_manipulation.rb index e4aa8e89..abd05ca7 100644 --- a/lib/thor/actions/file_manipulation.rb +++ b/lib/thor/actions/file_manipulation.rb @@ -249,7 +249,8 @@ def inject_into_module(path, module_name, *args, &block) # path:: path of the file to be changed # flag:: the regexp or string to be replaced # replacement:: the replacement, can be also given as a block - # config:: give :verbose => false to not log the status, and + # config:: give :verbose => false to not log the status, + # :error_on_no_change => true to raise an error if the file does not change, and # :force => true, to force the replacement regardless of runner behavior. # # ==== Example @@ -270,7 +271,12 @@ def gsub_file(path, flag, *args, &block) unless options[:pretend] content = File.binread(path) - content.gsub!(flag, *args, &block) + success = content.gsub!(flag, *args, &block) + + if success.nil? && config.fetch(:error_on_no_change, false) + raise Thor::Error, "The content of #{path} did not change" + end + File.open(path, "wb") { |file| file.write(content) } end end diff --git a/spec/actions/file_manipulation_spec.rb b/spec/actions/file_manipulation_spec.rb index a1b902af..5277d5b0 100644 --- a/spec/actions/file_manipulation_spec.rb +++ b/spec/actions/file_manipulation_spec.rb @@ -318,6 +318,26 @@ def file it "does not log status if required" do expect(action(:gsub_file, file, "__", verbose: false) { |match| match * 2 }).to be_empty end + + it "does not care if the file contents did not change" do + action :gsub_file, "doc/README", "___start___", "START" + expect(File.binread(file)).to eq("__start__\nREADME\n__end__\n") + end + + context "with error_on_no_change" do + it "replaces the content in the file" do + action :gsub_file, "doc/README", "__start__", "START", error_on_no_change: true + expect(File.binread(file)).to eq("START\nREADME\n__end__\n") + end + + it "raises if the file contents did not change" do + expect do + action :gsub_file, "doc/README", "___start___", "START", error_on_no_change: true + end.to raise_error(Thor::Error) + + expect(File.binread(file)).to eq("__start__\nREADME\n__end__\n") + end + end end context "with revoke behavior" do