samovar 2.3.0 → 2.4.1
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
- checksums.yaml.gz.sig +0 -0
- data/context/getting-started.md +215 -0
- data/context/index.yaml +14 -0
- data/lib/samovar/command.rb +119 -26
- data/lib/samovar/error.rb +33 -2
- data/lib/samovar/failure.rb +1 -0
- data/lib/samovar/flags.rb +104 -6
- data/lib/samovar/many.rb +42 -1
- data/lib/samovar/nested.rb +40 -2
- data/lib/samovar/one.rb +42 -1
- data/lib/samovar/option.rb +66 -6
- data/lib/samovar/options.rb +73 -6
- data/lib/samovar/output/columns.rb +19 -0
- data/lib/samovar/output/header.rb +18 -0
- data/lib/samovar/output/row.rb +15 -2
- data/lib/samovar/output/rows.rb +40 -4
- data/lib/samovar/output/usage_formatter.rb +32 -14
- data/lib/samovar/output.rb +2 -2
- data/lib/samovar/split.rb +44 -3
- data/lib/samovar/table.rb +44 -2
- data/lib/samovar/version.rb +3 -2
- data/lib/samovar.rb +3 -3
- data/license.md +1 -1
- data/readme.md +23 -147
- data/releases.md +21 -0
- data.tar.gz.sig +0 -0
- metadata +9 -9
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e1051db069257cf9d25e3599a5ddb5c5547a921cb90d04552a777d3af5c335b2
|
4
|
+
data.tar.gz: 632d0819eb51db7f9640feb8491e543706721a4313243527bb5380da576a578b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f5daa04c5dff0500f95c9dec3cabe02bbbb10fd5a9d5a06f89f6d9e6687eb11af89325472df628170ea04d0458d3c8600849c4fab1299c83bf523e58e1e268ed
|
7
|
+
data.tar.gz: 304cc7d54293e3998dae9e3e3247506db3f82d2d0f6d66e988b4ad21cad0150846a1325a039c4dd3f4746fe0903e6e6afd5a6e2f615d724d7e7ee788da49310b
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
@@ -0,0 +1,215 @@
|
|
1
|
+
# Getting Started
|
2
|
+
|
3
|
+
This guide explains how to use `samovar` to build command-line tools and applications.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add the gem to your project:
|
8
|
+
|
9
|
+
~~~ bash
|
10
|
+
$ bundle add samovar
|
11
|
+
~~~
|
12
|
+
|
13
|
+
Or install it yourself as:
|
14
|
+
|
15
|
+
~~~ bash
|
16
|
+
$ gem install samovar
|
17
|
+
~~~
|
18
|
+
|
19
|
+
## Core Concepts
|
20
|
+
|
21
|
+
Samovar provides a declarative class-based DSL for building command-line parsers. The main concepts include:
|
22
|
+
|
23
|
+
- **Commands**: Classes that represent specific functions in your program, inheriting from {ruby Samovar::Command}.
|
24
|
+
- **Options**: Command-line flags and arguments that can be parsed using the `options` block.
|
25
|
+
- **Nested Commands**: Sub-commands that can be composed using the `nested` method.
|
26
|
+
- **Tokens**: Positional arguments parsed using `one` and `many` methods.
|
27
|
+
- **Splits**: Separating arguments at a specific delimiter (e.g., `--`) using the `split` method.
|
28
|
+
|
29
|
+
## Usage
|
30
|
+
|
31
|
+
Create `Command` classes that represent specific functions in your program. The top level command might look something like this:
|
32
|
+
|
33
|
+
~~~ ruby
|
34
|
+
require "samovar"
|
35
|
+
|
36
|
+
class List < Samovar::Command
|
37
|
+
self.description = "List the current directory"
|
38
|
+
|
39
|
+
def call
|
40
|
+
system("ls -lah")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class Application < Samovar::Command
|
45
|
+
options do
|
46
|
+
option "--help", "Do you need help?"
|
47
|
+
end
|
48
|
+
|
49
|
+
nested :command, {
|
50
|
+
"list" => List
|
51
|
+
}, default: "list"
|
52
|
+
|
53
|
+
def call
|
54
|
+
if @options[:help]
|
55
|
+
self.print_usage
|
56
|
+
else
|
57
|
+
@command.call
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
Application.call # Defaults to ARGV.
|
63
|
+
~~~
|
64
|
+
|
65
|
+
### Basic Options
|
66
|
+
|
67
|
+
Options allow you to parse command-line flags and arguments:
|
68
|
+
|
69
|
+
~~~ ruby
|
70
|
+
require "samovar"
|
71
|
+
|
72
|
+
class Application < Samovar::Command
|
73
|
+
options do
|
74
|
+
option "-f/--frobulate <text>", "Frobulate the text"
|
75
|
+
option "-x | -y", "Specify either x or y axis.", key: :axis
|
76
|
+
option "-F/--yeah/--flag", "A boolean flag with several forms."
|
77
|
+
option "--things <a,b,c>", "A list of things" do |value|
|
78
|
+
value.split(/\s*,\s*/)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
application = Application.new(["-f", "Algebraic!"])
|
84
|
+
application.options[:frobulate] # 'Algebraic!'
|
85
|
+
|
86
|
+
application = Application.new(["-x", "-y"])
|
87
|
+
application.options[:axis] # :y
|
88
|
+
|
89
|
+
application = Application.new(["-F"])
|
90
|
+
application.options[:flag] # true
|
91
|
+
|
92
|
+
application = Application.new(["--things", "x,y,z"])
|
93
|
+
application.options[:things] # ['x', 'y', 'z']
|
94
|
+
~~~
|
95
|
+
|
96
|
+
### Nested Commands
|
97
|
+
|
98
|
+
You can create sub-commands that are nested within your main application:
|
99
|
+
|
100
|
+
~~~ ruby
|
101
|
+
require "samovar"
|
102
|
+
|
103
|
+
class Create < Samovar::Command
|
104
|
+
def invoke(parent)
|
105
|
+
puts "Creating"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
class Application < Samovar::Command
|
110
|
+
nested "<command>",
|
111
|
+
"create" => Create
|
112
|
+
|
113
|
+
def invoke(program_name: File.basename($0))
|
114
|
+
if @command
|
115
|
+
@command.invoke
|
116
|
+
else
|
117
|
+
print_usage(program_name)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
Application.new(["create"]).invoke
|
123
|
+
~~~
|
124
|
+
|
125
|
+
### ARGV Splits
|
126
|
+
|
127
|
+
You can split arguments at a delimiter (typically `--`):
|
128
|
+
|
129
|
+
~~~ ruby
|
130
|
+
require "samovar"
|
131
|
+
|
132
|
+
class Application < Samovar::Command
|
133
|
+
many :packages
|
134
|
+
split :argv
|
135
|
+
end
|
136
|
+
|
137
|
+
application = Application.new(["foo", "bar", "baz", "--", "apples", "oranges", "feijoas"])
|
138
|
+
application.packages # ['foo', 'bar', 'baz']
|
139
|
+
application.argv # ['apples', 'oranges', 'feijoas']
|
140
|
+
~~~
|
141
|
+
|
142
|
+
### Parsing Tokens
|
143
|
+
|
144
|
+
You can parse positional arguments using `one` and `many`:
|
145
|
+
|
146
|
+
~~~ ruby
|
147
|
+
require "samovar"
|
148
|
+
|
149
|
+
class Application < Samovar::Command
|
150
|
+
self.description = "Mix together your favorite things."
|
151
|
+
|
152
|
+
one :fruit, "Name one fruit"
|
153
|
+
many :cakes, "Any cakes you like"
|
154
|
+
end
|
155
|
+
|
156
|
+
application = Application.new(["apple", "chocolate cake", "fruit cake"])
|
157
|
+
application.fruit # 'apple'
|
158
|
+
application.cakes # ['chocolate cake', 'fruit cake']
|
159
|
+
~~~
|
160
|
+
|
161
|
+
### Explicit Commands
|
162
|
+
|
163
|
+
Given a custom `Samovar::Command` subclass, you can instantiate it with options:
|
164
|
+
|
165
|
+
~~~ ruby
|
166
|
+
application = Application["--root", path]
|
167
|
+
~~~
|
168
|
+
|
169
|
+
You can also duplicate an existing command instance with additions/changes:
|
170
|
+
|
171
|
+
~~~ ruby
|
172
|
+
concurrent_application = application["--threads", 12]
|
173
|
+
~~~
|
174
|
+
|
175
|
+
These forms can be useful when invoking one command from another, or in unit tests.
|
176
|
+
|
177
|
+
## Error Handling
|
178
|
+
|
179
|
+
Samovar provides two entry points with different error handling behaviors:
|
180
|
+
|
181
|
+
### `call()` - High-Level Entry Point
|
182
|
+
|
183
|
+
Use `call()` for CLI applications. It handles parsing errors gracefully by printing usage information:
|
184
|
+
|
185
|
+
~~~ ruby
|
186
|
+
# Automatically handles errors and prints usage
|
187
|
+
Application.call(ARGV)
|
188
|
+
~~~
|
189
|
+
|
190
|
+
If parsing fails or the command raises a {ruby Samovar::Error}, it will:
|
191
|
+
- Print the usage information with the error highlighted
|
192
|
+
- Return `nil` instead of raising an exception
|
193
|
+
|
194
|
+
### `parse()` - Low-Level Parsing
|
195
|
+
|
196
|
+
Use `parse()` when you need explicit error handling or for testing:
|
197
|
+
|
198
|
+
~~~ ruby
|
199
|
+
begin
|
200
|
+
app = Application.parse(["--unknown-flag"])
|
201
|
+
rescue Samovar::InvalidInputError => error
|
202
|
+
# Handle the error yourself
|
203
|
+
puts "Invalid input: #{error.message}"
|
204
|
+
end
|
205
|
+
~~~
|
206
|
+
|
207
|
+
The `parse()` method raises exceptions on parsing errors, giving you full control over error handling.
|
208
|
+
|
209
|
+
### Error Types
|
210
|
+
|
211
|
+
Samovar defines several error types:
|
212
|
+
|
213
|
+
- {ruby Samovar::InvalidInputError}: Raised when unexpected command-line input is encountered
|
214
|
+
- {ruby Samovar::MissingValueError}: Raised when required arguments or options are missing
|
215
|
+
|
data/context/index.yaml
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# Automatically generated context index for Utopia::Project guides.
|
2
|
+
# Do not edit then files in this directory directly, instead edit the guides and then run `bake utopia:project:agent:context:update`.
|
3
|
+
---
|
4
|
+
description: Samovar is a flexible option parser excellent support for sub-commands
|
5
|
+
and help documentation.
|
6
|
+
metadata:
|
7
|
+
documentation_uri: https://ioquatix.github.io/samovar/
|
8
|
+
funding_uri: https://github.com/sponsors/ioquatix/
|
9
|
+
source_code_uri: https://github.com/ioquatix/samovar.git
|
10
|
+
files:
|
11
|
+
- path: getting-started.md
|
12
|
+
title: Getting Started
|
13
|
+
description: This guide explains how to use `samovar` to build command-line tools
|
14
|
+
and applications.
|
data/lib/samovar/command.rb
CHANGED
@@ -1,54 +1,85 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2016-
|
4
|
+
# Copyright, 2016-2025, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative
|
7
|
-
require_relative
|
8
|
-
require_relative
|
9
|
-
require_relative
|
10
|
-
require_relative
|
11
|
-
require_relative
|
6
|
+
require_relative "table"
|
7
|
+
require_relative "options"
|
8
|
+
require_relative "nested"
|
9
|
+
require_relative "one"
|
10
|
+
require_relative "many"
|
11
|
+
require_relative "split"
|
12
12
|
|
13
|
-
require_relative 'output'
|
14
13
|
|
15
|
-
require_relative
|
14
|
+
require_relative "output"
|
15
|
+
|
16
|
+
require_relative "error"
|
16
17
|
|
17
18
|
module Samovar
|
19
|
+
# Represents a command in the command-line interface.
|
20
|
+
#
|
21
|
+
# Commands are the main building blocks of Samovar applications. Each command is a class that can parse command-line arguments, options, and sub-commands.
|
18
22
|
class Command
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
# The
|
26
|
-
def self.
|
27
|
-
self.
|
23
|
+
# Parse and execute the command with the given input.
|
24
|
+
#
|
25
|
+
# This is the high-level entry point for CLI applications. It handles errors gracefully by printing usage and returning nil.
|
26
|
+
#
|
27
|
+
# @parameter input [Array(String)] The command-line arguments to parse.
|
28
|
+
# @parameter output [IO] The output stream for error messages.
|
29
|
+
# @returns [Object | Nil] The result of the command's call method, or nil if parsing/execution failed.
|
30
|
+
def self.call(input = ARGV, output: $stderr)
|
31
|
+
self.parse(input).call
|
28
32
|
rescue Error => error
|
29
|
-
error.command.print_usage(output:
|
33
|
+
error.command.print_usage(output: output) do |formatter|
|
30
34
|
formatter.map(error)
|
31
35
|
end
|
32
36
|
|
33
37
|
return nil
|
34
38
|
end
|
35
39
|
|
40
|
+
# Parse the command-line input and create a command instance.
|
41
|
+
#
|
42
|
+
# This is the low-level parsing primitive. It raises {Error} exceptions on parsing failures.
|
43
|
+
# For CLI applications, use {call} instead which handles errors gracefully.
|
44
|
+
#
|
45
|
+
# @parameter input [Array(String)] The command-line arguments to parse.
|
46
|
+
# @returns [Command] The parsed command instance.
|
47
|
+
# @raises [Error] If parsing fails.
|
48
|
+
def self.parse(input)
|
49
|
+
self.new(input)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Create a new command instance with the given arguments.
|
53
|
+
#
|
54
|
+
# This is a convenience method for creating command instances with explicit arguments.
|
55
|
+
#
|
56
|
+
# @parameter input [Array(String)] The command-line arguments to parse.
|
57
|
+
# @parameter options [Hash] Additional options to pass to the command.
|
58
|
+
# @returns [Command] The command instance.
|
36
59
|
def self.[](*input, **options)
|
37
60
|
self.new(input, **options)
|
38
61
|
end
|
39
62
|
|
40
63
|
class << self
|
64
|
+
# A description of the command's purpose.
|
65
|
+
#
|
66
|
+
# @attribute [String]
|
41
67
|
attr_accessor :description
|
42
68
|
end
|
43
69
|
|
70
|
+
# The table of rows for parsing command-line arguments.
|
71
|
+
#
|
72
|
+
# @returns [Table] The table of parsing rows.
|
44
73
|
def self.table
|
45
74
|
@table ||= Table.nested(self)
|
46
75
|
end
|
47
76
|
|
77
|
+
# Append a row to the parsing table.
|
78
|
+
#
|
79
|
+
# @parameter row The row to append to the table.
|
48
80
|
def self.append(row)
|
49
81
|
if method_defined?(row.key, false)
|
50
|
-
|
51
|
-
# raise ArgumentError, "Method for key #{row.key} is already defined!"
|
82
|
+
raise ArgumentError, "Method for key #{row.key} is already defined!"
|
52
83
|
end
|
53
84
|
|
54
85
|
attr_accessor(row.key) if row.respond_to?(:key)
|
@@ -56,26 +87,51 @@ module Samovar
|
|
56
87
|
self.table << row
|
57
88
|
end
|
58
89
|
|
90
|
+
# Define command-line options for this command.
|
91
|
+
#
|
92
|
+
# @parameter arguments [Array] The arguments for the options.
|
93
|
+
# @parameter options [Hash] Additional options.
|
94
|
+
# @yields {|...| ...} A block that defines the options using {Options}.
|
59
95
|
def self.options(*arguments, **options, &block)
|
60
96
|
append Options.parse(*arguments, **options, &block)
|
61
97
|
end
|
62
98
|
|
99
|
+
# Define a nested sub-command.
|
100
|
+
#
|
101
|
+
# @parameter arguments [Array] The arguments for the nested command.
|
102
|
+
# @parameter options [Hash] A hash mapping command names to command classes.
|
63
103
|
def self.nested(*arguments, **options)
|
64
104
|
append Nested.new(*arguments, **options)
|
65
105
|
end
|
66
106
|
|
107
|
+
# Define a single required positional argument.
|
108
|
+
#
|
109
|
+
# @parameter arguments [Array] The arguments for the positional parameter.
|
110
|
+
# @parameter options [Hash] Additional options.
|
67
111
|
def self.one(*arguments, **options)
|
68
112
|
append One.new(*arguments, **options)
|
69
113
|
end
|
70
114
|
|
115
|
+
# Define multiple positional arguments.
|
116
|
+
#
|
117
|
+
# @parameter arguments [Array] The arguments for the positional parameters.
|
118
|
+
# @parameter options [Hash] Additional options.
|
71
119
|
def self.many(*arguments, **options)
|
72
120
|
append Many.new(*arguments, **options)
|
73
121
|
end
|
74
122
|
|
123
|
+
# Define a split point in the argument list (typically `--`).
|
124
|
+
#
|
125
|
+
# @parameter arguments [Array] The arguments for the split.
|
126
|
+
# @parameter options [Hash] Additional options.
|
75
127
|
def self.split(*arguments, **options)
|
76
128
|
append Split.new(*arguments, **options)
|
77
129
|
end
|
78
130
|
|
131
|
+
# Generate usage information for this command.
|
132
|
+
#
|
133
|
+
# @parameter rows [Output::Rows] The rows to append usage information to.
|
134
|
+
# @parameter name [String] The name of the command.
|
79
135
|
def self.usage(rows, name)
|
80
136
|
rows.nested(name, self) do |rows|
|
81
137
|
return unless table = self.table.merged
|
@@ -90,14 +146,22 @@ module Samovar
|
|
90
146
|
end
|
91
147
|
end
|
92
148
|
|
149
|
+
# Generate a command-line usage string.
|
150
|
+
#
|
151
|
+
# @parameter name [String] The name of the command.
|
152
|
+
# @returns [String] The command-line usage string.
|
93
153
|
def self.command_line(name)
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
name
|
98
|
-
end
|
154
|
+
table = self.table.merged
|
155
|
+
|
156
|
+
return "#{name} #{table.usage}"
|
99
157
|
end
|
100
158
|
|
159
|
+
# Initialize a new command instance.
|
160
|
+
#
|
161
|
+
# @parameter input [Array(String) | Nil] The command-line arguments to parse.
|
162
|
+
# @parameter name [String] The name of the command (defaults to the script name).
|
163
|
+
# @parameter parent [Command | Nil] The parent command, if this is a nested command.
|
164
|
+
# @parameter output [IO | Nil] The output stream for usage information.
|
101
165
|
def initialize(input = nil, name: File.basename($0), parent: nil, output: nil)
|
102
166
|
@name = name
|
103
167
|
@parent = parent
|
@@ -106,23 +170,47 @@ module Samovar
|
|
106
170
|
parse(input) if input
|
107
171
|
end
|
108
172
|
|
173
|
+
# The output stream for usage information.
|
174
|
+
#
|
175
|
+
# @attribute [IO]
|
109
176
|
attr :output
|
110
177
|
|
178
|
+
# The output stream for usage information, defaults to `$stdout`.
|
179
|
+
#
|
180
|
+
# @returns [IO] The output stream.
|
111
181
|
def output
|
112
182
|
@output || $stdout
|
113
183
|
end
|
114
184
|
|
185
|
+
# Generate a string representation of the command.
|
186
|
+
#
|
187
|
+
# @returns [String] The class name.
|
115
188
|
def to_s
|
116
189
|
self.class.name
|
117
190
|
end
|
118
191
|
|
192
|
+
# The name of the command.
|
193
|
+
#
|
194
|
+
# @attribute [String]
|
119
195
|
attr :name
|
196
|
+
|
197
|
+
# The parent command, if this is a nested command.
|
198
|
+
#
|
199
|
+
# @attribute [Command | Nil]
|
120
200
|
attr :parent
|
121
201
|
|
202
|
+
# Duplicate the command with additional arguments.
|
203
|
+
#
|
204
|
+
# @parameter input [Array(String)] The additional command-line arguments to parse.
|
205
|
+
# @returns [Command] The duplicated command instance.
|
122
206
|
def [](*input)
|
123
207
|
self.dup.tap{|command| command.parse(input)}
|
124
208
|
end
|
125
209
|
|
210
|
+
# Parse the command-line input.
|
211
|
+
#
|
212
|
+
# @parameter input [Array(String)] The command-line arguments to parse.
|
213
|
+
# @returns [Command] The command instance.
|
126
214
|
def parse(input)
|
127
215
|
self.class.table.merged.parse(input, self)
|
128
216
|
|
@@ -133,6 +221,11 @@ module Samovar
|
|
133
221
|
end
|
134
222
|
end
|
135
223
|
|
224
|
+
# Print usage information for this command.
|
225
|
+
#
|
226
|
+
# @parameter output [IO] The output stream to print to.
|
227
|
+
# @parameter formatter [Class] The formatter class to use for output.
|
228
|
+
# @yields {|formatter| ...} A block to customize the output.
|
136
229
|
def print_usage(output: self.output, formatter: Output::UsageFormatter, &block)
|
137
230
|
rows = Output::Rows.new
|
138
231
|
|
data/lib/samovar/error.rb
CHANGED
@@ -1,13 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2019-
|
4
|
+
# Copyright, 2019-2025, by Samuel Williams.
|
5
5
|
|
6
6
|
module Samovar
|
7
|
+
# The base class for all Samovar errors.
|
7
8
|
class Error < StandardError
|
8
9
|
end
|
9
|
-
|
10
|
+
|
11
|
+
# Raised when invalid input is provided on the command line.
|
10
12
|
class InvalidInputError < Error
|
13
|
+
# Initialize a new invalid input error.
|
14
|
+
#
|
15
|
+
# @parameter command [Command] The command that encountered the error.
|
16
|
+
# @parameter input [Array(String)] The remaining input that could not be parsed.
|
11
17
|
def initialize(command, input)
|
12
18
|
@command = command
|
13
19
|
@input = input
|
@@ -15,19 +21,37 @@ module Samovar
|
|
15
21
|
super "Could not parse token #{input.first.inspect}"
|
16
22
|
end
|
17
23
|
|
24
|
+
# The token that could not be parsed.
|
25
|
+
#
|
26
|
+
# @returns [String] The first unparsed token.
|
18
27
|
def token
|
19
28
|
@input.first
|
20
29
|
end
|
21
30
|
|
31
|
+
# Check if the error was caused by a help request.
|
32
|
+
#
|
33
|
+
# @returns [Boolean] True if the token is `--help`.
|
22
34
|
def help?
|
23
35
|
self.token == "--help"
|
24
36
|
end
|
25
37
|
|
38
|
+
# The command that encountered the error.
|
39
|
+
#
|
40
|
+
# @attribute [Command]
|
26
41
|
attr :command
|
42
|
+
|
43
|
+
# The remaining input that could not be parsed.
|
44
|
+
#
|
45
|
+
# @attribute [Array(String)]
|
27
46
|
attr :input
|
28
47
|
end
|
29
48
|
|
49
|
+
# Raised when a required value is missing.
|
30
50
|
class MissingValueError < Error
|
51
|
+
# Initialize a new missing value error.
|
52
|
+
#
|
53
|
+
# @parameter command [Command] The command that encountered the error.
|
54
|
+
# @parameter field [Symbol] The name of the missing field.
|
31
55
|
def initialize(command, field)
|
32
56
|
@command = command
|
33
57
|
@field = field
|
@@ -35,7 +59,14 @@ module Samovar
|
|
35
59
|
super "#{field} is required"
|
36
60
|
end
|
37
61
|
|
62
|
+
# The command that encountered the error.
|
63
|
+
#
|
64
|
+
# @attribute [Command]
|
38
65
|
attr :command
|
66
|
+
|
67
|
+
# The name of the missing field.
|
68
|
+
#
|
69
|
+
# @attribute [Symbol]
|
39
70
|
attr :field
|
40
71
|
end
|
41
72
|
end
|