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?