samovar 2.2.0 → 2.4.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/samovar/command.rb +122 -24
- data/lib/samovar/error.rb +33 -2
- data/lib/samovar/failure.rb +1 -0
- data/lib/samovar/flags.rb +169 -22
- 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 +68 -7
- data/lib/samovar/options.rb +75 -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 +47 -4
- data/lib/samovar/version.rb +3 -2
- data/lib/samovar.rb +3 -3
- data/license.md +1 -1
- data/readme.md +10 -158
- data.tar.gz.sig +0 -0
- metadata +6 -51
- metadata.gz.sig +0 -0
@@ -1,33 +1,45 @@
|
|
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
|
-
require
|
7
|
-
require
|
6
|
+
require "mapping/model"
|
7
|
+
require "console/terminal"
|
8
8
|
|
9
|
-
require_relative
|
9
|
+
require_relative "../error"
|
10
10
|
|
11
|
-
require_relative
|
11
|
+
require_relative "header"
|
12
12
|
|
13
|
-
require_relative
|
14
|
-
require_relative
|
13
|
+
require_relative "row"
|
14
|
+
require_relative "rows"
|
15
15
|
|
16
16
|
module Samovar
|
17
17
|
module Output
|
18
|
+
# Formats and prints usage information to a terminal.
|
19
|
+
#
|
20
|
+
# Uses the `mapping` gem to handle different output object types with custom formatting rules.
|
18
21
|
class UsageFormatter < Mapping::Model
|
22
|
+
# Print usage information to the output.
|
23
|
+
#
|
24
|
+
# @parameter rows [Rows] The rows to format and print.
|
25
|
+
# @parameter output [IO] The output stream to print to.
|
26
|
+
# @yields {|formatter| ...} Optional block to customize the formatter.
|
19
27
|
def self.print(rows, output)
|
20
|
-
formatter = self.new(
|
28
|
+
formatter = self.new(output)
|
21
29
|
|
22
30
|
yield formatter if block_given?
|
23
31
|
|
24
|
-
formatter.print
|
32
|
+
formatter.print(rows)
|
25
33
|
end
|
26
34
|
|
27
|
-
|
28
|
-
|
35
|
+
# Initialize a new usage formatter.
|
36
|
+
#
|
37
|
+
# @parameter rows [Rows] The rows to format.
|
38
|
+
# @parameter output [IO] The output stream to print to.
|
39
|
+
def initialize(output)
|
29
40
|
@output = output
|
30
41
|
@width = 80
|
42
|
+
@first = true
|
31
43
|
|
32
44
|
@terminal = Console::Terminal.for(@output)
|
33
45
|
@terminal[:header] = @terminal.style(nil, nil, :bright)
|
@@ -45,7 +57,11 @@ module Samovar
|
|
45
57
|
end
|
46
58
|
|
47
59
|
map(Header) do |header, rows|
|
48
|
-
|
60
|
+
if @first
|
61
|
+
@first = false
|
62
|
+
else
|
63
|
+
@terminal.puts
|
64
|
+
end
|
49
65
|
|
50
66
|
command_line = header.object.command_line(header.name)
|
51
67
|
@terminal.puts "#{rows.indentation}#{command_line}", style: :header
|
@@ -64,8 +80,10 @@ module Samovar
|
|
64
80
|
items.collect{|row, rows| map(row, rows)}
|
65
81
|
end
|
66
82
|
|
67
|
-
|
68
|
-
|
83
|
+
# Print the formatted usage output.
|
84
|
+
def print(rows, first: @first)
|
85
|
+
@first = first
|
86
|
+
map(rows)
|
69
87
|
end
|
70
88
|
end
|
71
89
|
end
|
data/lib/samovar/output.rb
CHANGED
data/lib/samovar/split.rb
CHANGED
@@ -1,11 +1,21 @@
|
|
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
6
|
module Samovar
|
7
|
+
# Represents a split point in the command-line arguments.
|
8
|
+
#
|
9
|
+
# A `Split` parser divides the argument list at a marker (typically `--`), allowing you to separate arguments meant for your command from those passed to another tool.
|
7
10
|
class Split
|
8
|
-
|
11
|
+
# Initialize a new split parser.
|
12
|
+
#
|
13
|
+
# @parameter key [Symbol] The name of the attribute to store the values after the split.
|
14
|
+
# @parameter description [String] A description of the split for help output.
|
15
|
+
# @parameter marker [String] The marker that indicates the split point.
|
16
|
+
# @parameter default [Object] The default value if no split is present.
|
17
|
+
# @parameter required [Boolean] Whether the split is required.
|
18
|
+
def initialize(key, description, marker: "--", default: nil, required: false)
|
9
19
|
@key = key
|
10
20
|
@description = description
|
11
21
|
@marker = marker
|
@@ -13,16 +23,41 @@ module Samovar
|
|
13
23
|
@required = required
|
14
24
|
end
|
15
25
|
|
26
|
+
# The name of the attribute to store the values after the split.
|
27
|
+
#
|
28
|
+
# @attribute [Symbol]
|
16
29
|
attr :key
|
30
|
+
|
31
|
+
# A description of the split for help output.
|
32
|
+
#
|
33
|
+
# @attribute [String]
|
17
34
|
attr :description
|
35
|
+
|
36
|
+
# The marker that indicates the split point.
|
37
|
+
#
|
38
|
+
# @attribute [String]
|
18
39
|
attr :marker
|
40
|
+
|
41
|
+
# The default value if no split is present.
|
42
|
+
#
|
43
|
+
# @attribute [Object]
|
19
44
|
attr :default
|
45
|
+
|
46
|
+
# Whether the split is required.
|
47
|
+
#
|
48
|
+
# @attribute [Boolean]
|
20
49
|
attr :required
|
21
50
|
|
51
|
+
# Generate a string representation for usage output.
|
52
|
+
#
|
53
|
+
# @returns [String] The usage string.
|
22
54
|
def to_s
|
23
55
|
"#{@marker} <#{@key}...>"
|
24
56
|
end
|
25
57
|
|
58
|
+
# Generate an array representation for usage output.
|
59
|
+
#
|
60
|
+
# @returns [Array] The usage array.
|
26
61
|
def to_a
|
27
62
|
usage = [to_s, @description]
|
28
63
|
|
@@ -35,13 +70,19 @@ module Samovar
|
|
35
70
|
return usage
|
36
71
|
end
|
37
72
|
|
73
|
+
# Parse arguments after the split marker.
|
74
|
+
#
|
75
|
+
# @parameter input [Array(String)] The command-line arguments.
|
76
|
+
# @parameter parent [Command | Nil] The parent command.
|
77
|
+
# @parameter default [Object | Nil] An override for the default value.
|
78
|
+
# @returns [Array(String) | Object | Nil] The arguments after the split, or the default if no split.
|
38
79
|
def parse(input, parent = nil, default = nil)
|
39
80
|
if offset = input.index(@marker)
|
40
81
|
input.pop(input.size - offset).tap(&:shift)
|
41
82
|
elsif default ||= @default
|
42
83
|
return default
|
43
84
|
elsif @required
|
44
|
-
raise MissingValueError.new(parent,
|
85
|
+
raise MissingValueError.new(parent, @key)
|
45
86
|
end
|
46
87
|
end
|
47
88
|
end
|
data/lib/samovar/table.rb
CHANGED
@@ -1,10 +1,18 @@
|
|
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
6
|
module Samovar
|
7
|
+
# Represents a table of parsing rows for a command.
|
8
|
+
#
|
9
|
+
# A table manages the collection of options, arguments, and nested commands that define how to parse a command line.
|
7
10
|
class Table
|
11
|
+
# Create a nested table that inherits from the parent class's table.
|
12
|
+
#
|
13
|
+
# @parameter klass [Class] The command class to create a table for.
|
14
|
+
# @parameter parent [Table | Nil] The parent table to inherit from.
|
15
|
+
# @returns [Table] The new table.
|
8
16
|
def self.nested(klass, parent = nil)
|
9
17
|
if klass.superclass.respond_to?(:table)
|
10
18
|
parent = klass.superclass.table
|
@@ -13,12 +21,19 @@ module Samovar
|
|
13
21
|
self.new(parent, name: klass.name)
|
14
22
|
end
|
15
23
|
|
24
|
+
# Initialize a new table.
|
25
|
+
#
|
26
|
+
# @parameter parent [Table | Nil] The parent table to inherit from.
|
27
|
+
# @parameter name [String | Nil] The name of the command this table belongs to.
|
16
28
|
def initialize(parent = nil, name: nil)
|
17
29
|
@parent = parent
|
18
30
|
@name = name
|
19
31
|
@rows = {}
|
20
32
|
end
|
21
33
|
|
34
|
+
# Freeze this table.
|
35
|
+
#
|
36
|
+
# @returns [Table] The frozen table.
|
22
37
|
def freeze
|
23
38
|
return self if frozen?
|
24
39
|
|
@@ -27,14 +42,24 @@ module Samovar
|
|
27
42
|
super
|
28
43
|
end
|
29
44
|
|
45
|
+
# Get a row by key.
|
46
|
+
#
|
47
|
+
# @parameter key [Symbol] The key to look up.
|
48
|
+
# @returns [Object | Nil] The row with the given key.
|
30
49
|
def [] key
|
31
50
|
@rows[key]
|
32
51
|
end
|
33
52
|
|
53
|
+
# Iterate over each row.
|
54
|
+
#
|
55
|
+
# @yields {|row| ...} Each row in the table.
|
34
56
|
def each(&block)
|
35
57
|
@rows.each_value(&block)
|
36
58
|
end
|
37
59
|
|
60
|
+
# Add a row to the table.
|
61
|
+
#
|
62
|
+
# @parameter row The row to add.
|
38
63
|
def << row
|
39
64
|
if existing_row = @rows[row.key] and existing_row.respond_to?(:merge!)
|
40
65
|
existing_row.merge!(row)
|
@@ -44,10 +69,17 @@ module Samovar
|
|
44
69
|
end
|
45
70
|
end
|
46
71
|
|
72
|
+
# Check if this table is empty.
|
73
|
+
#
|
74
|
+
# @returns [Boolean] True if this table and its parent are empty.
|
47
75
|
def empty?
|
48
76
|
@rows.empty? && @parent&.empty?
|
49
77
|
end
|
50
78
|
|
79
|
+
# Merge this table's rows into another table.
|
80
|
+
#
|
81
|
+
# @parameter table [Table] The table to merge into.
|
82
|
+
# @returns [Table] The merged table.
|
51
83
|
def merge_into(table)
|
52
84
|
@parent&.merge_into(table)
|
53
85
|
|
@@ -58,6 +90,9 @@ module Samovar
|
|
58
90
|
return table
|
59
91
|
end
|
60
92
|
|
93
|
+
# Get a merged table that includes parent rows.
|
94
|
+
#
|
95
|
+
# @returns [Table] The merged table.
|
61
96
|
def merged
|
62
97
|
if @parent.nil? or @parent.empty?
|
63
98
|
return self
|
@@ -66,18 +101,26 @@ module Samovar
|
|
66
101
|
end
|
67
102
|
end
|
68
103
|
|
104
|
+
# Generate a usage string from all rows.
|
105
|
+
#
|
106
|
+
# @returns [String] The usage string.
|
69
107
|
def usage
|
70
|
-
@rows.each_value.collect(&:to_s).reject(&:empty?).join(
|
108
|
+
@rows.each_value.collect(&:to_s).reject(&:empty?).join(" ")
|
71
109
|
end
|
72
110
|
|
111
|
+
# Parse the input according to the rows in this table.
|
112
|
+
#
|
113
|
+
# @parameter input [Array(String)] The command-line arguments.
|
114
|
+
# @parameter parent [Command] The parent command to store results in.
|
73
115
|
def parse(input, parent)
|
74
116
|
@rows.each do |key, row|
|
75
117
|
next unless row.respond_to?(:parse)
|
76
118
|
|
77
119
|
current = parent.send(key)
|
78
120
|
|
79
|
-
|
80
|
-
|
121
|
+
result = row.parse(input, parent, current)
|
122
|
+
if result != nil
|
123
|
+
parent.public_send("#{row.key}=", result)
|
81
124
|
end
|
82
125
|
end
|
83
126
|
end
|
data/lib/samovar/version.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
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
|
# Copyright, 2018, by Gabriel Mazetto.
|
6
6
|
|
7
|
+
# @namespace
|
7
8
|
module Samovar
|
8
|
-
VERSION = "2.
|
9
|
+
VERSION = "2.4.0"
|
9
10
|
end
|
data/lib/samovar.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
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
|
6
|
+
require_relative "samovar/version"
|
7
|
+
require_relative "samovar/command"
|
data/license.md
CHANGED
data/readme.md
CHANGED
@@ -12,165 +12,17 @@ I've been using [Optimist](https://github.com/ManageIQ/optimist) and while it's
|
|
12
12
|
|
13
13
|
One of the other issues I had with existing frameworks is testability. Most frameworks expect to have some pretty heavy logic directly in the binary executable, or at least don't structure your code in a way which makes testing easy. Samovar structures your command processing logic into classes which can be easily tested in isolation, which means that you can mock up and [spec your command-line executables easily](https://github.com/ioquatix/teapot/blob/master/spec/teapot/command_spec.rb).
|
14
14
|
|
15
|
-
## Examples
|
16
|
-
|
17
|
-
- [Teapot](https://github.com/ioquatix/teapot/blob/master/lib/teapot/command.rb) is a build system and uses multiple top-level commands.
|
18
|
-
- [Utopia](https://github.com/ioquatix/utopia/blob/master/lib/utopia/command.rb) is a web application platform and uses nested commands.
|
19
|
-
- [Synco](https://github.com/ioquatix/synco/blob/master/lib/synco/command.rb) is a backup tool and sends commands across the network and has lots of options with default values.
|
20
|
-
|
21
|
-
## Installation
|
22
|
-
|
23
|
-
Add this line to your application's Gemfile:
|
24
|
-
|
25
|
-
gem 'samovar'
|
26
|
-
|
27
|
-
And then execute:
|
28
|
-
|
29
|
-
$ bundle
|
30
|
-
|
31
|
-
Or install it yourself as:
|
32
|
-
|
33
|
-
$ gem install samovar
|
34
|
-
|
35
15
|
## Usage
|
36
16
|
|
37
|
-
|
17
|
+
Please see the [project documentation](https://ioquatix.github.io/samovar/) for more details.
|
38
18
|
|
39
|
-
|
40
|
-
require 'samovar'
|
41
|
-
|
42
|
-
class List < Samovar::Command
|
43
|
-
self.description = "List the current directory"
|
44
|
-
|
45
|
-
def call
|
46
|
-
system("ls -lah")
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
class Application < Samovar::Command
|
51
|
-
options do
|
52
|
-
option '--help', "Do you need help?"
|
53
|
-
end
|
54
|
-
|
55
|
-
nested :command, {
|
56
|
-
'list' => List
|
57
|
-
}, default: 'list'
|
58
|
-
|
59
|
-
def call
|
60
|
-
if @options[:help]
|
61
|
-
self.print_usage
|
62
|
-
else
|
63
|
-
@command.call
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
Application.call # Defaults to ARGV.
|
69
|
-
```
|
70
|
-
|
71
|
-
### Basic Options
|
72
|
-
|
73
|
-
``` ruby
|
74
|
-
require 'samovar'
|
75
|
-
|
76
|
-
class Application < Samovar::Command
|
77
|
-
options do
|
78
|
-
option '-f/--frobulate <text>', "Frobulate the text"
|
79
|
-
option '-x | -y', "Specify either x or y axis.", key: :axis
|
80
|
-
option '-F/--yeah/--flag', "A boolean flag with several forms."
|
81
|
-
option '--things <a,b,c>', "A list of things" do |value|
|
82
|
-
value.split(/\s*,\s*/)
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
application = Application.new(['-f', 'Algebraic!'])
|
88
|
-
application.options[:frobulate] # 'Algebraic!'
|
89
|
-
|
90
|
-
application = Application.new(['-x', '-y'])
|
91
|
-
application.options[:axis] # :y
|
92
|
-
|
93
|
-
application = Application.new(['-F'])
|
94
|
-
application.options[:flag] # true
|
95
|
-
|
96
|
-
application = Application.new(['--things', 'x,y,z'])
|
97
|
-
application.options[:things] # ['x', 'y', 'z']
|
98
|
-
```
|
99
|
-
|
100
|
-
### Nested Commands
|
101
|
-
|
102
|
-
``` ruby
|
103
|
-
require 'samovar'
|
104
|
-
|
105
|
-
class Create < Samovar::Command
|
106
|
-
def invoke(parent)
|
107
|
-
puts "Creating"
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
class Application < Samovar::Command
|
112
|
-
nested '<command>',
|
113
|
-
'create' => Create
|
114
|
-
|
115
|
-
def invoke(program_name: File.basename($0))
|
116
|
-
if @command
|
117
|
-
@command.invoke
|
118
|
-
else
|
119
|
-
print_usage(program_name)
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
Application.new(['create']).invoke
|
125
|
-
```
|
19
|
+
- [Getting Started](https://ioquatix.github.io/samovar/guides/getting-started/index) - This guide explains how to use `samovar` to build command-line tools and applications.
|
126
20
|
|
127
|
-
|
21
|
+
## See Also
|
128
22
|
|
129
|
-
|
130
|
-
|
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
|
-
``` ruby
|
145
|
-
require 'samovar'
|
146
|
-
|
147
|
-
class Application < Samovar::Command
|
148
|
-
self.description = "Mix together your favorite things."
|
149
|
-
|
150
|
-
one :fruit, "Name one fruit"
|
151
|
-
many :cakes, "Any cakes you like"
|
152
|
-
end
|
153
|
-
|
154
|
-
application = Application.new(['apple', 'chocolate cake', 'fruit cake'])
|
155
|
-
application.fruit # 'apple'
|
156
|
-
application.cakes # ['chocolate cake', 'fruit cake']
|
157
|
-
```
|
158
|
-
|
159
|
-
### Explicit Commands
|
160
|
-
|
161
|
-
Given a custom `Samovar::Command` subclass, you can instantiate it with options:
|
162
|
-
|
163
|
-
``` ruby
|
164
|
-
application = Application['--root', path]
|
165
|
-
```
|
166
|
-
|
167
|
-
You can also duplicate an existing command instance with additions/changes:
|
168
|
-
|
169
|
-
``` ruby
|
170
|
-
concurrent_application = application['--threads', 12]
|
171
|
-
```
|
172
|
-
|
173
|
-
These forms can be useful when invoking one command from another, or in unit tests.
|
23
|
+
- [Teapot](https://github.com/ioquatix/teapot/blob/master/lib/teapot/command.rb) is a build system and uses multiple top-level commands.
|
24
|
+
- [Synco](https://github.com/ioquatix/synco/blob/master/lib/synco/command.rb) is a backup tool and sends commands across the network and has lots of options with default values.
|
25
|
+
- [Bake](https://github.com/ioquatix/bake) is an alternative task runner that makes it easy to expose Ruby methods as command-line tasks.
|
174
26
|
|
175
27
|
## Contributing
|
176
28
|
|
@@ -184,13 +36,13 @@ We welcome contributions to this project.
|
|
184
36
|
|
185
37
|
### Developer Certificate of Origin
|
186
38
|
|
187
|
-
|
39
|
+
In order to protect users of this project, we require all contributors to comply with the [Developer Certificate of Origin](https://developercertificate.org/). This ensures that all contributions are properly licensed and attributed.
|
188
40
|
|
189
|
-
###
|
41
|
+
### Community Guidelines
|
190
42
|
|
191
|
-
This project is
|
43
|
+
This project is best served by a collaborative and respectful environment. Treat each other professionally, respect differing viewpoints, and engage constructively. Harassment, discrimination, or harmful behavior is not tolerated. Communicate clearly, listen actively, and support one another. If any issues arise, please inform the project maintainers.
|
192
44
|
|
193
|
-
|
45
|
+
### Future Work
|
194
46
|
|
195
47
|
### Multi-value Options
|
196
48
|
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: samovar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
8
|
- Gabriel Mazetto
|
9
|
-
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain:
|
12
11
|
- |
|
@@ -38,7 +37,7 @@ cert_chain:
|
|
38
37
|
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
39
38
|
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
40
39
|
-----END CERTIFICATE-----
|
41
|
-
date:
|
40
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
42
41
|
dependencies:
|
43
42
|
- !ruby/object:Gem::Dependency
|
44
43
|
name: console
|
@@ -68,50 +67,6 @@ dependencies:
|
|
68
67
|
- - "~>"
|
69
68
|
- !ruby/object:Gem::Version
|
70
69
|
version: '1.0'
|
71
|
-
- !ruby/object:Gem::Dependency
|
72
|
-
name: bundler
|
73
|
-
requirement: !ruby/object:Gem::Requirement
|
74
|
-
requirements:
|
75
|
-
- - ">="
|
76
|
-
- !ruby/object:Gem::Version
|
77
|
-
version: '0'
|
78
|
-
type: :development
|
79
|
-
prerelease: false
|
80
|
-
version_requirements: !ruby/object:Gem::Requirement
|
81
|
-
requirements:
|
82
|
-
- - ">="
|
83
|
-
- !ruby/object:Gem::Version
|
84
|
-
version: '0'
|
85
|
-
- !ruby/object:Gem::Dependency
|
86
|
-
name: covered
|
87
|
-
requirement: !ruby/object:Gem::Requirement
|
88
|
-
requirements:
|
89
|
-
- - ">="
|
90
|
-
- !ruby/object:Gem::Version
|
91
|
-
version: '0'
|
92
|
-
type: :development
|
93
|
-
prerelease: false
|
94
|
-
version_requirements: !ruby/object:Gem::Requirement
|
95
|
-
requirements:
|
96
|
-
- - ">="
|
97
|
-
- !ruby/object:Gem::Version
|
98
|
-
version: '0'
|
99
|
-
- !ruby/object:Gem::Dependency
|
100
|
-
name: sus
|
101
|
-
requirement: !ruby/object:Gem::Requirement
|
102
|
-
requirements:
|
103
|
-
- - ">="
|
104
|
-
- !ruby/object:Gem::Version
|
105
|
-
version: '0'
|
106
|
-
type: :development
|
107
|
-
prerelease: false
|
108
|
-
version_requirements: !ruby/object:Gem::Requirement
|
109
|
-
requirements:
|
110
|
-
- - ">="
|
111
|
-
- !ruby/object:Gem::Version
|
112
|
-
version: '0'
|
113
|
-
description:
|
114
|
-
email:
|
115
70
|
executables: []
|
116
71
|
extensions: []
|
117
72
|
extra_rdoc_files: []
|
@@ -141,8 +96,9 @@ homepage: https://github.com/ioquatix/samovar
|
|
141
96
|
licenses:
|
142
97
|
- MIT
|
143
98
|
metadata:
|
99
|
+
documentation_uri: https://ioquatix.github.io/samovar/
|
144
100
|
funding_uri: https://github.com/sponsors/ioquatix/
|
145
|
-
|
101
|
+
source_code_uri: https://github.com/ioquatix/samovar.git
|
146
102
|
rdoc_options: []
|
147
103
|
require_paths:
|
148
104
|
- lib
|
@@ -150,15 +106,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
150
106
|
requirements:
|
151
107
|
- - ">="
|
152
108
|
- !ruby/object:Gem::Version
|
153
|
-
version: '
|
109
|
+
version: '3.2'
|
154
110
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
155
111
|
requirements:
|
156
112
|
- - ">="
|
157
113
|
- !ruby/object:Gem::Version
|
158
114
|
version: '0'
|
159
115
|
requirements: []
|
160
|
-
rubygems_version: 3.
|
161
|
-
signing_key:
|
116
|
+
rubygems_version: 3.6.9
|
162
117
|
specification_version: 4
|
163
118
|
summary: Samovar is a flexible option parser excellent support for sub-commands and
|
164
119
|
help documentation.
|
metadata.gz.sig
CHANGED
Binary file
|