slop 1.7.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.yardopts +2 -2
- data/CHANGES.md +12 -0
- data/README.md +6 -65
- data/lib/slop.rb +108 -58
- data/lib/slop/option.rb +2 -3
- data/slop.gemspec +1 -1
- data/test/commands_test.rb +17 -0
- data/test/slop_test.rb +51 -7
- metadata +3 -3
    
        data/.yardopts
    CHANGED
    
    
    
        data/CHANGES.md
    CHANGED
    
    | @@ -1,3 +1,15 @@ | |
| 1 | 
            +
            1.8.0 (2011-06-12)
         | 
| 2 | 
            +
            ------------------
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            * Added `execute` method to Slop for commands. This block will be invoked
         | 
| 5 | 
            +
              when a specific command is used. The Slop object will be yielded to the
         | 
| 6 | 
            +
              block
         | 
| 7 | 
            +
            * Allow passing a class name to `on` to be used as an `:as` option. ie:
         | 
| 8 | 
            +
              `on :people, 'Some people', Array`
         | 
| 9 | 
            +
            * Get smart with parsing options optparse style: `on '--name NAME'` and
         | 
| 10 | 
            +
              `on 'password [OPTIONAL]'`
         | 
| 11 | 
            +
            * Feature: `:arguments` setting to enable argument passing for all options
         | 
| 12 | 
            +
             | 
| 1 13 | 
             
            1.7.0 (2011-06-06)
         | 
| 2 14 | 
             
            ------------------
         | 
| 3 15 |  | 
    
        data/README.md
    CHANGED
    
    | @@ -20,7 +20,7 @@ Usage | |
| 20 20 | 
             
            -----
         | 
| 21 21 | 
             
                # parse assumes ARGV, otherwise you can pass it your own Array
         | 
| 22 22 | 
             
                opts = Slop.parse do
         | 
| 23 | 
            -
                  on :v, :verbose, 'Enable verbose mode' | 
| 23 | 
            +
                  on :v, :verbose, 'Enable verbose mode'           # boolean value
         | 
| 24 24 | 
             
                  on :n, :name, 'Your name', true                  # option requires a compulsory argument
         | 
| 25 25 | 
             
                  on :s, :sex, 'Your sex', :optional => false      # the same thing
         | 
| 26 26 | 
             
                  on '-a', '--age', 'Your age', :optional => true  # optional argument
         | 
| @@ -33,6 +33,10 @@ Usage | |
| 33 33 | 
             
                opts.age?     #=> false
         | 
| 34 34 | 
             
                opts[:age]    #=> nil
         | 
| 35 35 |  | 
| 36 | 
            +
            For more information about creating options, see the
         | 
