engineyard-serverside 2.0.0 → 2.0.1

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 (36) hide show
  1. data/lib/engineyard-serverside/paths.rb +0 -1
  2. data/lib/engineyard-serverside/version.rb +1 -1
  3. data/lib/vendor/thor/{LICENSE → LICENSE.md} +2 -2
  4. data/lib/vendor/thor/README.md +28 -0
  5. data/lib/vendor/thor/lib/thor.rb +183 -48
  6. data/lib/vendor/thor/lib/thor/actions.rb +66 -23
  7. data/lib/vendor/thor/lib/thor/actions/create_file.rb +5 -3
  8. data/lib/vendor/thor/lib/thor/actions/create_link.rb +57 -0
  9. data/lib/vendor/thor/lib/thor/actions/directory.rb +14 -7
  10. data/lib/vendor/thor/lib/thor/actions/empty_directory.rb +24 -5
  11. data/lib/vendor/thor/lib/thor/actions/file_manipulation.rb +106 -21
  12. data/lib/vendor/thor/lib/thor/actions/inject_into_file.rb +15 -10
  13. data/lib/vendor/thor/lib/thor/base.rb +144 -43
  14. data/lib/vendor/thor/lib/thor/core_ext/dir_escape.rb +0 -0
  15. data/lib/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +1 -1
  16. data/lib/vendor/thor/lib/thor/error.rb +6 -1
  17. data/lib/vendor/thor/lib/thor/group.rb +41 -27
  18. data/lib/vendor/thor/lib/thor/invocation.rb +48 -58
  19. data/lib/vendor/thor/lib/thor/parser/argument.rb +29 -22
  20. data/lib/vendor/thor/lib/thor/parser/arguments.rb +26 -5
  21. data/lib/vendor/thor/lib/thor/parser/option.rb +42 -49
  22. data/lib/vendor/thor/lib/thor/parser/options.rb +39 -30
  23. data/lib/vendor/thor/lib/thor/rake_compat.rb +13 -8
  24. data/lib/vendor/thor/lib/thor/runner.rb +27 -20
  25. data/lib/vendor/thor/lib/thor/shell.rb +10 -5
  26. data/lib/vendor/thor/lib/thor/shell/basic.rb +228 -78
  27. data/lib/vendor/thor/lib/thor/shell/color.rb +40 -4
  28. data/lib/vendor/thor/lib/thor/shell/html.rb +123 -0
  29. data/lib/vendor/thor/lib/thor/task.rb +83 -53
  30. data/lib/vendor/thor/lib/thor/util.rb +57 -21
  31. data/lib/vendor/thor/lib/thor/version.rb +1 -1
  32. data/lib/vendor/thor/thor.gemspec +21 -115
  33. metadata +109 -217
  34. data/lib/vendor/thor/CHANGELOG.rdoc +0 -89
  35. data/lib/vendor/thor/README.rdoc +0 -297
  36. data/lib/vendor/thor/Thorfile +0 -69
@@ -18,14 +18,16 @@ class Thor
18
18
  # "vhost.name = #{hostname}"
19
19
  # end
20
20
  #
21
- # create_file "config/apach.conf", "your apache config"
21
+ # create_file "config/apache.conf", "your apache config"
22
22
  #
23
- def create_file(destination, data=nil, config={}, &block)
23
+ def create_file(destination, *args, &block)
24
+ config = args.last.is_a?(Hash) ? args.pop : {}
25
+ data = args.first
24
26
  action CreateFile.new(self, destination, block || data.to_s, config)
25
27
  end
26
28
  alias :add_file :create_file
27
29
 
28
- # AddFile is a subset of Template, which instead of rendering a file with
30
+ # CreateFile is a subset of Template, which instead of rendering a file with
29
31
  # ERB, it gets the content from the user.
30
32
  #
31
33
  class CreateFile < EmptyDirectory #:nodoc:
