Clone this wiki locally
GLI provides four hooks for running code at different parts of your application's lifecycle - a pre, a post, and around, and an error.
The pre hook is useful for setting up global data that most or all of your commands will need. For example, if your application interacts with a remote web service, the pre hook might use global options to establish a connection to the web service, and provide a global variable representing that connection to whichever command is actually requested by the user.
Once the command line arguments are parsed, the pre hook, if included, will be called. It's given the global options, the command the user issued, the command-specific options, and the arguments list.
pre do |global_options,command,options,args| # Set up here # the block should evaluate to true or false end
If the block evaluates to false, the program will stop and the command requested will not be executed.
Skipping the pre block
You can configure certain commands that, if issued by the user, will skip the pre block entirely. To do this, use
skips_pre before the command:
desc "Show what's in our local cache" skips_pre command [:lc,:local-cache] do |c| # .. end
This is useful if you have complex setup in your
pre block, but there are certain commands that either don't need or might not work if attempted.
The help command skips the pre block by default. This wasn't always the case and if you really want the help command to run the pre block, call
GLI::DefaultHelpCommand.skips_pre=false somewhere before GLI runs.
The post hook is called after your command runs, assuming there has been no error. The post hook is given the same arguments as the pre hook. This is useful if you need to close any open resources your application might've opened up or do any other genreal cleanup.
post do |global_options,command,options,args| # Cleanup code here end
Skipping the post block
You can configure certain commands that, if issued by the user, will skip the post block entirely. To do this, use
skips_post before the command.
The help command skips the post block by default. This wasn't always the case and if you really want the help command to run the post block, call
GLI::DefaultHelpCommand.skips_post=false somewhere before GLI runs.
Often, a global resource you want to set up expects to be given a block for resource management, such as an open file. The pre/post hook mechanism isn't convenient for this use case, so you can use an around hook. The only tricky part is that you have to remember to call the code block GLI gives you, which will execute the command:
around do |global_options,command,options,arguments,code| File.open(global_options[:filename],'w') do |file| options[:file] = file code.call end end
Inside the around block, calls like
help_now! work as you'd expect. To abort command execution, just don't call the command. Also note that the pre hook will have been called and if you exit the around block normally, the post hook will be called after.
Skipping the around hook
Just as with pre and post hooks, you can configure any command to skip the around hook. For example, GLI's help command skips it.
skips_around command :foo do |c| c.action do # around hook will not be called end end
Your commands should simply raise exceptions if anything went wrong and you wish to halt program execution. The Error hook is called in these cases. The error hook is also called at any other part of the application lifecycle, so the parsed command line options may not be available. All that is given to the block is the exception that triggered the error:
on_error do |ex| # evaluate to true or false end
If the block evaluates to true, GLI's normal error handling will occur. This currently amounts to printing the exception's message to the standard error. If the block evalulates to false, GLI will do nothing before exiting the program. This gives you some flexibility on what you want to do when there's an error.
Hooks and the help command
By default, hooks will not run for the help command. You can control this by using class methods on the class that implements the help command:
# run the pre block before help GLI::Commands::Help.skips_pre = false # run the post block after help GLI::Commands::Help.skips_post = false # run the around block around help GLI::Commands::Help.skips_around = false