consoler 1.0.3 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.rubocop.yml +45 -0
- data/.travis.yml +5 -4
- data/README.md +41 -34
- data/consoler.gemspec +3 -2
- data/lib/consoler/application.rb +38 -28
- data/lib/consoler/arguments.rb +0 -1
- data/lib/consoler/command.rb +0 -1
- data/lib/consoler/matcher.rb +66 -48
- data/lib/consoler/option.rb +75 -27
- data/lib/consoler/options.rb +34 -17
- data/lib/consoler/version.rb +1 -2
- metadata +17 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 49ca5e9011acc8b6817962ab10c90bae3b91b8f2e0fe351001bdd55b84d0338d
|
4
|
+
data.tar.gz: f8ced34f84e72074986fad4b16fcfd1ae0725ffaaade46b69d876b028f327ffd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3ab6c3d9629accdc064f3b74cb0458f65a14615e89a81e892e07e9498a7fd28607efcd439fc53278ad4e8be86c54b5031b891b0b9d67c5e6496c456e2f049b74
|
7
|
+
data.tar.gz: 14c391a50764df0359e0483fd5e59fcd2d765c982e69ea3d15e4b0ff6c5a00270b5f31df397cc2b5275f20d7d9c4e6e56e3000479f78d5e416f5c6287445bc5c
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.2
|
3
|
+
|
4
|
+
Exclude:
|
5
|
+
- 'test/**/*'
|
6
|
+
|
7
|
+
# 80 is not enough these days
|
8
|
+
Metrics/LineLength:
|
9
|
+
Max: 100
|
10
|
+
|
11
|
+
# Not ready for 100 yet
|
12
|
+
Metrics/ClassLength:
|
13
|
+
Max: 250
|
14
|
+
|
15
|
+
# Not ready for 20 yet
|
16
|
+
Metrics/MethodLength:
|
17
|
+
Max: 100
|
18
|
+
|
19
|
+
Metrics/AbcSize:
|
20
|
+
Enabled: false
|
21
|
+
|
22
|
+
# not ready for 10 just yet
|
23
|
+
Metrics/CyclomaticComplexity:
|
24
|
+
Max: 30
|
25
|
+
|
26
|
+
Metrics/BlockNesting:
|
27
|
+
Enabled: false
|
28
|
+
|
29
|
+
Metrics/PerceivedComplexity:
|
30
|
+
Enabled: false
|
31
|
+
|
32
|
+
# I prefer regular if statements in some cases
|
33
|
+
Style/IfUnlessModifier:
|
34
|
+
Enabled: false
|
35
|
+
Style/GuardClause:
|
36
|
+
Enabled: false
|
37
|
+
|
38
|
+
# `super` makes no sense in this case
|
39
|
+
# `#respond_to_missing?` is implemented
|
40
|
+
Style/MethodMissingSuper:
|
41
|
+
Enabled: false
|
42
|
+
|
43
|
+
# I like the comma
|
44
|
+
Style/TrailingCommaInArguments:
|
45
|
+
Enabled: false
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -9,17 +9,19 @@
|
|
9
9
|
app = Consoler::Application.new description: 'A simple app'
|
10
10
|
|
11
11
|
# define a command
|
12
|
-
app.build '[--clean] output_dir' do |clean, output_dir|
|
12
|
+
app.build '[--clean] <output_dir>' do |clean, output_dir|
|
13
13
|
# clean contains a boolean
|
14
14
|
clean_up if clean
|
15
15
|
|
16
16
|
# output_dir contains a string
|
17
17
|
build_project output_dir
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
|
+
# run with own args
|
21
|
+
app.run ['build', 'production', '--clean']
|
20
22
|
|
21
23
|
# this does not match, nothing is executed and the usage message is printed
|
22
|
-
app.run
|
24
|
+
app.run ['deploy', 'production']
|
23
25
|
|
24
26
|
# defaults to ARGV
|
25
27
|
app.run
|
@@ -30,6 +32,7 @@ app.run
|
|
30
32
|
- No fiddling with `ARGV` and friends
|
31
33
|
- Arguments filled based on their name, for easy access
|
32
34
|
- Grouped optionals
|
35
|
+
- Easy option aliasing
|
33
36
|
|
34
37
|
## Requirements
|
35
38
|
|
@@ -39,6 +42,7 @@ Tests are run against multiple ruby versions (latest supported):
|
|
39
42
|
- `2.3.x`
|
40
43
|
- `2.4.x`
|
41
44
|
- `2.5.x`
|
45
|
+
- `2.6.x`
|
42
46
|
|
43
47
|
No other requirements exist.
|
44
48
|
|
@@ -51,20 +55,20 @@ gem install consoler
|
|
51
55
|
or add to your `Gemfile` for applications
|
52
56
|
|
53
57
|
```ruby
|
54
|
-
gem 'consoler', '~> 1.0
|
58
|
+
gem 'consoler', '~> 1.1.0'
|
55
59
|
```
|
56
60
|
|
57
61
|
or to your `.gemspec` file for gems
|
58
62
|
|
59
63
|
```ruby
|
60
64
|
Gem::Specification.new do |spec|
|
61
|
-
spec.add_dependency 'consoler', '~> 1.0
|
65
|
+
spec.add_dependency 'consoler', '~> 1.1.0'
|
62
66
|
end
|
63
67
|
```
|
64
68
|
|
65
69
|
## Docs
|
66
70
|
|
67
|
-
Full API documentation can the found here:
|
71
|
+
Full API documentation can the found here: https://www.rubydoc.info/github/justim/consoler-rb/
|
68
72
|
|
69
73
|
### API
|
70
74
|
|
@@ -93,11 +97,11 @@ app.build do
|
|
93
97
|
end
|
94
98
|
|
95
99
|
# to add options to your command, provide a options definition as an argument
|
96
|
-
app.build '[--clean] [--env=] [-v] output_dir' do |clean, env,
|
100
|
+
app.build '[--clean] [--env=] [-v|--verbose] <output_dir>' do |clean, env, verbose, output_dir|
|
97
101
|
# parameters are matched based on name
|
98
102
|
# `clean` contains a boolean
|
99
103
|
# `env` contains a string or nil if not provided
|
100
|
-
# `
|
104
|
+
# `verbose` contains a number, counting the times it occurred in the arguments
|
101
105
|
# `output_dir` contains a string, if needed to match this command
|
102
106
|
end
|
103
107
|
```
|
@@ -111,23 +115,23 @@ end
|
|
111
115
|
app = Consoler::Application.new
|
112
116
|
|
113
117
|
# a build command
|
114
|
-
app.build '[--clean] [--env=] [-v] output_dir' do |clean, env,
|
115
|
-
puts 'Starting build...' if
|
118
|
+
app.build '[--clean] [--env=] [-v|--verbose] <output_dir>' do |clean, env, verbose, output_dir|
|
119
|
+
puts 'Starting build...' if verbose > 0
|
116
120
|
|
117
121
|
do_clean_up if clean
|
118
122
|
|
119
123
|
do_build env || 'development', output_dir
|
120
124
|
|
121
|
-
puts 'Build complete' if
|
125
|
+
puts 'Build complete' if verbose > 0
|
122
126
|
end
|
123
127
|
|
124
128
|
# a deploy command
|
125
|
-
app.build '[-v] [--env=]' do |env|
|
126
|
-
puts 'Starting deploy...' if
|
129
|
+
app.build '[-v|--verbose] [--env=]' do |env|
|
130
|
+
puts 'Starting deploy...' if verbose > 0
|
127
131
|
|
128
132
|
do_deploy env || 'development'
|
129
133
|
|
130
|
-
puts 'Deploy complete' if
|
134
|
+
puts 'Deploy complete' if verbose > 0
|
131
135
|
end
|
132
136
|
```
|
133
137
|
|
@@ -137,29 +141,34 @@ _Shell commands:_
|
|
137
141
|
ruby app.rb build --env production dist
|
138
142
|
|
139
143
|
# deploy
|
140
|
-
ruby app.rb deploy
|
144
|
+
ruby app.rb deploy --verbose
|
141
145
|
```
|
142
146
|
|
143
147
|
#### Options definition
|
144
148
|
|
145
|
-
| Option
|
146
|
-
|
|
147
|
-
| `-f`
|
148
|
-
| `--clean`
|
149
|
-
| `
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
149
|
+
| Option | Meaning | Example |
|
150
|
+
| -------------- | ------------------------------- | -------------------------------------- |
|
151
|
+
| `-f` | Short option with name `f` | `ruby app.rb build -f` |
|
152
|
+
| `--clean` | Long option with name `clean` | `ruby app.rb build --clean` |
|
153
|
+
| `-v|--verbose` | Alias option for `v` | `ruby app.rb build --verbose` |
|
154
|
+
| `<output_dir>` | Argument with name `output_dir` | `ruby app.rb build dist/` |
|
155
|
+
| `--env=` | Long option with value | `ruby app.rb build --env production` |
|
156
|
+
| `-e=` | Short option with value | `ruby app.rb build -e production` |
|
157
|
+
| `[ .. ]` | Optional options/arguments | `ruby app.rb build` would match `[-v]` |
|
153
158
|
|
154
|
-
|
159
|
+
Some notes about these options:
|
155
160
|
|
156
|
-
|
161
|
+
- The `<`, `>` around the argument name a optional, but are always shown in de usage message for better legibility
|
162
|
+
- Optional-tokens can occur anywhere in the options, as long as they are not nested and properly closed. You can group optional parts, meaning that both options/arguments should be available or both not.
|
163
|
+
- Options and/or arguments are mandatory unless specified otherwise.
|
164
|
+
- Aliases should be the same "type", meaning that if the original option expands an value, the alias must do as well
|
165
|
+
- Aliases are only allowed for short and long options, with or without value and can be optional, just like regular options
|
157
166
|
|
158
167
|
Grouping of optionals allows you do things like this:
|
159
168
|
|
160
169
|
```ruby
|
161
170
|
app = Consoler::Application.new
|
162
|
-
app.shout '[first_name last_name] [name]' do |first_name, last_name, name|
|
171
|
+
app.shout '[<first_name> <last_name>] [<name>]' do |first_name, last_name, name|
|
163
172
|
# by definition, `last_name` is also filled
|
164
173
|
unless first_name.nil? then
|
165
174
|
puts "Hello #{first_name} #{last_name}!"
|
@@ -172,11 +181,11 @@ end
|
|
172
181
|
|
173
182
|
# calling with two arguments can fill the first group
|
174
183
|
# prints "Hello John Doe!"
|
175
|
-
app.run
|
184
|
+
app.run ['shout', 'John', 'Doe']
|
176
185
|
|
177
186
|
# calling with one argument it is not possible to fill the first group
|
178
187
|
# prints "Hello Mr. White!"
|
179
|
-
app.run
|
188
|
+
app.run ['shout', 'Mr. White!']
|
180
189
|
```
|
181
190
|
|
182
191
|
#### Return types in action block
|
@@ -188,6 +197,8 @@ app.run(['shout', 'Mr. White!'])
|
|
188
197
|
| Value | `String` (`production`) | `nil` |
|
189
198
|
| Argument | `String` (`dist/`) | `nil` |
|
190
199
|
|
200
|
+
Aliased keep the properties as the original options; with a definition of `-v|--verbose` and providing `--verbose` as an argument, both `v` and `verbose` contain a number (`1` in this case). Same goes the other way around; with a definition of `--force|-f` and providing `-f` as an argument, both `force` and `f` contain a boolean (`true` in this case).
|
201
|
+
|
191
202
|
#### Subapplications
|
192
203
|
|
193
204
|
To make application nesting possible you can provide a complete application to a command, instead of an action block.
|
@@ -200,7 +211,7 @@ android = Consoler::Application.new
|
|
200
211
|
android.build do; end
|
201
212
|
|
202
213
|
# options are supported just like regular apps
|
203
|
-
android.clean '--force' do; end
|
214
|
+
android.clean '--force|-f' do; end
|
204
215
|
|
205
216
|
# create an application
|
206
217
|
app = Consoler::Application.new
|
@@ -245,7 +256,7 @@ app = Consoler::Application.new
|
|
245
256
|
app.db db
|
246
257
|
app.cache cache
|
247
258
|
|
248
|
-
app.build '[--clean] [--env=] [-v] output_dir -- build the project' do |clean, env, v, output_dir|
|
259
|
+
app.build '[--clean] [--env=] [-v] <output_dir> -- build the project' do |clean, env, v, output_dir|
|
249
260
|
puts 'Starting build...' if v > 0
|
250
261
|
|
251
262
|
if clean
|
@@ -274,10 +285,6 @@ Make the file executable with `chmod a+x app.rb`, you can now call it with `./ap
|
|
274
285
|
./app.rb
|
275
286
|
```
|
276
287
|
|
277
|
-
### Current wish-list
|
278
|
-
|
279
|
-
- Aliases, mostly to "document" short options, `-v|--verbose`
|
280
|
-
|
281
288
|
## Final notes
|
282
289
|
|
283
290
|
If you like what you see, feel free to use it anyway you like. Also, don't hold back if you have suggestions/question and create an issue to let me know, and we can talk about it. And if you don't like what you see, PRs are welcome. You should probably file an issue first to make sure it's something worth doing, and the right way to do it.
|
data/consoler.gemspec
CHANGED
@@ -22,9 +22,10 @@ Gem::Specification.new do |spec|
|
|
22
22
|
# build docs on install
|
23
23
|
spec.metadata['yard.run'] = 'yri'
|
24
24
|
|
25
|
+
spec.required_ruby_version = '>= 2.2'
|
25
26
|
spec.add_development_dependency 'bundler', '~> 1.15'
|
26
|
-
spec.add_development_dependency 'rake', '~> 12.3.0'
|
27
27
|
spec.add_development_dependency 'minitest', '~> 5.11.3'
|
28
|
-
spec.add_development_dependency '
|
28
|
+
spec.add_development_dependency 'rake', '~> 12.3.0'
|
29
29
|
spec.add_development_dependency 'simplecov', '~> 0.15.1'
|
30
|
+
spec.add_development_dependency 'yard', '~> 0.9.12'
|
30
31
|
end
|
data/lib/consoler/application.rb
CHANGED
@@ -4,7 +4,6 @@ require_relative 'options'
|
|
4
4
|
require_relative 'arguments'
|
5
5
|
|
6
6
|
module Consoler
|
7
|
-
|
8
7
|
# Consoler application
|
9
8
|
#
|
10
9
|
# @example A simple application
|
@@ -24,16 +23,25 @@ module Consoler
|
|
24
23
|
# # this does not match, nothing is executed and the usage message is printed
|
25
24
|
# app.run(['deploy', 'production'])
|
26
25
|
class Application
|
27
|
-
|
28
26
|
# Create a consoler application
|
29
27
|
#
|
30
28
|
# @param options [Hash] Options for the application
|
31
29
|
# @option options [String] :description The description for the application (optional)
|
32
|
-
def initialize(options={})
|
30
|
+
def initialize(options = {})
|
33
31
|
@description = options[:description]
|
34
32
|
@commands = []
|
35
33
|
end
|
36
34
|
|
35
|
+
# Accept all method_missing call
|
36
|
+
#
|
37
|
+
# We use the name as a command name, thus we accept all names
|
38
|
+
#
|
39
|
+
# @param _method_name [String] Name of the method
|
40
|
+
# @param _include_private [bool] Name of the method
|
41
|
+
def respond_to_missing?(_method_name, _include_private = false)
|
42
|
+
true
|
43
|
+
end
|
44
|
+
|
37
45
|
# Register a command for this app
|
38
46
|
#
|
39
47
|
# @param command_name [Symbol] Name of the command
|
@@ -44,21 +52,21 @@ module Consoler
|
|
44
52
|
action = nil
|
45
53
|
options_def = ''
|
46
54
|
|
47
|
-
unless block.nil?
|
55
|
+
unless block.nil?
|
48
56
|
action = block
|
49
57
|
options_def = input
|
50
58
|
|
51
|
-
if
|
59
|
+
if !options_def.nil? && !options_def.instance_of?(String)
|
52
60
|
raise 'Invalid options'
|
53
61
|
end
|
54
62
|
end
|
55
63
|
|
56
|
-
if input.instance_of? Consoler::Application
|
64
|
+
if input.instance_of? Consoler::Application
|
57
65
|
action = input
|
58
66
|
options_def = ''
|
59
67
|
end
|
60
68
|
|
61
|
-
if action.nil?
|
69
|
+
if action.nil?
|
62
70
|
raise 'Invalid subapp/block'
|
63
71
|
end
|
64
72
|
|
@@ -66,7 +74,7 @@ module Consoler
|
|
66
74
|
|
67
75
|
_add_command(command, options_def, action)
|
68
76
|
|
69
|
-
|
77
|
+
nil
|
70
78
|
end
|
71
79
|
|
72
80
|
# Run the application with a list of arguments
|
@@ -75,15 +83,15 @@ module Consoler
|
|
75
83
|
# @param disable_usage_message [Boolean] Disable the usage message when nothing it matched
|
76
84
|
# @return [mixed] Result of your matched command, <tt>nil</tt> otherwise
|
77
85
|
def run(args = ARGV, disable_usage_message = false)
|
78
|
-
# TODO signal handling of some kind?
|
86
|
+
# TODO: signal handling of some kind?
|
79
87
|
|
80
88
|
result, matched = _run(args.dup)
|
81
89
|
|
82
|
-
if
|
90
|
+
if !matched && !disable_usage_message
|
83
91
|
usage
|
84
92
|
end
|
85
93
|
|
86
|
-
|
94
|
+
result
|
87
95
|
end
|
88
96
|
|
89
97
|
# Show the usage message
|
@@ -93,7 +101,7 @@ module Consoler
|
|
93
101
|
puts "#{@description}\n\n" unless @description.nil?
|
94
102
|
puts 'Usage:'
|
95
103
|
|
96
|
-
_commands_usage $
|
104
|
+
_commands_usage $PROGRAM_NAME
|
97
105
|
end
|
98
106
|
|
99
107
|
protected
|
@@ -107,13 +115,13 @@ module Consoler
|
|
107
115
|
arguments = Consoler::Arguments.new args
|
108
116
|
|
109
117
|
@commands.each do |command|
|
110
|
-
if command.command == arg
|
118
|
+
if command.command == arg
|
111
119
|
# the matched command contains a subapp, run subapp with the same
|
112
120
|
# arguments (excluding the arg that matched this command)
|
113
|
-
if command.action.instance_of?
|
121
|
+
if command.action.instance_of?(Consoler::Application)
|
114
122
|
result, matched = command.action._run(args)
|
115
123
|
|
116
|
-
if matched
|
124
|
+
if matched
|
117
125
|
return result, true
|
118
126
|
end
|
119
127
|
else
|
@@ -126,26 +134,26 @@ module Consoler
|
|
126
134
|
end
|
127
135
|
end
|
128
136
|
|
129
|
-
|
137
|
+
[nil, false]
|
130
138
|
end
|
131
139
|
|
132
140
|
# Print the usage message for this command
|
133
141
|
#
|
134
142
|
# @param [String] prefix A prefix for the command from a parent app
|
135
143
|
# @return [Consoler::Application]
|
136
|
-
def _commands_usage(prefix='')
|
144
|
+
def _commands_usage(prefix = '')
|
137
145
|
@commands.each do |command|
|
138
146
|
# print the usage message of a subapp with a prefix from the current command
|
139
|
-
if command.action.instance_of?
|
147
|
+
if command.action.instance_of?(Consoler::Application)
|
140
148
|
command.action._commands_usage "#{prefix} #{command.command}"
|
141
149
|
else
|
142
150
|
print " #{prefix} #{command.command}"
|
143
151
|
|
144
|
-
if command.options.size
|
152
|
+
if command.options.size
|
145
153
|
print " #{command.options.to_definition}"
|
146
154
|
end
|
147
155
|
|
148
|
-
unless command.options.description.nil?
|
156
|
+
unless command.options.description.nil?
|
149
157
|
print " -- #{command.options.description}"
|
150
158
|
end
|
151
159
|
|
@@ -165,11 +173,13 @@ module Consoler
|
|
165
173
|
# @param [Proc, Consoler::Application] action Action or subapp
|
166
174
|
# @return [Consoler::Application]
|
167
175
|
def _add_command(command, options_def, action)
|
168
|
-
@commands.push(
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
176
|
+
@commands.push(
|
177
|
+
Consoler::Command.new(
|
178
|
+
command: command,
|
179
|
+
options: Consoler::Options.new(options_def),
|
180
|
+
action: action,
|
181
|
+
)
|
182
|
+
)
|
173
183
|
|
174
184
|
self
|
175
185
|
end
|
@@ -183,7 +193,7 @@ module Consoler
|
|
183
193
|
arguments = action.parameters.map do |parameter|
|
184
194
|
parameter_name = parameter[1].to_s
|
185
195
|
|
186
|
-
if match.
|
196
|
+
if match.key? parameter_name
|
187
197
|
match[parameter_name]
|
188
198
|
else
|
189
199
|
# check for the normalized name of every match to see
|
@@ -191,7 +201,7 @@ module Consoler
|
|
191
201
|
match.each do |name, value|
|
192
202
|
normalized_name = _normalize name
|
193
203
|
|
194
|
-
if parameter_name == normalized_name
|
204
|
+
if parameter_name == normalized_name
|
195
205
|
return value
|
196
206
|
end
|
197
207
|
end
|
@@ -212,7 +222,7 @@ module Consoler
|
|
212
222
|
# also be an syntax error, like starting with a number.
|
213
223
|
# this normalization is more of a comvenience than anything
|
214
224
|
# else
|
215
|
-
name.
|
225
|
+
name.tr('-', '_')
|
216
226
|
end
|
217
227
|
end
|
218
228
|
end
|
data/lib/consoler/arguments.rb
CHANGED
data/lib/consoler/command.rb
CHANGED
data/lib/consoler/matcher.rb
CHANGED
@@ -1,12 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Consoler
|
4
|
-
|
5
4
|
# Argument/Options matcher
|
6
5
|
#
|
7
6
|
# Given a list of arguments and a list option try to match them
|
8
7
|
class Matcher
|
9
|
-
|
10
8
|
# Create a matcher
|
11
9
|
#
|
12
10
|
# @param [Consoler::Arguments] arguments List of arguments
|
@@ -27,14 +25,14 @@ module Consoler
|
|
27
25
|
parse_options = true
|
28
26
|
|
29
27
|
_loop_args do |arg|
|
30
|
-
unless parse_options
|
28
|
+
unless parse_options
|
31
29
|
@argument_values.push arg
|
32
30
|
next
|
33
31
|
end
|
34
32
|
|
35
33
|
# when "argument" is --, then stop parsing the rest of the arguments
|
36
34
|
# and treat the rest as regular arguments
|
37
|
-
if arg == '--'
|
35
|
+
if arg == '--'
|
38
36
|
parse_options = false
|
39
37
|
next
|
40
38
|
end
|
@@ -49,12 +47,20 @@ module Consoler
|
|
49
47
|
remaining = _match_arguments
|
50
48
|
_fill_defaults
|
51
49
|
|
52
|
-
if @matched_options.size == @options.size
|
50
|
+
if @matched_options.size == @options.size
|
53
51
|
@matched_options['remaining'] = remaining
|
52
|
+
|
53
|
+
# make sure all aliases are also filled
|
54
|
+
@options.each do |option|
|
55
|
+
option.aliases.each do |alias_|
|
56
|
+
@matched_options[alias_.name] = @matched_options[option.name]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
54
60
|
return @matched_options
|
55
61
|
end
|
56
62
|
|
57
|
-
|
63
|
+
nil
|
58
64
|
end
|
59
65
|
|
60
66
|
private
|
@@ -68,59 +74,58 @@ module Consoler
|
|
68
74
|
is_short = false
|
69
75
|
name = nil
|
70
76
|
|
71
|
-
if arg[0..1] == '--'
|
77
|
+
if arg[0..1] == '--'
|
72
78
|
is_long = true
|
73
79
|
name = arg[2..-1]
|
74
|
-
elsif arg[0] == '-'
|
80
|
+
elsif arg[0] == '-'
|
75
81
|
is_short = true
|
76
82
|
name = arg[1..-1]
|
77
83
|
end
|
78
84
|
|
79
85
|
# arg is not a long/short option, add to arguments values
|
80
|
-
unless is_long
|
86
|
+
unless is_long || is_short
|
81
87
|
@argument_values.push arg
|
82
88
|
return true
|
83
89
|
end
|
84
90
|
|
85
|
-
unless name.nil?
|
91
|
+
unless name.nil?
|
86
92
|
# get the name of the option, short options use the first character
|
87
|
-
option_name = if is_short
|
93
|
+
option_name = if is_short
|
88
94
|
name[0]
|
89
95
|
else
|
90
96
|
name
|
91
97
|
end
|
92
98
|
|
93
|
-
option = @options.
|
99
|
+
option, matched = @options.get_with_alias option_name
|
94
100
|
|
95
101
|
# no option by this name in options
|
96
102
|
return nil if option.nil?
|
97
103
|
|
98
|
-
needs_short = option.is_short
|
99
|
-
needs_long = option.is_long
|
100
|
-
|
101
104
|
# see if the type if right, short or long
|
102
|
-
if
|
105
|
+
if matched.is_long && !is_long
|
103
106
|
return nil
|
104
|
-
elsif
|
107
|
+
elsif matched.is_short && !is_short
|
105
108
|
return nil
|
106
109
|
end
|
107
110
|
|
108
|
-
if is_long
|
109
|
-
if option.is_value
|
111
|
+
if is_long
|
112
|
+
if option.is_value
|
110
113
|
# is_value needs a next argument for its value
|
111
114
|
return nil if _peek_next.nil?
|
112
|
-
|
115
|
+
|
116
|
+
@matched_options[option.name] = _peek_next
|
113
117
|
_skip_next
|
114
118
|
else
|
115
|
-
|
119
|
+
option_value! option
|
116
120
|
end
|
117
121
|
end
|
118
122
|
|
119
|
-
if is_short
|
120
|
-
if name.size == 1
|
123
|
+
if is_short
|
124
|
+
if name.size == 1 && option.is_value
|
121
125
|
# is_value needs a next argument for its value
|
122
126
|
return nil if _peek_next.nil?
|
123
|
-
|
127
|
+
|
128
|
+
@matched_options[option.name] = _peek_next
|
124
129
|
_skip_next
|
125
130
|
else
|
126
131
|
# for every character (short option) increment the option value
|
@@ -128,17 +133,30 @@ module Consoler
|
|
128
133
|
short_option = @options.get n
|
129
134
|
return nil if short_option.nil?
|
130
135
|
|
131
|
-
|
132
|
-
@matched_options[n] = 0
|
133
|
-
end
|
134
|
-
|
135
|
-
@matched_options[n] += 1
|
136
|
+
option_value! short_option
|
136
137
|
end
|
137
138
|
end
|
138
139
|
end
|
139
140
|
end
|
140
141
|
|
141
|
-
|
142
|
+
true
|
143
|
+
end
|
144
|
+
|
145
|
+
# Set the value of an option
|
146
|
+
#
|
147
|
+
# Long or short option needed
|
148
|
+
#
|
149
|
+
# @param [Consoler::Option]
|
150
|
+
def option_value!(option)
|
151
|
+
if option.is_short
|
152
|
+
if @matched_options[option.name].nil?
|
153
|
+
@matched_options[option.name] = 0
|
154
|
+
end
|
155
|
+
|
156
|
+
@matched_options[option.name] += 1
|
157
|
+
else
|
158
|
+
@matched_options[option.name] = true
|
159
|
+
end
|
142
160
|
end
|
143
161
|
|
144
162
|
# Loop through the arguments
|
@@ -151,7 +169,7 @@ module Consoler
|
|
151
169
|
|
152
170
|
# use an incrementing index, to be able to peek to the next in the list
|
153
171
|
# and to skip an item
|
154
|
-
while @index < size
|
172
|
+
while @index < size
|
155
173
|
yield @arguments.args[@index]
|
156
174
|
|
157
175
|
_skip_next
|
@@ -197,7 +215,7 @@ module Consoler
|
|
197
215
|
# arguments supplied (info available from optionals map)
|
198
216
|
optionals.each do |_, optional|
|
199
217
|
optional.each do |before|
|
200
|
-
if before[:included]
|
218
|
+
if before[:included]
|
201
219
|
@matched_options[before[:name]] = @argument_values[argument_values_index]
|
202
220
|
argument_values_index += 1
|
203
221
|
end
|
@@ -205,7 +223,7 @@ module Consoler
|
|
205
223
|
end
|
206
224
|
|
207
225
|
# only fill mandatory argument if its not the :REMAINING key
|
208
|
-
if mandatory_arg_name != :REMAINING
|
226
|
+
if mandatory_arg_name != :REMAINING
|
209
227
|
@matched_options[mandatory_arg_name] = @argument_values[argument_values_index]
|
210
228
|
argument_values_index += 1
|
211
229
|
end
|
@@ -214,7 +232,7 @@ module Consoler
|
|
214
232
|
remaining = []
|
215
233
|
|
216
234
|
# left over arguments
|
217
|
-
while argument_values_index < @argument_values.size
|
235
|
+
while argument_values_index < @argument_values.size
|
218
236
|
remaining.push @argument_values[argument_values_index]
|
219
237
|
argument_values_index += 1
|
220
238
|
end
|
@@ -229,18 +247,18 @@ module Consoler
|
|
229
247
|
@optionals_before = {}
|
230
248
|
tracker = {}
|
231
249
|
|
232
|
-
@options.each do |option,
|
250
|
+
@options.each do |option, _key|
|
233
251
|
next unless option.is_argument
|
234
252
|
|
235
|
-
if option.is_optional
|
253
|
+
if option.is_optional
|
236
254
|
# setup tracker for optional group
|
237
255
|
tracker[option.is_optional] = [] if tracker[option.is_optional].nil?
|
238
256
|
|
239
257
|
# mark all optionals as not-included
|
240
|
-
tracker[option.is_optional].push(
|
258
|
+
tracker[option.is_optional].push(
|
241
259
|
included: false,
|
242
260
|
name: option.name,
|
243
|
-
|
261
|
+
)
|
244
262
|
else
|
245
263
|
@optionals_before[option.name] = tracker
|
246
264
|
tracker = {}
|
@@ -248,7 +266,7 @@ module Consoler
|
|
248
266
|
end
|
249
267
|
|
250
268
|
# make sure all optionals are accounted for in the map
|
251
|
-
if tracker != {}
|
269
|
+
if tracker != {}
|
252
270
|
# use a special key so we can handle it differently in the filling process
|
253
271
|
@optionals_before[:REMAINING] = tracker
|
254
272
|
@optionals_before_has_remaining = true
|
@@ -267,7 +285,7 @@ module Consoler
|
|
267
285
|
mandatories_matched = @optionals_before.size
|
268
286
|
|
269
287
|
# there are optionals at the end of the options, don't match the void
|
270
|
-
if @optionals_before_has_remaining
|
288
|
+
if @optionals_before_has_remaining
|
271
289
|
mandatories_matched -= 1
|
272
290
|
end
|
273
291
|
|
@@ -276,11 +294,11 @@ module Consoler
|
|
276
294
|
# loop through optional map
|
277
295
|
_each_optional_before_sorted do |before|
|
278
296
|
# are there enough arguments left to fill this optional group
|
279
|
-
if (total + before.size + mandatories_matched) <= @argument_values.size
|
297
|
+
if (total + before.size + mandatories_matched) <= @argument_values.size
|
280
298
|
total += before.size
|
281
299
|
|
282
300
|
before.each do |val|
|
283
|
-
val[:included] = true
|
301
|
+
val[:included] = true
|
284
302
|
end
|
285
303
|
end
|
286
304
|
end
|
@@ -293,10 +311,10 @@ module Consoler
|
|
293
311
|
# @return [Consoler::Matcher]
|
294
312
|
def _fill_defaults
|
295
313
|
@options.each do |option|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
314
|
+
next unless option.is_optional
|
315
|
+
|
316
|
+
unless @matched_options.key? option.name
|
317
|
+
@matched_options[option.name] = option.default_value
|
300
318
|
end
|
301
319
|
end
|
302
320
|
|
@@ -312,10 +330,10 @@ module Consoler
|
|
312
330
|
@optionals_before.each do |_, optionals|
|
313
331
|
tmp = []
|
314
332
|
optionals.each do |optional_index, before|
|
315
|
-
tmp.push(
|
333
|
+
tmp.push(
|
316
334
|
count: before.size,
|
317
335
|
index: optional_index,
|
318
|
-
|
336
|
+
)
|
319
337
|
end
|
320
338
|
|
321
339
|
tmp.sort! { |a, b| b[:count] - a[:count] }.each do |item|
|
data/lib/consoler/option.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Consoler
|
4
|
-
|
5
4
|
# Represents an option
|
6
5
|
#
|
7
6
|
# @attr_reader [String] name Name of the options
|
@@ -10,6 +9,7 @@ module Consoler
|
|
10
9
|
# @attr_reader [Boolean] is_argument Is the option an argument
|
11
10
|
# @attr_reader [Boolean] is_value Does the option need a value (<tt>--option=</tt>)
|
12
11
|
# @attr_reader [Integer] is_optional Is the option optional (> 0) (<tt>[option]</tt>)
|
12
|
+
# @attr_reader [Array] aliases List of aliases of option (<tt>-v|--verbose</tt>)
|
13
13
|
class Option
|
14
14
|
attr_reader :name
|
15
15
|
attr_reader :is_long
|
@@ -17,6 +17,7 @@ module Consoler
|
|
17
17
|
attr_reader :is_argument
|
18
18
|
attr_reader :is_value
|
19
19
|
attr_reader :is_optional
|
20
|
+
attr_reader :aliases
|
20
21
|
|
21
22
|
# Create a option
|
22
23
|
#
|
@@ -28,13 +29,13 @@ module Consoler
|
|
28
29
|
option = Option.new option_def, tracker
|
29
30
|
|
30
31
|
# split short options with more than 1 char in multiple options
|
31
|
-
if option.is_short
|
32
|
+
if option.is_short && option.name.size > 1
|
32
33
|
# remember state
|
33
34
|
old_tracking = tracker.is_tracking
|
34
35
|
old_is_value = option.is_value
|
35
36
|
|
36
37
|
# if the complete option is optional, fake the tracker
|
37
|
-
if option.is_optional
|
38
|
+
if option.is_optional
|
38
39
|
tracker.is_tracking = true
|
39
40
|
end
|
40
41
|
|
@@ -44,7 +45,7 @@ module Consoler
|
|
44
45
|
new_name = "-#{name}"
|
45
46
|
|
46
47
|
# if the short option should have a value, this only counts for the last option
|
47
|
-
if old_is_value
|
48
|
+
if old_is_value && i == names.count - 1
|
48
49
|
new_name = "#{new_name}="
|
49
50
|
end
|
50
51
|
|
@@ -67,14 +68,20 @@ module Consoler
|
|
67
68
|
def to_definition
|
68
69
|
definition = name
|
69
70
|
|
70
|
-
if is_long
|
71
|
+
if is_long
|
71
72
|
definition = "--#{definition}"
|
72
|
-
elsif is_short
|
73
|
+
elsif is_short
|
73
74
|
definition = "-#{definition}"
|
74
75
|
end
|
75
76
|
|
76
|
-
if is_value
|
77
|
+
if is_value
|
77
78
|
definition = "#{definition}="
|
79
|
+
elsif is_argument
|
80
|
+
definition = "<#{definition}>"
|
81
|
+
end
|
82
|
+
|
83
|
+
aliases.each do |alias_|
|
84
|
+
definition = "#{definition}|#{alias_.to_definition}"
|
78
85
|
end
|
79
86
|
|
80
87
|
definition
|
@@ -88,7 +95,7 @@ module Consoler
|
|
88
95
|
return 0 if is_short
|
89
96
|
return false if is_long
|
90
97
|
|
91
|
-
|
98
|
+
nil
|
92
99
|
end
|
93
100
|
|
94
101
|
protected
|
@@ -103,19 +110,33 @@ module Consoler
|
|
103
110
|
# Check for multiple attributes in the option definition till we got the
|
104
111
|
# final name and all of its attributes
|
105
112
|
|
106
|
-
|
113
|
+
# make sure we don't wrongly process any alias
|
114
|
+
alias_defs = option_def.split '|'
|
115
|
+
option = alias_defs.shift || ''
|
116
|
+
|
117
|
+
option, @is_optional = _is_optional option, tracker
|
107
118
|
option, @is_long = _is_long option
|
108
119
|
option, @is_short = _is_short option
|
109
|
-
@is_argument = (
|
120
|
+
@is_argument = (!@is_long && !@is_short)
|
110
121
|
option, @is_value = _value option, @is_argument
|
122
|
+
option, @aliases = _aliases option, alias_defs, tracker
|
123
|
+
|
124
|
+
if option[0] == '<'
|
125
|
+
raise 'Invalid <, missing >' if option[-1] != '>'
|
126
|
+
raise 'Only arguments support <, > around name' unless @is_argument
|
127
|
+
|
128
|
+
option = option[1..-2]
|
129
|
+
end
|
130
|
+
|
131
|
+
raise 'Missing starting <' if option[-1] == '>'
|
111
132
|
|
112
133
|
@name = option
|
113
134
|
|
114
|
-
if @name.empty?
|
135
|
+
if @name.empty?
|
115
136
|
raise 'Option must have a name'
|
116
137
|
end
|
117
138
|
|
118
|
-
if @is_long
|
139
|
+
if @is_long && @is_short
|
119
140
|
raise 'Option can not be a long and a short option'
|
120
141
|
end
|
121
142
|
end
|
@@ -135,8 +156,8 @@ module Consoler
|
|
135
156
|
# @raise [RuntimeError] if you try to close an unopened optional
|
136
157
|
# @return [(String, Integer|nil)] Remaining option definition, and, optional group if available
|
137
158
|
def _is_optional(option, tracker)
|
138
|
-
if option[0] == '['
|
139
|
-
if !tracker.is_tracking
|
159
|
+
if option[0] == '['
|
160
|
+
if !tracker.is_tracking
|
140
161
|
# mark tracker as tracking
|
141
162
|
tracker.is_tracking = true
|
142
163
|
tracker.index += 1
|
@@ -147,14 +168,12 @@ module Consoler
|
|
147
168
|
end
|
148
169
|
|
149
170
|
# get optional group index from tracking, if tracking
|
150
|
-
optional = if tracker.is_tracking
|
171
|
+
optional = if tracker.is_tracking
|
151
172
|
tracker.index
|
152
|
-
else
|
153
|
-
nil
|
154
173
|
end
|
155
174
|
|
156
|
-
if option[-1] == ']'
|
157
|
-
if tracker.is_tracking
|
175
|
+
if option[-1] == ']'
|
176
|
+
if tracker.is_tracking
|
158
177
|
# mark tracker as non-tracking
|
159
178
|
tracker.is_tracking = false
|
160
179
|
option = option[0..-2]
|
@@ -163,7 +182,7 @@ module Consoler
|
|
163
182
|
end
|
164
183
|
end
|
165
184
|
|
166
|
-
|
185
|
+
[option, optional]
|
167
186
|
end
|
168
187
|
|
169
188
|
# Check long definition
|
@@ -171,14 +190,14 @@ module Consoler
|
|
171
190
|
# @param [String] option Option definition
|
172
191
|
# @return [(String, Boolean)]
|
173
192
|
def _is_long(option)
|
174
|
-
if option[0..1] == '--'
|
193
|
+
if option[0..1] == '--'
|
175
194
|
long = true
|
176
195
|
option = option[2..-1]
|
177
196
|
else
|
178
197
|
long = false
|
179
198
|
end
|
180
199
|
|
181
|
-
|
200
|
+
[option, long]
|
182
201
|
end
|
183
202
|
|
184
203
|
# Check short definition
|
@@ -186,14 +205,14 @@ module Consoler
|
|
186
205
|
# @param [String] option Option definition
|
187
206
|
# @return [(String, Boolean)]
|
188
207
|
def _is_short(option)
|
189
|
-
if option[0] == '-'
|
208
|
+
if option[0] == '-'
|
190
209
|
short = true
|
191
210
|
option = option[1..-1]
|
192
211
|
else
|
193
212
|
short = false
|
194
213
|
end
|
195
214
|
|
196
|
-
|
215
|
+
[option, short]
|
197
216
|
end
|
198
217
|
|
199
218
|
# Check value definition
|
@@ -202,8 +221,8 @@ module Consoler
|
|
202
221
|
# @raise [RuntimeError] if you try to assign a value to an argument
|
203
222
|
# @return [(String, Boolean)]
|
204
223
|
def _value(option, argument)
|
205
|
-
if option[-1] == '='
|
206
|
-
if argument
|
224
|
+
if option[-1] == '='
|
225
|
+
if argument
|
207
226
|
raise 'Arguments can\'t have a value'
|
208
227
|
end
|
209
228
|
|
@@ -213,7 +232,36 @@ module Consoler
|
|
213
232
|
value = false
|
214
233
|
end
|
215
234
|
|
216
|
-
|
235
|
+
[option, value]
|
236
|
+
end
|
237
|
+
|
238
|
+
# Parse all possible aliases
|
239
|
+
#
|
240
|
+
# @param [String] option Option definition
|
241
|
+
# @param [Consoler::Tracker] tracker Optional tracker
|
242
|
+
# @raise [RuntimeError] On all kinds of occasions
|
243
|
+
# @return [(String, Array)] Remaining option definition, and, aliases if available
|
244
|
+
def _aliases(option, alias_defs, tracker)
|
245
|
+
return option, [] if alias_defs.empty?
|
246
|
+
|
247
|
+
raise 'Argument can\'t have aliases' if is_argument
|
248
|
+
raise 'Aliases are not allowed for multiple short options' if is_short && option.size > 1
|
249
|
+
|
250
|
+
aliases_ = []
|
251
|
+
alias_names = []
|
252
|
+
|
253
|
+
while (alias_def = alias_defs.shift)
|
254
|
+
Consoler::Option.create alias_def, tracker do |alias_|
|
255
|
+
raise "Duplicate alias name: #{alias_.name}" if alias_names.include? alias_.name
|
256
|
+
raise "Alias must have a value: #{alias_.name}" if is_value && !alias_.is_value
|
257
|
+
raise "Alias can't have a value: #{alias_.name}" if !is_value && alias_.is_value
|
258
|
+
|
259
|
+
aliases_.push alias_
|
260
|
+
alias_names.push alias_.name
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
[option, aliases_]
|
217
265
|
end
|
218
266
|
end
|
219
267
|
end
|
data/lib/consoler/options.rb
CHANGED
@@ -3,7 +3,6 @@
|
|
3
3
|
require_relative 'option'
|
4
4
|
|
5
5
|
module Consoler
|
6
|
-
|
7
6
|
# List of options
|
8
7
|
#
|
9
8
|
# @attr_reader [String] description Description of the options
|
@@ -21,7 +20,7 @@ module Consoler
|
|
21
20
|
return if options_def.nil?
|
22
21
|
|
23
22
|
# strip the description
|
24
|
-
if match = /(^|\s+)-- (?<description>.*)$/.match(options_def)
|
23
|
+
if (match = /(^|\s+)-- (?<description>.*)$/.match(options_def))
|
25
24
|
@description = match[:description]
|
26
25
|
options_def = options_def[0...-match[0].size]
|
27
26
|
end
|
@@ -31,28 +30,50 @@ module Consoler
|
|
31
30
|
|
32
31
|
option_names = []
|
33
32
|
|
34
|
-
while option_def = options.shift
|
33
|
+
while (option_def = options.shift)
|
35
34
|
Consoler::Option.create option_def, tracker do |option|
|
36
35
|
raise "Duplicate option name: #{option.name}" if option_names.include? option.name
|
37
36
|
|
38
|
-
@options.push option
|
39
37
|
option_names.push option.name
|
38
|
+
|
39
|
+
option.aliases.each do |alias_|
|
40
|
+
raise "Duplicate alias name: #{alias_.name}" if option_names.include? alias_.name
|
41
|
+
|
42
|
+
option_names.push alias_.name
|
43
|
+
end
|
44
|
+
|
45
|
+
@options.push option
|
40
46
|
end
|
41
47
|
end
|
42
48
|
end
|
43
49
|
|
44
|
-
# Get a
|
50
|
+
# Get a option by its name
|
51
|
+
#
|
52
|
+
# May be matched by one of its aliases
|
45
53
|
#
|
46
54
|
# @param name [String] Name of the option
|
47
55
|
# @return [Consoler::Option, nil]
|
48
56
|
def get(name)
|
57
|
+
option, = get_with_alias name
|
58
|
+
option
|
59
|
+
end
|
60
|
+
|
61
|
+
# Get a option by its name, with matched alias
|
62
|
+
#
|
63
|
+
# @param name [String] Name of the option
|
64
|
+
# @return [[(Consoler::Option, nil), (Consoler::Option, nil)]]
|
65
|
+
def get_with_alias(name)
|
49
66
|
each do |option, _|
|
50
|
-
if option.name == name
|
51
|
-
return option
|
67
|
+
if option.name == name
|
68
|
+
return option, option
|
69
|
+
end
|
70
|
+
|
71
|
+
option.aliases.each do |alias_|
|
72
|
+
return option, alias_ if alias_.name == name
|
52
73
|
end
|
53
74
|
end
|
54
75
|
|
55
|
-
|
76
|
+
[nil, nil]
|
56
77
|
end
|
57
78
|
|
58
79
|
# Loop through all options
|
@@ -84,19 +105,17 @@ module Consoler
|
|
84
105
|
each do |option, i|
|
85
106
|
definition += ' '
|
86
107
|
|
87
|
-
if optional.nil?
|
108
|
+
if optional.nil? && option.is_optional
|
88
109
|
definition += '['
|
89
110
|
optional = option.is_optional
|
90
111
|
end
|
91
112
|
|
92
113
|
definition += option.to_definition
|
93
114
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
optional = nil
|
99
|
-
end
|
115
|
+
# only close when the next option is not optional, or another optional group
|
116
|
+
if option.is_optional && (@options[i + 1].nil? || optional != @options[i + 1].is_optional)
|
117
|
+
definition += ']'
|
118
|
+
optional = nil
|
100
119
|
end
|
101
120
|
end
|
102
121
|
|
@@ -104,8 +123,6 @@ module Consoler
|
|
104
123
|
end
|
105
124
|
end
|
106
125
|
|
107
|
-
private
|
108
|
-
|
109
126
|
# Optionals tracker
|
110
127
|
#
|
111
128
|
# @attr [Boolean] is_tracking Is inside optional options
|
data/lib/consoler/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: consoler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-03-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -25,61 +25,61 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.15'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: minitest
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 5.11.3
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 5.11.3
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 12.3.0
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 12.3.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: simplecov
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.
|
61
|
+
version: 0.15.1
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.
|
68
|
+
version: 0.15.1
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: yard
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0.
|
75
|
+
version: 0.9.12
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0.
|
82
|
+
version: 0.9.12
|
83
83
|
description: Sinatra-like application builder for the console
|
84
84
|
email: me@justim.net
|
85
85
|
executables: []
|
@@ -88,6 +88,7 @@ extra_rdoc_files: []
|
|
88
88
|
files:
|
89
89
|
- ".editorconfig"
|
90
90
|
- ".gitignore"
|
91
|
+
- ".rubocop.yml"
|
91
92
|
- ".travis.yml"
|
92
93
|
- ".yardopts"
|
93
94
|
- Gemfile
|
@@ -116,7 +117,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
116
117
|
requirements:
|
117
118
|
- - ">="
|
118
119
|
- !ruby/object:Gem::Version
|
119
|
-
version: '
|
120
|
+
version: '2.2'
|
120
121
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
122
|
requirements:
|
122
123
|
- - ">="
|
@@ -124,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
124
125
|
version: '0'
|
125
126
|
requirements: []
|
126
127
|
rubyforge_project:
|
127
|
-
rubygems_version: 2.6
|
128
|
+
rubygems_version: 2.7.6
|
128
129
|
signing_key:
|
129
130
|
specification_version: 4
|
130
131
|
summary: Consoler
|