| 37 | 
            +
            [Creating Options](https://github.com/injekt/slop/wiki/Creating-Options)
         | 
| 38 | 
            +
            wiki page.
         | 
| 39 | 
            +
             | 
| 36 40 | 
             
            You can also return your options as a Hash
         | 
| 37 41 |  | 
| 38 42 | 
             
                opts.to_hash #=> {'name' => 'Lee Jarvis', 'verbose' => true, 'age' => nil, 'sex' => 'male'}
         | 
| @@ -51,19 +55,10 @@ Will output something like | |
| 51 55 |  | 
| 52 56 | 
             
            You can also add a banner using the `banner` method
         | 
| 53 57 |  | 
| 54 | 
            -
                opts = Slop.parse
         | 
| 55 | 
            -
                opts.banner = "Usage: foo.rb [options]"
         | 
| 56 | 
            -
             | 
| 57 | 
            -
            or
         | 
| 58 | 
            -
             | 
| 59 58 | 
             
                opts = Slop.parse do
         | 
| 60 59 | 
             
                  banner "Usage: foo.rb [options]"
         | 
| 61 60 | 
             
                end
         | 
| 62 61 |  | 
| 63 | 
            -
            or
         | 
| 64 | 
            -
             | 
| 65 | 
            -
                opts = Slop.new "Usage: foo.rb [options]"
         | 
| 66 | 
            -
             | 
| 67 62 | 
             
            Helpful Help
         | 
| 68 63 | 
             
            ------------
         | 
| 69 64 |  | 
| @@ -196,26 +191,6 @@ You can of course also parse lists into options. Here's how: | |
| 196 191 | 
             
            Slop supports a few styles of list parsing. Check out
         | 
| 197 192 | 
             
            [this wiki page](https://github.com/injekt/slop/wiki/Lists) for more info.
         | 
| 198 193 |  | 
| 199 | 
            -
            Smart
         | 
| 200 | 
            -
            -----
         | 
| 201 | 
            -
             | 
| 202 | 
            -
            Slop is pretty smart when it comes to building your options, for example if you
         | 
| 203 | 
            -
            want your option to have a flag attribute, but no `--option` attribute, you
         | 
| 204 | 
            -
            can do this:
         | 
| 205 | 
            -
             | 
| 206 | 
            -
                on :n, "Your name"
         | 
| 207 | 
            -
             | 
| 208 | 
            -
            and Slop will detect a description in place of an option, so you don't have to
         | 
| 209 | 
            -
            do this:
         | 
| 210 | 
            -
             | 
| 211 | 
            -
                on :n, nil, "Your name", true
         | 
| 212 | 
            -
             | 
| 213 | 
            -
            You can also try other variations:
         | 
| 214 | 
            -
             | 
| 215 | 
            -
                on :name, "Your name"
         | 
| 216 | 
            -
                on :n, :name
         | 
| 217 | 
            -
                on :name, true
         | 
| 218 | 
            -
             | 
| 219 194 | 
             
            Strict Mode
         | 
| 220 195 | 
             
            -----------
         | 
| 221 196 |  | 
| @@ -225,41 +200,6 @@ when an invalid option is found (`false` by default): | |
| 225 200 | 
             
                Slop.new(:strict => true).parse(%w/--foo/)
         | 
| 226 201 | 
             
                # => Slop::InvalidOptionError: Unknown option -- 'foo'
         | 
| 227 202 |  | 
| 228 | 
            -
            Commands
         | 
| 229 | 
            -
            --------
         | 
| 230 | 
            -
             | 
| 231 | 
            -
            Slop allows you to nest more instances of Slop inside of `commands`. These
         | 
| 232 | 
            -
            instances will then be used to parse arguments if they're called upon.
         | 
| 233 | 
            -
             | 
| 234 | 
            -
            Slop will use the first argument in the list of items passed to `parse` to
         | 
| 235 | 
            -
            check if it is a `command`.
         | 
| 236 | 
            -
             | 
| 237 | 
            -
                Slop.parse ['foo', '--bar', 'baz']
         | 
| 238 | 
            -
             | 
| 239 | 
            -
            Slop will look to see if the `foo` command exists, and if it does, it'll pass
         | 
| 240 | 
            -
            the options `['--bar', 'baz']` to the instance of Slop that belongs to `foo`.
         | 
| 241 | 
            -
            Here's how commands might look:
         | 
| 242 | 
            -
             | 
| 243 | 
            -
                opts = Slop.new do
         | 
| 244 | 
            -
                  command :foo do
         | 
| 245 | 
            -
                    on :b, :bar, 'something', true
         | 
| 246 | 
            -
                  end
         | 
| 247 | 
            -
             | 
| 248 | 
            -
                  command :clean do
         | 
| 249 | 
            -
                    on :v, :verbose, do
         | 
| 250 | 
            -
                      puts 'Enabled verbose mode for clean'
         | 
| 251 | 
            -
                    end
         | 
| 252 | 
            -
                  end
         | 
| 253 | 
            -
             | 
| 254 | 
            -
                  # non-command specific options
         | 
| 255 | 
            -
                  on :v, :version do
         | 
| 256 | 
            -
                    puts 'version 1'
         | 
| 257 | 
            -
                  end
         | 
| 258 | 
            -
                end
         | 
| 259 | 
            -
             | 
| 260 | 
            -
            * `run.rb -v       #=> version 1`
         | 
| 261 | 
            -
            * `run.rb clean -v #=> Enabled verbose mode for clean`
         | 
| 262 | 
            -
             | 
| 263 203 | 
             
            Features
         | 
| 264 204 | 
             
            --------
         | 
| 265 205 |  | 
| @@ -267,6 +207,7 @@ Check out the following wiki pages for more features: | |
| 267 207 |  | 
| 268 208 | 
             
            * [Ranges](https://github.com/injekt/slop/wiki/Ranges)
         | 
| 269 209 | 
             
            * [Auto Create](https://github.com/injekt/slop/wiki/Auto-Create)
         | 
| 210 | 
            +
            * [Commands](https://github.com/injekt/slop/wiki/Commands)
         | 
| 270 211 |  | 
| 271 212 | 
             
            Woah woah, why you hating on OptionParser?
         | 
| 272 213 | 
             
            ------------------------------------------
         | 
    
        data/lib/slop.rb
    CHANGED
    
    | @@ -16,9 +16,9 @@ class Slop | |
| 16 16 | 
             
              class InvalidOptionError < RuntimeError; end
         | 
| 17 17 |  | 
| 18 18 | 
             
              # @return [String] The current version string
         | 
| 19 | 
            -
              VERSION = '1. | 
| 19 | 
            +
              VERSION = '1.8.0'
         | 
| 20 20 |  | 
| 21 | 
            -
              # Parses the items from a CLI format into a friendly object | 
| 21 | 
            +
              # Parses the items from a CLI format into a friendly object
         | 
| 22 22 | 
             
              #
         | 
| 23 23 | 
             
              # @param [Array] items Items to parse into options.
         | 
| 24 24 | 
             
              # @example Specifying three options to parse:
         | 
| @@ -27,15 +27,15 @@ class Slop | |
| 27 27 | 
             
              #    on :n, :name,    'Your name'
         | 
| 28 28 | 
             
              #    on :a, :age,     'Your age'
         | 
| 29 29 | 
             
              #  end
         | 
| 30 | 
            -
              # @return [Slop] Returns an instance of Slop | 
| 30 | 
            +
              # @return [Slop] Returns an instance of Slop
         | 
| 31 31 | 
             
              def self.parse(items=ARGV, options={}, &block)
         | 
| 32 32 | 
             
                initialize_and_parse items, false, options, &block
         | 
| 33 33 | 
             
              end
         | 
| 34 34 |  | 
| 35 35 | 
             
              # Identical to {Slop.parse}, but removes parsed options from the
         | 
| 36 | 
            -
              # original Array | 
| 36 | 
            +
              # original Array
         | 
| 37 37 | 
             
              #
         | 
| 38 | 
            -
              # @return [Slop] Returns an instance of Slop | 
| 38 | 
            +
              # @return [Slop] Returns an instance of Slop
         | 
| 39 39 | 
             
              def self.parse!(items=ARGV, options={}, &block)
         | 
| 40 40 | 
             
                initialize_and_parse items, true, options, &block
         | 
| 41 41 | 
             
              end
         | 
| @@ -54,25 +54,43 @@ class Slop | |
| 54 54 | 
             
              # @return [Integer] The length of the longest flag slop knows of
         | 
| 55 55 | 
             
              attr_accessor :longest_flag
         | 
| 56 56 |  | 
| 57 | 
            -
              # @ | 
| 58 | 
            -
              #  | 
| 59 | 
            -
              # | 
| 60 | 
            -
              # | 
| 61 | 
            -
              #  | 
| 62 | 
            -
              # | 
| 63 | 
            -
              # | 
| 64 | 
            -
              #  | 
| 65 | 
            -
              #  | 
| 66 | 
            -
              # | 
| 67 | 
            -
              # | 
| 68 | 
            -
              # | 
| 69 | 
            -
              #  | 
| 70 | 
            -
              # | 
| 71 | 
            -
              # @option opts [ | 
| 72 | 
            -
              #  | 
| 73 | 
            -
              # | 
| 74 | 
            -
              # | 
| 75 | 
            -
              # | 
| 57 | 
            +
              # @option opts [Boolean] :help
         | 
| 58 | 
            +
              #   * Automatically add the `help` option
         | 
| 59 | 
            +
              #
         | 
| 60 | 
            +
              # @option opts [Boolean] :strict
         | 
| 61 | 
            +
              #   * Raises when a non listed option is found, false by default
         | 
| 62 | 
            +
              #
         | 
| 63 | 
            +
              # @option opts [Boolean] :multiple_switches
         | 
| 64 | 
            +
              #   * Allows `-abc` to be processed as the options 'a', 'b', 'c' and will
         | 
| 65 | 
            +
              #     force their argument values to true. By default Slop with parse this
         | 
| 66 | 
            +
              #     as 'a' with the argument 'bc'
         | 
| 67 | 
            +
              #
         | 
| 68 | 
            +
              # @option opts [String] :banner
         | 
| 69 | 
            +
              #   * The banner text used for the help
         | 
| 70 | 
            +
              #
         | 
| 71 | 
            +
              # @option opts [Proc, #call] :on_empty
         | 
| 72 | 
            +
              #   * Any object that respondes to `call` which is executed when Slop has
         | 
| 73 | 
            +
              #     no items to parse
         | 
| 74 | 
            +
              #
         | 
| 75 | 
            +
              # @option opts [IO, #puts] :io ($stderr)
         | 
| 76 | 
            +
              #   * An IO object for writing to when :help => true is used
         | 
| 77 | 
            +
              #
         | 
| 78 | 
            +
              # @option opts [Boolean] :exit_on_help (true)
         | 
| 79 | 
            +
              #   * When false and coupled with the :help option, Slop will not exit
         | 
| 80 | 
            +
              #     inside of the `help` option
         | 
| 81 | 
            +
              #
         | 
| 82 | 
            +
              # @option opts [Boolean] :ignore_case (false)
         | 
| 83 | 
            +
              #   * Ignore options case
         | 
| 84 | 
            +
              #
         | 
| 85 | 
            +
              # @option opts [Proc, #call] :on_noopts
         | 
| 86 | 
            +
              #   * Trigger an event when no options are found
         | 
| 87 | 
            +
              #
         | 
| 88 | 
            +
              # @option opts [Boolean] :autocreate (false)
         | 
| 89 | 
            +
              #   * Autocreate options depending on the Array passed to {#parse}
         | 
| 90 | 
            +
              #
         | 
| 91 | 
            +
              # @option opts [Boolean] :arguments (false)
         | 
| 92 | 
            +
              #   * Set to true to enable all specified options to accept arguments
         | 
| 93 | 
            +
              #     by default
         | 
| 76 94 | 
             
              def initialize(*opts, &block)
         | 
| 77 95 | 
             
                sloptions = opts.last.is_a?(Hash) ? opts.pop : {}
         | 
| 78 96 | 
             
                sloptions[:banner] = opts.shift if opts[0].respond_to? :to_str
         | 
| @@ -80,6 +98,7 @@ class Slop | |
| 80 98 |  | 
| 81 99 | 
             
                @options = Options.new
         | 
| 82 100 | 
             
                @commands = {}
         | 
| 101 | 
            +
                @execution_block = nil
         | 
| 83 102 |  | 
| 84 103 | 
             
                @longest_flag = 0
         | 
| 85 104 | 
             
                @invalid_options = []
         | 
| @@ -89,6 +108,7 @@ class Slop | |
| 89 108 | 
             
                @ignore_case = sloptions[:ignore_case]
         | 
| 90 109 | 
             
                @multiple_switches = sloptions[:multiple_switches]
         | 
| 91 110 | 
             
                @autocreate = sloptions[:autocreate]
         | 
| 111 | 
            +
                @arguments = sloptions[:arguments]
         | 
| 92 112 | 
             
                @on_empty = sloptions[:on_empty]
         | 
| 93 113 | 
             
                @on_noopts = sloptions[:on_noopts] || sloptions[:on_optionless]
         | 
| 94 114 | 
             
                @sloptions = sloptions
         | 
| @@ -105,27 +125,27 @@ class Slop | |
| 105 125 | 
             
                end
         | 
| 106 126 | 
             
              end
         | 
| 107 127 |  | 
| 108 | 
            -
              # Set or return banner text | 
| 128 | 
            +
              # Set or return banner text
         | 
| 109 129 | 
             
              #
         | 
| 110 | 
            -
              # @param [String] text Displayed banner text | 
| 130 | 
            +
              # @param [String] text Displayed banner text
         | 
| 111 131 | 
             
              # @example
         | 
| 112 132 | 
             
              #   opts = Slop.parse do
         | 
| 113 133 | 
             
              #     banner "Usage - ruby foo.rb [arguments]"
         | 
| 114 134 | 
             
              #   end
         | 
| 115 | 
            -
              # @return [String] The current banner | 
| 135 | 
            +
              # @return [String] The current banner
         | 
| 116 136 | 
             
              def banner(text=nil)
         | 
| 117 137 | 
             
                @banner = text if text
         | 
| 118 138 | 
             
                @banner
         | 
| 119 139 | 
             
              end
         | 
| 120 140 |  | 
| 121 | 
            -
              # Parse a list of options, leaving the original Array unchanged | 
| 141 | 
            +
              # Parse a list of options, leaving the original Array unchanged
         | 
| 122 142 | 
             
              #
         | 
| 123 143 | 
             
              # @param [Array] items A list of items to parse
         | 
| 124 144 | 
             
              def parse(items=ARGV, &block)
         | 
| 125 145 | 
             
                parse_items items, &block
         | 
| 126 146 | 
             
              end
         | 
| 127 147 |  | 
| 128 | 
            -
              # Parse a list of options, removing parsed options from the original Array | 
| 148 | 
            +
              # Parse a list of options, removing parsed options from the original Array
         | 
| 129 149 | 
             
              #
         | 
| 130 150 | 
             
              # @param [Array] items A list of items to parse
         | 
| 131 151 | 
             
              def parse!(items=ARGV, &block)
         | 
| @@ -137,7 +157,7 @@ class Slop | |
| 137 157 | 
             
                @options.each(&block)
         | 
| 138 158 | 
             
              end
         | 
| 139 159 |  | 
| 140 | 
            -
              # @param [Symbol] key Option symbol | 
| 160 | 
            +
              # @param [Symbol] key Option symbol
         | 
| 141 161 | 
             
              # @example
         | 
| 142 162 | 
             
              #   opts[:name] #=> "Emily"
         | 
| 143 163 | 
             
              #   opts.get(:name) #=> "Emily"
         | 
| @@ -149,7 +169,7 @@ class Slop | |
| 149 169 | 
             
              end
         | 
| 150 170 | 
             
              alias :get :[]
         | 
| 151 171 |  | 
| 152 | 
            -
              # Specify an option with a short or long version, description and type | 
| 172 | 
            +
              # Specify an option with a short or long version, description and type
         | 
| 153 173 | 
             
              #
         | 
| 154 174 | 
             
              # @param [*] args Option configuration.
         | 
| 155 175 | 
             
              # @option args [Symbol, String] :short_flag Short option name.
         | 
| @@ -173,7 +193,8 @@ class Slop | |
| 173 193 | 
             
              def option(*args, &block)
         | 
| 174 194 | 
             
                options = args.last.is_a?(Hash) ? args.pop : {}
         | 
| 175 195 |  | 
| 176 | 
            -
                short, long, desc, arg = clean_options args
         | 
| 196 | 
            +
                short, long, desc, arg, extras = clean_options args
         | 
| 197 | 
            +
                options.merge!(extras)
         | 
| 177 198 | 
             
                option = Option.new self, short, long, desc, arg, options, &block
         | 
| 178 199 | 
             
                @options << option
         | 
| 179 200 |  | 
| @@ -240,7 +261,31 @@ class Slop | |
| 240 261 | 
             
              end
         | 
| 241 262 | 
             
              alias :on_optionless :on_noopts
         | 
| 242 263 |  | 
| 243 | 
            -
              #  | 
| 264 | 
            +
              # Add an execution block (for commands)
         | 
| 265 | 
            +
              #
         | 
| 266 | 
            +
              # @example
         | 
| 267 | 
            +
              #   opts = Slop.new do
         | 
| 268 | 
            +
              #     command :foo do
         | 
| 269 | 
            +
              #       on :v, :verbose
         | 
| 270 | 
            +
              #
         | 
| 271 | 
            +
              #       execute { |o| p o.verbose? }
         | 
| 272 | 
            +
              #     end
         | 
| 273 | 
            +
              #   end
         | 
| 274 | 
            +
              #   opts.parse %w[foo --verbose] #=> true
         | 
| 275 | 
            +
              #
         | 
| 276 | 
            +
              # @param [Object, #call] obj The object to be triggered when this command
         | 
| 277 | 
            +
              #   is invoked
         | 
| 278 | 
            +
              # @since 1.8.0
         | 
| 279 | 
            +
              # @yields [Slop] an instance of Slop for this command
         | 
| 280 | 
            +
              def execute(obj=nil, &block)
         | 
| 281 | 
            +
                if obj || block_given?
         | 
| 282 | 
            +
                  @execution_block = obj || block
         | 
| 283 | 
            +
                elsif @execution_block.respond_to?(:call)
         | 
| 284 | 
            +
                  @execution_block.call(self)
         | 
| 285 | 
            +
                end
         | 
| 286 | 
            +
              end
         | 
| 287 | 
            +
             | 
| 288 | 
            +
              # Returns the parsed list into a option/value hash
         | 
| 244 289 | 
             
              #
         | 
| 245 290 | 
             
              # @example
         | 
| 246 291 | 
             
              #   opts.to_hash #=> { 'name' => 'Emily' }
         | 
| @@ -253,7 +298,8 @@ class Slop | |
| 253 298 | 
             
              end
         | 
| 254 299 | 
             
              alias :to_h :to_hash
         | 
| 255 300 |  | 
| 256 | 
            -
              # Allows you to check whether an option was specified in the parsed list | 
| 301 | 
            +
              # Allows you to check whether an option was specified in the parsed list
         | 
| 302 | 
            +
              #
         | 
| 257 303 | 
             
              # Merely sugar for `present?`
         | 
| 258 304 | 
             
              #
         | 
| 259 305 | 
             
              # @example
         | 
| @@ -267,8 +313,10 @@ class Slop | |
| 267 313 | 
             
                present? meth.to_s.chomp '?'
         | 
| 268 314 | 
             
              end
         | 
| 269 315 |  | 
| 270 | 
            -
              # Check if an option is specified in the parsed list | 
| 271 | 
            -
              # | 
| 316 | 
            +
              # Check if an option is specified in the parsed list
         | 
| 317 | 
            +
              #
         | 
| 318 | 
            +
              # Does the same as Slop#option? but a convenience method for unacceptable
         | 
| 319 | 
            +
              # method names
         | 
| 272 320 | 
             
              #
         | 
| 273 321 | 
             
              # @param [Object] The object name to check
         | 
| 274 322 | 
             
              # @since 1.5.0
         | 
| @@ -277,7 +325,7 @@ class Slop | |
| 277 325 | 
             
                !!get(option_name)
         | 
| 278 326 | 
             
              end
         | 
| 279 327 |  | 
| 280 | 
            -
              # Returns the banner followed by available options listed on the next line | 
| 328 | 
            +
              # Returns the banner followed by available options listed on the next line
         | 
| 281 329 | 
             
              #
         | 
| 282 330 | 
             
              # @example
         | 
| 283 331 | 
             
              #  opts = Slop.parse do
         | 
| @@ -342,11 +390,17 @@ class Slop | |
| 342 390 |  | 
| 343 391 | 
             
                    if option.expects_argument? || option.accepts_optional_argument?
         | 
| 344 392 | 
             
                      argument ||= items.at(index + 1)
         | 
| 345 | 
            -
                      check_valid_argument!(option, argument)
         | 
| 346 393 | 
             
                      trash << index + 1
         | 
| 347 394 |  | 
| 395 | 
            +
                      if !option.accepts_optional_argument? && flag?(argument)
         | 
| 396 | 
            +
                        raise MissingArgumentError, "'#{option.key}' expects an argument, none given"
         | 
| 397 | 
            +
                      end
         | 
| 398 | 
            +
             | 
| 348 399 | 
             
                      if argument
         | 
| 349 | 
            -
                         | 
| 400 | 
            +
                        if option.match && !argument.match(option.match)
         | 
| 401 | 
            +
                          raise InvalidArgumentError, "'#{argument}' does not match #{option.match.inspect}"
         | 
| 402 | 
            +
                        end
         | 
| 403 | 
            +
             | 
| 350 404 | 
             
                        option.argument_value = argument
         | 
| 351 405 | 
             
                        option.call option.argument_value unless option.omit_exec?(items)
         | 
| 352 406 | 
             
                      else
         | 
| @@ -367,18 +421,6 @@ class Slop | |
| 367 421 | 
             
                items
         | 
| 368 422 | 
             
              end
         | 
| 369 423 |  | 
| 370 | 
            -
              def check_valid_argument!(option, argument)
         | 
| 371 | 
            -
                if !option.accepts_optional_argument? && flag?(argument)
         | 
| 372 | 
            -
                  raise MissingArgumentError, "'#{option.key}' expects an argument, none given"
         | 
| 373 | 
            -
                end
         | 
| 374 | 
            -
              end
         | 
| 375 | 
            -
             | 
| 376 | 
            -
              def check_matching_argument!(option, argument)
         | 
| 377 | 
            -
                if option.match && !argument.match(option.match)
         | 
| 378 | 
            -
                  raise InvalidArgumentError, "'#{argument}' does not match #{option.match.inspect}"
         | 
| 379 | 
            -
                end
         | 
| 380 | 
            -
              end
         | 
| 381 | 
            -
             | 
| 382 424 | 
             
              def check_optional_argument!(option, flag)
         | 
| 383 425 | 
             
                if option.accepts_optional_argument?
         | 
| 384 426 | 
             
                  option.call
         | 
| @@ -389,8 +431,7 @@ class Slop | |
| 389 431 |  | 
| 390 432 | 
             
              def raise_if_invalid_options!
         | 
| 391 433 | 
             
                return if !@strict || @invalid_options.empty?
         | 
| 392 | 
            -
                message = "Unknown option"
         | 
| 393 | 
            -
                message << 's' if @invalid_options.size > 1
         | 
| 434 | 
            +
                message = "Unknown option#{'s' if @invalid_options.size > 1}"
         | 
| 394 435 | 
             
                message << ' -- ' << @invalid_options.map { |o| "'#{o}'" }.join(', ')
         | 
| 395 436 | 
             
                raise InvalidOptionError, message
         | 
| 396 437 | 
             
              end
         | 
| @@ -400,9 +441,8 @@ class Slop | |
| 400 441 | 
             
                  if option = @options[switch]
         | 
| 401 442 | 
             
                    if option.expects_argument?
         | 
| 402 443 | 
             
                      raise MissingArgumentError, "'-#{switch}' expects an argument, used in multiple_switch context"
         | 
| 403 | 
            -
                    else
         | 
| 404 | 
            -
                      option.argument_value = true
         | 
| 405 444 | 
             
                    end
         | 
| 445 | 
            +
                    option.argument_value = true
         | 
| 406 446 | 
             
                  else
         | 
| 407 447 | 
             
                    raise InvalidOptionError, "Unknown option '-#{switch}'" if @strict
         | 
| 408 448 | 
             
                  end
         | 
| @@ -439,7 +479,7 @@ class Slop | |
| 439 479 | 
             
                  items.shift
         | 
| 440 480 | 
             
                  opts = @commands[command]
         | 
| 441 481 | 
             
                  delete ? opts.parse!(items) : opts.parse(items)
         | 
| 442 | 
            -
                   | 
| 482 | 
            +
                  opts.execute
         | 
| 443 483 | 
             
                end
         | 
| 444 484 | 
             
              end
         | 
| 445 485 |  | 
| @@ -452,6 +492,10 @@ class Slop | |
| 452 492 |  | 
| 453 493 | 
             
              def clean_options(args)
         | 
| 454 494 | 
             
                options = []
         | 
| 495 | 
            +
                extras = {}
         | 
| 496 | 
            +
                extras[:as] = args.find {|c| c.is_a? Class }
         | 
| 497 | 
            +
                args.delete(extras[:as])
         | 
| 498 | 
            +
                extras.delete(:as) unless extras[:as]
         | 
| 455 499 |  | 
| 456 500 | 
             
                short = args.first.to_s.sub(/\A--?/, '')
         | 
| 457 501 | 
             
                if short.size == 1
         | 
| @@ -463,14 +507,20 @@ class Slop | |
| 463 507 |  | 
| 464 508 | 
             
                long = args.first
         | 
| 465 509 | 
             
                boolean = [true, false].include? long
         | 
| 466 | 
            -
                if !boolean && long.to_s =~ /\A(?:--?)?[a- | 
| 510 | 
            +
                if !boolean && long.to_s =~ /\A(?:--?)?[a-z_-]+\s[A-Z\s\[\]]+\z/
         | 
| 511 | 
            +
                  arg, help = args.shift.split(/ /, 2)
         | 
| 512 | 
            +
                  options.push arg.sub(/\A--?/, '')
         | 
| 513 | 
            +
                  extras[:optional] = help[0, 1] == '[' && help[-1, 1] == ']'
         | 
| 514 | 
            +
                  extras[:help] = help
         | 
| 515 | 
            +
                elsif !boolean && long.to_s =~ /\A(?:--?)?[a-zA-Z][a-zA-Z0-9_-]+\z/
         | 
| 467 516 | 
             
                  options.push args.shift.to_s.sub(/\A--?/, '')
         | 
| 468 517 | 
             
                else
         | 
| 469 518 | 
             
                  options.push nil
         | 
| 470 519 | 
             
                end
         | 
| 471 520 |  | 
| 472 521 | 
             
                options.push args.first.respond_to?(:to_sym) ? args.shift : nil
         | 
| 473 | 
            -
                options.push args.shift ? true : false | 
| 522 | 
            +
                options.push @arguments ?  true : (args.shift ? true : false)
         | 
| 523 | 
            +
                options.push extras
         | 
| 474 524 | 
             
              end
         | 
| 475 525 |  | 
| 476 526 | 
             
              def flag?(str)
         | 
    
        data/lib/slop/option.rb
    CHANGED
    
    | @@ -195,11 +195,10 @@ class Slop | |
| 195 195 | 
             
                def build_longest_flag
         | 
| 196 196 | 
             
                  if @long_flag && @long_flag.size > @slop.longest_flag
         | 
| 197 197 | 
             
                    if @help.respond_to? :to_str
         | 
| 198 | 
            -
                       | 
| 198 | 
            +
                      @slop.longest_flag = @long_flag.size + @help.size
         | 
| 199 199 | 
             
                    else
         | 
| 200 | 
            -
                       | 
| 200 | 
            +
                      @slop.longest_flag = @long_flag.size
         | 
| 201 201 | 
             
                    end
         | 
| 202 | 
            -
                    @slop.longest_flag = size
         | 
| 203 202 | 
             
                  end
         | 
| 204 203 | 
             
                end
         | 
| 205 204 | 
             
              end
         | 
    
        data/slop.gemspec
    CHANGED
    
    
    
        data/test/commands_test.rb
    CHANGED
    
    | @@ -69,4 +69,21 @@ class CommandsTest < TestCase | |
| 69 69 | 
             
                assert incmd
         | 
| 70 70 | 
             
                refute inslop
         | 
| 71 71 | 
             
              end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
              test 'executing blocks' do
         | 
| 74 | 
            +
                foo = bar = nil
         | 
| 75 | 
            +
                slop = Slop.new
         | 
| 76 | 
            +
                slop.command :foo do
         | 
| 77 | 
            +
                  on :v, :verbose
         | 
| 78 | 
            +
                  execute { |o| foo = o.verbose? }
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
                slop.command :bar do
         | 
| 81 | 
            +
                  on :v, :verbose
         | 
| 82 | 
            +
                  execute { |o| bar = o.verbose? }
         | 
| 83 | 
            +
                end
         | 
| 84 | 
            +
                slop.parse %w[ foo --verbose ]
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                assert foo
         | 
| 87 | 
            +
                refute bar
         | 
| 88 | 
            +
              end
         | 
| 72 89 | 
             
            end
         | 
    
        data/test/slop_test.rb
    CHANGED
    
    | @@ -184,32 +184,45 @@ class SlopTest < TestCase | |
| 184 184 |  | 
| 185 185 | 
             
              test 'the shit out of clean_options' do
         | 
| 186 186 | 
             
                assert_equal(
         | 
| 187 | 
            -
                  ['s', 'short', 'short option', false],
         | 
| 187 | 
            +
                  ['s', 'short', 'short option', false, {}],
         | 
| 188 188 | 
             
                  clean_options('-s', '--short', 'short option')
         | 
| 189 189 | 
             
                )
         | 
| 190 190 |  | 
| 191 191 | 
             
                assert_equal(
         | 
| 192 | 
            -
                  [nil, 'long', 'long option only', true],
         | 
| 192 | 
            +
                  [nil, 'long', 'long option only', true, {}],
         | 
| 193 193 | 
             
                  clean_options('--long', 'long option only', true)
         | 
| 194 194 | 
             
                )
         | 
| 195 195 |  | 
| 196 196 | 
             
                assert_equal(
         | 
| 197 | 
            -
                  ['S', 'symbol', 'symbolize', false],
         | 
| 197 | 
            +
                  ['S', 'symbol', 'symbolize', false, {}],
         | 
| 198 198 | 
             
                  clean_options(:S, :symbol, 'symbolize')
         | 
| 199 199 | 
             
                )
         | 
| 200 200 |  | 
| 201 201 | 
             
                assert_equal(
         | 
| 202 | 
            -
                  ['a', nil, 'alphabetical only', true],
         | 
| 202 | 
            +
                  ['a', nil, 'alphabetical only', true, {}],
         | 
| 203 203 | 
             
                  clean_options('a', 'alphabetical only', true)
         | 
| 204 204 | 
             
                )
         | 
| 205 205 |  | 
| 206 206 | 
             
                assert_equal( # for description-less options
         | 
| 207 | 
            -
                  [nil, 'optiononly', nil, false],
         | 
| 207 | 
            +
                  [nil, 'optiononly', nil, false, {}],
         | 
| 208 208 | 
             
                  clean_options('--optiononly')
         | 
| 209 209 | 
             
                )
         | 
| 210 210 |  | 
| 211 | 
            -
                assert_equal( | 
| 212 | 
            -
             | 
| 211 | 
            +
                assert_equal(
         | 
| 212 | 
            +
                  ['f', 'foo', 'some description', false, {:optional => false, :help => 'BAR'}],
         | 
| 213 | 
            +
                  clean_options(:f, 'foo BAR', 'some description')
         | 
| 214 | 
            +
                )
         | 
| 215 | 
            +
             | 
| 216 | 
            +
                assert_equal(
         | 
| 217 | 
            +
                  [nil, 'bar', nil, false, {:optional => true, :help => '[STUFF]'}],
         | 
| 218 | 
            +
                  clean_options('bar [STUFF]')
         | 
| 219 | 
            +
                )
         | 
| 220 | 
            +
             | 
| 221 | 
            +
                assert_equal([nil, 'foo', nil, false, {:as => Array}], clean_options(:foo, Array, false))
         | 
| 222 | 
            +
                assert_equal([nil, 'foo', nil, false, {:as => Array}], clean_options(Array, :foo, false))
         | 
| 223 | 
            +
             | 
| 224 | 
            +
                assert_equal(['c', nil, nil, true, {}], clean_options(:c, true))
         | 
| 225 | 
            +
                assert_equal(['c', nil, nil, false, {}], clean_options(:c, false))
         | 
| 213 226 | 
             
              end
         | 
| 214 227 |  | 
| 215 228 | 
             
              test '[] returns an options argument value or a command or nil (in that order)' do
         | 
| @@ -407,4 +420,35 @@ class SlopTest < TestCase | |
| 407 420 | 
             
                assert_equal %w/foo bar etc/, opts[:a]
         | 
| 408 421 | 
             
              end
         | 
| 409 422 |  | 
| 423 | 
            +
              test ':arguments => true' do
         | 
| 424 | 
            +
                opts = Slop.new(:arguments) { on :foo }
         | 
| 425 | 
            +
                opts.parse %w/--foo bar/
         | 
| 426 | 
            +
             | 
| 427 | 
            +
                assert_equal 'bar', opts[:foo]
         | 
| 428 | 
            +
              end
         | 
| 429 | 
            +
             | 
| 430 | 
            +
              test 'long flag strings' do
         | 
| 431 | 
            +
                opts = Slop.new do
         | 
| 432 | 
            +
                  on 'f', 'foo BAR'
         | 
| 433 | 
            +
                  on 'bar [HELLO]'
         | 
| 434 | 
            +
                end
         | 
| 435 | 
            +
             | 
| 436 | 
            +
                assert opts.options[:foo].expects_argument?
         | 
| 437 | 
            +
                assert opts.options[:bar].accepts_optional_argument?
         | 
| 438 | 
            +
             | 
| 439 | 
            +
                assert_equal '    -f, --foo BAR     ', opts.options[:foo].to_s
         | 
| 440 | 
            +
                assert_equal '        --bar [HELLO] ', opts.options[:bar].to_s
         | 
| 441 | 
            +
              end
         | 
| 442 | 
            +
             | 
| 443 | 
            +
              test 'inline classes' do
         | 
| 444 | 
            +
                opts = Slop.new do
         | 
| 445 | 
            +
                  on :foo, Array, true
         | 
| 446 | 
            +
                  on Symbol, :bar, true
         | 
| 447 | 
            +
                end
         | 
| 448 | 
            +
                opts.parse %w/--foo one,two --bar hello/
         | 
| 449 | 
            +
             | 
| 450 | 
            +
                assert_equal %w[one two], opts[:foo]
         | 
| 451 | 
            +
                assert_equal :hello, opts[:bar]
         | 
| 452 | 
            +
              end
         | 
| 453 | 
            +
             | 
| 410 454 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -2,7 +2,7 @@ | |
| 2 2 | 
             
            name: slop
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 4 | 
             
              prerelease: 
         | 
| 5 | 
            -
              version: 1. | 
| 5 | 
            +
              version: 1.8.0
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors: 
         | 
| 8 8 | 
             
            - Lee Jarvis
         | 
| @@ -10,7 +10,7 @@ autorequire: | |
| 10 10 | 
             
            bindir: bin
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 12 |  | 
| 13 | 
            -
            date: 2011-06- | 
| 13 | 
            +
            date: 2011-06-12 00:00:00 Z
         | 
| 14 14 | 
             
            dependencies: []
         | 
| 15 15 |  | 
| 16 16 | 
             
            description: A simple DSL for gathering options and parsing the command line
         | 
| @@ -60,7 +60,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 60 60 | 
             
            requirements: []
         | 
| 61 61 |  | 
| 62 62 | 
             
            rubyforge_project: 
         | 
| 63 | 
            -
            rubygems_version: 1.8. | 
| 63 | 
            +
            rubygems_version: 1.8.5
         | 
| 64 64 | 
             
            signing_key: 
         | 
| 65 65 | 
             
            specification_version: 3
         | 
| 66 66 | 
             
            summary: Option gathering made easy
         |