lib/methadone/main.rb in methadone-1.0.0.rc1 vs lib/methadone/main.rb in methadone-1.0.0.rc2
- old
+ new
@@ -12,46 +12,61 @@
# DSL. This is a *very* lightweight layer on top of what you might
# normally write that gives you just a bit of help to keep your code structured
# in a sensible way. You can use as much or as little as you want, though
# you must at least use #main to get any benefits.
#
+ # Further, you must provide access to a logger via a method named
+ # #logger. If you include Methadone::CLILogging, this will be done for you
+ #
# You also get a more expedient interface to OptionParser as well
# as checking for required arguments to your app. For example, if
# we want our app to accept a negatable switch named "switch", a flag
# named "flag", and two arguments "needed" (which is required)
# and "maybe" which is optional, we can do the following:
#
- # #!/usr/bin/env ruby -w
+ # #!/usr/bin/env ruby
#
# require 'methadone'
#
- # include Methadone::Main
- #
- # main do |needed, maybe|
- # options[:switch] => true or false, based on command line
- # options[:flag] => value of flag passed on command line
+ # class App
+ # include Methadone::Main
+ # include Methadone::CLILogging
+ #
+ # main do |needed, maybe|
+ # options[:switch] => true or false, based on command line
+ # options[:flag] => value of flag passed on command line
+ # end
+ #
+ # # Proxy to an OptionParser instance's on method
+ # on("--[no]-switch")
+ # on("--flag VALUE")
+ #
+ # arg :needed
+ # arg :maybe, :optional
+ #
+ # go!
# end
- #
- # # Proxy to an OptionParser instance's on method
- # on("--[no]-switch")
- # on("--flag VALUE")
#
- # arg :needed
- # arg :maybe, :optional
- #
- # go!
- #
# Our app then acts as follows:
#
# $ our_app
# # => parse error: 'needed' is required
# $ our_app foo
# # => succeeds; "maybe" in main is nil
#
- # This also includes Methadone::CLILogging to give you access to simple logging
+ # Note that we've done all of this inside a class that we called +App+. This isn't strictly
+ # necessary, and you can just +include+ Methadone::Main and Methadone::CLILogging at the root
+ # of your +bin+ file if you like. This is somewhat unsafe, because +self+ inside the +bin+
+ # file is Object, and any methods you create (or cause to be created via +include+) will be
+ # present on *every* object. This can cause odd problems, so it's recommended that you
+ # *not* do this.
+ #
module Main
- include Methadone::CLILogging
+ def self.included(k)
+ k.extend(self)
+ end
+
# Declare the main method for your app.
# This allows you to specify the general logic of your
# app at the top of your bin file, but can rely on any methods
# or other code that you define later.
#
@@ -95,10 +110,18 @@
# This does *not* affect Methadone::Error exceptions; those will NOT leak through.
def leak_exceptions(leak)
@leak_exceptions = leak
end
+ # Set the name of the environment variable where users can place default
+ # options for your app. Omit this to disable the feature.
+ def defaults_from_env_var(env_var)
+ @env_var = env_var
+ opts.separator ''
+ opts.separator "Default values can be placed in the #{env_var} environment variable"
+ opts.separator ''
+ end
# Start your command-line app, exiting appropriately when
# complete.
#
# This *will* exit your program when it completes. If your
@@ -111,20 +134,25 @@
# If a required argument (see #arg) is not found, this exits with
# 64 and a message about that missing argument.
#
def go!
normalize_defaults
+ if @env_var
+ String(ENV[@env_var]).split(/\s+/).each do |arg|
+ ::ARGV.unshift(arg)
+ end
+ end
opts.parse!
opts.check_args!
result = call_main
if result.kind_of? Fixnum
exit result
else
exit 0
end
rescue OptionParser::ParseError => ex
- error ex.message
+ logger.error ex.message
puts
puts opts.help
exit 64 # Linux standard for bad command line
end
@@ -251,15 +279,15 @@
# Handle calling main and trapping any exceptions thrown
def call_main
@main_block.call(*ARGV)
rescue Methadone::Error => ex
raise ex if ENV['DEBUG']
- error ex.message unless no_message? ex
+ logger.error ex.message unless no_message? ex
ex.exit_code
rescue => ex
raise ex if ENV['DEBUG']
raise ex if @leak_exceptions
- error ex.message unless no_message? ex
+ logger.error ex.message unless no_message? ex
70 # Linux sysexit code for internal software error
end
def no_message?(exception)
exception.message.nil? || exception.message.strip.empty?