|
@@ -0,0 +1,132 @@
|
|
|
|
+#
|
|
|
|
+# Author:: Nuo Yan (<nuo@opscode.com>)
|
|
|
|
+# Copyright:: Copyright (c) 2009 Opscode, Inc.
|
|
|
|
+# License:: Apache License, Version 2.0
|
|
|
|
+#
|
|
|
|
+# Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
+# you may not use this file except in compliance with the License.
|
|
|
|
+# You may obtain a copy of the License at
|
|
|
|
+#
|
|
|
|
+# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
+#
|
|
|
|
+# Unless required by applicable law or agreed to in writing, software
|
|
|
|
+# distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
+# See the License for the specific language governing permissions and
|
|
|
|
+# limitations under the License.
|
|
|
|
+
|
|
|
|
+require 'fileutils'
|
|
|
|
+require 'tempfile'
|
|
|
|
+
|
|
|
|
+class Chef
|
|
|
|
+ class Util
|
|
|
|
+ class FileEdit
|
|
|
|
+
|
|
|
|
+ private
|
|
|
|
+
|
|
|
|
+ attr_accessor :original_pathname, :contents, :file_edited
|
|
|
|
+
|
|
|
|
+ public
|
|
|
|
+
|
|
|
|
+ def initialize(filepath)
|
|
|
|
+ @original_pathname = filepath
|
|
|
|
+ @file_edited = false
|
|
|
|
+
|
|
|
|
+ raise ArgumentError, "File doesn't exist" unless File.exist? @original_pathname
|
|
|
|
+ raise ArgumentError, "File is blank" unless (@contents = File.new(@original_pathname).readlines).length > 0
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ #search the file line by line and match each line with the given regex
|
|
|
|
+ #if matched, replace the whole line with newline.
|
|
|
|
+ def search_file_replace_line(regex, newline)
|
|
|
|
+ search_match(regex, newline, 'r', 1)
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ #search the file line by line and match each line with the given regex
|
|
|
|
+ #if matched, replace the match (all occurances) with the replace parameter
|
|
|
|
+ def search_file_replace(regex, replace)
|
|
|
|
+ search_match(regex, replace, 'r', 2)
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ #search the file line by line and match each line with the given regex
|
|
|
|
+ #if matched, delete the line
|
|
|
|
+ def search_file_delete_line(regex)
|
|
|
|
+ search_match(regex, " ", 'd', 1)
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ #search the file line by line and match each line with the given regex
|
|
|
|
+ #if matched, delete the match (all occurances) from the line
|
|
|
|
+ def search_file_delete(regex)
|
|
|
|
+ search_match(regex, " ", 'd', 2)
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ #search the file line by line and match each line with the given regex
|
|
|
|
+ #if matched, insert newline after each matching line
|
|
|
|
+ def insert_line_after_match(regex, newline)
|
|
|
|
+ search_match(regex, newline, 'i', 1)
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ #search the file line by line and match each line with the given regex
|
|
|
|
+ #if not matched, insert newline at the end of the file
|
|
|
|
+ def insert_line_if_no_match(regex, newline)
|
|
|
|
+ search_match(regex, newline, 'i', 2)
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ #Make a copy of old_file and write new file out (only if file changed)
|
|
|
|
+ def write_file
|
|
|
|
+
|
|
|
|
+ # file_edited is false when there was no match in the whole file and thus no contents have changed.
|
|
|
|
+ if file_edited
|
|
|
|
+ backup_pathname = original_pathname + ".old"
|
|
|
|
+ FileUtils.cp(original_pathname, backup_pathname, :preserve => true)
|
|
|
|
+ File.open(original_pathname, "w") do |newfile|
|
|
|
|
+ contents.each do |line|
|
|
|
|
+ newfile.puts(line)
|
|
|
|
+ end
|
|
|
|
+ newfile.flush
|
|
|
|
+ end
|
|
|
|
+ end
|
|
|
|
+ self.file_edited = false
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ private
|
|
|
|
+
|
|
|
|
+ #helper method to do the match, replace, delete, and insert operations
|
|
|
|
+ #command is the switch of delete, replace, and insert ('d', 'r', 'i')
|
|
|
|
+ #method is to control operation on whole line or only the match (1 for line, 2 for match)
|
|
|
|
+ def search_match(regex, replace, command, method)
|
|
|
|
+
|
|
|
|
+ #convert regex to a Regexp object (if not already is one) and store it in exp.
|
|
|
|
+ exp = Regexp.new(regex)
|
|
|
|
+
|
|
|
|
+ #loop through contents and do the appropriate operation depending on 'command' and 'method'
|
|
|
|
+ new_contents = []
|
|
|
|
+
|
|
|
|
+ contents.each do |line|
|
|
|
|
+ if line.match(exp)
|
|
|
|
+ self.file_edited = true
|
|
|
|
+ case
|
|
|
|
+ when command == 'r'
|
|
|
|
+ new_contents << ((method == 1) ? replace : line.gsub!(exp, replace))
|
|
|
|
+ when command == 'd'
|
|
|
|
+ if method == 2
|
|
|
|
+ new_contents << line.gsub!(exp, "")
|
|
|
|
+ end
|
|
|
|
+ when command == 'i'
|
|
|
|
+ new_contents << line
|
|
|
|
+ new_contents << replace unless method == 2
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ new_contents << line
|
|
|
|
+ end
|
|
|
|
+ end
|
|
|
|
+ if command == 'i' && method == 2 && ! file_edited
|
|
|
|
+ new_contents << replace
|
|
|
|
+ self.file_edited = true
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ self.contents = new_contents
|
|
|
|
+ end
|
|
|
|
+ end
|
|
|
|
+ end
|
|
|
|
+end
|