Module: GLI::App

Includes:
AppSupport, DSL
Included in:
GLI
Defined in:
lib/gli/app.rb

Overview

A means to define and parse a command line interface that works as Git’s does, in that you specify global options, a command name, command specific options, and then command arguments.

Instance Method Summary collapse

Methods included from AppSupport

#accepts, #argument_handling_strategy, #around_blocks, #autocomplete, #clear_nexts, #commands, #commands_declaration_order, #config_file_name, #context_description, #error_device=, #exe_name, #flags, #get_default_command, #help_sort_type, #help_text_wrap_type, included, #override_command_defaults, #override_default, #override_defaults_based_on_config, #parse_config, #post_block, #pre_block, #reset, #run, #stderr, #subcommand_option_handling_strategy, #switches, #synopsis_format_type, #version_string

Methods included from DSL

#arg, #arg_name, #clear_nexts, #command, #command_missing, #default_value, #desc, #flag, #flags_declaration_order, #long_desc, #switch, #switches_declaration_order

Instance Method Details

#accept(object, &block) ⇒ Object

Configure a type conversion not already provided by the underlying OptionParser. This works more or less like the OptionParser version. It’s global.

object

the class (or whatever) that triggers the type conversion

block

the block that will be given the string argument and is expected to return the converted value

Example

accept(Hash) do |value|
  result = {}
  value.split(/,/).each do |pair|
    k,v = pair.split(/:/)
    result[k] = v
  end
  result
end

flag :properties, :type => Hash


212
213
214
# File 'lib/gli/app.rb', line 212

def accept(object,&block)
  accepts[object] = block
end

#arguments(handling_strategy) ⇒ Object

How to handle argument validation.

handling_strategy

One of:

:loose

no argument validation. Use of ‘arg` or `arg_name` is for documentation purposes only. (Default)

:strict

arguments are validated according to their specification. action blocks may assume the value of ‘arguments` matches the specification provided in `arg`. Note that to use this strategy, you must also be sure that subcommand_option_handling is set.



301
302
303
# File 'lib/gli/app.rb', line 301

def arguments(handling_strategy)
  @argument_handling_strategy = handling_strategy
end

#around(&a_proc) ⇒ Object

This inverts the pre/post concept. This is useful when you have a global shared resource that is governed by a block instead of separate open/close methods. The block you pass here will be given four parameters:

global options

the parsed global options

command

The GLI::Command that the user is going to invoke

options

the command specific options

args

unparsed command-line args

code

a block that you must call to execute the command.

#help_now! and #exit_now! work as expected; you can abort the command call by simply not calling it.

You can declare as many #around blocks as you want. They will be called in the order in which they are defined.

Note that if you declare #around blocks, #pre and #post blocks will still work. The #pre is called first, followed by the around, followed by the #post.

Call #skips_around before a command that should not have this hook fired



147
148
149
150
# File 'lib/gli/app.rb', line 147

def around(&a_proc)
  @around_blocks ||= []
  @around_blocks << a_proc
end

#autocomplete_commands(boolean) ⇒ Object

Enables/Disables command autocomplete, where partially spelled commands are automatically expanded to their full form

Example: When enabled, executing ‘shake’ would execute ‘shake_hand’ (if no ‘shake’ command is defined). When disabled, executing ‘shake’ would throw an UnknownCommand error

boolean

Boolean value to enable or disable autocomplete, respectively. True by default.



313
314
315
# File 'lib/gli/app.rb', line 313

def autocomplete_commands(boolean)
  @autocomplete = boolean
end

#commands_from(path) ⇒ Object

Loads ruby files in the load path that start with path, which are presumed to be commands for your executable. This is useful for decomposing your bin file into different classes, but can also be used as a plugin mechanism, allowing users to provide additional commands for your app at runtime. All that being said, it’s basically a glorified require.

path

a path from which to load .rb files that, presumably, contain commands. If this is an absolute path, any files in that path are loaded. If not, it is interpretted as relative to somewhere in the LOAD_PATH.

Example:

# loads *.rb from your app's install - great for decomposing your bin file
commands_from "my_app/commands"

# loads *.rb files from the user's home dir - great and an extension/plugin mechanism
commands_from File.join(ENV["HOME"],".my_app","plugins")


32
33
34
35
36
37
38
39
40
41
# File 'lib/gli/app.rb', line 32

