xoptparse 0.2.0 → 0.6.2

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: ed8ba0e138b8c1d6e68ca65d8e022ef51f3456647121207904074ffa8d53ac9f
4
- data.tar.gz: e3ffc6e2caa748fadeb8b9a6f3129491d2997c8edf89780689bc6eac02c07489
3
+ metadata.gz: 0fec1922d2cc3feb99ef500264fabd725220b8cd6fc4763a65e76314a2524900
4
+ data.tar.gz: 8625af6499870c233f0b0f9a46be9e3b04fee65aa4d5f10172e4b0f400cd867a
5
5
  SHA512:
6
- metadata.gz: f160dfefb34a43a2b9f60ec775679e810613665edba3138857836467285eb5d8ce58c664687bd823322c619ea32a8c84ddab328b7e6a432c5f784dfffdff9727
7
- data.tar.gz: '0950deea41a448199bc90aa1fb65365940fee26c3e3dd994c27d62e8e5677aaaf160e2234a91e24539ae36ecbc498f17aded45674e50e694c1ce4599c45ed1d5'
6
+ metadata.gz: 2a6d1ccfbbbf79867f826c18b8548b786dd3792d02c30d317685931716ee204175e28f6b1e31bd7fbaa959d226459ba78153212ca56aea0cd91644d312e85d29
7
+ data.tar.gz: 292a0fa1c8e5e62c0809ae1df4fab5bd865d0b0921d513c2bcac94dfdbcbc6acd35838bd605df2e261674c0b9cd571f2f83a0044b01a0e551764420c6e1028ef
@@ -12,6 +12,9 @@ Metrics/AbcSize:
12
12
  Exclude:
13
13
  - test/**/*
14
14
 
15
+ Metrics/BlockLength:
16
+ Enabled: false
17
+
15
18
  Metrics/ClassLength:
16
19
  Enabled: false
