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 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: []