Class: CommandLion::App

Inherits:
Base
  • Object
show all
Defined in:
lib/command_lion/app.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

build, key_value, simple_attr, simple_attrs

Class Method Details

.default_help(app) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/command_lion/app.rb', line 5

def self.default_help(app)
  flagz = app.commands.map do |_, cmd|
    if cmd.flags?
      if cmd.flags.long?
        cmd.flags.short + cmd.flags.long
      else  
        cmd.flags.short
      end  
    elsif cmd.index?
      cmd.index.to_s if cmd.index?
    else
      raise "No flags or index was given!"
    end
  end 
  max_flag = flagz.map(&:length).max + 2
  max_desc = app.commands.values.map(&:description).select{|d| d unless d.nil? }.map(&:length).max
  puts app.name
  if app.version?
    puts
    puts "VERSION"
    puts app.version
    puts unless app.description?
  end
  if app.description?
    puts 
    puts "DESCRIPTION"
    puts app.description
    puts
  end
  if app.usage?
    puts
    puts "USAGE"
    puts usage
    puts
  end
  puts unless app.version? || app.description? || app.usage?
  puts "COMMANDS"
  app.commands.values.select { |cmd| cmd unless cmd.is_a? CommandLion::Option }.each do |command|
    if command.flags?
      short = command.flags.long? ? command.flags.short + ", " : command.flags.short
      short_long = "#{short}#{command.flags.long}".ljust(max_flag)
    else
      short_long = "#{command.index.to_s}".ljust(max_flag)
    end
    puts "#{short_long}  #{command.description}"
    if command.options?
      command.options.each do |_, option|
        if option.flags?
          short = option.flags.long? ? option.flags.short + ", " : option.flags.short
          short_long = "  " + "#{short}#{option.flags.long}".ljust(max_flag - 2)
        else
          short_long = "  " + "#{option.index.to_s}".ljust(max_flag - 2)
        end
        puts "#{short_long}  #{option.description}"
      end
    end
    puts
  end
end

.run(&block) ⇒ Object

The run method will run a given block of code using the Commmand Lion DSL.



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/command_lion/app.rb', line 68

def self.run(&block)
  # Initialize an instance of an App object.
  app = new
  # Evaluate the block of code within the context of that App object.
  app.instance_eval(&block)
  # Parse the application logic out.
  app.parse
  # Sometimes a command-line application is run without being given any arguments.
  if ARGV.empty?
    # Default to a help menu.
    if cmd = app.commands[:help]
      cmd.before.call if cmd.before?
      cmd.action.call if cmd.action?
      cmd.after.call  if cmd.after?
      exit 0
    else
      # Use the default help menu for the application unless that's been
      # explictly removed by the author for whatever reason.
      default_help(app) unless app.default_help_menu_removed?
    end
  else
    app.commands.each do |_, cmd|
      next unless cmd.given?
      cmd.options.each do |_, opt|
        next unless opt.given?
        opt.before.call if opt.before?
        opt.action.call if opt.action?
        opt.after.call  if opt.after?
      end if cmd.options?
      cmd.before.call if cmd.before?
      cmd.action.call if cmd.action?
      cmd.after.call  if cmd.after?
    end
  end
end

Instance Method Details

#command(index, &block) ⇒ Object

An application usually has multiple commands.

Example

app = CommandLion::App.build
  # meta information

  command :example1 do
    # more code
  end

  command :example2 do
    # more code
  end
end

app.commands.map(&:name)
# => [:example1, :example2]


146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/command_lion/app.rb', line 146

def command(index, &block)
  if index.is_a? Command
    cmd = index
  else
    cmd = Command.new
    cmd.index= index
    cmd.instance_eval(&block)
  end
  @commands = {} unless @commands
  @flags = [] unless @flags
  if cmd.flags?
    @flags << cmd.flags.short if cmd.flags.short?
    @flags << cmd.flags.long  if cmd.flags.long?
  elsif cmd.index # just use index
    @flags << cmd.index.to_s
  else
    raise "No index or flags were given to use this command."
  end
  if cmd.options?
    cmd.options.each do |_, option|
      if option.flags?
        @flags << option.flags.short if option.flags.short?
        @flags << option.flags.long  if option.flags.long?
      else # just use index
        @flags << option.index.to_s
      end
      @commands[option.index] = option
      #@commands << option
    end
  end
  @commands[cmd.index] = cmd
  cmd
end

#commandsObject

Direct access to the various commands an application has. Helpful for debugging.



201
202
203
# File 'lib/command_lion/app.rb', line 201

def commands
  @commands.reject { |_, v| v.is_a? CommandLion::Option }
end

#ctrl_c(&block) ⇒ Object



180
181
182
# File 'lib/command_lion/app.rb', line 180

def ctrl_c(&block)
  trap("SIGINT") { block.call }
end

#default_help_menu_removed?Boolean

Check if the default help menu for the application has been explicitly removed.

Returns:

  • (Boolean)


