rcli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. data/LICENSE +20 -0
  2. data/README.md +193 -0
  3. data/README.rdoc +194 -0
  4. data/Rakefile +61 -0
  5. data/bin/rcli +12 -0
  6. data/lib/commands/compile.rb +15 -0
  7. data/lib/commands/debug.rb +86 -0
  8. data/lib/commands/edit.rb +34 -0
  9. data/lib/commands/generate.rb +43 -0
  10. data/lib/commands/help.rb +47 -0
  11. data/lib/commands/install.rb +86 -0
  12. data/lib/commands/list.rb +28 -0
  13. data/lib/commands/uninstall.rb +36 -0
  14. data/lib/commands/version.rb +11 -0
  15. data/lib/core/actions/create_file.rb +106 -0
  16. data/lib/core/actions/empty_directory.rb +88 -0
  17. data/lib/core/actions/file_binary_read.rb +9 -0
  18. data/lib/core/actions.rb +9 -0
  19. data/lib/core/command.rb +137 -0
  20. data/lib/core/commander.rb +48 -0
  21. data/lib/core/console.rb +5 -0
  22. data/lib/core/global_functions.rb +16 -0
  23. data/lib/core/shared/rcli_installation.rb +9 -0
  24. data/lib/core/thor_actions/create_file.rb +100 -0
  25. data/lib/core/thor_actions/directory.rb +89 -0
  26. data/lib/core/thor_actions/empty_directory.rb +134 -0
  27. data/lib/core/thor_actions/file_binary_read.rb +9 -0
  28. data/lib/core/thor_actions/file_manipulation.rb +223 -0
  29. data/lib/core/thor_actions/inject_into_file.rb +102 -0
  30. data/lib/core/thor_actions.rb +302 -0
  31. data/lib/core/traceable_factory.rb +20 -0
  32. data/lib/core/traceable_object.rb +45 -0
  33. data/lib/core/tracer.rb +23 -0
  34. data/lib/rcli.rb +65 -0
  35. data/lib/templates/new_app/RCLIAPPNAME.rb +9 -0
  36. data/lib/templates/new_app/lib/commands/default.rb +12 -0
  37. data/lib/templates/new_app/lib/commands/version.rb +6 -0
  38. data/lib/vendor/mainline/lib/trollop.rb +782 -0
  39. data/lib/vendor/mainline/test/test_trollop.rb +1094 -0
  40. data/lib/vendor/trollop.rb +782 -0
  41. data/test/helper.rb +10 -0
  42. data/test/test_rcli-gem.rb +7 -0
  43. metadata +137 -0
