]> gitweb.fluxo.info Git - puppet-stdlib.git/commitdiff
(PUP-2571) add 'before' functionality to file_line
authorStephen Benjamin <stephen@bitbin.de>
Wed, 14 May 2014 18:33:57 +0000 (20:33 +0200)
committerStephen Benjamin <stephen@bitbin.de>
Wed, 14 May 2014 18:33:57 +0000 (20:33 +0200)
file_line supports adding lines after a match, but there are use cases when
having "before" would be useful. For example, in Debian-based OS's, the last
line of /etc/rc.local is "exit 0" it's an incredible pain to deal with
that scenario today.

This commit adds a 'before' parameter to the file_line type, and implements
it for the ruby provider.

lib/puppet/provider/file_line/ruby.rb
lib/puppet/type/file_line.rb
spec/unit/puppet/provider/file_line/ruby_spec.rb
spec/unit/puppet/type/file_line_spec.rb

index 94e7fac9196ec454cd9928951c15176886a7c633..2cbd1724db1e294c7c12f037a176e087ff2df5bf 100644 (file)
@@ -9,7 +9,9 @@ Puppet::Type.type(:file_line).provide(:ruby) do
     if resource[:match]
       handle_create_with_match
     elsif resource[:after]
-      handle_create_with_after
+      handle_create_with_position :after
+    elsif resource[:before]
+      handle_create_with_position :before
     else
       append_line
     end
@@ -49,29 +51,29 @@ Puppet::Type.type(:file_line).provide(:ruby) do
     end
   end
 
-  def handle_create_with_after
-    regex = Regexp.new(resource[:after])
+  def handle_create_with_position(position)
+    regex = resource[position] ? Regexp.new(resource[position]) : nil
 
     count = lines.count {|l| l.match(regex)}
 
     case count
-    when 1 # find the line to put our line after
+    when 1 # find the line to put our line before/after
       File.open(resource[:path], 'w') do |fh|
         lines.each do |l|
-          fh.puts(l)
+          fh.puts(l) if position == :after
           if regex.match(l) then
             fh.puts(resource[:line])
           end
+          fh.puts(l) if position == :before
         end
       end
     when 0 # append the line to the end of the file
       append_line
     else
-      raise Puppet::Error, "#{count} lines match pattern '#{resource[:after]}' in file '#{resource[:path]}'.  One or no line must match the pattern."
+      raise Puppet::Error, "#{count} lines match pattern '#{resource[position]}' in file '#{resource[:path]}'.  One or no line must match the pattern."
     end
   end
 
-  ##
   # append the line to the file.
   #
   # @api private
index 323fc4c9c7f7054e2bac68d10333b9c6290b8dae..bc6745f657c934355000ea64f4eff07b40ba7ba8 100644 (file)
@@ -46,6 +46,10 @@ Puppet::Type.newtype(:file_line) do
     desc 'An optional value used to specify the line after which we will add any new lines. (Existing lines are added in place)'
   end
 
+  newparam(:before) do
+    desc 'An optional value used to specify the line before which we will add any new lines. (Existing lines are added in place)'
+  end
+
   newparam(:line) do
     desc 'The line to be appended to the file located by the path parameter.'
   end
index a016b685c35df541d862df95cd19d9e6f6bc8a67..d004af44ace5bdc615f7c4aeb2c3a1c32ec0888f 100755 (executable)
@@ -183,6 +183,65 @@ describe provider_class do
         end
       end
     end
+
+    describe 'using before' do
+      let :resource do
+        Puppet::Type::File_line.new(
+          {
+            :name  => 'foo',
+            :path  => @tmpfile,
+            :line  => 'inserted = line',
+            :before => '^foo1',
+          }
+        )
+      end
+
+      let :provider do
+        provider_class.new(resource)
+      end
+
+      context 'with one line matching the before expression' do
+        before :each do
+          File.open(@tmpfile, 'w') do |fh|
+            fh.write("foo1\nfoo = blah\nfoo2\nfoo = baz")
+          end
+        end
+
+        it 'inserts the specified line before the line matching the "before" expression' do
+          provider.create
+          File.read(@tmpfile).chomp.should eql("inserted = line\nfoo1\nfoo = blah\nfoo2\nfoo = baz")
+        end
+      end
+
+      context 'with two lines matching the before expression' do
+        before :each do
+          File.open(@tmpfile, 'w') do |fh|
+            fh.write("foo1\nfoo = blah\nfoo2\nfoo1\nfoo = baz")
+          end
+        end
+
+        it 'errors out stating "One or no line must match the pattern"' do
+          expect { provider.create }.to raise_error(Puppet::Error, /One or no line must match the pattern/)
+        end
+      end
+
+      context 'with no lines matching the after expression' do
+        let :content do
+          "foo3\nfoo = blah\nfoo2\nfoo = baz\n"
+        end
+
+        before :each do
+          File.open(@tmpfile, 'w') do |fh|
+            fh.write(content)
+          end
+        end
+
+        it 'appends the specified line to the file' do
+          provider.create
+          File.read(@tmpfile).should eq(content << resource[:line] << "\n")
+        end
+      end
+    end
   end
 
   context "when removing" do
index ab5b81bb96b74c461edb4fc35bbfe9d079b4bcd9..b85b9f4ec4db3683c41fa428dcb5b7d096b2322e 100755 (executable)
@@ -15,6 +15,14 @@ describe Puppet::Type.type(:file_line) do
     file_line[:match] = '^foo.*$'
     file_line[:match].should == '^foo.*$'
   end
+  it 'should accept an after regex' do
+    file_line[:after] = '^foo.*$'
+    file_line[:after].should == '^foo.*$'
+  end
+  it 'should accept a before regex' do
+    file_line[:before] = '^foo.*$'
+    file_line[:before].should == '^foo.*$'
+  end
   it 'should not accept a match regex that does not match the specified line' do
     expect {
       Puppet::Type.type(:file_line).new(