Class: Philiprehberger::CliKit::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/philiprehberger/cli_kit/parser.rb

Overview

DSL-based argument parser for CLI applications.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeParser

Returns a new instance of Parser.



9
10
11
12
13
14
15
16
17
18
19
# File 'lib/philiprehberger/cli_kit/parser.rb', line 9

def initialize
  @flag_definitions = {}
  @option_definitions = {}
  @command_definitions = {}
  @flags = {}
  @options = {}
  @arguments = []
  @supplied_options = []
  @command_name = nil
  @program_name = nil
end

Instance Attribute Details

#argumentsObject (readonly)

Returns the value of attribute arguments.



7
8
9
# File 'lib/philiprehberger/cli_kit/parser.rb', line 7

def arguments
  @arguments
end

#command_nameSymbol? (readonly)

Return the matched command name, or nil if no command matched.

Returns:

  • (Symbol, nil)


69
70
71
# File 'lib/philiprehberger/cli_kit/parser.rb', line 69

def command_name
  @command_name
end

#flagsObject (readonly)

Returns the value of attribute flags.



7
8
9
# File 'lib/philiprehberger/cli_kit/parser.rb', line 7

def flags
  @flags
end

#optionsObject (readonly)

Returns the value of attribute options.



7
8
9
# File 'lib/philiprehberger/cli_kit/parser.rb', line 7

def options
  @options
end

Instance Method Details

#command(name = nil) {|Parser| ... } ⇒ Symbol, ...

Define a subcommand or return the matched command name.

When called with a name and block, defines a subcommand. When called with no arguments, returns the matched command name.

Parameters:

  • name (Symbol, nil) (defaults to: nil)

    the command name (nil to query)

Yields:

  • (Parser)

    the command parser for defining command-specific flags and options

Returns:

  • (Symbol, nil, void)


56
57
58
59
60
61
62
63
64
# File 'lib/philiprehberger/cli_kit/parser.rb', line 56

def command(name = nil, &block)
  if name.nil?
    @command_name
  else
    cmd_parser = Parser.new
    cmd_parser.instance_eval(&block) if block
    @command_definitions[name] = cmd_parser
  end
end

#flag(name, short: nil, desc: nil) ⇒ void

This method returns an undefined value.

Define a boolean flag.

Parameters:

  • name (Symbol)

    the flag name

  • short (Symbol, nil) (defaults to: nil)

    short alias (single character)

  • desc (String, nil) (defaults to: nil)

    description for help text



27
28
29
30
# File 'lib/philiprehberger/cli_kit/parser.rb', line 27

def flag(name, short: nil, desc: nil)
  @flag_definitions[name] = { short: short, desc: desc }
  @flags[name] = false
end

#help_requested?Boolean

Check if help was requested.

Returns:

  • (Boolean)


145
146
147
# File 'lib/philiprehberger/cli_kit/parser.rb', line 145

def help_requested?
  @help_requested || false
end

#help_textString

Return the formatted help text without printing.

Returns:

  • (String)


74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/philiprehberger/cli_kit/parser.rb', line 74

def help_text
  lines = []
  lines << "Usage: #{@program_name || 'command'} [options]"
  lines << ''

  unless @flag_definitions.empty? && @option_definitions.empty?
    lines << 'Options:'
    @flag_definitions.each do |name, defn|
      lines << format_flag_help(name, defn)
    end
    @option_definitions.each do |name, defn|
      lines << format_option_help(name, defn)
    end
  end

  unless @command_definitions.empty?
    lines << '' unless @flag_definitions.empty? && @option_definitions.empty?
    lines << 'Commands:'
    @command_definitions.each_key do |name|
      lines << "  #{name}"
    end
  end

  lines.join("\n")
end

#option(name, short: nil, default: nil, desc: nil, multi: false, required: false) ⇒ void

This method returns an undefined value.

Define a value option.

Parameters:

  • name (Symbol)

    the option name

  • short (Symbol, nil) (defaults to: nil)

    short alias (single character)

  • default (Object, nil) (defaults to: nil)

    default value

  • desc (String, nil) (defaults to: nil)

    description for help text

  • multi (Boolean) (defaults to: false)

    when true, collect repeated values into an array

  • required (Boolean) (defaults to: false)

    when true, raise if the option is not supplied at parse time



41
42
43
44
45
46
# File 'lib/philiprehberger/cli_kit/parser.rb', line 41

def option(name, short: nil, default: nil, desc: nil, multi: false, required: false)
  @option_definitions[name] = {
    short: short, default: default, desc: desc, multi: multi, required: required
  }
  @options[name] = multi ? [] : default
end

#parse(args) ⇒ self

Parse the given argument array.

Parameters:

  • args (Array<String>)

    command-line arguments

Returns:

  • (self)


104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/philiprehberger/cli_kit/parser.rb', line 104

def parse(args)
  args = args.dup

  # Check for --help / -h before anything else
  if args.include?('--help') || args.include?('-h')
    @help_requested = true
    return self
  end

  # Try to match a subcommand
  if @command_definitions.any? && args.any?
    potential_cmd = args.first.to_sym
    if @command_definitions.key?(potential_cmd)
      @command_name = potential_cmd
      cmd_parser = @command_definitions[potential_cmd]
      args.shift
      cmd_parser.parse(args)
      @flags = cmd_parser.flags
      @options = cmd_parser.options
      @arguments = cmd_parser.arguments
      return self
    end
  end

  while args.any?
    arg = args.shift
    if arg.start_with?('--')
      parse_long(arg, args)
    elsif arg.start_with?('-') && arg.length > 1
      parse_short(arg, args)
    else
      @arguments << arg
    end
  end
  validate_required_options!
  self
end