Skip to content

Commit ebf7348

Browse files
committed
Merge pull request #494 from CENGN/fix/master/file_line_replace
[#puppethack] Adding replace attribute to file_line
2 parents 41a7297 + 35e9264 commit ebf7348

5 files changed

Lines changed: 81 additions & 11 deletions

File tree

README.markdown

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ All parameters are optional, unless otherwise noted.
9999
* `multiple`: Determines if `match` and/or `after` can change multiple lines. If set to false, an exception will be raised if more than one line matches. Valid options: 'true', 'false'. Default: Undefined.
100100
* `name`: Sets the name to use as the identity of the resource. This is necessary if you want the resource namevar to differ from the supplied `title` of the resource. Valid options: String. Default: Undefined.
101101
* `path`: **Required.** Defines the file in which Puppet will ensure the line specified by `line`. Must be an absolute path to the file.
102+
* `replace`: Defines whether the resource will overwrite an existing line that matches the `match` parameter. If set to false and a line is found matching the `match` param, the line will not be placed in the file. Valid options: true, false, yes, no. Default: true
102103

103104

104105
### Functions

lib/puppet/provider/file_line/ruby.rb

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
Puppet::Type.type(:file_line).provide(:ruby) do
22
def exists?
3-
lines.find do |line|
4-
line.chomp == resource[:line].chomp
3+
if !resource[:replace] and count_matches(match_regex) > 0
4+
true
5+
else
6+
lines.find do |line|
7+
line.chomp == resource[:line].chomp
8+
end
59
end
610
end
711

812
def create
9-
if resource[:match]
10-
handle_create_with_match
11-
elsif resource[:after]
12-
handle_create_with_after
13-
else
14-
append_line
13+
unless !resource[:replace] and count_matches(match_regex) > 0
14+
if resource[:match]
15+
handle_create_with_match
16+
elsif resource[:after]
17+
handle_create_with_after
18+
else
19+
append_line
20+
end
1521
end
1622
end
1723

@@ -32,18 +38,21 @@ def lines
3238
@lines ||= File.readlines(resource[:path])
3339
end
3440

41+
def match_regex
42+
resource[:match] ? Regexp.new(resource[:match]) : nil
43+
end
44+
3545
def handle_create_with_match()
36-
regex = resource[:match] ? Regexp.new(resource[:match]) : nil
3746
regex_after = resource[:after] ? Regexp.new(resource[:after]) : nil
38-
match_count = count_matches(regex)
47+
match_count = count_matches(match_regex)
3948

4049
if match_count > 1 && resource[:multiple].to_s != 'true'
4150
raise Puppet::Error, "More than one line in file '#{resource[:path]}' matches pattern '#{resource[:match]}'"
4251
end
4352

4453
File.open(resource[:path], 'w') do |fh|
4554
lines.each do |l|
46-
fh.puts(regex.match(l) ? resource[:line] : l)
55+
fh.puts(match_regex.match(l) ? resource[:line] : l)
4756
if (match_count == 0 and regex_after)
4857
if regex_after.match(l)
4958
fh.puts(resource[:line])

lib/puppet/type/file_line.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
require 'puppet/parameter/boolean'
12
Puppet::Type.newtype(:file_line) do
23

34
desc <<-EOT
@@ -78,6 +79,11 @@
7879
end
7980
end
8081

82+
newparam(:replace, :boolean => true, :parent => Puppet::Parameter::Boolean) do
83+
desc 'If true, replace line that matches. If false, do not write line if a match is found'
84+
defaultto true
85+
end
86+
8187
# Autorequire the file resource if it's being managed
8288
autorequire(:file) do
8389
self[:path]

spec/unit/puppet/provider/file_line/ruby_spec.rb

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,58 @@
3636
expect(File.read(tmpfile).chomp).to eq('foo')
3737
end
3838
end
39+
context 'when using replace' do
40+
before :each do
41+
# TODO: these should be ported over to use the PuppetLabs spec_helper
42+
# file fixtures once the following pull request has been merged:
43+
# https://github.com/puppetlabs/puppetlabs-stdlib/pull/73/files
44+
tmp = Tempfile.new('tmp')
45+
@tmpfile = tmp.path
46+
tmp.close!
47+
@resource = Puppet::Type::File_line.new(
48+
{
49+
:name => 'foo',
50+
:path => @tmpfile,
51+
:line => 'foo = bar',
52+
:match => '^foo\s*=.*$',
53+
:replace => false,
54+
}
55+
)
56+
@provider = provider_class.new(@resource)
57+
end
3958

59+
it 'should not replace the matching line' do
60+
File.open(@tmpfile, 'w') do |fh|
61+
fh.write("foo1\nfoo=blah\nfoo2\nfoo3")
62+
end
63+
expect(@provider.exists?).to be_truthy
64+
@provider.create
65+
expect(File.read(@tmpfile).chomp).to eql("foo1\nfoo=blah\nfoo2\nfoo3")
66+
end
67+
68+
it 'should append the line if no matches are found' do
69+
File.open(@tmpfile, 'w') do |fh|
70+
fh.write("foo1\nfoo2")
71+
end
72+
expect(@provider.exists?).to be_nil
73+
@provider.create
74+
expect(File.read(@tmpfile).chomp).to eql("foo1\nfoo2\nfoo = bar")
75+
end
76+
77+
it 'should raise an error with invalid values' do
78+
expect {
79+
@resource = Puppet::Type::File_line.new(
80+
{
81+
:name => 'foo',
82+
:path => @tmpfile,
83+
:line => 'foo = bar',
84+
:match => '^foo\s*=.*$',
85+
:replace => 'asgadga',
86+
}
87+
)
88+
}.to raise_error(Puppet::Error, /Invalid value "asgadga"\. Valid values are true, false, yes, no\./)
89+
end
90+
end
4091
context "when matching" do
4192
before :each do
4293
# TODO: these should be ported over to use the PuppetLabs spec_helper

spec/unit/puppet/type/file_line_spec.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@
4949
it 'should default to ensure => present' do
5050
expect(file_line[:ensure]).to eq :present
5151
end
52+
it 'should default to replace => true' do
53+
expect(file_line[:replace]).to eq true
54+
end
5255

5356
it "should autorequire the file it manages" do
5457
catalog = Puppet::Resource::Catalog.new

0 commit comments

Comments
 (0)