Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,26 @@ Or with a regex:
with "vm.swappiness=60"
end


replace_line_or_add
------------

Search the file line by line and match each line with the given regex if matched, replace the whole line with the replace parameter.
If no match is found, add entry like the append_line resource

replace_line_or_add "/etc/sysctl.conf" do
replace "vm.swappiness"
with "vm.swappiness=60"
end

Or with a regex:

replace_line_or_add "/etc/sysctl.conf" do
replace /.*vm.swappiness.*/
with "vm.swappiness=60"
end


append_line
-----------

Expand Down
4 changes: 4 additions & 0 deletions libraries/matchers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,8 @@ def run_replace(resource_name)
def run_replace_line(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:replace_line, :run, resource_name)
end

def run_replace_line_or_add(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:replace_line_or_add, :run, resource_name)
end
end
Empty file removed recipes/default.rb
Empty file.
59 changes: 59 additions & 0 deletions resources/replace_line_or_add.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
resource_name 'replace_line_or_add'
actions :run
default_action :run

property :name, :name_property => true, :kind_of => String, :required => true
property :file, :kind_of => String
property :path, :kind_of => String
property :replace, :kind_of => [String, Regexp], :required => true
property :with, :kind_of => String, :required => true

action :run do

file_path = file || path || name

# Check if we got a regex or a string
if replace.is_a?(Regexp)
regex = replace
else
regex = Regexp.new(Regexp.escape(replace))
end

# Check if file matches the regex
if ::File.read(file_path) =~ regex
# Calculate file hash before changes
before = Digest::SHA256.file(file_path).hexdigest

# Do changes
file = Chef::Util::FileEdit.new(file_path)
file.search_file_replace_line(regex, with)
file.write_file

# Notify file changes
if Digest::SHA256.file(file_path).hexdigest != before
Chef::Log.info "- #{replace}"
Chef::Log.info "+ #{with}"
updated_by_last_action(true)
end

else
regex = /^#{Regexp.escape(with)}$/
# Calculate file hash before changes
before = Digest::SHA256.file(file_path).hexdigest

# Do changes
file = Chef::Util::FileEdit.new(file_path)
file.insert_line_if_no_match(regex, with)
file.write_file

# Notify file changes
if Digest::SHA256.file(file_path).hexdigest != before
Chef::Log.info "- #{replace}"
Chef::Log.info "+ #{with}"
updated_by_last_action(true)
end

# Remove backup file
::File.delete(file_path + ".old") if ::File.exist?(file_path + ".old")
end
end