cl 0.1.12 → 0.1.13
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -3
- data/Gemfile.lock +2 -2
- data/NOTES.md +12 -8
- data/README.md +897 -13
- data/examples/readme/alias +22 -0
- data/examples/readme/arg +16 -0
- data/examples/readme/arg_array +16 -0
- data/examples/readme/arg_type +18 -0
- data/examples/readme/args_splat +43 -0
- data/examples/readme/array +18 -0
- data/examples/readme/default +18 -0
- data/examples/readme/deprecated +21 -0
- data/examples/readme/deprecated_alias +20 -0
- data/examples/readme/downcase +18 -0
- data/examples/readme/enum +26 -0
- data/examples/readme/example +17 -0
- data/examples/readme/format +29 -0
- data/examples/readme/internal +18 -0
- data/examples/readme/opts +29 -0
- data/examples/readme/opts_block +26 -0
- data/examples/readme/range +29 -0
- data/examples/readme/required +29 -0
- data/examples/readme/requireds +36 -0
- data/examples/readme/requires +32 -0
- data/examples/readme/see +21 -0
- data/examples/readme/type +22 -0
- data/lib/cl.rb +26 -66
- data/lib/cl/arg.rb +9 -5
- data/lib/cl/cast.rb +5 -1
- data/lib/cl/cmd.rb +11 -49
- data/lib/cl/ctx.rb +3 -5
- data/lib/cl/dsl.rb +176 -0
- data/lib/cl/errors.rb +73 -0
- data/lib/cl/help/cmd.rb +8 -3
- data/lib/cl/helper.rb +8 -0
- data/lib/cl/opt.rb +13 -0
- data/lib/cl/opts.rb +27 -8
- data/lib/cl/runner.rb +10 -0
- data/lib/cl/runner/default.rb +22 -2
- data/lib/cl/runner/multi.rb +6 -4
- data/lib/cl/ui.rb +11 -2
- data/lib/cl/version.rb +1 -1
- metadata +27 -2
    
        data/lib/cl/errors.rb
    ADDED
    
    | @@ -0,0 +1,73 @@ | |
| 1 | 
            +
            class Cl
         | 
| 2 | 
            +
              class Error < StandardError
         | 
| 3 | 
            +
                MSGS = {
         | 
| 4 | 
            +
                  unknown_cmd:    'Unknown command: %s',
         | 
| 5 | 
            +
                  missing_args:   'Missing arguments (given: %s, required: %s)',
         | 
| 6 | 
            +
                  too_many_args:  'Too many arguments (given: %s, allowed: %s)',
         | 
| 7 | 
            +
                  wrong_type:     'Wrong argument type (given: %s, expected: %s)',
         | 
| 8 | 
            +
                  out_of_range:   'Out of range: %s',
         | 
| 9 | 
            +
                  invalid_format: 'Invalid format: %s',
         | 
| 10 | 
            +
                  unknown_values: 'Unknown value: %s',
         | 
| 11 | 
            +
                  required_opt:   'Missing required option: %s',
         | 
| 12 | 
            +
                  required_opts:  'Missing required options: %s',
         | 
| 13 | 
            +
                  requires_opt:   'Missing option: %s',
         | 
| 14 | 
            +
                  requires_opts:  'Missing options: %s',
         | 
| 15 | 
            +
                }
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def initialize(msg, *args)
         | 
| 18 | 
            +
                  super(MSGS[msg] ? MSGS[msg] % args : msg)
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              ArgumentError = Class.new(Error)
         | 
| 23 | 
            +
              OptionError = Class.new(Error)
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              class UnknownCmd < Error
         | 
| 26 | 
            +
                def initialize(args)
         | 
| 27 | 
            +
                  super(:unknown_cmd, args.join(' '))
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              class RequiredOpts < OptionError
         | 
| 32 | 
            +
                def initialize(opts)
         | 
| 33 | 
            +
                  msg = opts.size == 1 ? :required_opt : :required_opts
         | 
| 34 | 
            +
                  super(msg, opts.join(', '))
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              class RequiredsOpts < OptionError
         | 
| 39 | 
            +
                def initialize(opts)
         | 
