tty-option 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e48f8a476c72fb96d9f6bf49daea6533b2cc6940a536eb0e5a56fce19ff6c75b
4
- data.tar.gz: cbadbde794e8469c8d0b1bc5ade00c47e2420d885f5a5fd6e410dce5950d3d8a
3
+ metadata.gz: fabf2ee6efdc82e500dee823a54a90675a52dc06e90496b922396fe412c7780f
4
+ data.tar.gz: c2e00f207d86ca4adfbe84b0e8a99298720d50e754cdb77e3ab815c11d9152eb
5
5
  SHA512:
6
- metadata.gz: b6257d839aefe82f045f8708ebd5b5443a2df85090b1c3a722f8dbe3ba40704c79277a203e44d78e458405200ad465e3471dc4b3575fc101806d7b4b93717ee6
7
- data.tar.gz: 461f0b5454e44e5bebf59dcd308ffa2fda57f457d0191c709b859dae216880b781ff62d40e96e2cc101f8637ee94b1029174c7d63c2d872c345614b692412e34
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.1.0]: https://github.com/piotrmurach/tty-option/compare/v0.1.0
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://piotrmurach.github.io/tty" target="_blank"><img width="130" src="https://github.com/piotrmurach/tty/raw/master/images/tty.png" alt="tty logo" /></a>
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
- [![Build Status](https://secure.travis-ci.org/piotrmurach/tty-option.svg?branch=master)][travis]
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](http://inch-ci.org/github/piotrmurach/tty-option.svg?branch=master)][inchpages]
12
+ [![Inline docs](https://inch-ci.org/github/piotrmurach/tty-option.svg?branch=master)][inchpages]
13
13
 
14
- [gem]: http://badge.fury.io/rb/tty-option
15
- [travis]: http://travis-ci.org/piotrmurach/tty-option
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]: http://inch-ci.org/github/piotrmurach/tty-option
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 intenger
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 intenger
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 intengers
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 intengers
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
- message = messages.first
78
+ msg = messages.first
79
79
  label = "Error: "
80
80
  output << "#{space_indent}#{label}" \
81
- "#{wrap(message, indent: indent + label.length, width: width)}"
81
+ "#{wrap(msg, indent: indent + label.length, width: width)}"
82
82
  else
83
- output << space_indent + "Errors:"
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
- raise_invalid_argument(:bool, val)
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
- raise_invalid_argument(:date, val)
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
- raise_invalid_argument(:float, val)
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
- raise_invalid_argument(:integer, val)
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
- raise_invalid_argument(:regexp, val)
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
- raise_invalid_argument(:symbol, val)
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
- raise_invalid_argument(:uri, val)
76
+ Const::Undefined
83
77
  end
84
78
  end
85
79
 
86
80
  convert :list, :array do |val|
87
- (val.respond_to?(:to_a) ? val : val.split(/(?<!\\),/))
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
- values = val.respond_to?(:to_a) ? val : val.split(/[& ]/)
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).map do |obj|
111
- conversions[type].(obj)
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
- h[k] = conversions[type].(v)
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
@@ -32,7 +32,7 @@ module TTY
32
32
  names.each do |name|
33
33
  if contain?(name)
34
34
  raise ConversionAlreadyDefined,
35
- "conversion #{name.inspect} is already defined"
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
- "unsupported conversion type #{conv_name.inspect}"
59
+ "unsupported conversion type #{conv_name.inspect}"
60
60
  end
61
61
  end # Converter
62
62
  end # Option
@@ -14,7 +14,6 @@ module TTY
14
14
  # @api public
15
15
  def self.deep_dup(object)
16
16
  case object
17
- when String then object.dup
18
17
  when *NONDUPLICATABLE then object
19
18
  when Hash then deep_dup_hash(object)
20
19
  when Array then deep_dup_array(object)
@@ -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
- if usage.command.empty?
32
- usage.command(dasherize(demodulize(self.name)))
33
- end
34
- end
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 = { default: false }
72
+ defaults = {default: false}
73
73
  option(name, **defaults.merge(settings), &block)
74
74
  end
75
75
 
@@ -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(&block)
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. << "]" if param.optional?
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"] # => 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) unless param.convert?
18
+ return Result.success(value) if !param.convert? || value.nil?
18
19
 
19
- case cast = param.convert
20
- when Proc
21
- Result.success(cast.(value))
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(Conversions[cast].(value))
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 :[] :call
32
+ alias [] call
31
33
  module_function :[]
32
34
  end # ParamConversion
33
35
  end # Option
@@ -23,7 +23,7 @@ module TTY
23
23
  end
24
24
  module_function :call
25
25
 
26
- alias :[] :call
26
+ alias [] call
27
27
  module_function :[]
28
28
  end # ParamPermitted
29
29
  end # Option
@@ -41,7 +41,7 @@ module TTY
41
41
  end
42
42
  module_function :call
43
43
 
44
- alias :[] :call
44
+ alias [] call
45
45
  module_function :[]
46
46
  end # ParamValidation
47
47
  end # Option
@@ -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 |key, val|
36
- case key.to_sym
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
- key, val = :required, check_required(!val)
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[key.to_sym] = val
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) { false }
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) { false }
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 %r{\*|any} then value = -1
254
- when %r{\+} then value = -2
255
- else value = value.to_i
256
- end
257
-
258
- if value.zero?
259
- raise ConfigurationError, "#{to_sym} '#{name}' arity cannot be zero"
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
- !self.public_send(name).empty?
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
@@ -15,7 +15,7 @@ module TTY
15
15
  keywords: TTY::Option::Parser::Keywords,
