clive 0.6.2 → 0.7.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/README.md +129 -126
- data/lib/clive.rb +30 -119
- data/lib/clive/bool.rb +32 -34
- data/lib/clive/command.rb +171 -54
- data/lib/clive/exceptions.rb +2 -2
- data/lib/clive/ext.rb +21 -3
- data/lib/clive/flag.rb +80 -67
- data/lib/clive/formatter.rb +180 -0
- data/lib/clive/option.rb +41 -25
- data/lib/clive/output.rb +14 -18
- data/lib/clive/parser.rb +79 -16
- data/lib/clive/switch.rb +8 -17
- data/lib/clive/tokens.rb +1 -1
- data/lib/clive/version.rb +2 -2
- data/spec/clive/bool_spec.rb +54 -0
- data/spec/clive/command_spec.rb +260 -0
- data/spec/clive/exceptions_spec.rb +1 -0
- data/spec/clive/ext_spec.rb +1 -0
- data/spec/clive/flag_spec.rb +84 -0
- data/spec/clive/formatter_spec.rb +108 -0
- data/spec/clive/option_spec.rb +34 -0
- data/spec/clive/output_spec.rb +5 -0
- data/spec/clive/parser_spec.rb +106 -0
- data/spec/clive/switch_spec.rb +14 -0
- data/spec/clive/tokens_spec.rb +38 -0
- data/spec/shared_specs.rb +16 -0
- data/spec/spec_helper.rb +12 -0
- metadata +34 -8
    
        data/lib/clive/bool.rb
    CHANGED
    
    | @@ -1,7 +1,8 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 1 | 
            +
            module Clive
         | 
| 2 | 
            +
             | 
| 3 3 | 
             
              # A switch which can be triggered with either --no-[name] and --[name].
         | 
| 4 | 
            -
              # The ' | 
| 4 | 
            +
              # The 'truth' of this is then passed to the block.
         | 
| 5 | 
            +
              #
         | 
| 5 6 | 
             
              class Bool < Option
         | 
| 6 7 | 
             
                attr_accessor :truth
         | 
| 7 8 |  | 
| @@ -13,27 +14,27 @@ class Clive | |
| 13 14 | 
             
                # +short+ and/or +desc+ can be omitted when creating a Boolean, all
         | 
| 14 15 | 
             
                # other arguments must be present.
         | 
| 15 16 | 
             
                #
         | 
| 16 | 
            -
                # @ | 
| 17 | 
            -
                #    | 
| 18 | 
            -
                #    | 
| 19 | 
            -
                #    | 
| 20 | 
            -
                # | 
| 17 | 
            +
                # @param names [Array[Symbol]]
         | 
| 18 | 
            +
                #   Names that the boolean switch can be called with, must include
         | 
| 19 | 
            +
                #   a long name (eg. 2 or more characters) so that the --no- can
         | 
| 20 | 
            +
                #   be prefixed.
         | 
| 21 | 
            +
                #
         | 
| 22 | 
            +
                # @param desc [String]
         | 
| 23 | 
            +
                #   A description of the bool.
         | 
| 24 | 
            +
                #
         | 
| 25 | 
            +
                # @param truth [true, false] 
         | 
| 26 | 
            +
                #   Truth of the switch to create.
         | 
| 21 27 | 
             
                #
         | 
| 22 | 
            -
                # @yield [ | 
| 23 | 
            -
                # @raise [MissingLongName]  | 
| 28 | 
            +
                # @yield [true, false] A block to be run when the switch is triggered
         | 
| 29 | 
            +
                # @raise [MissingLongName] Raised when a long name is not given
         | 
| 24 30 | 
             
                #
         | 