@@ -0,0 +1,57 @@
1
+ require 'thor/actions/create_file'
2
+
3
+ class Thor
4
+ module Actions
5
+
6
+ # Create a new file relative to the destination root from the given source.
7
+ #
8
+ # ==== Parameters
9
+ # destination<String>:: the relative path to the destination root.
10
+ # source<String|NilClass>:: the relative path to the source root.
11
+ # config<Hash>:: give :verbose => false to not log the status.
12
+ # :: give :symbolic => false for hard link.
13
+ #
14
+ # ==== Examples
15
+ #
16
+ # create_link "config/apache.conf", "/etc/apache.conf"
17
+ #
18
+ def create_link(destination, *args, &block)
19
+ config = args.last.is_a?(Hash) ? args.pop : {}
20
+ source = args.first
21
+ action CreateLink.new(self, destination, source, config)
22
+ end
23
+ alias :add_link :create_link
24
+
25
+ # CreateLink is a subset of CreateFile, which instead of taking a block of
26
+ # data, just takes a source string from the user.
27
+ #
28
+ class CreateLink < CreateFile #:nodoc:
29
+ attr_reader :data
30
+
31
+ # Checks if the content of the file at the destination is identical to the rendered result.
32
+ #
33
+ # ==== Returns
34
+ # Boolean:: true if it is identical, false otherwise.
35
+ #
36
+ def identical?
37
+ exists? && File.identical?(render, destination)
38
+ end
39
+
40
+ def invoke!
41
+ invoke_with_conflict_check do
42
+ FileUtils.mkdir_p(File.dirname(destination))
43
+ # Create a symlink by default
44
+ config[:symbolic] = true if config[:symbolic].nil?
45
+ File.unlink(destination) if exists?
46
+ if config[:symbolic]
47
+ File.symlink(render, destination)
48
+ else
49
+ File.link(render, destination)
50
+ end
51
+ end
52
+ given_destination
53
+ end
54
+
55
+ end
56
+ end
57
+ end
@@ -2,13 +2,13 @@ require 'thor/actions/empty_directory'
2
2
 
3
3
  class Thor
4
4
  module Actions
5
-
6
5
  # Copies recursively the files from source directory to root directory.
7
6
  # If any of the files finishes with .tt, it's considered to be a template
8
7
  # and is placed in the destination without the extension .tt. If any
9
8
  # empty directory is found, it's copied and all .empty_directory files are
10
- # ignored. Remember that file paths can also be encoded, let's suppose a doc
11
- # directory with the following files:
9
+ # ignored. If any file name is wrapped within % signs, the text within
10
+ # the % signs will be executed as a method and replaced with the returned
11
+ # value. Let's suppose a doc directory with the following files:
12
12
  #
13
13
  # doc/
14
14
  # components/.empty_directory
@@ -21,7 +21,7 @@ class Thor
21
21
  # directory "doc"
22
22
  #
23
23
  # It will create a doc directory in the destination with the following
24
- # files (assuming that the app_name is "blog"):
24
+ # files (assuming that the `app_name` method returns the value "blog"):
25
25
  #
26
26
  # doc/
27
27
  # components/
@@ -29,6 +29,10 @@ class Thor
29
29
  # rdoc.rb
30
30
  # blog.rb
31
31
  #
32
+ # <b>Encoded path note:</b> Since Thor internals use Object#respond_to? to check if it can
33
+ # expand %something%, this `something` should be a public method in the class calling
34
+ # #directory. If a method is private, Thor stack raises PrivateMethodEncodedError.
35
+ #
32
36
  # ==== Parameters
33
37
  # source<String>:: the relative path to the source root.
34
38
  # destination<String>:: the relative path to the destination root.
@@ -40,7 +44,9 @@ class Thor
40
44
  # directory "doc"
41
45
  # directory "doc", "docs", :recursive => false
42
46
  #
43
- def directory(source, destination=nil, config={}, &block)
47
+ def directory(source, *args, &block)
48
+ config = args.last.is_a?(Hash) ? args.pop : {}
49
+ destination = args.first || source
44
50
  action Directory.new(self, source, destination || source, config, &block)
45
51
  end
46
52
 
@@ -65,10 +71,11 @@ class Thor
65
71
  protected
66
72
 
67
73
  def execute!
68
- lookup = config[:recursive] ? File.join(source, '**') : source
74
+ lookup = Util.escape_globs(source)
75
+ lookup = config[:recursive] ? File.join(lookup, '**') : lookup
69
76
  lookup = File.join(lookup, '{*,.[a-z]*}')
70
77
 
71
- Dir[lookup].each do |file_source|
78
+ Dir[lookup].sort.each do |file_source|
72
79
  next if File.directory?(file_source)
73
80
  file_destination = File.join(given_destination, file_source.gsub(source, '.'))
74
81
  file_destination.gsub!('/./', '/')
@@ -90,16 +90,35 @@ class Thor
90
90
 
