diff --git a/features/actions/file_replace_content.feature b/features/actions/file_replace_content.feature new file mode 100644 index 0000000..e460957 --- /dev/null +++ b/features/actions/file_replace_content.feature @@ -0,0 +1,31 @@ +@sshd +Feature: `file_replace_content' task action + + Background: + Given a remote file named "some_file" with "some content" + + Scenario: replace a string by another in the requested file + Given a recipe with: + """ + target 'some_host.test' + + task :replace_string_in_file do + file_replace_content 'some_file', 'content', 'other content' + end + """ + When I execute the recipe + Then the exit status must be 0 + And the remote file "some_file" must contain exactly "some other content" + + Scenario: replace a regular expression by a string in the requested file + Given a recipe with: + """ + target 'some_host.test' + + task :replace_string_in_file do + file_replace_content 'some_file', /\w+\z/, 'other content' + end + """ + When I execute the recipe + Then the exit status must be 0 + And the remote file "some_file" must contain exactly "some other content" diff --git a/features/steps/remote_steps.rb b/features/steps/remote_steps.rb index 4bbfd5f..8e34b4a 100644 --- a/features/steps/remote_steps.rb +++ b/features/steps/remote_steps.rb @@ -17,3 +17,7 @@ end Then /^the remote file "([^"]+)" should contain "([^"]+)"/ do |path, content| check_file_content path, content, true end + +Then /^the remote file "([^"]+)" should contain exactly "([^"]+)"/ do |path, content| + check_exact_file_content path, content +end diff --git a/lib/producer/core.rb b/lib/producer/core.rb index eb37e2f..122eaf8 100644 --- a/lib/producer/core.rb +++ b/lib/producer/core.rb @@ -10,6 +10,7 @@ require 'producer/core/action' require 'producer/core/actions/echo' require 'producer/core/actions/shell_command' require 'producer/core/actions/mkdir' +require 'producer/core/actions/file_replace_content' require 'producer/core/actions/file_writer' # condition tests (need to be defined before the condition DSL) diff --git a/lib/producer/core/actions/file_replace_content.rb b/lib/producer/core/actions/file_replace_content.rb new file mode 100644 index 0000000..00fcdf0 --- /dev/null +++ b/lib/producer/core/actions/file_replace_content.rb @@ -0,0 +1,27 @@ +module Producer + module Core + module Actions + class FileReplaceContent < Action + def apply + fs.file_write path, replaced_content + end + + def path + arguments[0] + end + + def pattern + arguments[1] + end + + def replacement + arguments[2] + end + + def replaced_content + fs.file_read(path).gsub pattern, replacement + end + end + end + end +end diff --git a/lib/producer/core/task/dsl.rb b/lib/producer/core/task/dsl.rb index d82dad8..73830ea 100644 --- a/lib/producer/core/task/dsl.rb +++ b/lib/producer/core/task/dsl.rb @@ -13,8 +13,9 @@ module Producer define_action :echo, Actions::Echo define_action :sh, Actions::ShellCommand - define_action :mkdir, Actions::Mkdir - define_action :file_write, Actions::FileWriter + define_action :mkdir, Actions::Mkdir + define_action :file_write, Actions::FileWriter + define_action :file_replace_content, Actions::FileReplaceContent attr_reader :env, :block, :actions diff --git a/spec/producer/core/actions/file_replace_content_spec.rb b/spec/producer/core/actions/file_replace_content_spec.rb new file mode 100644 index 0000000..9cd5757 --- /dev/null +++ b/spec/producer/core/actions/file_replace_content_spec.rb @@ -0,0 +1,49 @@ +require 'spec_helper' + +module Producer::Core + module Actions + describe FileReplaceContent, :env do + let(:path) { 'some_path' } + let(:pattern) { 'content' } + let(:replacement) { 'other content' } + let(:content) { 'some content' } + subject(:action) { FileReplaceContent.new(env, path, pattern, replacement) } + + it_behaves_like 'action' + + before { allow(remote_fs).to receive(:file_read).with(path) { content } } + + describe '#apply' do + it 'writes replaced content to file on remote filesystem' do + expect(remote_fs) + .to receive(:file_write).with(path, action.replaced_content) + action.apply + end + end + + describe '#path' do + it 'returns the file path' do + expect(action.path).to eq path + end + end + + describe '#pattern' do + it 'returns the pattern' do + expect(action.pattern).to eq pattern + end + end + + describe '#replacement' do + it 'returns the replacement' do + expect(action.replacement).to eq replacement + end + end + + describe '#replaced_content' do + it 'returns content with pattern occurrences pattern replaced' do + expect(action.replaced_content).to eq 'some other content' + end + end + end + end +end diff --git a/spec/producer/core/task/dsl_spec.rb b/spec/producer/core/task/dsl_spec.rb index a15d68e..f46d139 100644 --- a/spec/producer/core/task/dsl_spec.rb +++ b/spec/producer/core/task/dsl_spec.rb @@ -7,7 +7,7 @@ module Producer::Core let(:env) { Env.new } subject(:dsl) { DSL.new(env, &block) } - %w[echo sh mkdir file_write].each do |action| + %w[echo sh mkdir file_write file_replace_content].each do |action| it "has `#{action}' action defined" do expect(dsl).to respond_to action.to_sym end