diff --git a/lib/puppet/provider/file_line/ruby.rb b/lib/puppet/provider/file_line/ruby.rb index ae1a8b3db..e7854f001 100644 --- a/lib/puppet/provider/file_line/ruby.rb +++ b/lib/puppet/provider/file_line/ruby.rb @@ -34,13 +34,22 @@ def lines def handle_create_with_match() regex = resource[:match] ? Regexp.new(resource[:match]) : nil + regex_after = resource[:after] ? Regexp.new(resource[:after]) : nil match_count = count_matches(regex) + if match_count > 1 && resource[:multiple].to_s != 'true' raise Puppet::Error, "More than one line in file '#{resource[:path]}' matches pattern '#{resource[:match]}'" end + File.open(resource[:path], 'w') do |fh| lines.each do |l| fh.puts(regex.match(l) ? resource[:line] : l) + if (match_count == 0 and regex_after) + if regex_after.match(l) + fh.puts(resource[:line]) + match_count += 1 #Increment match_count to indicate that the new line has been inserted. + end + end end if (match_count == 0) @@ -78,7 +87,10 @@ def count_matches(regex) # # @api private def append_line - File.open(resource[:path], 'a') do |fh| + File.open(resource[:path], 'w') do |fh| + lines.each do |l| + fh.puts(l) + end fh.puts resource[:line] end end diff --git a/spec/unit/puppet/provider/file_line/ruby_spec.rb b/spec/unit/puppet/provider/file_line/ruby_spec.rb index d2a129c32..a84fc78e7 100755 --- a/spec/unit/puppet/provider/file_line/ruby_spec.rb +++ b/spec/unit/puppet/provider/file_line/ruby_spec.rb @@ -46,12 +46,12 @@ @tmpfile = tmp.path tmp.close! @resource = Puppet::Type::File_line.new( - { - :name => 'foo', - :path => @tmpfile, - :line => 'foo = bar', - :match => '^foo\s*=.*$', - } + { + :name => 'foo', + :path => @tmpfile, + :line => 'foo = bar', + :match => '^foo\s*=.*$', + } ) @provider = provider_class.new(@resource) end @@ -69,11 +69,11 @@ it 'should replace all lines that matches' do @resource = Puppet::Type::File_line.new( { - :name => 'foo', - :path => @tmpfile, - :line => 'foo = bar', - :match => '^foo\s*=.*$', - :multiple => true + :name => 'foo', + :path => @tmpfile, + :line => 'foo = bar', + :match => '^foo\s*=.*$', + :multiple => true, } ) @provider = provider_class.new(@resource) @@ -89,11 +89,11 @@ expect { @resource = Puppet::Type::File_line.new( { - :name => 'foo', - :path => @tmpfile, - :line => 'foo = bar', - :match => '^foo\s*=.*$', - :multiple => 'asgadga' + :name => 'foo', + :path => @tmpfile, + :line => 'foo = bar', + :match => '^foo\s*=.*$', + :multiple => 'asgadga', } ) }.to raise_error(Puppet::Error, /Invalid value "asgadga"\. Valid values are true, false\./) @@ -140,7 +140,54 @@ let :provider do provider_class.new(resource) end - + context 'match and after set' do + shared_context 'resource_create' do + let(:match) { '^foo2$' } + let(:after) { '^foo1$' } + let(:resource) { + Puppet::Type::File_line.new( + { + :name => 'foo', + :path => @tmpfile, + :line => 'inserted = line', + :after => after, + :match => match, + } + ) + } + end + before :each do + File.open(@tmpfile, 'w') do |fh| + fh.write("foo1\nfoo2\nfoo = baz") + end + end + describe 'inserts at match' do + include_context 'resource_create' + it { + provider.create + expect(File.read(@tmpfile).chomp).to eq("foo1\ninserted = line\nfoo = baz") + } + end + describe 'inserts a new line after when no match' do + include_context 'resource_create' do + let(:match) { '^nevergoingtomatch$' } + end + it { + provider.create + expect(File.read(@tmpfile).chomp).to eq("foo1\ninserted = line\nfoo2\nfoo = baz") + } + end + describe 'append to end of file if no match for both after and match' do + include_context 'resource_create' do + let(:match) { '^nevergoingtomatch$' } + let(:after) { '^stillneverafter' } + end + it { + provider.create + expect(File.read(@tmpfile).chomp).to eq("foo1\nfoo2\nfoo = baz\ninserted = line") + } + end + end context 'with one line matching the after expression' do before :each do File.open(@tmpfile, 'w') do |fh| @@ -194,7 +241,12 @@ @tmpfile = tmp.path tmp.close! @resource = Puppet::Type::File_line.new( - {:name => 'foo', :path => @tmpfile, :line => 'foo', :ensure => 'absent' } + { + :name => 'foo', + :path => @tmpfile, + :line => 'foo', + :ensure => 'absent', + } ) @provider = provider_class.new(@resource) end