91
91
  # Filenames in the encoded form are converted. If you have a file:
92
92
  #
93
- # %class_name%.rb
93
+ # %file_name%.rb
94
94
  #
95
- # It gets the class name from the base and replace it:
95
+ # It calls #file_name from the base and replaces %-string with the
96
+ # return value (should be String) of #file_name:
96
97
  #
97
98
  # user.rb
98
99
  #
100
+ # The method referenced by %-string SHOULD be public. Otherwise you
101
+ # get the exception with the corresponding error message.
102
+ #
99
103
  def convert_encoded_instructions(filename)
100
- filename.gsub(/%(.*?)%/) do |string|
101
- instruction = $1.strip
102
- base.respond_to?(instruction) ? base.send(instruction) : string
104
+ filename.gsub(/%(.*?)%/) do |initial_string|
105
+ call_public_method($1.strip) or initial_string
106
+ end
107
+ end
108
+
109
+ # Calls `base`'s public method `sym`.
110
+ # Returns:: result of `base.sym` or `nil` if `sym` wasn't found in
111
+ # `base`
112
+ # Raises:: Thor::PrivateMethodEncodedError if `sym` references
113
+ # a private method.
114
+ def call_public_method(sym)
115
+ if base.respond_to?(sym)
116
+ base.send(sym)
117
+ elsif base.respond_to?(sym, true)
118
+ raise Thor::PrivateMethodEncodedError,
119
+ "Method #{base.class}##{sym} should be public, not private"
120
+ else
121
+ nil
103
122
  end
104
123
  end
105
124
 
@@ -18,8 +18,9 @@ class Thor
18
18
  #
19
19
  # copy_file "doc/README"
20
20
  #
21
- def copy_file(source, destination=nil, config={}, &block)
22
- destination ||= source
21
+ def copy_file(source, *args, &block)
22
+ config = args.last.is_a?(Hash) ? args.pop : {}
23
+ destination = args.first || source
23
24
  source = File.expand_path(find_in_source_paths(source.to_s))
24
25
 
25
26
  create_file destination, nil, config do
@@ -29,6 +30,28 @@ class Thor
29
30
  end
30
31
  end
31
32
 
33
+ # Links the file from the relative source to the relative destination. If
34
+ # the destination is not given it's assumed to be equal to the source.
35
+ #
36
+ # ==== Parameters
37
+ # source<String>:: the relative path to the source root.
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
+ # link_file "README", "doc/README"
44
+ #
45
+ # link_file "doc/README"
46
+ #
47
+ def link_file(source, *args, &block)
48
+ config = args.last.is_a?(Hash) ? args.pop : {}
49
+ destination = args.first || source
50
+ source = File.expand_path(find_in_source_paths(source.to_s))
51
+
52
+ create_link destination, source, config
53
+ end
54
+
32
55
  # Gets the content at the given address and places it at the given relative
33
56
  # destination. If a block is given instead of destination, the content of
34
57
  # the url is yielded and used as location.
@@ -46,9 +69,12 @@ class Thor
46
69
  # content.split("\n").first
47
70
  # end
48
71
  #
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).binmode.read
72
+ def get(source, *args, &block)
73
+ config = args.last.is_a?(Hash) ? args.pop : {}
74
+ destination = args.first
75
+
76
+ source = File.expand_path(find_in_source_paths(source.to_s)) unless source =~ /^https?\:\/\//
77
+ render = open(source) {|input| input.binmode.read }
52
78
 
53
79
  destination ||= if block_given?
54
80
  block.arity == 1 ? block.call(render) : block.call
@@ -74,13 +100,15 @@ class Thor
74
100
  #
75
101
  # template "doc/README"
76
102
  #
77
- def template(source, destination=nil, config={}, &block)
78
- destination ||= source
103
+ def template(source, *args, &block)
104
+ config = args.last.is_a?(Hash) ? args.pop : {}
105
+ destination = args.first || source.sub(/\.tt$/, '')
106
+
79
107
  source = File.expand_path(find_in_source_paths(source.to_s))
80
108
  context = instance_eval('binding')
81
109
 
82
110
  create_file destination, nil, config do
83
- content = ERB.new(::File.binread(source), nil, '-').result(context)
111
+ content = ERB.new(::File.binread(source), nil, '-', '@output_buffer').result(context)
84
112
  content = block.call(content) if block
85
113
  content
86
114
  end