def commands_from(path)
  if Pathname.new(path).absolute? and File.exist?(path)
    load_commands(path)
  else
    $LOAD_PATH.each do |load_path|
      commands_path = File.join(load_path,path)
      load_commands(commands_path)
    end
  end
end

#config_file(filename) ⇒ Object

Sets that this app uses a config file as well as the name of the config file.

filename

A String representing the path to the file to use for the config file. If it’s an absolute path, this is treated as the path to the file. If it’s not, it’s treated as relative to the user’s home directory as produced by File.expand_path('~').



102
103
104
105
106
107
108
109
110
111
# File 'lib/gli/app.rb', line 102

def config_file(filename)
  if filename =~ /^\//
    @config_file = filename
  else
    @config_file = File.join(File.expand_path(ENV['HOME']),filename)
  end
  commands[:initconfig] = InitConfig.new(@config_file,commands,flags,switches)
  @commands_declaration_order << commands[:initconfig]
  @config_file
end

#default_command(command) ⇒ Object

Sets a default command to run when none is specified on the command line. Note that if you use this, you won’t be able to pass arguments, flags, or switches to the command when run in default mode. All flags and switches are treated as global, and any argument will be interpretted as the command name and likely fail.

command

Command as a Symbol to run as default



280
281
282
# File 'lib/gli/app.rb', line 280

def default_command(command)
  @default_command = command.to_sym
end

#exit_now!(message, exit_code = 1) ⇒ Object

Simpler means of exiting with a custom exit code. This will raise a CustomExit with the given message and exit code, which will ultimatley cause your application to exit with the given exit_code as its exit status Use #help_now! if you want to show the help in addition to the error message

message

message to show the user

exit_code

exit code to exit as, defaults to 1

Raises:



223
224
225
# File 'lib/gli/app.rb', line 223

def exit_now!(message,exit_code=1)
  raise CustomExit.new(message,exit_code)
end

#help_now!(message = nil) ⇒ Object

Exit now, showing the user help for the command they executed. Use #exit_now! to just show the error message

message

message to indicate how the user has messed up the CLI invocation or nil to just simply show help



230
231
232
233
234
235
236
# File 'lib/gli/app.rb', line 230

def help_now!(message=nil)
  exception = OptionParser::ParseError.new(message)
  class << exception
    def exit_code; 64; end
  end
  raise exception
end

#hide_commands_without_desc(hide = nil) ⇒ Object

Provide a flag to choose whether to hide or not from the help the undescribed commands. By default the undescribed commands will be shown in the help.

hide

A Bool for hide the undescribed commands



69
70
71
72
73
74
# File 'lib/gli/app.rb', line 69

def hide_commands_without_desc(hide=nil)
  unless hide.nil?
    @hide_commands_without_desc = hide
  end
  @hide_commands_without_desc || false
end

#on_error(&a_proc) ⇒ Object

Define a block to run if an error occurs. The block will receive any Exception that was caught. It should evaluate to false to avoid the built-in error handling (which basically just prints out a message). GLI uses a variety of exceptions that you can use to find out what errors might’ve occurred during command-line parsing:

  • GLI::CustomExit

  • GLI::UnknownCommandArgument

  • GLI::UnknownGlobalArgument

  • GLI::UnknownCommand

  • GLI::BadCommandLine



162
163
164
# File 'lib/gli/app.rb', line 162

def on_error(&a_proc)
  @error_block = a_proc
end

#post(&a_proc) ⇒ Object

Define a block to run after the command was executed, only if there was not an error. The block will receive the global-options,command,options, and arguments



126
127
128
# File 'lib/gli/app.rb', line 126

def post(&a_proc)
  @post_block = a_proc
end

#pre(&a_proc) ⇒ Object

Define a block to run after command line arguments are parsed but before any command is run. If this block raises an exception the command specified will not be executed. The block will receive the global-options,command,options, and arguments If this block evaluates to true, the program will proceed; otherwise the program will end immediately and exit nonzero



119
120
121
# File 'lib/gli/app.rb', line 119

def pre(&a_proc)
  @pre_block = a_proc
end

#preserve_argv(preserve = true) ⇒ Object

By default, GLI mutates the argument passed to it. This is consistent with OptionParser, but be less than ideal. Since that value, for scaffolded apps, is ARGV, you might want to refer to the entire command-line via ARGV and thus not want it mutated.



179
180
181
# File 'lib/gli/app.rb', line 179

def preserve_argv(preserve=true)
  @preserve_argv = preserve
end

#program_desc(description = nil) ⇒ Object