| 40 | 
            +
                  opts = opts.map { |alts| alts.map { |alt| Array(alt).join(' and ') }.join(', or ' ) }
         | 
| 41 | 
            +
                  super(:requires_opts, opts.join('; '))
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
              class RequiresOpts < OptionError
         | 
| 46 | 
            +
                def initialize(opts)
         | 
| 47 | 
            +
                  msg = opts.size == 1 ? :requires_opt : :requires_opts
         | 
| 48 | 
            +
                  opts = opts.map { |one, other| "#{one} (required by #{other})" }.join(', ')
         | 
| 49 | 
            +
                  super(msg, opts)
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
              class OutOfRange < OptionError
         | 
| 54 | 
            +
                def initialize(opts)
         | 
| 55 | 
            +
                  opts = opts.map { |opt, opts| "#{opt} (#{opts.map { |pair| pair.join(': ') }.join(', ')})" }.join(', ')
         | 
| 56 | 
            +
                  super(:out_of_range, opts)
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
              end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
              class InvalidFormat < OptionError
         | 
| 61 | 
            +
                def initialize(opts)
         | 
| 62 | 
            +
                  opts = opts.map { |opt, format| "#{opt} (format: #{format})" }.join(', ')
         | 
| 63 | 
            +
                  super(:invalid_format, opts)
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
              end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
              class UnknownValues < OptionError
         | 
| 68 | 
            +
                def initialize(opts)
         | 
| 69 | 
            +
                  opts = opts.map { |(key, value, known)| "#{key}=#{value} (known values: #{known.join(', ')})" }.join(', ')
         | 
| 70 | 
            +
                  super(:unknown_values, opts)
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
              end
         | 
| 73 | 
            +
            end
         | 
    
        data/lib/cl/help/cmd.rb
    CHANGED
    
    | @@ -13,7 +13,7 @@ class Cl | |
| 13 13 | 
             
                  end
         | 
| 14 14 |  | 
| 15 15 | 
             
                  def format
         | 
