Class: CF::Command

Inherits:
Thor
  • Object
show all
Includes:
Interactive
Defined in:
lib/cf/cli/command.rb

Direct Known Subclasses

App, App::Env, Service, User

Constant Summary

Constants included from Dots

Dots::COLOR_CODES, Dots::DOT_COUNT, Dots::DOT_TICK

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Interactive

#ask, #handler, #input_state, #list_choices, #prompt

Methods included from Dots

b, c, #dots!, #stop_dots!, #with_progress

Class Method Details

.add_callback(name, task, callback) ⇒ Object



157
158
159
# File 'lib/cf/cli/command.rb', line 157

def self.add_callback(name, task, callback)
  callbacks[name][task] << callback
end

.after(task, &callback) ⇒ Object



165
166
167
# File 'lib/cf/cli/command.rb', line 165

def self.after(task, &callback)
  add_callback(:after, task, callback)
end

.around(task, &callback) ⇒ Object



173
174
175
# File 'lib/cf/cli/command.rb', line 173

def self.around(task, &callback)
  add_callback(:around, task, callback)
end

.before(task, &callback) ⇒ Object



161
162
163
# File 'lib/cf/cli/command.rb', line 161

def self.before(task, &callback)
  add_callback(:before, task, callback)
end

.callbacksObject



149
150
151
152
153
154
155
# File 'lib/cf/cli/command.rb', line 149

def self.callbacks
  @callbacks ||= Hash.new do |h, name|
    h[name] = Hash.new do |h, task|
      h[task] = []
    end
  end
end

.callbacks_for(name) ⇒ Object



140
141
142
143
144
145
146
147
# File 'lib/cf/cli/command.rb', line 140

def self.callbacks_for(name)
  cs = callbacks[name]
  if superclass.respond_to? :callbacks
    cs.merge superclass.callbacks_for(name)
  else
    cs
  end
end

.ensuring(task, &callback) ⇒ Object



169
170
171
# File 'lib/cf/cli/command.rb', line 169

def self.ensuring(task, &callback)
  add_callback(:ensuring, task, callback)
end

.flag(name, options = {}, &query) ⇒ Object



132
133
134
135
136
137
138
# File 'lib/cf/cli/command.rb', line 132

def self.flag(name, options = {}, &query)
  if query
    options[:default] ||= InteractiveDefault.new(query)
  end

  method_option(name, options)
end

Instance Method Details

#invoke_task(task, args) ⇒ Object



247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
# File 'lib/cf/cli/command.rb', line 247

def invoke_task(task, args)
  callbacks_for(:before)[task.name.to_sym].each do |c|
    c.call
  end

  action = proc do |*new_args|
    if new_args.empty?
      task.run(self, args)
    elsif new_args.first.is_a? Array
      task.run(self, new_args.first)
    else
      task.run(self, new_args)
    end
  end

  callbacks_for(:around)[task.name.to_sym].each do |a|
    before = action
    action = proc do |passed_args|
      # with more than one wrapper, when the outer wrapper passes args to
      # inner wrapper, which calls the next inner with no args, it should
      # get the args passed to it by outer
      args = passed_args if passed_args
      instance_exec(before, args, &a)
    end
  end

  res = instance_exec(args, &action)

  callbacks_for(:after)[task.name.to_sym].each do |c|
    c.call
  end

  res
rescue Interrupt
  $exit_status = 130
rescue Thor::Error
  raise
rescue Exception => e
  msg = e.class.name
  msg << ": #{e}" unless e.to_s.empty?
  err msg

  ensure_config_dir

  File.open(File.expand_path(CF::CRASH_FILE), "w") do |f|
    f.print "Time of crash:\n  "
    f.puts Time.now
    f.puts ""
    f.puts msg
    f.puts ""

    e.backtrace.each do |loc|
      if loc =~ /\/gems\//
        f.puts loc.sub(/.*\/gems\//, "")
      else
        f.puts loc.sub(File.expand_path("../../../..", __FILE__) + "/", "")
      end
    end
  end
ensure
  callbacks_for(:ensuring)[task.name.to_sym].each do |c|
    c.call
  end
end