116
117
118
# File 'lib/command_lion/app.rb', line 116

def default_help_menu_removed?
  @remove_default_help_menu || false
end

#flagsObject

Direct access to the various flags an application has. Helpfulp for debugging.



196
197
198
# File 'lib/command_lion/app.rb', line 196

def flags
  @flags
end

#help(&block) ⇒ Object



184
185
186
# File 'lib/command_lion/app.rb', line 184

def help(&block)
  command :help, &block
end

#help?Boolean

Check if there has been an indexed help command.

Returns:

  • (Boolean)


105
106
107
108
# File 'lib/command_lion/app.rb', line 105

def help?
  return true if @commands[:help]
  false
end

#parseObject

Parse arguments off of ARGV.



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/command_lion/app.rb', line 208

def parse
  @commands.each do |_, cmd|
    if cmd.flags?
      # or for the || seems to not do what I want it to do...
      next unless argv_index = ARGV.index(cmd.flags.short) || ARGV.index(cmd.flags.long)
    else
      next unless argv_index = ARGV.index(cmd.index.to_s)
    end
    cmd.given = true unless argv_index.nil?
    if cmd.type.nil?
      yield cmd if block_given?
    else
      if parsed = parse_cmd(cmd, flags)
        cmd.arguments = parsed || cmd.default
        yield cmd if block_given?
      elsif cmd.default
        cmd.arguments = cmd.default
        yield cmd if block_given?
      end
    end
  end
end

#parse_cmd(cmd, flags) ⇒ Object

Parse a given command with its given flags.



233
234
235
236
237
238
239
240
241
242
243
244
245
246
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
311
312
313
314
# File 'lib/command_lion/app.rb', line 233

def parse_cmd(cmd, flags)
  if cmd.flags?
    args = Raw.arguments_to(cmd.flags.short, flags)
    if args.nil? || args.empty?
      args = Raw.arguments_to(cmd.flags.long, flags)
    end
  else
    args = Raw.arguments_to(cmd.index.to_s, flags)
  end
  unless cmd.type.to_s =~ /stdin/
    return nil if args.nil?
  end
  case cmd.type
  when :stdin
    args = STDIN.gets.strip
  when :stdin_stream
    args = STDIN
  when :stdin_string
    args = STDIN.gets.strip
  when :stdin_strings
    args = []
    while arg = STDIN.gets
      next if arg.nil?
      arg = arg.strip
      args << arg
    end
    args
  when :stdin_integer
    args = STDIN.gets.strip.to_i
  when :stdin_integers
    args = []
    while arg = STDIN.gets
      next if arg.nil?
      arg = arg.strip
      parse = arg.to_i
      if parse.to_s == arg
        args << parse
      end
    end
    args
  when :stdin_bool
    args = STDIN.gets.strip.downcase == "true"
  when :single, :string
    args = args.first
  when :strings, :multi
    if cmd.delimiter?
      if args.count > 1
        args = args.first.split(cmd.delimiter)
      else
        args = args.map { |arg| arg.split(cmd.delimiter) }.flatten
      end
    end
    args
  when :integer
    args = args.first.to_i
  when :integers
    if cmd.delimiter?
      if args.count > 1
        args = args.join
        args = args.select { |arg| arg if arg.include?(cmd.delimiter) }
        args = args.map { |arg| arg.split(cmd.delimiter) }.flatten
      else
        args = args.map { |arg| arg.split(cmd.delimiter) }.flatten
      end
    end
    args = args.map(&:to_i)
  when :bool, :bools
    if cmd.delimiter?
      if args.count > 1
        args = args.join
        args = args.select { |arg| arg if arg.include?(cmd.delimiter) }
        args = args.map { |arg| arg.split(cmd.delimiter) }.flatten
      else
        args = args.map { |arg| arg.split(cmd.delimiter) }.flatten
      end
    end
    args = args.map { |arg| arg == "true" }
  end
rescue => e# this is dangerous
  puts e
  nil
end

#plugin(command) ⇒ Object

Plugin a command that’s probably been built outside of the application’s run or build block. This is helpful for sharing or reusing commands in applications.

Parameters:



191
192
193
# File 'lib/command_lion/app.rb', line 191

def plugin(command)
  command(command)
end

#remove_default_help_menuObject

Explicitly remove the default help menu from the application.



111
112
113
# File 'lib/command_lion/app.rb', line 111

def remove_default_help_menu
  @remove_default_help_menu = true
end

#run!Object



316
317
318
319
320
321
322
323
324
325
326
327
328
329
# File 'lib/command_lion/app.rb', line 316

def run!
  parse do |cmd|
    next unless cmd.given?
    cmd.options.each do |_, opt|
      next unless opt.given?
      opt.before.call if opt.before?
      opt.action.call if opt.action?
      opt.after.call  if opt.after?
    end if cmd.options?
    cmd.before.call if cmd.before?
    cmd.action.call if cmd.action?
    cmd.after.call  if cmd.after?
  end 
end