engineyard-serverside 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
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])