| 25 | 
            -
                def initialize( | 
| 31 | 
            +
                def initialize(names, desc, truth, &block)
         | 
| 26 32 | 
             
                  @names = []
         | 
| 27 | 
            -
                   | 
| 28 | 
            -
                     | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 32 | 
            -
                      else
         | 
| 33 | 
            -
                        @names << "no-#{i.to_s}" if i.length > 1
         | 
| 34 | 
            -
                      end
         | 
| 35 | 
            -
                    when String
         | 
| 36 | 
            -
                      @desc = i
         | 
| 33 | 
            +
                  names.each do |i|
         | 
| 34 | 
            +
                    if truth
         | 
| 35 | 
            +
                      @names << i.to_s
         | 
| 36 | 
            +
                    else
         | 
| 37 | 
            +
                      @names << "no-#{i.to_s}" if i.length > 1
         | 
| 37 38 | 
             
                    end
         | 
| 38 39 | 
             
                  end
         | 
| 39 40 |  | 
| @@ -42,27 +43,24 @@ class Clive | |
| 42 43 | 
             
                    raise MissingLongName, @names[0]
         | 
| 43 44 | 
             
                  end
         | 
| 44 45 |  | 
| 46 | 
            +
                  @desc = desc
         | 
| 45 47 | 
             
                  @truth = truth
         | 
| 46 48 | 
             
                  @block = block
         | 
| 47 49 | 
             
                end
         | 
| 48 50 |  | 
| 49 | 
            -
                # Run the block with  | 
| 51 | 
            +
                # Run the block with the switches truth.
         | 
| 50 52 | 
             
                def run
         | 
| 51 53 | 
             
                  @block.call(@truth)
         | 
| 52 54 | 
             
                end
         | 
| 53 55 |  | 
| 54 | 
            -
                #  | 
| 55 | 
            -
                # @ | 
| 56 | 
            -
                 | 
| 57 | 
            -
             | 
| 58 | 
            -
             | 
| 59 | 
            -
                  
         | 
| 60 | 
            -
             | 
| 61 | 
            -
                   | 
| 62 | 
            -
                  spaces = 1 if spaces < 1
         | 
| 63 | 
            -
                  s = spaces(spaces)
         | 
| 64 | 
            -
                  p = spaces(prepend)
         | 
| 65 | 
            -
                  "#{p}#{n}#{s}#{@desc}"
         | 
| 56 | 
            +
                # Should only return a hash when this is the 'true' switch.
         | 
| 57 | 
            +
                # @see Clive::Option#to_h
         | 
| 58 | 
            +
                def to_h
         | 
| 59 | 
            +
                  if @truth
         | 
| 60 | 
            +
                    {'names' => names_to_strings(true), 'desc' => @desc}
         | 
| 61 | 
            +
                  else
         | 
| 62 | 
            +
                    nil
         | 
| 63 | 
            +
                  end
         | 
| 66 64 | 
             
                end
         | 
| 67 65 |  | 
| 68 66 | 
             
              end
         | 
    
        data/lib/clive/command.rb
    CHANGED
    
    | @@ -1,4 +1,4 @@ | |
| 1 | 
            -
             | 
| 1 | 
            +
            module Clive
         | 
| 2 2 |  | 
| 3 3 | 
             
              # A string which describes the command to execute
         | 
| 4 4 | 
             
              #   eg. git add
         | 
| @@ -8,18 +8,18 @@ class Clive | |
| 8 8 |  | 
| 9 9 | 
             
                attr_accessor :options, :commands
         | 
| 10 10 | 
             
                attr_accessor :argv, :base
         | 
| 11 | 
            -
                 | 
| 11 | 
            +
                attr_reader   :names, :current_desc
         | 
| 12 12 |  | 
| 13 13 | 
             
                # Create a new Command instance
         | 
| 14 14 | 
             
                #
         | 
| 15 15 | 
             
                # @overload initialize(base, &block)
         | 
| 16 16 | 
             
                #   Creates a new base Command to house everything else
         | 
| 17 | 
            -
                #   @param [Boolean]  | 
| 17 | 
            +
                #   @param base [Boolean] whether the command is the base
         | 
| 18 18 | 
             
                #
         | 
| 19 | 
            -
                # @overload initialize( | 
| 19 | 
            +
                # @overload initialize(names, desc, &block)
         | 
| 20 20 | 
             
                #   Creates a new Command as part of the base Command
         | 
| 21 | 
            -
                #   @param [Symbol]  | 
| 22 | 
            -
                #   @param [String]  | 
| 21 | 
            +
                #   @param names [Symbol] the name of the command
         | 
| 22 | 
            +
                #   @param desc [String] the description of the command
         | 
| 23 23 | 
             
                #
         | 
| 24 24 | 
             
                # @yield A block to run, containing switches, flags and commands
         | 
| 25 25 | 
             
                #
         | 
| @@ -47,10 +47,15 @@ class Clive | |
| 47 47 | 
             
                    @block = block
         | 
| 48 48 | 
             
                  end
         | 
| 49 49 |  | 
| 50 | 
            -
                   | 
| 51 | 
            -
                   | 
| 52 | 
            -
                  @header  | 
| 50 | 
            +
                  # Create basic header "Usage: filename [command] [options]
         | 
| 51 | 
            +
                  #                  or "Usage: filename commandname(s) [options]
         | 
| 52 | 
            +
                  @header = "Usage: #{File.basename($0, '.*')} " << 
         | 
| 53 | 
            +
                            (@base ? "[command]" : @names.join(', ')) << 
         | 
| 54 | 
            +
                            " [options]"
         | 
| 55 | 
            +
                            
         | 
| 53 56 | 
             
                  @footer = nil
         | 
| 57 | 
            +
                  @current_desc = ""
         | 
| 58 | 
            +
                  help_formatter :default
         | 
| 54 59 |  | 
| 55 60 | 
             
                  self.build_help
         | 
| 56 61 | 
             
                end
         | 
| @@ -146,7 +151,7 @@ class Clive | |
| 146 151 | 
             
                      pre_command << i
         | 
| 147 152 | 
             
                    end
         | 
| 148 153 | 
             
                  end
         | 
| 149 | 
            -
             | 
| 154 | 
            +
             | 
| 150 155 | 
             
                  post_command = Tokens.new(tokens.array - pre_command - [command])
         | 
| 151 156 | 
             
                  pre_command_tokens = parse(pre_command)
         | 
| 152 157 | 
             
                  r = pre_command_tokens
         | 
| @@ -179,7 +184,7 @@ class Clive | |
| 179 184 | 
             
                    else
         | 
| 180 185 | 
             
                      if k == :word
         | 
| 181 186 | 
             
                        # add to last flag?
         | 
| 182 | 
            -
                        if r.last && r.last[0] == :flag && r.last.size - 2 < r.last[1]. | 
| 187 | 
            +
                        if r.last && r.last[0] == :flag && r.last.size - 2 < r.last[1].arg_size
         | 
| 183 188 | 
             
                          r.last.push(v)
         | 
| 184 189 | 
             
                        else
         | 
| 185 190 | 
             
                          r << [:argument, v]
         | 
| @@ -192,13 +197,16 @@ class Clive | |
| 192 197 | 
             
                  r
         | 
| 193 198 | 
             
                end
         | 
| 194 199 |  | 
| 195 | 
            -
             | 
| 200 | 
            +
                def to_h
         | 
| 201 | 
            +
                  {
         | 
| 202 | 
            +
                    'names' => @names,
         | 
| 203 | 
            +
                    'desc'  => @desc
         | 
| 204 | 
            +
                  }
         | 
| 205 | 
            +
                end
         | 
| 196 206 |  | 
| 197 | 
            -
                 | 
| 198 | 
            -
                  @option_missing = block
         | 
| 199 | 
            -
                end      
         | 
| 207 | 
            +
                
         | 
| 200 208 |  | 
| 201 | 
            -
              # @group  | 
| 209 | 
            +
              # @group DSL
         | 
| 202 210 |  | 
| 203 211 | 
             
                # Add a new command to +@commands+
         | 
| 204 212 | 
             
                #
         | 
| @@ -211,19 +219,35 @@ class Clive | |
| 211 219 | 
             
                #   and flags
         | 
| 212 220 | 
             
                #
         | 
| 213 221 | 
             
                def command(*args, &block)
         | 
| 214 | 
            -
                  @commands << Command.new(*args, &block)
         | 
| 222 | 
            +
                  @commands << Command.new(*args, @current_desc, &block)
         | 
| 223 | 
            +
                  @current_desc = ""
         | 
| 215 224 | 
             
                end
         | 
| 216 225 |  | 
| 217 226 | 
             
                # Add a new switch to +@switches+
         | 
| 218 227 | 
             
                # @see Switch#initialize
         | 
| 219 228 | 
             
                def switch(*args, &block)
         | 
| 220 | 
            -
                  @options << Switch.new( | 
| 229 | 
            +
                  @options << Switch.new(args, @current_desc, &block)
         | 
| 230 | 
            +
                  @current_desc = ""
         | 
| 221 231 | 
             
                end
         | 
| 222 232 |  | 
| 223 233 | 
             
                # Adds a new flag to +@flags+
         | 
| 224 234 | 
             
                # @see Flag#initialize
         | 
| 225 235 | 
             
                def flag(*args, &block)
         | 
| 226 | 
            -
                   | 
| 236 | 
            +
                  names = []
         | 
| 237 | 
            +
                  arg = []
         | 
| 238 | 
            +
                  args.each do |i|
         | 
| 239 | 
            +
                    if i.is_a? Symbol
         | 
| 240 | 
            +
                      names << i
         | 
| 241 | 
            +
                    else
         | 
| 242 | 
            +
                      if i[:arg]
         | 
| 243 | 
            +
                        arg << i[:arg]
         | 
| 244 | 
            +
                      else
         | 
| 245 | 
            +
                        arg << i[:args]
         | 
| 246 | 
            +
                      end
         | 
| 247 | 
            +
                    end
         | 
| 248 | 
            +
                  end
         | 
| 249 | 
            +
                  @options << Flag.new(names, @current_desc, arg, &block)
         | 
| 250 | 
            +
                  @current_desc = ""
         | 
| 227 251 | 
             
                end
         | 
| 228 252 |  | 
| 229 253 | 
             
                # Creates a boolean switch. This is done by adding two switches of
         | 
| @@ -232,21 +256,48 @@ class Clive | |
| 232 256 | 
             
                #
         | 
| 233 257 | 
             
                # @see Bool#initialize
         | 
| 234 258 | 
             
                def bool(*args, &block)
         | 
| 235 | 
            -
                  @options << Bool.new( | 
| 236 | 
            -
                  @options << Bool.new( | 
| 259 | 
            +
                  @options << Bool.new(args, @current_desc, true, &block)
         | 
| 260 | 
            +
                  @options << Bool.new(args, @current_desc, false, &block)
         | 
| 261 | 
            +
                  @current_desc= ""
         | 
| 237 262 | 
             
                end
         | 
| 238 263 |  | 
| 239 | 
            -
             | 
| 240 | 
            -
                
         | 
| 241 | 
            -
                # | 
| 242 | 
            -
                #  | 
| 243 | 
            -
                 | 
| 244 | 
            -
             | 
| 245 | 
            -
             | 
| 246 | 
            -
             | 
| 264 | 
            +
                # Add a description for the next option in the class. Or acts as an 
         | 
| 265 | 
            +
                # accessor for @desc.
         | 
| 266 | 
            +
                #
         | 
| 267 | 
            +
                # @example
         | 
| 268 | 
            +
                #
         | 
| 269 | 
            +
                #   class CLI
         | 
| 270 | 
            +
                #     include Clive::Parser
         | 
| 271 | 
            +
                #
         | 
| 272 | 
            +
                #     desc 'Force build docs'
         | 
| 273 | 
            +
                #     switch :force do
         | 
| 274 | 
            +
                #       # code
         | 
| 275 | 
            +
                #     end
         | 
| 276 | 
            +
                #   end
         | 
| 277 | 
            +
                #
         | 
| 278 | 
            +
                def desc(str=nil)
         | 
| 279 | 
            +
                  if str
         | 
| 280 | 
            +
                    @current_desc = str
         | 
| 281 | 
            +
                  else
         | 
| 282 | 
            +
                    @desc
         | 
| 247 283 | 
             
                  end
         | 
| 248 284 | 
             
                end
         | 
| 249 285 |  | 
| 286 | 
            +
                # Define a block to execute when the option to execute cannot be found.
         | 
| 287 | 
            +
                #
         | 
| 288 | 
            +
                # @example
         | 
| 289 | 
            +
                #
         | 
| 290 | 
            +
                #   class CLI
         | 
| 291 | 
            +
                #     include Clive::Parser
         | 
| 292 | 
            +
                #
         | 
| 293 | 
            +
                #     option_missing do |name|
         | 
| 294 | 
            +
                #       puts "#{name} couldn't be found"
         | 
| 295 | 
            +
                #     end
         | 
| 296 | 
            +
                #
         | 
| 297 | 
            +
                def option_missing(&block)
         | 
| 298 | 
            +
                  @option_missing = block
         | 
| 299 | 
            +
                end      
         | 
| 300 | 
            +
                
         | 
| 250 301 | 
             
                # Set the header
         | 
| 251 302 | 
             
                def header(val)
         | 
| 252 303 | 
             
                  @header = val
         | 
| @@ -257,40 +308,106 @@ class Clive | |
| 257 308 | 
             
                  @footer = val
         | 
| 258 309 | 
             
                end
         | 
| 259 310 |  | 
| 260 | 
            -
             | 
| 261 | 
            -
                  a = @names.sort.join(', ')
         | 
| 262 | 
            -
                  b = @desc
         | 
| 263 | 
            -
                  s = spaces(width-a.length)
         | 
| 264 | 
            -
                  p = spaces(prepend)
         | 
| 265 | 
            -
                  "#{p}#{a}#{s}#{b}"
         | 
| 266 | 
            -
                end
         | 
| 311 | 
            +
              # @group Help
         | 
| 267 312 |  | 
| 313 | 
            +
                # This actually creates a switch with "-h" and "--help" that controls
         | 
| 314 | 
            +
                # the help on this command.
         | 
| 315 | 
            +
                def build_help
         | 
| 316 | 
            +
                  @options << Switch.new([:h, :help], "Display help") do
         | 
| 317 | 
            +
                    puts self.help
         | 
| 318 | 
            +
                    exit 0
         | 
| 319 | 
            +
                  end
         | 
| 320 | 
            +
                end
         | 
| 321 | 
            +
             | 
| 268 322 | 
             
                # Generate the summary for help, show all flags and switches, but do not
         | 
| 269 323 | 
             
                # show the flags and switches within each command. Should also prepend the
         | 
| 270 324 | 
             
                # header and append the footer if set.
         | 
| 271 | 
            -
                def help | 
| 272 | 
            -
                   | 
| 325 | 
            +
                def help
         | 
| 326 | 
            +
                  @formatter.format(@header, @footer, @commands, @options)
         | 
| 327 | 
            +
                end
         | 
| 328 | 
            +
                
         | 
| 329 | 
            +
                # This allows you to define how the output from #help looks.
         | 
| 330 | 
            +
                #
         | 
| 331 | 
            +
                # For this you have access to several tokens which are evaluated in an object
         | 
| 332 | 
            +
                # with the correct values, this means you are able to use #join on arrays or
         | 
| 333 | 
            +
                # prepend, etc. The variables (tokens) are:
         | 
| 334 | 
            +
                #
         | 
| 335 | 
            +
                # * prepend - a string of spaces as specified when #help_formatter is called
         | 
| 336 | 
            +
                # * names - an array of names for the option
         | 
| 337 | 
            +
                # * spaces - a string of spaces to align the descriptions properly
         | 
| 338 | 
            +
                # * desc - a string of the description for the option
         | 
| 339 | 
            +
                #
         | 
| 340 | 
            +
                # And for flags you have access to:
         | 
| 341 | 
            +
                #
         | 
| 342 | 
            +
                # * args - an array of arguments for the flag
         | 
| 343 | 
            +
                # * options - an array of options to choose from
         | 
| 344 | 
            +
                #
         | 
| 345 | 
            +
                #
         | 
| 346 | 
            +
                # @overload help_formatter(args, &block)
         | 
| 347 | 
            +
                #   Create a new help formatter to use.
         | 
| 348 | 
            +
                #   @param args [Hash]
         | 
| 349 | 
            +
                #   @option args [Integer] :width Width before flexible spaces
         | 
| 350 | 
            +
                #   @option args [Integer] :prepend Width of spaces to prepend with
         | 
| 351 | 
            +
                #
         | 
| 352 | 
            +
                # @overload help_formatter(name)
         | 
| 353 | 
            +
                #   Use an existing help formatter.
         | 
| 354 | 
            +
                #   @param name [Symbol] name of the formatter (either +:default+ or +:white+)
         | 
| 355 | 
            +
                #
         | 
| 356 | 
            +
                #
         | 
| 357 | 
            +
                # @example
         | 
| 358 | 
            +
                #   
         | 
| 359 | 
            +
                #   CLI.help_formatter do |h|
         | 
| 360 | 
            +
                #
         | 
| 361 | 
            +
                #     h.switch  "{prepend}{names.join(', ')} {spaces}{desc.grey}"
         | 
| 362 | 
            +
                #     h.bool    "{prepend}{names.join(', ')} {spaces}{desc.grey}"
         | 
| 363 | 
            +
                #     h.flag    "{prepend}{names.join(', ')} {args.join(' ')} {spaces}{desc.grey}"
         | 
| 364 | 
            +
                #     h.command "{prepend}{names.join(', ')} {spaces}{desc.grey}"
         | 
| 365 | 
            +
                #
         | 
| 366 | 
            +
                #   end
         | 
| 367 | 
            +
                #   
         | 
| 368 | 
            +
                #   
         | 
| 369 | 
            +
                def help_formatter(*args, &block)    
         | 
| 370 | 
            +
                  if block_given?
         | 
| 371 | 
            +
                    width   = 30
         | 
| 372 | 
            +
                    prepend = 5
         | 
| 273 373 |  | 
| 274 | 
            -
             | 
| 275 | 
            -
             | 
| 276 | 
            -
             | 
| 277 | 
            -
             | 
| 278 | 
            -
             | 
| 374 | 
            +
                    unless args.empty?
         | 
| 375 | 
            +
                      args[0].each do |k,v|
         | 
| 376 | 
            +
                        case k
         | 
| 377 | 
            +
                        when :width
         | 
| 378 | 
            +
                          width = v
         | 
| 379 | 
            +
                        when :prepend
         | 
| 380 | 
            +
                          prepend = v
         | 
| 381 | 
            +
                        end
         | 
| 382 | 
            +
                      end
         | 
| 279 383 | 
             
                    end
         | 
| 280 | 
            -
             | 
| 281 | 
            -
             | 
| 282 | 
            -
             | 
| 283 | 
            -
                     | 
| 284 | 
            -
             | 
| 285 | 
            -
             | 
| 384 | 
            +
                    
         | 
| 385 | 
            +
                    @formatter = Formatter.new(width, prepend)
         | 
| 386 | 
            +
                    block.call(@formatter)
         | 
| 387 | 
            +
                    @formatter
         | 
| 388 | 
            +
                  else
         | 
| 389 | 
            +
                    case args[0]
         | 
| 390 | 
            +
                    when :default
         | 
| 391 | 
            +
                       help_formatter do |h|
         | 
| 392 | 
            +
                        h.switch  "{prepend}{names.join(', ')}  {spaces}{desc.grey}"
         | 
| 393 | 
            +
                        h.bool    "{prepend}{names.join(', ')}  {spaces}{desc.grey}"
         | 
| 394 | 
            +
                        h.flag    "{prepend}{names.join(', ')} {args.join(' ')}  {spaces}" << 
         | 
| 395 | 
            +
                                    "{desc.grey} {options.join('(', ', ', ')').blue.bold}"
         | 
| 396 | 
            +
                        h.command "{prepend}{names.join(', ')}  {spaces}{desc.grey}"
         | 
| 397 | 
            +
                      end
         | 
| 398 | 
            +
                    
         | 
| 399 | 
            +
                    when :white
         | 
| 400 | 
            +
                      help_formatter do |h|
         | 
| 401 | 
            +
                        h.switch  "{prepend}{names.join(', ')}  {spaces}{desc}"
         | 
| 402 | 
            +
                        h.bool    "{prepend}{names.join(', ')}  {spaces}{desc}"
         | 
| 403 | 
            +
                        h.flag    "{prepend}{names.join(', ')} {args.join(' ')}  {spaces}" << 
         | 
| 404 | 
            +
                                    "{desc} {options.join('(', ', ', ')').bold}"
         | 
| 405 | 
            +
                        h.command "{prepend}{names.join(', ')}  {spaces}{desc}"
         | 
| 406 | 
            +
                      end
         | 
| 407 | 
            +
                    
         | 
| 286 408 | 
             
                    end
         | 
| 287 409 | 
             
                  end
         | 
| 288 | 
            -
                  
         | 
| 289 | 
            -
                  summary << "\n#{@footer}\n" if @footer
         | 
| 290 | 
            -
                 
         | 
| 291 | 
            -
                  summary
         | 
| 292 410 | 
             
                end
         | 
| 293 411 |  | 
| 294 | 
            -
                
         | 
| 295 412 | 
             
              end
         | 
| 296 413 | 
             
            end
         | 
    
        data/lib/clive/exceptions.rb
    CHANGED
    
    
    
        data/lib/clive/ext.rb
    CHANGED
    
    | @@ -1,5 +1,4 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 1 | 
            +
            module Clive
         | 
| 3 2 | 
             
              class Array < ::Array
         | 
| 4 3 |  | 
| 5 4 | 
             
                # If passed a Symbol or String will get the option or command with that name.
         | 
| @@ -49,5 +48,24 @@ class Clive | |
| 49 48 | 
             
                  result
         | 
| 50 49 | 
             
                end
         | 
| 51 50 |  | 
| 51 | 
            +
                alias_method :_join, :join
         | 
| 52 | 
            +
                
         | 
| 53 | 
            +
                def join(*args)
         | 
| 54 | 
            +
                  case args.size
         | 
| 55 | 
            +
                  when 1
         | 
| 56 | 
            +
                    self._join(args[0])
         | 
| 57 | 
            +
                    
         | 
| 58 | 
            +
                  when 2 # use second for last eg. 1, 2 and 3
         | 
| 59 | 
            +
                    self[0..-2]._join(args[0]) << args[1] << self[-1]
         | 
| 60 | 
            +
                    
         | 
| 61 | 
            +
                  when 3 # prepend and append 1st and 3rd eg. (1, 2, 3)
         | 
| 62 | 
            +
                    if self[0] != ""
         | 
| 63 | 
            +
                      args[0] << self._join(args[1]) << args[2]
         | 
| 64 | 
            +
                    else
         | 
| 65 | 
            +
                      ""
         | 
| 66 | 
            +
                    end
         | 
| 67 | 
            +
                  end
         | 
| 68 | 
            +
                end
         | 
| 69 | 
            +
                
         | 
| 52 70 | 
             
              end
         | 
| 53 | 
            -
            end
         | 
| 71 | 
            +
            end
         |