17
20
 
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- xoptparse (0.2.0)
4
+ xoptparse (0.6.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -52,7 +52,7 @@ DEPENDENCIES
52
52
  minitest-power_assert
53
53
  minitest-reporters
54
54
  rake (~> 12.3.3)
55
- rubocop (= 0.84.0)
55
+ rubocop
56
56
  simplecov
57
57
  xoptparse!
58
58
 
@@ -55,130 +55,201 @@ class XOptionParser < ::OptionParser
55
55
  end
56
56
  private :search_arg_switch_atype
57
57
 
58
- def fix_arg_switch(sw0)
59
- pattern, conv = search_arg_switch_atype(sw0)
60
- Switch::SimpleArgument.new(pattern, conv, nil, nil, sw0.desc[0], sw0.desc[1..], sw0.block)
58
+ def fix_arg_switch(sw0) # rubocop:disable Metrics/AbcSize
59
+ if !(sw0.short || sw0.long)
60
+ pattern, conv = search_arg_switch_atype(sw0)
61
+ Switch::SimpleArgument.new(pattern, conv, nil, nil, sw0.desc[0], sw0.desc[1..], sw0.block)
62
+ elsif sw0.is_a?(Switch::PlacedArgument) && sw0.long.size == 1 && /^--\[no-\]/ =~ sw0.long.first
63
+ args = [sw0.pattern, sw0.conv, sw0.short, sw0.long, sw0.arg, sw0.desc, sw0.block]
64
+ Switch::FlagArgument.new(*args)
65
+ else
66
+ sw0
67
+ end
61
68
  end
62
69
  private :fix_arg_switch
63
70
 
64
71
  def make_switch(opts, block = nil)
65
72
  sw = super(opts, block || proc {})
66
- sw0 = sw[0]
73
+ sw0 = sw[0] = fix_arg_switch(sw[0])
67
74
  return sw if sw0.short || sw0.long
68
75
 
69
- sw0 = fix_arg_switch(sw0)
70
- long = sw0.arg.scan(/(?:\[\s*(.*?)\s*\]|(\S+))/).flatten.compact
76
+ long = sw0.arg_parameters.map(&:first)
71
77
  [sw0, nil, long]
72
78
  end
73
79
 
74
- def parse_arguments(argv) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
75
- arg_sws = select { |sw| sw.is_a?(Switch::SimpleArgument) }
80
+ def parse_arguments(argv, setter = nil, opts = {}) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
81
+ arg_sws = select { |sw| sw.is_a?(Switch::SummarizeArgument) && !opts.include?(sw.switch_name) }
76
82
  return argv if arg_sws.empty?
77
83
 
78
84
  sws_ranges = arg_sws.map(&:ranges).flatten(1)
79
85
  req_count = sws_ranges.sum(&:begin)
80
- raise MissingArgument, argv.join(' ') if argv.size < req_count
81
-
82
86
  opt_count = sws_ranges.sum(&:size) - sws_ranges.size
83
87
  opt_index = argv[req_count...].index { |arg| @commands.include?(arg) } unless @commands.empty?
84
88
  opt_count = [opt_count, opt_index || Float::INFINITY, argv.size - req_count].min
85
89
 
86
- arg_sws.each do |sw|
87
- conv = proc { |v| sw.send(:conv_arg, *sw.send(:parse_arg, v))[2] }
88
- a = sw.ranges.map do |r|
89
- if r.end.nil?
90
- rest_size = r.begin + opt_count
91
- req_count -= r.begin
92
- opt_count = 0
93
- argv.slice!(0...rest_size).map(&conv)
94
- elsif r.begin.zero?
95
- next conv.call(nil) if opt_count.zero?
96
-
97
- opt_count -= 1
98
- conv.call(argv.shift)
99
- else
100
- req_count -= 1
101
- conv.call(argv.shift)
90
+ arg_sws.each_with_index do |sw, i|
91
+ if sw.is_a?(Switch::SimpleArgument)
92
+ callable = false
93
+ conv = proc do |v|
94
+ callable = true
95
+ sw.send(:conv_arg, *sw.send(:parse_arg, v))[2]
96
+ end
97
+ a = sw.ranges.map do |r|
98
+ raise MissingArgument if r.begin.positive? && argv.empty?
99
+
100
+ if r.end.nil?
101
+ rest_size = r.begin + opt_count
102
+ req_count -= r.begin
103
+ opt_count = 0
104
+ argv.slice!(0...rest_size).map(&conv)
105
+ elsif r.begin.positive?
106
+ req_count -= 1
107
+ conv.call(argv.shift)
108
+ elsif opt_count.positive?
109
+ opt_count -= 1
110
+ conv.call(argv.shift)
111
+ end
102
112
  end
113
+ if callable
114
+ val = sw.block.call(*a)
115
+ setter&.call(sw.switch_name, val)
116
+ end
117
+ elsif sw.pattern =~ argv.first
118
+ argv.shift
119
+ @command_switch = sw
120
+ break
121
+ elsif !argv.empty? && i == arg_sws.size - 1
122
+ raise MissingArgument
103
123
  end
104
- sw.block.call(*a)
105
124
  end
106
125
 
107
126
  argv
108
127
  end
109
128
  private :parse_arguments
110
129
 
111
- def parse_in_order(*args, &nonopt)
112
- argv = []
130
+ def parse_in_order(argv = default_argv, setter = nil, &nonopt)
131
+ nonopts = []
132
+ opts = {}
133
+ opts_setter = proc do |name, val|
134
+ opts[name] = true
135
+ setter&.call(name, val)
136
+ end
113
137
  rest = if nonopt
114
- super(*args, &argv.method(:<<))
138
+ super(argv, opts_setter, &nonopts.method(:<<))
115
139
  else
116
- argv = super(*args)
140
+ nonopts = super(argv, opts_setter)
117
141
  end
118
- parse_arguments(argv).map(&nonopt)
142
+ parse_arguments(nonopts, setter, opts).map(&nonopt)
119
143
  rest
120
144
  end
121
145
  private :parse_in_order
122
146
 
123
- def order!(*args, **kwargs)
124
- return super(*args, **kwargs) if @commands.empty?
125
-
126
- argv = super(*args, **kwargs, &nil)
127
- return argv if argv.empty?
147
+ def order!(*args, into: nil, **kwargs)
148
+ return super(*args, into: into, **kwargs) if @commands.empty?
128
149
 
129
- name = argv.shift
130
- sw = @commands[name]
131
- return sw.block.call.send(block_given? ? :permute! : :order!, *args, **kwargs) if sw
150
+ @command_switch = nil
151
+ argv = super(*args, into: into, **kwargs, &nil)
152
+ return argv unless @command_switch
132
153
 
133
- puts "#{program_name}:" \
134
- "'#{name}' is not a #{program_name} command. See '#{program_name} --help'."
135
- exit
154
+ into = into[@command_switch.arg.to_sym] = {} if into
155
+ @command_switch.block.call.send(block_given? ? :permute! : :order!, *args, into: into, **kwargs)
136
156
  end
137
157
 
138
158
  def command(name, desc = nil, *args, &block)
139
- sw0 = Switch::SummarizeArgument.new(nil, nil, nil, nil, name.to_s, desc ? [desc] : [], nil) do
159
+ name = name.to_s
160
+ pattern = /^#{name.gsub('_', '[-_]?')}$/i
161
+ sw0 = Switch::SummarizeArgument.new(pattern, nil, nil, nil, name, desc ? [desc] : [], nil) do
140
162
  self.class.new(desc, *args) do |opt|
141
163
  opt.program_name = "#{program_name} #{name}"
142
164
  block&.call(opt)
143
165
  end
144
166
  end
145
167
  top.append(sw0, nil, [sw0.arg])
146
- @commands[name.to_s] = sw0
168
+ @commands[name] = sw0
147
169
  nil
148
170
  end
149
171
 
150
172
  class Switch < ::OptionParser::Switch
151
- class SummarizeArgument < NoArgument
173
+ class SummarizeArgument < self
152
174
  undef_method :add_banner
153
175
 
154
- def summarize(*args)
176
+ attr_reader :ranges
177
+ attr_reader :arg_parameters
178
+
179
+ def initialize(*)
180
+ super
181
+ @ranges = []
182
+ @arg_parameters = arg.scan(/\[\s*(.*?)\s*\]|(\S+)/).map do |opt, req|
183
+ name = opt || req
184
+ [name.sub(/\s*\.\.\.$/, ''), opt ? :opt : :req, name.end_with?('...') ? :rest : nil]
185
+ end
186
+ end
187
+
188
+ def summarize(*)
155
189
  original_arg = arg
156
- @short = arg.scan(/\[\s*.*?\s*\]|\S+/)
190
+ @short = arg_parameters.map do |name, type, rest|
191
+ var = "#{name}#{rest ? '...' : ''}"
192
+ type == :req ? var : "[#{var}]"
193
+ end
157
194
  @arg = nil
158
- res = super(*args)
195
+ res = super
159
196
  @arg = original_arg
160
197
  @short = nil
161
198
  res
162
199
  end
163
200
 
164
- def match_nonswitch?(*args)
165
- super(*args) if @pattern.is_a?(Regexp)
201
+ def match_nonswitch?(*)
202
+ nil
203
+ end
204
+
205
+ def switch_name
206
+ arg_parameters.first.first
207
+ end
208
+
209
+ def parse(_arg, _argv)
210
+ raise XOptionParser::InvalidOption
166
211
  end
167
212
  end
168
213
 
169
214
  class SimpleArgument < SummarizeArgument
170
- attr_reader :ranges
171
-
172
- def initialize(*args)
173
- super(*args)
174
- @ranges = arg.scan(/\[\s*(.*?)\s*\]|(\S+)/).map do |opt, req|
175
- (opt ? 0 : 1)..((opt || req).end_with?('...') ? nil : 1)
215
+ def initialize(*)
216
+ super
217
+ @ranges = arg_parameters.map do |_name, type, rest|
218
+ (type == :req ? 1 : 0)..(rest == :rest ? nil : 1)
176
219
  end
177
220
  end
178
221
 
179
222
  def add_banner(to)
180
223
  to << " #{arg}"
181
224
  end
225
+
226
+ def parse(arg, argv) # rubocop:disable Metrics/CyclomaticComplexity
227
+ case ranges.size
228
+ when 0
229
+ yield(NeedlessArgument, arg) if arg
230
+ conv_arg(arg)
231
+ when 1
232
+ unless arg
233
+ raise XOptionParser::MissingArgument if argv.empty?
234
+
235
+ arg = argv.shift
236
+ end
237
+ arg = [arg] if ranges.first.end.nil?
238
+ conv_arg(*parse_arg(arg, &method(:raise)))
239
+ else
240
+ super(arg, argv)
241
+ end
242
+ end
243
+ end
244
+
245
+ class FlagArgument < PlacedArgument
246
+ def parse(arg, argv, &error)
247
+ super(arg, argv, &error).tap do |val|
248
+ raise OptionParser::InvalidArgument if val[0].nil? && val[2].nil?
249
+ end
250
+ rescue OptionParser::InvalidArgument
251
+ conv_arg(arg)
252
+ end
182
253
  end
183
254
  end
184
255
  end
@@ -3,5 +3,5 @@
3
3
  require 'optparse'
4
4
 
5
5
  class XOptionParser < ::OptionParser
6
- VERSION = '0.2.0'
6
+ VERSION = '0.6.2'
7
7
  end
@@ -29,6 +29,6 @@ Gem::Specification.new do |spec|
29
29
  spec.add_development_dependency 'minitest-power_assert'
30
30
  spec.add_development_dependency 'minitest-reporters'
31
31
  spec.add_development_dependency 'rake', '~> 12.3.3'
32
- spec.add_development_dependency 'rubocop', '0.84.0'
32
+ spec.add_development_dependency 'rubocop'
33
33
  spec.add_development_dependency 'simplecov'
34
34
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xoptparse
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - ofk
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-12 00:00:00.000000000 Z
11
+ date: 2020-10-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -84,16 +84,16 @@ dependencies:
84
84
  name: rubocop
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - '='
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
- version: 0.84.0
89
+ version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - '='
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
- version: 0.84.0
96
+ version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: simplecov
99
99
  requirement: !ruby/object:Gem::Requirement