Skip to content

Commit aed6222

Browse files
Christopher BrownNuo Yan
authored andcommitted
review for chef-78
1 parent 7f8a1d6 commit aed6222

3 files changed

Lines changed: 50 additions & 35 deletions

File tree

chef/lib/chef/util/FileEdit.rb

Lines changed: 41 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
1-
class FileEdit
1+
require 'ftools'
2+
require 'fileutils'
3+
require 'tempfile'
24

3-
require 'ftools'
5+
class FileEdit
46

57
private
6-
attr_accessor :filename, :contents, :match
8+
9+
attr_accessor :original_pathname, :contents, :file_edited
710

811
public
912

1013
def initialize(filepath)
11-
@filename = filepath
12-
@match = false
13-
14-
raise ArgumentError, "File doesn't exist" unless File.exist? @filename
15-
raise ArgumentError, "File is blank" unless (@contents = File.new(@filename).readlines).length > 0
14+
@original_pathname = filepath
15+
@file_edited = false
1616

17+
raise ArgumentError, "File doesn't exist" unless File.exist? @original_pathname
18+
raise ArgumentError, "File is blank" unless (@contents = File.new(@original_pathname).readlines).length > 0
1719
end
1820

1921
#search the file line by line and match each line with the given regex
@@ -48,17 +50,21 @@ def insert_line_after_match(regex, newline)
4850

4951
#Make a copy of old_file and write new file out (only if file changed)
5052
def write_file
51-
# @match is false when there is no match in the whole file. Nothing need to be done.
52-
if @match == true
53-
File.copy(@filename, @filename + ".old")
54-
newfile = File.new("temp", "w")
55-
@contents.each() do |line|
56-
newfile.puts(line)
53+
54+
# file_edited is false when there was no match in the whole file and thus no contents have changed.
55+
if file_edited
56+
backup_pathname = original_pathname + ".old"
57+
File.copy(original_pathname, backup_pathname)
58+
Tempfile.open("w") do |newfile|
59+
contents.each do |line|
60+
newfile.puts(line)
61+
end
62+
newfile.flush
63+
FileUtils.mv(newfile.path, original_pathname)
5764
end
58-
newfile.close
59-
File.rename("temp", @filename)
6065
end
61-
@match = false
66+
self.file_edited = false
67+
6268
end
6369

6470
private
@@ -67,39 +73,39 @@ def write_file
6773
#command is the switch of delete, replace, and insert ('d', 'r', 'i')
6874
#method is to control operation on whole line or only the match (1 for line, 2 for match)
6975
def search_match(regex, replace, command, method)
70-
76+
7177
#check if regex is Regexp object or simple string and store the Regexp object in exp.
72-
(regex.kind_of? Regexp)? exp = regex : exp = Regexp.new(regex)
78+
exp = (regex.respond_to?(:gsub!) ? regex : Regexp.new(regex.to_s))
7379

74-
#loop through @contents and do the appropriate operation depending on 'command' and 'method'
75-
i = 0
76-
begin
77-
line = @contents[i]
78-
if line =~ exp
79-
@match = true
80+
#loop through contents and do the appropriate operation depending on 'command' and 'method'
81+
new_contents = []
82+
83+
contents.each do |line|
84+
if exp.match(line) # =~ exp
85+
self.file_edited = true
8086
case
8187
when command == 'r'
82-
(method == 1)? @contents[i] = replace: @contents[i].gsub!(exp, replace)
88+
new_contents << ((method == 1) ? replace : line.gsub!(exp, replace))
8389
when command == 'd'
84-
if method == 1
85-
@contents.delete_at(i)
86-
i = i - 1
87-
else
88-
@contents[i].gsub!(exp, "")
90+
if method == 2
91+
new_contents << line.gsub!(exp, "")
8992
end
9093
when command == 'i'
91-
@contents.insert(i+1, replace)
94+
new_contents << line
95+
new_contents << replace
9296
end
97+
else
98+
new_contents << line
9399
end
94-
i = i+1
95-
end until i == @contents.length
100+
end
101+
102+
self.contents = new_contents
96103
end
97104
end
98105

99106
#test
100107
if __FILE__ == $0
101108
fedit = FileEdit.new("test")
102-
103109
fedit.insert_line_after_match(/test/, "new Line Inserted")
104110
fedit.search_file_replace(/test/, "replace")
105111
fedit.search_file_replace_line(/replace/, "this line is replaced")

chef/lib/chef/util/test

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#content starts here
2+
line is replaced
3+
line is replaced
4+
#content ends here

chef/lib/chef/util/test.backup

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#content starts here
2+
test
3+
this is a test
4+
new line here
5+
#content ends here

0 commit comments

Comments
 (0)