| 16 | 
            -
                    [usage, arguments, options, common,  | 
| 16 | 
            +
                    [usage, summary, description, arguments, options, common, examples].compact.join("\n\n")
         | 
| 17 17 | 
             
                  end
         | 
| 18 18 |  | 
| 19 19 | 
             
                  def usage
         | 
| @@ -40,6 +40,10 @@ class Cl | |
| 40 40 | 
             
                    ['Common Options:', table(:cmmn)] if common?
         | 
| 41 41 | 
             
                  end
         | 
| 42 42 |  | 
| 43 | 
            +
                  def examples
         | 
| 44 | 
            +
                    ['Examples:', indent(cmd.examples)] if cmd.examples
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
             | 
| 43 47 | 
             
                  def table(name)
         | 
| 44 48 | 
             
                    table = send(name)
         | 
| 45 49 | 
             
                    indent(table.to_s(width - table.width + 5))
         | 
| @@ -77,7 +81,7 @@ class Cl | |
| 77 81 | 
             
                    opts = cmd.required
         | 
| 78 82 | 
             
                    strs = opts.map { |alts| alts.map { |alt| Array(alt).join(' and ') }.join(', or ' ) }
         | 
| 79 83 | 
             
                    strs = strs.map { |str| "Either #{str} are required." }.join("\n")
         | 
| 80 | 
            -
                    indent(strs)
         | 
| 84 | 
            +
                    indent(strs) unless strs.empty?
         | 
| 81 85 | 
             
                  end
         | 
| 82 86 |  | 
| 83 87 | 
             
                  def common?
         | 
| @@ -90,7 +94,7 @@ class Cl | |
| 90 94 |  | 
| 91 95 | 
             
                  def format_obj(obj)
         | 
| 92 96 | 
             
                    opts = []
         | 
| 93 | 
            -
                    opts << "type: #{format_type(obj)}"
         | 
| 97 | 
            +
                    opts << "type: #{format_type(obj)}" unless obj.type == :flag
         | 
| 94 98 | 
             
                    opts << 'required: true' if obj.required?
         | 
| 95 99 | 
             
                    opts += format_opt(obj) if obj.is_a?(Opt)
         | 
| 96 100 | 
             
                    opts = opts.join(', ')
         | 
| @@ -107,6 +111,7 @@ class Cl | |
| 107 111 | 
             
                    opts << "known values: #{format_enum(opt)}" if opt.enum?
         | 
| 108 112 | 
             
                    opts << "format: #{opt.format}" if opt.format?
         | 
| 109 113 | 
             
                    opts << "downcase: true" if opt.downcase?
         | 
| 114 | 
            +
                    opts << "min: #{opt.min}" if opt.min?
         | 
| 110 115 | 
             
                    opts << "max: #{opt.max}" if opt.max?
         | 
| 111 116 | 
             
                    opts << "e.g.: #{opt.example}" if opt.example?
         | 
| 112 117 | 
             
                    opts << "see: #{opt.see}" if opt.see?
         | 
    
        data/lib/cl/helper.rb
    CHANGED
    
    
    
        data/lib/cl/opt.rb
    CHANGED
    
    | @@ -64,6 +64,7 @@ class Cl | |
| 64 64 | 
             
                def deprecated
         | 
| 65 65 | 
             
                  return [name, opts[:deprecated]] unless opts[:deprecated].is_a?(Symbol)
         | 
| 66 66 | 
             
                  [opts[:deprecated], name] if opts[:deprecated]
         | 
| 67 | 
            +
                  # [name, opts[:deprecated]] if opts[:deprecated]
         | 
| 67 68 | 
             
                end
         | 
| 68 69 |  | 
| 69 70 | 
             
                def downcase?
         | 
| @@ -119,6 +120,14 @@ class Cl | |
| 119 120 | 
             
                  !!opts[:internal]
         | 
| 120 121 | 
             
                end
         | 
| 121 122 |  | 
| 123 | 
            +
                def min?
         | 
| 124 | 
            +
                  int? && !!opts[:min]
         | 
| 125 | 
            +
                end
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                def min
         | 
| 128 | 
            +
                  opts[:min]
         | 
| 129 | 
            +
                end
         | 
| 130 | 
            +
             | 
| 122 131 | 
             
                def max?
         | 
| 123 132 | 
             
                  int? && !!opts[:max]
         | 
| 124 133 | 
             
                end
         | 
| @@ -147,6 +156,10 @@ class Cl | |
| 147 156 | 
             
                  opts[:see]
         | 
| 148 157 | 
             
                end
         | 
| 149 158 |  | 
| 159 | 
            +
                def separator
         | 
| 160 | 
            +
                  opts[:sep]
         | 
| 161 | 
            +
                end
         | 
| 162 | 
            +
             | 
| 150 163 | 
             
                def block
         | 
| 151 164 | 
             
                  # raise if no block was given, and the option's name cannot be inferred
         | 
| 152 165 | 
             
                  super || method(:assign)
         | 
    
        data/lib/cl/opts.rb
    CHANGED
    
    | @@ -24,6 +24,7 @@ class Cl | |
| 24 24 | 
             
                end
         | 
| 25 25 |  | 
| 26 26 | 
             
                def <<(opt)
         | 
| 27 | 
            +
                  delete(opt)
         | 
| 27 28 | 
             
                  # keep the --help option at the end for help output
         | 
| 28 29 | 
             
                  opts.empty? ? opts << opt : opts.insert(-2, opt)
         | 
| 29 30 | 
             
                end
         | 
| @@ -36,6 +37,10 @@ class Cl | |
| 36 37 | 
             
                  opts.each(&block)
         | 
| 37 38 | 
             
                end
         | 
| 38 39 |  | 
| 40 | 
            +
                def delete(opt)
         | 
| 41 | 
            +
                  opts.delete(opts.detect { |o| o.strs == opt.strs })
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 39 44 | 
             
                def to_a
         | 
| 40 45 | 
             
                  opts
         | 
| 41 46 | 
             
                end
         | 
| @@ -60,7 +65,7 @@ class Cl | |
| 60 65 | 
             
                    validate_requireds(cmd, opts)
         | 
| 61 66 | 
             
                    validate_required(opts)
         | 
| 62 67 | 
             
                    validate_requires(opts)
         | 
| 63 | 
            -
                     | 
| 68 | 
            +
                    validate_range(opts)
         | 
| 64 69 | 
             
                    validate_format(opts)
         | 
| 65 70 | 
             
                    validate_enum(opts)
         | 
| 66 71 | 
             
                  end
         | 
| @@ -81,9 +86,9 @@ class Cl | |
| 81 86 | 
             
                    raise RequiresOpts.new(invert(opts)) if opts.any?
         | 
| 82 87 | 
             
                  end
         | 
| 83 88 |  | 
| 84 | 
            -
                  def  | 
| 85 | 
            -
                    opts =  | 
| 86 | 
            -
                    raise  | 
| 89 | 
            +
                  def validate_range(opts)
         | 
| 90 | 
            +
                    opts = out_of_range(opts)
         | 
| 91 | 
            +
                    raise OutOfRange.new(opts) if opts.any?
         | 
| 87 92 | 
             
                  end
         | 
| 88 93 |  | 
| 89 94 | 
             
                  def validate_format(opts)
         | 
| @@ -114,13 +119,19 @@ class Cl | |
| 114 119 | 
             
                    end.compact
         | 
| 115 120 | 
             
                  end
         | 
| 116 121 |  | 
| 117 | 
            -
                  def  | 
| 118 | 
            -
                     | 
| 119 | 
            -
                      value = opts[opt.name]
         | 
| 120 | 
            -
                       | 
| 122 | 
            +
                  def out_of_range(opts)
         | 
| 123 | 
            +
                    self.opts.map do |opt|
         | 
| 124 | 
            +
                      next unless value = opts[opt.name]
         | 
| 125 | 
            +
                      range = only(opt.opts, :min, :max)
         | 
| 126 | 
            +
                      [opt.name, compact(range)] if out_of_range?(range, value)
         | 
| 121 127 | 
             
                    end.compact
         | 
| 122 128 | 
             
                  end
         | 
| 123 129 |  | 
| 130 | 
            +
                  def out_of_range?(range, value)
         | 
| 131 | 
            +
                    min, max = range.values_at(:min, :max)
         | 
| 132 | 
            +
                    min && value < min || max && value > max
         | 
| 133 | 
            +
                  end
         | 
| 134 | 
            +
             | 
| 124 135 | 
             
                  def invalid_format(opts)
         | 
| 125 136 | 
             
                    select(&:format?).map do |opt|
         | 
| 126 137 | 
             
                      value = opts[opt.name]
         | 
| @@ -163,6 +174,14 @@ class Cl | |
| 163 174 | 
             
                    end.to_h
         | 
| 164 175 | 
             
                  end
         | 
| 165 176 |  | 
| 177 | 
            +
                  def compact(hash, *keys)
         | 
| 178 | 
            +
                    hash.reject { |_, value| value.nil? }.to_h
         | 
| 179 | 
            +
                  end
         | 
| 180 | 
            +
             | 
| 181 | 
            +
                  def only(hash, *keys)
         | 
| 182 | 
            +
                    hash.select { |key, _| keys.include?(key) }.to_h
         | 
| 183 | 
            +
                  end
         | 
| 184 | 
            +
             | 
| 166 185 | 
             
                  def invert(hash)
         | 
| 167 186 | 
             
                    hash.map { |key, obj| Array(obj).map { |obj| [obj, key] } }.flatten(1).to_h
         | 
| 168 187 | 
             
                  end
         | 
    
        data/lib/cl/runner.rb
    ADDED
    
    
    
        data/lib/cl/runner/default.rb
    CHANGED
    
    | @@ -5,6 +5,8 @@ require 'cl/helper' | |
| 5 5 | 
             
            class Cl
         | 
| 6 6 | 
             
              module Runner
         | 
| 7 7 | 
             
                class Default
         | 
| 8 | 
            +
                  Runner.register :default, self
         | 
| 9 | 
            +
             | 
| 8 10 | 
             
                  extend Forwardable
         | 
| 9 11 | 
             
                  include Merge
         | 
| 10 12 |  | 
| @@ -29,11 +31,28 @@ class Cl | |
| 29 31 | 
             
                    Help.new(ctx, [cmd.registry_key])
         | 
| 30 32 | 
             
                  end
         | 
| 31 33 |  | 
| 32 | 
            -
             | 
| 34 | 
            +
                    private
         | 
| 33 35 |  | 
| 34 | 
            -
                    #  | 
| 36 | 
            +
                    # Finds a command class to run for the given arguments.
         | 
| 37 | 
            +
                    #
         | 
| 38 | 
            +
                    # Stopping at any arg that starts with a dash, find the command
         | 
| 35 39 | 
             
                    # with the key matching the most args when joined with ":", and
         | 
| 36 40 | 
             
                    # remove these used args from the array
         | 
| 41 | 
            +
                    #
         | 
| 42 | 
            +
                    # For example, if there are commands registered with the keys
         | 
| 43 | 
            +
                    #
         | 
| 44 | 
            +
                    #   git:pull
         | 
| 45 | 
            +
                    #   git:push
         | 
| 46 | 
            +
                    #
         | 
| 47 | 
            +
                    # then for the arguments:
         | 
| 48 | 
            +
                    #
         | 
| 49 | 
            +
                    #   git push master
         | 
| 50 | 
            +
                    #
         | 
| 51 | 
            +
                    # the method `lookup` will find the constant registered as `git:push`,
         | 
| 52 | 
            +
                    # remove these from the `args` array, and return both the constant, and
         | 
| 53 | 
            +
                    # the remaining args.
         | 
| 54 | 
            +
                    #
         | 
| 55 | 
            +
                    # @param args [Array<String>] arguments to run (usually ARGV)
         | 
| 37 56 | 
             
                    def lookup(args)
         | 
| 38 57 | 
             
                      keys = args.take_while { |key| !key.start_with?('-') }
         | 
| 39 58 |  | 
| @@ -44,6 +63,7 @@ class Cl | |
| 44 63 | 
             
                      end
         | 
| 45 64 |  | 
| 46 65 | 
             
                      cmd, keys = keys[0].last
         | 
| 66 | 
            +
                      cmd || raise(UnknownCmd.new(args))
         | 
| 47 67 | 
             
                      keys.each { |key| args.delete_at(args.index(key)) }
         | 
| 48 68 | 
             
                      [cmd, args]
         | 
| 49 69 | 
             
                    end
         | 
    
        data/lib/cl/runner/multi.rb
    CHANGED
    
    | @@ -1,10 +1,12 @@ | |
| 1 1 | 
             
            class Cl
         | 
| 2 2 | 
             
              module Runner
         | 
| 3 3 | 
             
                class Multi
         | 
| 4 | 
            -
                   | 
| 4 | 
            +
                  Runner.register :multi, self
         | 
| 5 5 |  | 
| 6 | 
            -
                   | 
| 7 | 
            -
             | 
| 6 | 
            +
                  attr_reader :ctx, :cmds
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  def initialize(ctx, *args)
         | 
| 9 | 
            +
                    @ctx = ctx
         | 
| 8 10 | 
             
                    @cmds = build(group(args))
         | 
| 9 11 | 
             
                  end
         | 
| 10 12 |  | 
| @@ -24,7 +26,7 @@ class Cl | |
| 24 26 |  | 
| 25 27 | 
             
                    def build(cmds)
         | 
| 26 28 | 
             
                      cmds.map do |(cmd, *args)|
         | 
| 27 | 
            -
                        cmd.new( | 
| 29 | 
            +
                        cmd.new(ctx, args)
         | 
| 28 30 | 
             
                      end
         | 
| 29 31 | 
             
                    end
         | 
| 30 32 | 
             
                end
         | 
    
        data/lib/cl/ui.rb
    CHANGED
    
    | @@ -17,8 +17,13 @@ class Cl | |
| 17 17 | 
             
                    @stdout ||= opts[:stdout] || $stdout
         | 
| 18 18 | 
             
                  end
         | 
| 19 19 |  | 
| 20 | 
            -
                  def puts(* | 
| 21 | 
            -
                    stdout.puts(* | 
| 20 | 
            +
                  def puts(*strs)
         | 
| 21 | 
            +
                    stdout.puts(*strs)
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  def abort(error, *strs)
         | 
| 25 | 
            +
                    self.error [error.message, *strs].join("\n\n")
         | 
| 26 | 
            +
                    exit 1
         | 
| 22 27 | 
             
                  end
         | 
| 23 28 | 
             
                end
         | 
| 24 29 |  | 
| @@ -38,6 +43,10 @@ class Cl | |
| 38 43 | 
             
                  def stdout
         | 
| 39 44 | 
             
                    @stdout ||= StringIO.new
         | 
| 40 45 | 
             
                  end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  def abort(error, *strs)
         | 
| 48 | 
            +
                    raise error
         | 
| 49 | 
            +
                  end
         | 
| 41 50 | 
             
                end
         | 
| 42 51 |  | 
| 43 52 | 
             
                class Pipe < Base
         | 
    
        data/lib/cl/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: cl
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.1. | 
| 4 | 
            +
              version: 0.1.13
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Sven Fuchs
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2019-05- | 
| 11 | 
            +
            date: 2019-05-18 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: regstry
         | 
| @@ -43,6 +43,28 @@ files: | |
| 43 43 | 
             
            - examples/gem
         | 
| 44 44 | 
             
            - examples/heroku
         | 
| 45 45 | 
             
            - examples/rakeish
         | 
| 46 | 
            +
            - examples/readme/alias
         | 
| 47 | 
            +
            - examples/readme/arg
         | 
| 48 | 
            +
            - examples/readme/arg_array
         | 
| 49 | 
            +
            - examples/readme/arg_type
         | 
| 50 | 
            +
            - examples/readme/args_splat
         | 
| 51 | 
            +
            - examples/readme/array
         | 
| 52 | 
            +
            - examples/readme/default
         | 
| 53 | 
            +
            - examples/readme/deprecated
         | 
| 54 | 
            +
            - examples/readme/deprecated_alias
         | 
| 55 | 
            +
            - examples/readme/downcase
         | 
| 56 | 
            +
            - examples/readme/enum
         | 
| 57 | 
            +
            - examples/readme/example
         | 
| 58 | 
            +
            - examples/readme/format
         | 
| 59 | 
            +
            - examples/readme/internal
         | 
| 60 | 
            +
            - examples/readme/opts
         | 
| 61 | 
            +
            - examples/readme/opts_block
         | 
| 62 | 
            +
            - examples/readme/range
         | 
| 63 | 
            +
            - examples/readme/required
         | 
| 64 | 
            +
            - examples/readme/requireds
         | 
| 65 | 
            +
            - examples/readme/requires
         | 
| 66 | 
            +
            - examples/readme/see
         | 
| 67 | 
            +
            - examples/readme/type
         | 
| 46 68 | 
             
            - lib/cl.rb
         | 
| 47 69 | 
             
            - lib/cl/arg.rb
         | 
| 48 70 | 
             
            - lib/cl/args.rb
         | 
| @@ -52,6 +74,8 @@ files: | |
| 52 74 | 
             
            - lib/cl/config/env.rb
         | 
| 53 75 | 
             
            - lib/cl/config/files.rb
         | 
| 54 76 | 
             
            - lib/cl/ctx.rb
         | 
| 77 | 
            +
            - lib/cl/dsl.rb
         | 
| 78 | 
            +
            - lib/cl/errors.rb
         | 
| 55 79 | 
             
            - lib/cl/help.rb
         | 
| 56 80 | 
             
            - lib/cl/help/cmd.rb
         | 
| 57 81 | 
             
            - lib/cl/help/cmds.rb
         | 
| @@ -61,6 +85,7 @@ files: | |
| 61 85 | 
             
            - lib/cl/opt.rb
         | 
| 62 86 | 
             
            - lib/cl/opts.rb
         | 
| 63 87 | 
             
            - lib/cl/parser.rb
         | 
| 88 | 
            +
            - lib/cl/runner.rb
         | 
| 64 89 | 
             
            - lib/cl/runner/default.rb
         | 
| 65 90 | 
             
            - lib/cl/runner/multi.rb
         | 
| 66 91 | 
             
            - lib/cl/ui.rb
         |