Describe the overall application/programm. This should be a one-sentence summary of what your program does that will appear in the help output.

description

A String of the short description of your program’s purpose



47
48
49
50
51
52
# File 'lib/gli/app.rb', line 47

def program_desc(description=nil)
  if description
    @program_desc = description
  end
  @program_desc
end

#program_long_desc(description = nil) ⇒ Object

Provide a longer description of the program. This can be as long as needed, and use double-newlines for paragraphs. This will show up in the help output.

description

A String for the description



58
59
60
61
62
63
# File 'lib/gli/app.rb', line 58

def program_long_desc(description=nil)
  if description
    @program_long_desc = description
  end
  @program_long_desc
end

#program_name(override = nil) ⇒ Object

:nodoc:



269
270
271
# File 'lib/gli/app.rb', line 269

def program_name(override=nil) #:nodoc:
  warn "#program_name has been deprecated"
end

#skips_aroundObject

Use this if the following command should not have the around block executed. By default, the around block is executed, but for commands that might not want the setup to happen, this can be handy



93
94
95
# File 'lib/gli/app.rb', line 93

def skips_around
  @skips_around = true
end

#skips_postObject

Use this if the following command should not have the post block executed. By default, the post block is executed after each command. Using this will avoid that behavior for the following command



86
87
88
# File 'lib/gli/app.rb', line 86

def skips_post
  @skips_post = true
end

#skips_preObject

Use this if the following command should not have the pre block executed. By default, the pre block is executed before each command and can result in aborting the call. Using this will avoid that behavior for the following command



79
80
81
# File 'lib/gli/app.rb', line 79

def skips_pre
  @skips_pre = true
end

#sort_help(sort_type) ⇒ Object

Control how commands and options are sorted in help output. By default, they are sorted alphabetically.

sort_type

How you want help commands/options sorted:

:manually

help commands/options are ordered in the order declared.

:alpha

sort alphabetically (default)



243
244
245
# File 'lib/gli/app.rb', line 243

def sort_help(sort_type)
  @help_sort_type = sort_type
end

#subcommand_option_handling(handling_strategy) ⇒ Object

How to handle subcommand options. In general, you want to set this to :normal, which treats each subcommand as establishing its own namespace for options. This is what the scaffolding should generate, but it is not what GLI 2.5.x and lower apps had as a default. To maintain backwards compatibility, the default is :legacy, which is that all subcommands of a particular command share a namespace for options, making it impossible for two subcommands to have options of the same name.



290
291
292
# File 'lib/gli/app.rb', line 290

def subcommand_option_handling(handling_strategy)
  @subcommand_option_handling_strategy = handling_strategy
end

#synopsis_format(format) ⇒ Object

Control how the SYNOPSIS is formatted.

format

one of:

:full

the default, show subcommand options and flags inline

:terminal

if :full would be wider than the terminal, use :compact

:compact

use a simpler and shorter SYNOPSIS. Useful if your app has a lot of options and showing them in the SYNOPSIS makes things more confusing



265
266
267
# File 'lib/gli/app.rb', line 265

def synopsis_format(format)
  @synopsis_format_type = format
end

#use_openstruct(use_openstruct) ⇒ Object

Call this with true will cause the global_options and options passed to your code to be wrapped in Options, which is a subclass of OpenStruct that adds [] and []= methods.

use_openstruct

a Boolean indicating if we should use OpenStruct instead of Hashes



189
190
191
# File 'lib/gli/app.rb', line 189

def use_openstruct(use_openstruct)
  @use_openstruct = use_openstruct
end

#version(version) ⇒ Object

Indicate the version of your application

version

String containing the version of your application.



169
170
171
172
173
# File 'lib/gli/app.rb', line 169

def version(version)
  @version = version
  desc 'Display the program version'
  switch :version, :negatable => false
end

#wrap_help_text(wrap_type) ⇒ Object

Set how help text is wrapped.

wrap_type

Symbol indicating how you’d like text wrapped:

:to_terminal

Wrap text based on the width of the terminal (default)

:verbatim

Format text exactly as it was given to the various methods. This is useful if your output has formatted output, e.g. ascii tables and you don’t want it messed with.

:one_line

Do not wrap text at all. This will bring all help content onto one line, removing any newlines

:tty_only

Wrap like :to_terminal if this output is going to a TTY, otherwise don’t wrap (like :one_line)



255
256
257
# File 'lib/gli/app.rb', line 255

def wrap_help_text(wrap_type)
  @help_text_wrap_type = wrap_type
end