@@ -0,0 +1,100 @@
1
+ class Rcli
2
+ module Actions
3
+
4
+ # Create a new file relative to the destination root with the given data,
5
+ # which is the return value of a block or a data string.
6
+ #
7
+ # ==== Parameters
8
+ # destination<String>:: the relative path to the destination root.
9
+ # data<String|NilClass>:: the data to append to the file.
10
+ # config<Hash>:: give :verbose => false to not log the status.
11
+ #
12
+ # ==== Examples
13
+ #
14
+ # create_file "lib/fun_party.rb" do
15
+ # hostname = ask("What is the virtual hostname I should use?")
16
+ # "vhost.name = #{hostname}"
17
+ # end
18
+ #
19
+ # create_file "config/apach.conf", "your apache config"
20
+ #
21
+ def create_file(destination, data=nil, config={}, &block)
22
+ action CreateFile.new(self, destination, block || data.to_s, config)
23
+ end
24
+ alias :add_file :create_file
25
+
26
+ # AddFile is a subset of Template, which instead of rendering a file with
27
+ # ERB, it gets the content from the user.
28
+ #
29
+ class CreateFile < EmptyDirectory #:nodoc:
30
+ attr_reader :data
31
+
32
+ def initialize(base, destination, data, config={})
33
+ @data = data
34
+ super(base, destination, config)
35
+ end
36
+
37
+ # Checks if the content of the file at the destination is identical to the rendered result.
38
+ #
39
+ # ==== Returns
40
+ # Boolean:: true if it is identical, false otherwise.
41
+ #
42
+ def identical?
43
+ exists? && File.binread(destination) == render
44
+ end
45
+
46
+ # Holds the content to be added to the file.
47
+ #
48
+ def render
49
+ @render ||= if data.is_a?(Proc)
50
+ data.call
51
+ else
52
+ data
53
+ end
54
+ end
55
+
56
+ def invoke!
57
+ invoke_with_conflict_check do
58
+ FileUtils.mkdir_p(File.dirname(destination))
59
+ File.open(destination, 'wb') { |f| f.write render }
60
+ end
61
+ end
62
+
63
+ protected
64
+
65
+ # Now on conflict we check if the file is identical or not.
66
+ #
67
+ def on_conflict_behavior(&block)
68
+ if identical?
69
+ say_status :identical, :blue
70
+ else
71
+ options = base.options.merge(config)
72
+ force_or_skip_or_conflict(options[:force], options[:skip], &block)
73
+ end
74
+ end
75
+
76
+ # If force is true, run the action, otherwise check if it's not being
77
+ # skipped. If both are false, show the file_collision menu, if the menu
78
+ # returns true, force it, otherwise skip.
79
+ #
80
+ def force_or_skip_or_conflict(force, skip, &block)
81
+ if force
82
+ say_status :force, :yellow
83
+ block.call unless pretend?
84
+ elsif skip
85
+ say_status :skip, :yellow
86
+ else
87
+ say_status :conflict, :red
88
+ force_or_skip_or_conflict(force_on_collision?, true, &block)
89
+ end
90
+ end
91
+
92
+ # Shows the file collision menu to the user and gets the result.
93
+ #
94
+ def force_on_collision?
95
+ base.shell.file_collision(destination){ render }
96
+ end
97
+
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,89 @@
1
+ class Rcli
2
+ module Actions
3
+
4
+ # Copies recursively the files from source directory to root directory.
5
+ # If any of the files finishes with .tt, it's considered to be a template
6
+ # and is placed in the destination without the extension .tt. If any
7
+ # empty directory is found, it's copied and all .empty_directory files are
8
+ # ignored. Remember that file paths can also be encoded, let's suppose a doc
9
+ # directory with the following files:
10
+ #
11
+ # doc/
12
+ # components/.empty_directory
13
+ # README
14
+ # rdoc.rb.tt
15
+ # %app_name%.rb
16
+ #
17
+ # When invoked as:
18
+ #
19
+ # directory "doc"
20
+ #
21
+ # It will create a doc directory in the destination with the following
22
+ # files (assuming that the app_name is "blog"):
23
+ #
24
+ # doc/
25
+ # components/
26
+ # README
27
+ # rdoc.rb
28
+ # blog.rb
29
+ #
30
+ # ==== Parameters
31
+ # source<String>:: the relative path to the source root.
32
+ # destination<String>:: the relative path to the destination root.
33
+ # config<Hash>:: give :verbose => false to not log the status.
34
+ # If :recursive => false, does not look for paths recursively.
35
+ #
36
+ # ==== Examples
37
+ #
38
+ # directory "doc"
39
+ # directory "doc", "docs", :recursive => false
40
+ #
41
+ def directory(source, destination=nil, config={}, &block)
42
+ action Directory.new(self, source, destination || source, config, &block)
43
+ end
44
+
45
+ class Directory < EmptyDirectory #:nodoc:
46
+ attr_reader :source
47
+
48
+ def initialize(base, source, destination=nil, config={}, &block)
49
+ @source = File.expand_path(base.find_in_source_paths(source.to_s))
50
+ @block = block
51
+ super(base, destination, { :recursive => true }.merge(config))
52
+ end
53
+
54
+ def invoke!
55
+ base.empty_directory given_destination, config
56
+ execute!
57
+ end
58
+
59
+ def revoke!
60
+ execute!
61
+ end
62
+
63
+ protected
64
+
65
+ def execute!
66
+ lookup = config[:recursive] ? File.join(source, '**') : source
67
+ lookup = File.join(lookup, '{*,.[a-z]*}')
68
+
69
+ Dir[lookup].each do |file_source|
70
+ next if File.directory?(file_source)
71
+ file_destination = File.join(given_destination, file_source.gsub(source, '.'))
72
+ file_destination.gsub!('/./', '/')
73
+
74
+ case file_source
75
+ when /\.empty_directory$/
76
+ dirname = File.dirname(file_destination).gsub(/\/\.$/, '')
77
+ next if dirname == given_destination
78
+ base.empty_directory(dirname, config)
79
+ when /\.tt$/
80
+ destination = base.template(file_source, file_destination[0..-4], config, &@block)
81
+ else
82
+ destination = base.copy_file(file_source, file_destination, config, &@block)
83
+ end
84
+ end
85
+ end
86
+
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,134 @@
1
+ class Rcli
2
+ module Actions
3
+
4
+ # Creates an empty directory.
5
+ #
6
+ # ==== Parameters
7
+ # destination<String>:: the relative path to the destination root.
8
+ # config<Hash>:: give :verbose => false to not log the status.
9
+ #
10
+ # ==== Examples
11
+ #
12
+ # empty_directory "doc"
13
+ #
14
+ def empty_directory(destination, config={})
15
+ action EmptyDirectory.new(self, destination, config)
16
+ end
17
+
18
+ # Class which holds create directory logic. This is the base class for
19
+ # other actions like create_file and directory.
20
+ #
21
+ # This implementation is based in Templater actions, created by Jonas Nicklas
22
+ # and Michael S. Klishin under MIT LICENSE.
23
+ #
24
+ class EmptyDirectory #:nodoc:
25
+ attr_reader :base, :destination, :given_destination, :relative_destination, :config
26
+
27
+ # Initializes given the source and destination.
28
+ #
29
+ # ==== Parameters
30
+ # base<Thor::Base>:: A Thor::Base instance
31
+ # source<String>:: Relative path to the source of this file
32
+ # destination<String>:: Relative path to the destination of this file
33
+ # config<Hash>:: give :verbose => false to not log the status.
34
+ #
35
+ def initialize(base, destination, config={})
36
+ @base, @config = base, { :verbose => true }.merge(config)
37
+ self.destination = destination
38
+ end
39
+
40
+ # Checks if the destination file already exists.
41
+ #
42
+ # ==== Returns
43
+ # Boolean:: true if the file exists, false otherwise.
44
+ #
45
+ def exists?
46
+ ::File.exists?(destination)
47
+ end
48
+
49
+ def invoke!
50
+ invoke_with_conflict_check do
51
+ ::FileUtils.mkdir_p(destination)
52
+ end
53
+ end
54
+
55
+ def revoke!
56
+ say_status :remove, :red
57
+ ::FileUtils.rm_rf(destination) if !pretend? && exists?
58
+ given_destination
59
+ end
60
+
61
+ protected
62
+
63
+ # Shortcut for pretend.
64
+ #
65
+ def pretend?
66
+ base.options[:pretend]
67
+ end
68
+
69
+ # Sets the absolute destination value from a relative destination value.
70
+ # It also stores the given and relative destination. Let's suppose our
71
+ # script is being executed on "dest", it sets the destination root to
72
+ # "dest". The destination, given_destination and relative_destination
73
+ # are related in the following way:
74
+ #
75
+ # inside "bar" do
76
+ # empty_directory "baz"
77
+ # end
78
+ #
79
+ # destination #=> dest/bar/baz
80
+ # relative_destination #=> bar/baz
81
+ # given_destination #=> baz
82
+ #
83
+ def destination=(destination)
84
+ if destination
85
+ @given_destination = convert_encoded_instructions(destination.to_s)
86
+ @destination = ::File.expand_path(@given_destination, base.destination_root)
87
+ @relative_destination = base.relative_to_original_destination_root(@destination)
88
+ end
89
+ end
90
+
91
+ # Filenames in the encoded form are converted. If you have a file:
92
+ #
93
+ # %class_name%.rb
94
+ #
95
+ # It gets the class name from the base and replace it:
96
+ #
97
+ # user.rb
98
+ #
99
+ def convert_encoded_instructions(filename)
100
+ filename.gsub(/%(.*?)%/) do |string|
101
+ instruction = $1.strip
102
+ base.respond_to?(instruction) ? base.send(instruction) : string
103
+ end
104
+ end
105
+
106
+ # Receives a hash of options and just execute the block if some
107
+ # conditions are met.
108
+ #
109
+ def invoke_with_conflict_check(&block)
110
+ if exists?
111
+ on_conflict_behavior(&block)
112
+ else
113
+ say_status :create, :green
114
+ block.call unless pretend?
115
+ end
116
+
117
+ destination
118
+ end
119
+
120
+ # What to do when the destination file already exists.
121
+ #
122
+ def on_conflict_behavior(&block)
123
+ say_status :exist, :blue
124
+ end
125
+
126
+ # Shortcut to say_status shell method.
127
+ #
128
+ def say_status(status, color)
129
+ base.shell.say_status status, relative_destination, color if config[:verbose]
130
+ end
131
+
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,9 @@
1
+ class File #:nodoc:
2
+
3
+ unless File.respond_to?(:binread)
4
+ def self.binread(file)
5
+ File.open(file, 'rb') { |f| f.read }
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,223 @@
1
+ require 'erb'
2
+ require 'open-uri'
3
+
4
+ class Rcli
5
+ module Actions
6
+
7
+ # Copies the file from the relative source to the relative destination. If
8
+ # the destination is not given it's assumed to be equal to the source.
9
+ #
10
+ # ==== Parameters
11
+ # source<String>:: the relative path to the source root.
12
+ # destination<String>:: the relative path to the destination root.
13
+ # config<Hash>:: give :verbose => false to not log the status.
14
+ #
15
+ # ==== Examples
16
+ #
17
+ # copy_file "README", "doc/README"
18
+ #
19
+ # copy_file "doc/README"
20
+ #
21
+ def copy_file(source, destination=nil, config={}, &block)
22
+ destination ||= source
23
+ source = File.expand_path(find_in_source_paths(source.to_s))
24
+
25
+ create_file destination, nil, config do
26
+ content = File.binread(source)
27
+ content = block.call(content) if block
28
+ content
29
+ end
30
+ end
31
+
32
+ # Gets the content at the given address and places it at the given relative
33
+ # destination. If a block is given instead of destination, the content of
34
+ # the url is yielded and used as location.
35
+ #
36
+ # ==== Parameters
37
+ # source<String>:: the address of the given content.
38
+ # destination<String>:: the relative path to the destination root.
39
+ # config<Hash>:: give :verbose => false to not log the status.
40
+ #
41
+ # ==== Examples
42
+ #
43
+ # get "http://gist.github.com/103208", "doc/README"
44
+ #
45
+ # get "http://gist.github.com/103208" do |content|
46
+ # content.split("\n").first
47
+ # end
48
+ #
49
+ def get(source, destination=nil, config={}, &block)
50
+ source = File.expand_path(find_in_source_paths(source.to_s)) unless source =~ /^http\:\/\//
51
+ render = open(source) {|input| input.binmode.read }
52
+
53
+ destination ||= if block_given?
54
+ block.arity == 1 ? block.call(render) : block.call
55
+ else
56
+ File.basename(source)
57
+ end
58
+
59
+ create_file destination, render, config
60
+ end
61
+
62
+ # Gets an ERB template at the relative source, executes it and makes a copy
63
+ # at the relative destination. If the destination is not given it's assumed
64
+ # to be equal to the source removing .tt from the filename.
65
+ #
66
+ # ==== Parameters
67
+ # source<String>:: the relative path to the source root.
68
+ # destination<String>:: the relative path to the destination root.
69
+ # config<Hash>:: give :verbose => false to not log the status.
70
+ #
71
+ # ==== Examples
72
+ #
73
+ # template "README", "doc/README"
74
+ #
75
+ # template "doc/README"
76
+ #
77
+ def template(source, destination=nil, config={}, &block)
78
+ destination ||= source
79
+ source = File.expand_path(find_in_source_paths(source.to_s))
80
+ context = instance_eval('binding')
81
+
82
+ create_file destination, nil, config do
83
+ content = ERB.new(::File.binread(source), nil, '-').result(context)
84
+ content = block.call(content) if block
85
+ content
86
+ end
87
+ end
88
+
89
+ # Changes the mode of the given file or directory.
90
+ #
91
+ # ==== Parameters
92
+ # mode<Integer>:: the file mode
93
+ # path<String>:: the name of the file to change mode
94
+ # config<Hash>:: give :verbose => false to not log the status.
95
+ #
96
+ # ==== Example
97
+ #
98
+ # chmod "script/*", 0755
99
+ #
100
+ def chmod(path, mode, config={})
101
+ return unless behavior == :invoke
102
+ path = File.expand_path(path, destination_root)
103
+ say_status :chmod, relative_to_original_destination_root(path), config.fetch(:verbose, true)
104
+ FileUtils.chmod_R(mode, path) unless options[:pretend]
105
+ end
106
+
107
+ # Prepend text to a file. Since it depends on inject_into_file, it's reversible.
108
+ #
109
+ # ==== Parameters
110
+ # path<String>:: path of the file to be changed
111
+ # data<String>:: the data to prepend to the file, can be also given as a block.
112
+ # config<Hash>:: give :verbose => false to not log the status.
113
+ #
114
+ # ==== Example
115
+ #
116
+ # prepend_file 'config/environments/test.rb', 'config.gem "rspec"'
117
+ #
118
+ # prepend_file 'config/environments/test.rb' do
119
+ # 'config.gem "rspec"'
120
+ # end
121
+ #
122
+ def prepend_file(path, *args, &block)
123
+ config = args.last.is_a?(Hash) ? args.pop : {}
124
+ config.merge!(:after => /\A/)
125
+ inject_into_file(path, *(args << config), &block)
126
+ end
127
+
128
+ # Append text to a file. Since it depends on inject_into_file, it's reversible.
129
+ #
130
+ # ==== Parameters
131
+ # path<String>:: path of the file to be changed
132
+ # data<String>:: the data to append to the file, can be also given as a block.
133
+ # config<Hash>:: give :verbose => false to not log the status.
134
+ #
135
+ # ==== Example
136
+ #
137
+ # append_file 'config/environments/test.rb', 'config.gem "rspec"'
138
+ #
139
+ # append_file 'config/environments/test.rb' do
140
+ # 'config.gem "rspec"'
141
+ # end
142
+ #
143
+ def append_file(path, *args, &block)
144
+ config = args.last.is_a?(Hash) ? args.pop : {}
145
+ config.merge!(:before => /\z/)
146
+ inject_into_file(path, *(args << config), &block)
147
+ end
148
+
149
+ # Injects text right after the class definition. Since it depends on
150
+ # inject_into_file, it's reversible.
151
+ #
152
+ # ==== Parameters
153
+ # path<String>:: path of the file to be changed
154
+ # klass<String|Class>:: the class to be manipulated
155
+ # data<String>:: the data to append to the class, can be also given as a block.
156
+ # config<Hash>:: give :verbose => false to not log the status.
157
+ #
158
+ # ==== Examples
159
+ #
160
+ # inject_into_class "app/controllers/application_controller.rb", " filter_parameter :password\n"
161
+ #
162
+ # inject_into_class "app/controllers/application_controller.rb", ApplicationController do
163
+ # " filter_parameter :password\n"
164
+ # end
165
+ #
166
+ def inject_into_class(path, klass, *args, &block)
167
+ config = args.last.is_a?(Hash) ? args.pop : {}
168
+ config.merge!(:after => /class #{klass}\n|class #{klass} .*\n/)
169
+ inject_into_file(path, *(args << config), &block)
170
+ end
171
+
172
+ # Run a regular expression replacement on a file.
173
+ #
174
+ # ==== Parameters
175
+ # path<String>:: path of the file to be changed
176
+ # flag<Regexp|String>:: the regexp or string to be replaced
177
+ # replacement<String>:: the replacement, can be also given as a block
178
+ # config<Hash>:: give :verbose => false to not log the status.
179
+ #
180
+ # ==== Example
181
+ #
182
+ # gsub_file 'app/controllers/application_controller.rb', /#\s*(filter_parameter_logging :password)/, '\1'
183
+ #
184
+ # gsub_file 'README', /rake/, :green do |match|
185
+ # match << " no more. Use thor!"
186
+ # end
187
+ #
188
+ def gsub_file(path, flag, *args, &block)
189
+ return unless behavior == :invoke
190
+ config = args.last.is_a?(Hash) ? args.pop : {}
191
+
192
+ path = File.expand_path(path, destination_root)
193
+ say_status :gsub, relative_to_original_destination_root(path), config.fetch(:verbose, true)
194
+
195
+ unless options[:pretend]
196
+ content = File.binread(path)
197
+ content.gsub!(flag, *args, &block)
198
+ File.open(path, 'wb') { |file| file.write(content) }
199
+ end
200
+ end
201
+
202
+ # Removes a file at the given location.
203
+ #
204
+ # ==== Parameters
205
+ # path<String>:: path of the file to be changed
206
+ # config<Hash>:: give :verbose => false to not log the status.
207
+ #
208
+ # ==== Example
209
+ #
210
+ # remove_file 'README'
211
+ # remove_file 'app/controllers/application_controller.rb'
212
+ #
213
+ def remove_file(path, config={})
214
+ return unless behavior == :invoke
215
+ path = File.expand_path(path, destination_root)
216
+
217
+ say_status :remove, relative_to_original_destination_root(path), config.fetch(:verbose, true)
218
+ ::FileUtils.rm_rf(path) if !options[:pretend] && File.exists?(path)
219
+ end
220
+ alias :remove_dir :remove_file
221
+
222
+ end
223
+ end
@@ -0,0 +1,102 @@
1
+ class Rcli
2
+ module Actions
3
+
4
+ # Injects the given content into a file. Different from gsub_file, this
5
+ # method is reversible.
6
+ #
7
+ # ==== Parameters
8
+ # destination<String>:: Relative path to the destination root
9
+ # data<String>:: Data to add to the file. Can be given as a block.
10
+ # config<Hash>:: give :verbose => false to not log the status and the flag
11
+ # for injection (:after or :before) or :force => true for
12
+ # insert two or more times the same content.
13
+ #
14
+ # ==== Examples
15
+ #
16
+ # inject_into_file "config/environment.rb", "config.gem :thor", :after => "Rails::Initializer.run do |config|\n"
17
+ #
18
+ # inject_into_file "config/environment.rb", :after => "Rails::Initializer.run do |config|\n" do
19
+ # gems = ask "Which gems would you like to add?"
20
+ # gems.split(" ").map{ |gem| " config.gem :#{gem}" }.join("\n")
21
+ # end
22
+ #
23
+ def inject_into_file(destination, *args, &block)
24
+ if block_given?
25
+ data, config = block, args.shift
26
+ else
27
+ data, config = args.shift, args.shift
28
+ end
29
+ action InjectIntoFile.new(self, destination, data, config)
30
+ end
31
+
32
+ class InjectIntoFile < EmptyDirectory #:nodoc:
33
+ attr_reader :replacement, :flag, :behavior
34
+
35
+ def initialize(base, destination, data, config)
36
+ super(base, destination, { :verbose => true }.merge(config))
37
+
38
+ @behavior, @flag = if @config.key?(:after)
39
+ [:after, @config.delete(:after)]
40
+ else
41
+ [:before, @config.delete(:before)]
42
+ end
43
+
44
+ @replacement = data.is_a?(Proc) ? data.call : data
45
+ @flag = Regexp.escape(@flag) unless @flag.is_a?(Regexp)
46
+ end
47
+
48
+ def invoke!
49
+ say_status :invoke
50
+
51
+ content = if @behavior == :after
52
+ '\0' + replacement
53
+ else
54
+ replacement + '\0'
55
+ end
56
+
57
+ replace!(/#{flag}/, content, config[:force])
58
+ end
59
+
60
+ def revoke!
61
+ say_status :revoke
62
+
63
+ regexp = if @behavior == :after
64
+ content = '\1\2'
65
+ /(#{flag})(.*)(#{Regexp.escape(replacement)})/m
66
+ else
67
+ content = '\2\3'
68
+ /(#{Regexp.escape(replacement)})(.*)(#{flag})/m
69
+ end
70
+
71
+ replace!(regexp, content, true)
72
+ end
73
+
74
+ protected
75
+
76
+ def say_status(behavior)
77
+ status = if flag == /\A/
78
+ behavior == :invoke ? :prepend : :unprepend
79
+ elsif flag == /\z/
80
+ behavior == :invoke ? :append : :unappend
81
+ else
82
+ behavior == :invoke ? :inject : :deinject
83
+ end
84
+
85
+ super(status, config[:verbose])
86
+ end
87
+
88
+ # Adds the content to the file.
89
+ #
90
+ def replace!(regexp, string, force)
91
+ unless base.options[:pretend]
92
+ content = File.binread(destination)
93
+ if force || !content.include?(replacement)
94
+ content.gsub!(regexp, string)
95
+ File.open(destination, 'wb') { |file| file.write(content) }
96
+ end
97
+ end
98
+ end
99
+
100
+ end
101
+ end
102
+ end