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
# File 'lib/philiprehberger/cli_kit/parser.rb', line 9

def initialize
  @flag_definitions = {}
  @option_definitions = {}
  @command_definitions = {}
  @flags = {}
  @options = {}
  @arguments = []
  @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)


65
66
67
# File 'lib/philiprehberger/cli_kit/parser.rb', line 65

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)


52
53
54
55
56
57
58
59
60
# File 'lib/philiprehberger/cli_kit/parser.rb', line 52

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



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

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)


140
141
142
# File 'lib/philiprehberger/cli_kit/parser.rb', line 140

def help_requested?
  @help_requested || false
end

#help_textString

Return the formatted help text without printing.

Returns:

  • (String)


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

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) ⇒ 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



39
40
41
42
# File 'lib/philiprehberger/cli_kit/parser.rb', line 39

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

#parse(args) ⇒ self

Parse the given argument array.

Parameters:

  • args (Array<String>)

    command-line arguments

Returns:

  • (self)


100
101
102
103
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
# File 'lib/philiprehberger/cli_kit/parser.rb', line 100

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
  self
end