@@ -104,7 +132,7 @@ class Thor
104
132
  FileUtils.chmod_R(mode, path) unless options[:pretend]
105
133
  end
106
134
 
107
- # Prepend text to a file. Since it depends on inject_into_file, it's reversible.
135
+ # Prepend text to a file. Since it depends on insert_into_file, it's reversible.
108
136
  #
109
137
  # ==== Parameters
110
138
  # path<String>:: path of the file to be changed
@@ -113,19 +141,20 @@ class Thor
113
141
  #
114
142
  # ==== Example
115
143
  #
116
- # prepend_file 'config/environments/test.rb', 'config.gem "rspec"'
144
+ # prepend_to_file 'config/environments/test.rb', 'config.gem "rspec"'
117
145
  #
118
- # prepend_file 'config/environments/test.rb' do
146
+ # prepend_to_file 'config/environments/test.rb' do
119
147
  # 'config.gem "rspec"'
120
148
  # end
121
149
  #
122
- def prepend_file(path, *args, &block)
150
+ def prepend_to_file(path, *args, &block)
123
151
  config = args.last.is_a?(Hash) ? args.pop : {}
124
152
  config.merge!(:after => /\A/)
125
- inject_into_file(path, *(args << config), &block)
153
+ insert_into_file(path, *(args << config), &block)
126
154
  end
155
+ alias_method :prepend_file, :prepend_to_file
127
156
 
128
- # Append text to a file. Since it depends on inject_into_file, it's reversible.
157
+ # Append text to a file. Since it depends on insert_into_file, it's reversible.
129
158
  #
130
159
  # ==== Parameters
131
160
  # path<String>:: path of the file to be changed
@@ -134,20 +163,21 @@ class Thor
134
163
  #
135
164
  # ==== Example
136
165
  #
137
- # append_file 'config/environments/test.rb', 'config.gem "rspec"'
166
+ # append_to_file 'config/environments/test.rb', 'config.gem "rspec"'
138
167
  #
139
- # append_file 'config/environments/test.rb' do
168
+ # append_to_file 'config/environments/test.rb' do
140
169
  # 'config.gem "rspec"'
141
170
  # end
142
171
  #
143
- def append_file(path, *args, &block)
172
+ def append_to_file(path, *args, &block)
144
173
  config = args.last.is_a?(Hash) ? args.pop : {}
145
174
  config.merge!(:before => /\z/)
146
- inject_into_file(path, *(args << config), &block)
175
+ insert_into_file(path, *(args << config), &block)
147
176
  end
177
+ alias_method :append_file, :append_to_file
148
178
 
149
179
  # Injects text right after the class definition. Since it depends on
150
- # inject_into_file, it's reversible.
180
+ # insert_into_file, it's reversible.
151
181
  #
152
182
  # ==== Parameters
153
183
  # path<String>:: path of the file to be changed
@@ -157,7 +187,7 @@ class Thor
157
187
  #
158
188
  # ==== Examples
159
189
  #
160
- # inject_into_class "app/controllers/application_controller.rb", " filter_parameter :password\n"
190
+ # inject_into_class "app/controllers/application_controller.rb", ApplicationController, " filter_parameter :password\n"
161
191
  #
162
192
  # inject_into_class "app/controllers/application_controller.rb", ApplicationController do
163
193
  # " filter_parameter :password\n"
@@ -166,7 +196,7 @@ class Thor
166
196
  def inject_into_class(path, klass, *args, &block)
167
197
  config = args.last.is_a?(Hash) ? args.pop : {}