16
16
  arguments: TTY::Option::Parser::Arguments,
17
17
  environments: TTY::Option::Parser::Environments
18
- }
18
+ }.freeze
19
19
 
20
20
  ARGUMENT_SEPARATOR = /^-{2,}$/.freeze
21
21
 
@@ -109,7 +109,7 @@ module TTY
109
109
  values = []
110
110
  arity = arg.arity.abs - 1
111
111
 
112
- arity.times do |i|
112
+ arity.times do
113
113
  break if @argv.empty?
114
114
  value = @argv.shift
115
115
  if argument?(value)
@@ -12,7 +12,7 @@ module TTY
12
12
  def add(param)
13
13
  @multiplies << param
14
14
  end
15
- alias :<< :add
15
+ alias << add
16
16
 
17
17
  # Check if parameter matches arity
18
18
  #
@@ -150,10 +150,10 @@ module TTY
150
150
  if allowed
151
151
  case value
152
152
  when Hash
153
- (@parsed[env_arg.key] ||= {}).merge!(value)
153
+ (@parsed[env_arg.key] ||= {}).merge!(value)
154
154
  else
155
155
  Array(value).each do |v|
156
- (@parsed[env_arg.key] ||= []) << v
156
+ (@parsed[env_arg.key] ||= []) << v
157
157
  end
158
158
  end
159
159
  else
@@ -142,7 +142,7 @@ module TTY
142
142
  (@parsed[kwarg.key] ||= {}).merge!(value)
143
143
  else
144
144
  Array(value).each do |v|
145
- (@parsed[kwarg.key] ||= []) << v
145
+ (@parsed[kwarg.key] ||= []) << v
146
146
  end
147
147
  end
148
148
  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(/^[^-][^=]*\z/).nil?
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(/^[\p{Lu}_\-\d]+=/).nil?
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(/^([^-=][\p{Ll}_\-\d]*)=([^=]+)/).nil?
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(/^-./).nil?
58
+ !value.match(OPTION_PARAMETER).nil?
47
59
  end
48
60
  end # ParamTypes
49
61
  end # Parser
@@ -12,7 +12,7 @@ module TTY
12
12
  def add(param)
13
13
  @required << param
14
14
  end
15
- alias :<< :add
15
+ alias << add
16
16
 
17
17
  def delete(param)
18
18
  @required.delete(param)
@@ -11,7 +11,7 @@ module TTY
11
11
  ParamConversion,
12
12
  ParamPermitted,
13
13
  ParamValidation
14
- ]
14
+ ].freeze
15
15
 
16
16
  # Create a param processing pipeline
17
17
  #
@@ -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
@@ -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), &block)
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 ? " " * indent : "") + line
20
+ lines << (indent_first ? indentation : "") + line
20
21
 
21
22
  while !rest.nil?
22
23
  line, rest = *next_line(rest, wrap: wrap)
23
- lines << " " * indent + line.strip
24
+ lines << indentation + line.strip
24
25
  end
25
26
 
26
27
  lines.join("\n")
@@ -2,6 +2,6 @@
2
2
 
3
3
  module TTY
4
4
  module Option
5
- VERSION = "0.1.0"
5
+ VERSION = "0.2.0"
6
6
  end # Option
7
7
  end # TTY
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.1.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: 2020-05-18 00:00:00.000000000 Z
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: []