tty-option 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -1
- data/LICENSE.txt +1 -1
- data/README.md +10 -10
- data/lib/tty/option/aggregate_errors.rb +3 -3
- data/lib/tty/option/const.rb +17 -0
- data/lib/tty/option/conversions.rb +27 -19
- data/lib/tty/option/converter.rb +2 -2
- data/lib/tty/option/deep_dup.rb +0 -1
- data/lib/tty/option/dsl.rb +5 -5
- data/lib/tty/option/formatter.rb +5 -5
- data/lib/tty/option/param_conversion.rb +11 -9
- data/lib/tty/option/param_permitted.rb +1 -1
- data/lib/tty/option/param_validation.rb +1 -1
- data/lib/tty/option/parameter.rb +21 -14
- data/lib/tty/option/parameters.rb +15 -1
- data/lib/tty/option/parser.rb +1 -1
- data/lib/tty/option/parser/arguments.rb +1 -1
- data/lib/tty/option/parser/arity_check.rb +1 -1
- data/lib/tty/option/parser/environments.rb +2 -2
- data/lib/tty/option/parser/keywords.rb +1 -1
- data/lib/tty/option/parser/param_types.rb +16 -4
- data/lib/tty/option/parser/required_check.rb +1 -1
- data/lib/tty/option/pipeline.rb +1 -1
- data/lib/tty/option/result.rb +25 -3
- data/lib/tty/option/usage.rb +58 -1
- data/lib/tty/option/usage_wrapper.rb +3 -2
- data/lib/tty/option/version.rb +1 -1
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fabf2ee6efdc82e500dee823a54a90675a52dc06e90496b922396fe412c7780f
|
4
|
+
data.tar.gz: c2e00f207d86ca4adfbe84b0e8a99298720d50e754cdb77e3ab815c11d9152eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c484049a77722baae844331533373d174f35999ab621040b2be38968fd64b0d6fa14372873741e4df40d75fa15d36f7f22557d02f48f5d25de40f14ad42da400
|
7
|
+
data.tar.gz: 173e26541c883f4111a69b5f1d8287cea032bd727275ac04f62ab4da3d4925680b5dcd8ef0cf81a7cc5d73a32e67aaf71042b7dbe5c72817429155a5abc55479
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,22 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
|
+
## [v0.2.0] - 2021-08-04
|
4
|
+
|
5
|
+
### Added
|
6
|
+
* Add predicate methods for checking if a given parameter is supported
|
7
|
+
|
8
|
+
### Changed
|
9
|
+
* Change Conversions to stop raising error and return Undefined value instead
|
10
|
+
* Change to skip conversion of parameters with nil value
|
11
|
+
|
12
|
+
### Fixed
|
13
|
+
* Fix conversion of nil into array or hash to stop raising an error
|
14
|
+
* Fix #no_command to correctly mark command as not present
|
15
|
+
* Fix warnings about shadowing local variables
|
16
|
+
|
3
17
|
## [v0.1.0] - 2020-05-18
|
4
18
|
|
5
19
|
* Initial implementation and release
|
6
20
|
|
7
|
-
[v0.
|
21
|
+
[v0.2.0]: https://github.com/piotrmurach/tty-option/compare/v0.1.0...v0.2.0
|
22
|
+
[v0.1.0]: https://github.com/piotrmurach/tty-option/compare/95179f0...v0.1.0
|
data/LICENSE.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2020 Piotr Murach
|
3
|
+
Copyright (c) 2020 Piotr Murach (piotrmurach.com)
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
@@ -1,22 +1,22 @@
|
|
1
1
|
<div align="center">
|
2
|
-
<a href="https://
|
2
|
+
<a href="https://ttytoolkit.org"><img width="130" src="https://github.com/piotrmurach/tty/raw/master/images/tty.png" alt="TTY Toolkit logo"/></a>
|
3
3
|
</div>
|
4
4
|
|
5
5
|
# TTY::Option
|
6
6
|
|
7
7
|
[![Gem Version](https://badge.fury.io/rb/tty-option.svg)][gem]
|
8
|
-
[![
|
8
|
+
[![Actions CI](https://github.com/piotrmurach/tty-option/workflows/CI/badge.svg?branch=master)][gh_actions_ci]
|
9
9
|
[![Build status](https://ci.appveyor.com/api/projects/status/gxml9ttyvgpeasy5?svg=true)][appveyor]
|
10
10
|
[![Maintainability](https://api.codeclimate.com/v1/badges/1083a2fd114d6faf5d65/maintainability)][codeclimate]
|
11
11
|
[![Coverage Status](https://coveralls.io/repos/github/piotrmurach/tty-option/badge.svg)][coverage]
|
12
|
-
[![Inline docs](
|
12
|
+
[![Inline docs](https://inch-ci.org/github/piotrmurach/tty-option.svg?branch=master)][inchpages]
|
13
13
|
|
14
|
-
[gem]:
|
15
|
-
[
|
14
|
+
[gem]: https://badge.fury.io/rb/tty-option
|
15
|
+
[gh_actions_ci]: https://github.com/piotrmurach/tty-option/actions?query=workflow%3ACI
|
16
16
|
[appveyor]: https://ci.appveyor.com/project/piotrmurach/tty-option
|
17
17
|
[codeclimate]: https://codeclimate.com/github/piotrmurach/tty-option/maintainability
|
18
18
|
[coverage]: https://coveralls.io/github/piotrmurach/tty-option
|
19
|
-
[inchpages]:
|
19
|
+
[inchpages]: https://inch-ci.org/github/piotrmurach/tty-option
|
20
20
|
|
21
21
|
> Parser for command line arguments, keywords, options and environment variables
|
22
22
|
|
@@ -280,7 +280,7 @@ argument :foo do
|
|
280
280
|
required # a default
|
281
281
|
variable "foo(int)" # name for the usage display
|
282
282
|
arity one_or_more # how many times to occur
|
283
|
-
convert :int # values converted to
|
283
|
+
convert :int # values converted to integer
|
284
284
|
validate -> { |v| v < 14 } # validation rule
|
285
285
|
desc "Some foo desc" # description for the usage display
|
286
286
|
end
|
@@ -338,7 +338,7 @@ A more involved example to parse multiple keyword arguments requires use of help
|
|
338
338
|
keyword :foo do
|
339
339
|
required # by default keywrod is not required
|
340
340
|
arity one_or_more # how many times to occur
|
341
|
-
convert :int # values converted to
|
341
|
+
convert :int # values converted to integer
|
342
342
|
validate -> { |v| v < 14 } # validation rule
|
343
343
|
desc "Some foo desc" # description for the usage display
|
344
344
|
end
|
@@ -362,7 +362,7 @@ You can also specify for the keyword argument to accept a list type:
|
|
362
362
|
keyword :foo do
|
363
363
|
required # by default keyword is not required
|
364
364
|
arity one_or_more # how many times to occur
|
365
|
-
convert :int_list # input can be a list of
|
365
|
+
convert :int_list # input can be a list of integers
|
366
366
|
validate -> { |v| v < 14 } # validation rule
|
367
367
|
desc "Some foo desc" # description for the usage display
|
368
368
|
end
|
@@ -453,7 +453,7 @@ option :foo do
|
|
453
453
|
arity one_or_more # how many times option can occur
|
454
454
|
short "-f" # declares a short flag name
|
455
455
|
long "--foo list" # declares a long flag with a required argument
|
456
|
-
convert :int_list # input can be a list of
|
456
|
+
convert :int_list # input can be a list of integers
|
457
457
|
validate -> { |v| v < 14 } # validation rule
|
458
458
|
desc "Some foo desc" # description for the usage display
|
459
459
|
end
|
@@ -75,12 +75,12 @@ module TTY
|
|
75
75
|
output = []
|
76
76
|
space_indent = " " * indent
|
77
77
|
if messages.count == 1
|
78
|
-
|
78
|
+
msg = messages.first
|
79
79
|
label = "Error: "
|
80
80
|
output << "#{space_indent}#{label}" \
|
81
|
-
"#{wrap(
|
81
|
+
"#{wrap(msg, indent: indent + label.length, width: width)}"
|
82
82
|
else
|
83
|
-
output << space_indent
|
83
|
+
output << "#{space_indent}Errors:"
|
84
84
|
messages.each_with_index do |message, num|
|
85
85
|
entry = " #{num + 1}) "
|
86
86
|
output << "#{space_indent}#{entry}" \
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TTY
|
4
|
+
module Option
|
5
|
+
module Const
|
6
|
+
Undefined = Object.new.tap do |obj|
|
7
|
+
def obj.to_s
|
8
|
+
"undefined"
|
9
|
+
end
|
10
|
+
|
11
|
+
def obj.inspect
|
12
|
+
"undefined".inspect
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end # Const
|
16
|
+
end # Option
|
17
|
+
end # TTY
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "const"
|
3
4
|
require_relative "converter"
|
4
5
|
|
5
6
|
module TTY
|
@@ -10,13 +11,6 @@ module TTY
|
|
10
11
|
TRUE_VALUES = /^(true|y(es)?|t|1)$/i.freeze
|
11
12
|
FALSE_VALUES = /^(false|n(o)?|f|0)$/i.freeze
|
12
13
|
|
13
|
-
# @api public
|
14
|
-
def self.raise_invalid_argument(conv_name, val)
|
15
|
-
raise ConversionError,
|
16
|
-
format("invalid value of %<value>s for %<conv>s conversion",
|
17
|
-
value: val.inspect, conv: conv_name.inspect)
|
18
|
-
end
|
19
|
-
|
20
14
|
convert :bool, :boolean do |val|
|
21
15
|
case val.to_s
|
22
16
|
when TRUE_VALUES
|
@@ -24,7 +18,7 @@ module TTY
|
|
24
18
|
when FALSE_VALUES
|
25
19
|
false
|
26
20
|
else
|
27
|
-
|
21
|
+
Const::Undefined
|
28
22
|
end
|
29
23
|
end
|
30
24
|
|
@@ -33,7 +27,7 @@ module TTY
|
|
33
27
|
require "date" unless defined?(::Date)
|
34
28
|
::Date.parse(val)
|
35
29
|
rescue ArgumentError, TypeError
|
36
|
-
|
30
|
+
Const::Undefined
|
37
31
|
end
|
38
32
|
end
|
39
33
|
|
@@ -41,7 +35,7 @@ module TTY
|
|
41
35
|
begin
|
42
36
|
Float(val)
|
43
37
|
rescue ArgumentError, TypeError
|
44
|
-
|
38
|
+
Const::Undefined
|
45
39
|
end
|
46
40
|
end
|
47
41
|
|
@@ -49,7 +43,7 @@ module TTY
|
|
49
43
|
begin
|
50
44
|
Float(val).to_i
|
51
45
|
rescue ArgumentError, TypeError
|
52
|
-
|
46
|
+
Const::Undefined
|
53
47
|
end
|
54
48
|
end
|
55
49
|
|
@@ -62,7 +56,7 @@ module TTY
|
|
62
56
|
begin
|
63
57
|
Regexp.new(val.to_s)
|
64
58
|
rescue TypeError, RegexpError
|
65
|
-
|
59
|
+
Const::Undefined
|
66
60
|
end
|
67
61
|
end
|
68
62
|
|
@@ -70,7 +64,7 @@ module TTY
|
|
70
64
|
begin
|
71
65
|
String(val).to_sym
|
72
66
|
rescue ArgumentError
|
73
|
-
|
67
|
+
Const::Undefined
|
74
68
|
end
|
75
69
|
end
|
76
70
|
|
@@ -79,18 +73,22 @@ module TTY
|
|
79
73
|
require "uri"
|
80
74
|
::URI.parse(val)
|
81
75
|
rescue ::URI::InvalidURIError
|
82
|
-
|
76
|
+
Const::Undefined
|
83
77
|
end
|
84
78
|
end
|
85
79
|
|
86
80
|
convert :list, :array do |val|
|
87
|
-
|
81
|
+
next Const::Undefined if val.nil?
|
82
|
+
|
83
|
+
(val.respond_to?(:map) ? val : val.to_s.split(/(?<!\\),/))
|
88
84
|
.map { |v| v.strip.gsub(/\\,/, ",") }
|
89
85
|
.reject(&:empty?)
|
90
86
|
end
|
91
87
|
|
92
88
|
convert :map, :hash do |val|
|
93
|
-
|
89
|
+
next Const::Undefined if val.nil?
|
90
|
+
|
91
|
+
values = val.respond_to?(:each) ? val : val.to_s.split(/[& ]/)
|
94
92
|
values.each_with_object({}) do |pair, pairs|
|
95
93
|
key, value = pair.split(/[=:]/, 2)
|
96
94
|
if (current = pairs[key.to_sym])
|
@@ -107,16 +105,26 @@ module TTY
|
|
107
105
|
|
108
106
|
[:"#{type}_list", :"#{type}_array", :"#{type}s"].each do |new_type|
|
109
107
|
convert new_type do |val|
|
110
|
-
conversions[:list].(val)
|
111
|
-
|
108
|
+
list_conversion = conversions[:list].(val)
|
109
|
+
next list_conversion if list_conversion == Const::Undefined
|
110
|
+
|
111
|
+
list_conversion.map do |obj|
|
112
|
+
converted = conversions[type].(obj)
|
113
|
+
break converted if converted == Const::Undefined
|
114
|
+
converted
|
112
115
|
end
|
113
116
|
end
|
114
117
|
end
|
115
118
|
|
116
119
|
[:"#{type}_map", :"#{type}_hash"].each do |new_type|
|
117
120
|
convert new_type do |val|
|
121
|
+
map_conversion = conversions[:map].(val)
|
122
|
+
next map_conversion if map_conversion == Const::Undefined
|
123
|
+
|
118
124
|
conversions[:map].(val).each_with_object({}) do |(k, v), h|
|
119
|
-
|
125
|
+
converted = conversions[type].(v)
|
126
|
+
break converted if converted == Const::Undefined
|
127
|
+
h[k] = converted
|
120
128
|
end
|
121
129
|
end
|
122
130
|
end
|
data/lib/tty/option/converter.rb
CHANGED
@@ -32,7 +32,7 @@ module TTY
|
|
32
32
|
names.each do |name|
|
33
33
|
if contain?(name)
|
34
34
|
raise ConversionAlreadyDefined,
|
35
|
-
|
35
|
+
"conversion #{name.inspect} is already defined"
|
36
36
|
end
|
37
37
|
conversions[name] = block
|
38
38
|
end
|
@@ -56,7 +56,7 @@ module TTY
|
|
56
56
|
# @api public
|
57
57
|
def raise_unsupported_error(conv_name)
|
58
58
|
raise UnsupportedConversion,
|
59
|
-
|
59
|
+
"unsupported conversion type #{conv_name.inspect}"
|
60
60
|
end
|
61
61
|
end # Converter
|
62
62
|
end # Option
|
data/lib/tty/option/deep_dup.rb
CHANGED
data/lib/tty/option/dsl.rb
CHANGED
@@ -28,10 +28,10 @@ module TTY
|
|
28
28
|
# @api public
|
29
29
|
def usage(**properties, &block)
|
30
30
|
@usage ||= Usage.create(**properties, &block).tap do |usage|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
unless usage.command? || usage.no_command?
|
32
|
+
usage.command(dasherize(demodulize(self.name)))
|
33
|
+
end
|
34
|
+
end
|
35
35
|
end
|
36
36
|
|
37
37
|
# Specify an argument
|
@@ -69,7 +69,7 @@ module TTY
|
|
69
69
|
#
|
70
70
|
# @api public
|
71
71
|
def flag(name, **settings, &block)
|
72
|
-
defaults = {
|
72
|
+
defaults = {default: false}
|
73
73
|
option(name, **defaults.merge(settings), &block)
|
74
74
|
end
|
75
75
|
|
data/lib/tty/option/formatter.rb
CHANGED
@@ -53,10 +53,12 @@ module TTY
|
|
53
53
|
|
54
54
|
# A formatted help usage information
|
55
55
|
#
|
56
|
+
# @yieldparam [TTY::Option::Sections] sections
|
57
|
+
#
|
56
58
|
# @return [String]
|
57
59
|
#
|
58
60
|
# @api public
|
59
|
-
def help
|
61
|
+
def help
|
60
62
|
sections = Sections.new
|
61
63
|
|
62
64
|
sections.add(:header, help_header) if @usage.header?
|
@@ -82,9 +84,7 @@ module TTY
|
|
82
84
|
sections.add(:examples, help_examples) if @usage.example?
|
83
85
|
sections.add(:footer, help_footer) if @usage.footer?
|
84
86
|
|
85
|
-
if block_given?
|
86
|
-
yield(sections)
|
87
|
-
end
|
87
|
+
yield(sections) if block_given?
|
88
88
|
|
89
89
|
formatted = sections.reject(&:empty?).join(NEWLINE)
|
90
90
|
formatted.end_with?(NEWLINE) ? formatted : formatted + NEWLINE
|
@@ -182,7 +182,7 @@ module TTY
|
|
182
182
|
args << "[" if param.optional?
|
183
183
|
args << param_name
|
184
184
|
(param.arity - 1).times { args << " #{param_name}" }
|
185
|
-
args
|
185
|
+
args << "]" if param.optional?
|
186
186
|
args.join
|
187
187
|
else
|
188
188
|
(param.arity.abs - 1).times { args << param_name }
|
@@ -10,24 +10,26 @@ module TTY
|
|
10
10
|
#
|
11
11
|
# @example
|
12
12
|
# param = Parameter::Argument.create(:foo, convert: :int)
|
13
|
-
# ParamConversion[param, "12"]
|
13
|
+
# result = ParamConversion[param, "12"]
|
14
|
+
# result.value # => 12
|
14
15
|
#
|
15
16
|
# @api public
|
16
17
|
def call(param, value)
|
17
|
-
return Result.success(value)
|
18
|
+
return Result.success(value) if !param.convert? || value.nil?
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
cast = param.convert
|
21
|
+
cast = cast.is_a?(Proc) ? cast : Conversions[cast]
|
22
|
+
converted = cast.(value)
|
23
|
+
|
24
|
+
if converted == Const::Undefined
|
25
|
+
Result.failure(InvalidConversionArgument.new(param, value))
|
22
26
|
else
|
23
|
-
Result.success(
|
27
|
+
Result.success(converted)
|
24
28
|
end
|
25
|
-
rescue ConversionError
|
26
|
-
Result.failure(InvalidConversionArgument.new(param, value))
|
27
29
|
end
|
28
30
|
module_function :call
|
29
31
|
|
30
|
-
alias
|
32
|
+
alias [] call
|
31
33
|
module_function :[]
|
32
34
|
end # ParamConversion
|
33
35
|
end # Option
|
data/lib/tty/option/parameter.rb
CHANGED
@@ -11,6 +11,12 @@ module TTY
|
|
11
11
|
include DSL::Arity
|
12
12
|
include DSL::Conversion
|
13
13
|
|
14
|
+
# Zero or more parameter arity pattern
|
15
|
+
ZERO_OR_MORE_ARITY = /\*|any/.freeze
|
16
|
+
|
17
|
+
# One or more parameter arity pattern
|
18
|
+
ONE_OR_MORE_ARITY = /\+/.freeze
|
19
|
+
|
14
20
|
# A parameter factory
|
15
21
|
#
|
16
22
|
# @api public
|
@@ -32,20 +38,20 @@ module TTY
|
|
32
38
|
def initialize(key, **settings, &block)
|
33
39
|
@key = key
|
34
40
|
@settings = {}
|
35
|
-
settings.each do |
|
36
|
-
case
|
41
|
+
settings.each do |name, val|
|
42
|
+
case name.to_sym
|
37
43
|
when :arity
|
38
44
|
val = check_arity(val)
|
39
45
|
when :default
|
40
46
|
val = check_default(val)
|
41
47
|
when :optional
|
42
|
-
|
48
|
+
name, val = :required, check_required(!val)
|
43
49
|
when :permit
|
44
50
|
val = check_permitted(val)
|
45
51
|
when :validate
|
46
52
|
val = check_validation(val)
|
47
53
|
end
|
48
|
-
@settings[
|
54
|
+
@settings[name.to_sym] = val
|
49
55
|
end
|
50
56
|
|
51
57
|
instance_eval(&block) if block_given?
|
@@ -136,7 +142,7 @@ module TTY
|
|
136
142
|
end
|
137
143
|
|
138
144
|
def required?
|
139
|
-
@settings.fetch(:required
|
145
|
+
@settings.fetch(:required, false)
|
140
146
|
end
|
141
147
|
|
142
148
|
def hidden
|
@@ -144,7 +150,7 @@ module TTY
|
|
144
150
|
end
|
145
151
|
|
146
152
|
def hidden?
|
147
|
-
@settings.fetch(:hidden
|
153
|
+
@settings.fetch(:hidden, false)
|
148
154
|
end
|
149
155
|
|
150
156
|
def display?
|
@@ -203,6 +209,7 @@ module TTY
|
|
203
209
|
# @api public
|
204
210
|
def ==(other)
|
205
211
|
return false unless instance_of?(other.class)
|
212
|
+
|
206
213
|
name == other.name && to_h == other.to_h
|
207
214
|
end
|
208
215
|
|
@@ -211,6 +218,7 @@ module TTY
|
|
211
218
|
# @api public
|
212
219
|
def eql?(other)
|
213
220
|
return false unless instance_of?(other.class)
|
221
|
+
|
214
222
|
name.eql?(other.name) && to_h.eql?(other.to_h)
|
215
223
|
end
|
216
224
|
|
@@ -250,15 +258,14 @@ module TTY
|
|
250
258
|
end
|
251
259
|
|
252
260
|
case value.to_s
|
253
|
-
when
|
254
|
-
when
|
255
|
-
else value
|
256
|
-
end
|
257
|
-
|
258
|
-
|
259
|
-
|
261
|
+
when ZERO_OR_MORE_ARITY then -1
|
262
|
+
when ONE_OR_MORE_ARITY then -2
|
263
|
+
else value.to_i
|
264
|
+
end.tap do |val|
|
265
|
+
if val.zero?
|
266
|
+
raise ConfigurationError, "#{to_sym} '#{name}' arity cannot be zero"
|
267
|
+
end
|
260
268
|
end
|
261
|
-
value
|
262
269
|
end
|
263
270
|
|
264
271
|
# @api private
|
@@ -13,7 +13,16 @@ module TTY
|
|
13
13
|
# @api private
|
14
14
|
def self.define_query(name)
|
15
15
|
define_method(:"#{name}?") do
|
16
|
-
!
|
16
|
+
!public_send(name).empty?
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Define a predicate method to check if a parameter is supported
|
21
|
+
#
|
22
|
+
# @api private
|
23
|
+
def self.define_param_query(name)
|
24
|
+
define_method(:"#{name}?") do |param|
|
25
|
+
public_send(:"#{name}s").map(&:key).include?(param)
|
17
26
|
end
|
18
27
|
end
|
19
28
|
|
@@ -37,6 +46,11 @@ module TTY
|
|
37
46
|
define_query :options
|
38
47
|
define_query :environments
|
39
48
|
|
49
|
+
define_param_query :argument
|
50
|
+
define_param_query :keyword
|
51
|
+
define_param_query :option
|
52
|
+
define_param_query :environment
|
53
|
+
|
40
54
|
# A parameters list
|
41
55
|
#
|
42
56
|
# @api private
|
data/lib/tty/option/parser.rb
CHANGED
@@ -150,10 +150,10 @@ module TTY
|
|
150
150
|
if allowed
|
151
151
|
case value
|
152
152
|
when Hash
|
153
|
-
(@parsed[env_arg.key] ||=
|
153
|
+
(@parsed[env_arg.key] ||= {}).merge!(value)
|
154
154
|
else
|
155
155
|
Array(value).each do |v|
|
156
|
-
(@parsed[env_arg.key] ||=
|
156
|
+
(@parsed[env_arg.key] ||= []) << v
|
157
157
|
end
|
158
158
|
end
|
159
159
|
else
|
@@ -4,6 +4,18 @@ module TTY
|
|
4
4
|
module Option
|
5
5
|
class Parser
|
6
6
|
module ParamTypes
|
7
|
+
# Positional argument pattern
|
8
|
+
ARGUMENT_PARAMETER = /^[^-][^=]*\z/.freeze
|
9
|
+
|
10
|
+
# Environment variable pattern
|
11
|
+
ENV_VAR_PARAMETER = /^[\p{Lu}_\-\d]+=/.freeze
|
12
|
+
|
13
|
+
# Keyword pattern
|
14
|
+
KEYWORD_PARAMETER = /^([^-=][\p{Ll}_\-\d]*)=([^=]+)/.freeze
|
15
|
+
|
16
|
+
# Option and flag pattern
|
17
|
+
OPTION_PARAMETER = /^-./.freeze
|
18
|
+
|
7
19
|
# Check if value looks like an argument
|
8
20
|
#
|
9
21
|
# @param [String] value
|
@@ -12,7 +24,7 @@ module TTY
|
|
12
24
|
#
|
13
25
|
# @api public
|
14
26
|
def argument?(value)
|
15
|
-
!value.match(
|
27
|
+
!value.match(ARGUMENT_PARAMETER).nil?
|
16
28
|
end
|
17
29
|
|
18
30
|
# Check if value is an environment variable
|
@@ -23,7 +35,7 @@ module TTY
|
|
23
35
|
#
|
24
36
|
# @api public
|
25
37
|
def env_var?(value)
|
26
|
-
!value.match(
|
38
|
+
!value.match(ENV_VAR_PARAMETER).nil?
|
27
39
|
end
|
28
40
|
|
29
41
|
# Check to see if value is a keyword
|
@@ -32,7 +44,7 @@ module TTY
|
|
32
44
|
#
|
33
45
|
# @api public
|
34
46
|
def keyword?(value)
|
35
|
-
!value.to_s.match(
|
47
|
+
!value.to_s.match(KEYWORD_PARAMETER).nil?
|
36
48
|
end
|
37
49
|
|
38
50
|
# Check if value looks like an option
|
@@ -43,7 +55,7 @@ module TTY
|
|
43
55
|
#
|
44
56
|
# @api public
|
45
57
|
def option?(value)
|
46
|
-
!value.match(
|
58
|
+
!value.match(OPTION_PARAMETER).nil?
|
47
59
|
end
|
48
60
|
end # ParamTypes
|
49
61
|
end # Parser
|
data/lib/tty/option/pipeline.rb
CHANGED
data/lib/tty/option/result.rb
CHANGED
@@ -18,29 +18,51 @@ module TTY
|
|
18
18
|
Failure.new(value)
|
19
19
|
end
|
20
20
|
|
21
|
+
# Wrapped value
|
22
|
+
#
|
23
|
+
# @api public
|
21
24
|
attr_reader :value
|
22
25
|
|
26
|
+
# Reason for failure
|
27
|
+
#
|
28
|
+
# @api public
|
23
29
|
attr_reader :error
|
24
30
|
|
31
|
+
# Check whether or not a result is a success monad
|
32
|
+
#
|
33
|
+
# @return [Boolean]
|
34
|
+
#
|
35
|
+
# @api public
|
25
36
|
def success?
|
26
37
|
is_a?(Success)
|
27
38
|
end
|
28
39
|
|
40
|
+
# Check whether or not a result is a failure class
|
41
|
+
#
|
42
|
+
# @return [Boolean]
|
43
|
+
#
|
44
|
+
# @api public
|
29
45
|
def failure?
|
30
46
|
is_a?(Failure)
|
31
47
|
end
|
32
48
|
|
49
|
+
# Success monad containing a value
|
50
|
+
#
|
51
|
+
# @api private
|
33
52
|
class Success < Result
|
34
53
|
def initialize(value)
|
35
54
|
@value = value
|
36
55
|
end
|
37
56
|
end
|
38
57
|
|
58
|
+
# Failure monad containing an error
|
59
|
+
#
|
60
|
+
# @api private
|
39
61
|
class Failure < Result
|
40
62
|
def initialize(error)
|
41
63
|
@error = error
|
42
64
|
end
|
43
65
|
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
66
|
+
end # Result
|
67
|
+
end # Option
|
68
|
+
end # TTY
|
data/lib/tty/option/usage.rb
CHANGED
@@ -17,8 +17,11 @@ module TTY
|
|
17
17
|
# @api public
|
18
18
|
def initialize(**properties, &block)
|
19
19
|
@properties = {}
|
20
|
+
@no_command = false
|
20
21
|
properties.each do |key, val|
|
21
22
|
case key.to_sym
|
23
|
+
when :command
|
24
|
+
key, val = :command, Array(val)
|
22
25
|
when :desc, :description
|
23
26
|
key, val = :desc, [Array(val)]
|
24
27
|
when :header, :footer
|
@@ -34,8 +37,10 @@ module TTY
|
|
34
37
|
|
35
38
|
# Program name for display in help and error messages
|
36
39
|
#
|
40
|
+
# @param [String] name
|
41
|
+
#
|
37
42
|
# @api public
|
38
|
-
def program(name = (not_set = true)
|
43
|
+
def program(name = (not_set = true))
|
39
44
|
if not_set
|
40
45
|
@properties.fetch(:program) { ::File.basename($0, ".*") }
|
41
46
|
else
|
@@ -45,6 +50,8 @@ module TTY
|
|
45
50
|
|
46
51
|
# Action name for display in help and error messages
|
47
52
|
#
|
53
|
+
# @param [Array<String>] values
|
54
|
+
#
|
48
55
|
# @api public
|
49
56
|
def command(*values)
|
50
57
|
if values.empty?
|
@@ -60,15 +67,32 @@ module TTY
|
|
60
67
|
#
|
61
68
|
# @api public
|
62
69
|
def no_command
|
70
|
+
@no_command = true
|
63
71
|
@properties[:command] = []
|
64
72
|
end
|
65
73
|
|
74
|
+
# Whether or not to show command in usage
|
75
|
+
#
|
76
|
+
# @retrun [Boolean]
|
77
|
+
#
|
78
|
+
# @api public
|
79
|
+
def no_command?
|
80
|
+
@no_command
|
81
|
+
end
|
82
|
+
|
83
|
+
# Check for command definition
|
84
|
+
#
|
85
|
+
# @return [Boolean]
|
86
|
+
#
|
87
|
+
# @api public
|
66
88
|
def command?
|
67
89
|
@properties.key?(:command) && !@properties[:command].empty?
|
68
90
|
end
|
69
91
|
|
70
92
|
# Display info before anything else in the usage help
|
71
93
|
#
|
94
|
+
# @param [Array<String>] values
|
95
|
+
#
|
72
96
|
# @api public
|
73
97
|
def header(*values)
|
74
98
|
if values.empty?
|
@@ -78,12 +102,19 @@ module TTY
|
|
78
102
|
end
|
79
103
|
end
|
80
104
|
|
105
|
+
# Whether or not to show header in usage
|
106
|
+
#
|
107
|
+
# @return [Boolean]
|
108
|
+
#
|
109
|
+
# @api public
|
81
110
|
def header?
|
82
111
|
@properties.key?(:header) && !@properties[:header].empty?
|
83
112
|
end
|
84
113
|
|
85
114
|
# Main way to show how all parameters can be used
|
86
115
|
#
|
116
|
+
# @param [String] value
|
117
|
+
#
|
87
118
|
# @api public
|
88
119
|
def banner(value = (not_set = true))
|
89
120
|
if not_set
|
@@ -93,12 +124,19 @@ module TTY
|
|
93
124
|
end
|
94
125
|
end
|
95
126
|
|
127
|
+
# Whether or not to show banner in usage
|
128
|
+
#
|
129
|
+
# @return [Boolean]
|
130
|
+
#
|
131
|
+
# @api public
|
96
132
|
def banner?
|
97
133
|
@properties.key?(:banner) && !@properties[:banner].nil?
|
98
134
|
end
|
99
135
|
|
100
136
|
# Description
|
101
137
|
#
|
138
|
+
# @param [Array<String>] values
|
139
|
+
#
|
102
140
|
# @api public
|
103
141
|
def desc(*values)
|
104
142
|
if values.empty?
|
@@ -109,6 +147,11 @@ module TTY
|
|
109
147
|
end
|
110
148
|
alias description desc
|
111
149
|
|
150
|
+
# Whether or not to show description in usage
|
151
|
+
#
|
152
|
+
# @return [Boolean]
|
153
|
+
#
|
154
|
+
# @api public
|
112
155
|
def desc?
|
113
156
|
@properties.key?(:desc) && !@properties[:desc].empty?
|
114
157
|
end
|
@@ -116,6 +159,8 @@ module TTY
|
|
116
159
|
|
117
160
|
# Collects usage examples
|
118
161
|
#
|
162
|
+
# @param [Array<String>] values
|
163
|
+
#
|
119
164
|
# @api public
|
120
165
|
def example(*values)
|
121
166
|
if values.empty?
|
@@ -126,6 +171,11 @@ module TTY
|
|
126
171
|
end
|
127
172
|
alias examples example
|
128
173
|
|
174
|
+
# Whether or not to show example in usage
|
175
|
+
#
|
176
|
+
# @return [Boolean]
|
177
|
+
#
|
178
|
+
# @api public
|
129
179
|
def example?
|
130
180
|
@properties.key?(:example) && !@properties[:example].empty?
|
131
181
|
end
|
@@ -133,6 +183,8 @@ module TTY
|
|
133
183
|
|
134
184
|
# Display info after everyting else in the usage help
|
135
185
|
#
|
186
|
+
# @param [Array<String>] values
|
187
|
+
#
|
136
188
|
# @api public
|
137
189
|
def footer(*values)
|
138
190
|
if values.empty?
|
@@ -142,6 +194,11 @@ module TTY
|
|
142
194
|
end
|
143
195
|
end
|
144
196
|
|
197
|
+
# Whether or not to show footer in usage
|
198
|
+
#
|
199
|
+
# @return [Boolean]
|
200
|
+
#
|
201
|
+
# @api public
|
145
202
|
def footer?
|
146
203
|
@properties.key?(:footer) && !@properties[:footer].empty?
|
147
204
|
end
|
@@ -14,13 +14,14 @@ module TTY
|
|
14
14
|
def wrap(text, width: 80, indent: 2, indent_first: false)
|
15
15
|
wrap = width - indent
|
16
16
|
lines = []
|
17
|
+
indentation = " " * indent
|
17
18
|
|
18
19
|
line, rest = *next_line(text, wrap: wrap)
|
19
|
-
lines << (indent_first ?
|
20
|
+
lines << (indent_first ? indentation : "") + line
|
20
21
|
|
21
22
|
while !rest.nil?
|
22
23
|
line, rest = *next_line(rest, wrap: wrap)
|
23
|
-
lines <<
|
24
|
+
lines << indentation + line.strip
|
24
25
|
end
|
25
26
|
|
26
27
|
lines.join("\n")
|
data/lib/tty/option/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tty-option
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Murach
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-08-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -55,6 +55,7 @@ files:
|
|
55
55
|
- lib/tty-option.rb
|
56
56
|
- lib/tty/option.rb
|
57
57
|
- lib/tty/option/aggregate_errors.rb
|
58
|
+
- lib/tty/option/const.rb
|
58
59
|
- lib/tty/option/conversions.rb
|
59
60
|
- lib/tty/option/converter.rb
|
60
61
|
- lib/tty/option/deep_dup.rb
|
@@ -100,7 +101,7 @@ metadata:
|
|
100
101
|
documentation_uri: https://www.rubydoc.info/gems/tty-option
|
101
102
|
homepage_uri: https://ttytoolkit.org
|
102
103
|
source_code_uri: https://github.com/piotrmurach/tty-option
|
103
|
-
post_install_message:
|
104
|
+
post_install_message:
|
104
105
|
rdoc_options: []
|
105
106
|
require_paths:
|
106
107
|
- lib
|
@@ -116,7 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
116
117
|
version: '0'
|
117
118
|
requirements: []
|
118
119
|
rubygems_version: 3.1.2
|
119
|
-
signing_key:
|
120
|
+
signing_key:
|
120
121
|
specification_version: 4
|
121
|
-
summary: An intuitive and flexible command line parser
|
122
|
+
summary: An intuitive and flexible command line parser.
|
122
123
|
test_files: []
|