168
198
  config.merge!(:after => /class #{klass}\n|class #{klass} .*\n/)
169
- inject_into_file(path, *(args << config), &block)
199
+ insert_into_file(path, *(args << config), &block)
170
200
  end
171
201
 
172
202
  # Run a regular expression replacement on a file.
@@ -199,6 +229,44 @@ class Thor
199
229
  end
200
230
  end
201
231
 
232
+ # Uncomment all lines matching a given regex. It will leave the space
233
+ # which existed before the comment hash in tact but will remove any spacing
234
+ # between the comment hash and the beginning of the line.
235
+ #
236
+ # ==== Parameters
237
+ # path<String>:: path of the file to be changed
238
+ # flag<Regexp|String>:: the regexp or string used to decide which lines to uncomment
239
+ # config<Hash>:: give :verbose => false to not log the status.
240
+ #
241
+ # ==== Example
242
+ #
243
+ # uncomment_lines 'config/initializers/session_store.rb', /active_record/
244
+ #
245
+ def uncomment_lines(path, flag, *args)
246
+ flag = flag.respond_to?(:source) ? flag.source : flag
247
+
248
+ gsub_file(path, /^(\s*)#\s*(.*#{flag})/, '\1\2', *args)
249
+ end
250
+
251
+ # Comment all lines matching a given regex. It will leave the space
252
+ # which existed before the beginning of the line in tact and will insert
253
+ # a single space after the comment hash.
254
+ #
255
+ # ==== Parameters
256
+ # path<String>:: path of the file to be changed
257
+ # flag<Regexp|String>:: the regexp or string used to decide which lines to comment
258
+ # config<Hash>:: give :verbose => false to not log the status.
259
+ #
260
+ # ==== Example
261
+ #
262
+ # comment_lines 'config/initializers/session_store.rb', /cookie_store/
263
+ #
264
+ def comment_lines(path, flag, *args)
265
+ flag = flag.respond_to?(:source) ? flag.source : flag
266
+
267
+ gsub_file(path, /^(\s*)([^#|\n]*#{flag})/, '\1# \2', *args)
268
+ end
269
+
202
270
  # Removes a file at the given location.
203
271
  #
204
272
  # ==== Parameters
@@ -219,5 +287,22 @@ class Thor
219
287
  end
220
288
  alias :remove_dir :remove_file
221
289
 
290
+ private
291
+ attr_accessor :output_buffer
292
+ def concat(string)
293
+ @output_buffer.concat(string)
294
+ end
295
+
296
+ def capture(*args, &block)
297
+ with_output_buffer { block.call(*args) }
298
+ end
299
+
300
+ def with_output_buffer(buf = '') #:nodoc:
301
+ self.output_buffer, old_buffer = buf, output_buffer
302
+ yield
303
+ output_buffer
304
+ ensure
305
+ self.output_buffer = old_buffer
306
+ end
222
307
  end
223
308
  end
@@ -10,19 +10,19 @@ class Thor
10
10
  # destination<String>:: Relative path to the destination root
11
11
  # data<String>:: Data to add to the file. Can be given as a block.
12
12
  # config<Hash>:: give :verbose => false to not log the status and the flag
13
- # for injection (:after or :before) or :force => true for
13
+ # for injection (:after or :before) or :force => true for
14
14
  # insert two or more times the same content.
15
- #
15
+ #
16
16
  # ==== Examples
17
17
  #
18
- # inject_into_file "config/environment.rb", "config.gem :thor", :after => "Rails::Initializer.run do |config|\n"
18
+ # insert_into_file "config/environment.rb", "config.gem :thor", :after => "Rails::Initializer.run do |config|\n"
19
19
  #
20
- # inject_into_file "config/environment.rb", :after => "Rails::Initializer.run do |config|\n" do
20
+ # insert_into_file "config/environment.rb", :after => "Rails::Initializer.run do |config|\n" do
21
21
  # gems = ask "Which gems would you like to add?"
22
22
  # gems.split(" ").map{ |gem| " config.gem :#{gem}" }.join("\n")
23
23
  # end
24
24
  #
25
- def inject_into_file(destination, *args, &block)
25
+ def insert_into_file(destination, *args, &block)
26
26
  if block_given?
27
27
  data, config = block, args.shift
28
28
  else
@@ -30,6 +30,7 @@ class Thor
30
30
  end
31
31
  action InjectIntoFile.new(self, destination, data, config)
32
32
  end
33
+ alias_method :inject_into_file, :insert_into_file
33
34
 
34
35
  class InjectIntoFile < EmptyDirectory #:nodoc:
35
36
  attr_reader :replacement, :flag, :behavior
@@ -76,12 +77,16 @@ class Thor
76
77
  protected
77
78
 
78
79
  def say_status(behavior)
79
- status = if flag == /\A/
80
- behavior == :invoke ? :prepend : :unprepend
81
- elsif flag == /\z/
82
- behavior == :invoke ? :append : :unappend
80
+ status = if behavior == :invoke
81
+ if flag == /\A/
82
+ :prepend
83
+ elsif flag == /\z/
84
+ :append
85
+ else
86
+ :insert
87
+ end
83
88
  else
84
- behavior == :invoke ? :inject : :deinject
89
+ :subtract
85
90
  end
86
91
 
87
92
  super(status, config[:verbose])