squared 0.4.20 → 0.4.21

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.
@@ -10,8 +10,9 @@ module Squared
10
10
  include Common::Shell
11
11
  extend Forwardable
12
12
 
13
- OPT_VALUE = /\A([^=]+)=(.+)\z/
14
- private_constant :OPT_VALUE
13
+ OPT_VALUE = /\A-{0,2}([^= ]+)(?: *= *| +)(.+)\z/
14
+ OPT_SINGLE = /\A-([A-Za-z\d])(.+)\z/
15
+ private_constant :OPT_VALUE, :OPT_SINGLE
15
16
 
16
17
  class << self
17
18
  include Common::Format
@@ -45,11 +46,23 @@ module Squared
45
46
  exit 1 unless pass || confirm("Run? [#{sub_style(target, styles: styles)}] [y/N] ", 'N')
46
47
  end
47
48
 
49
+ def delete_key(target, *args, value: false, reverse: false, count: -1)
50
+ ret = []
51
+ args.each do |val|
52
+ next if (opts = target.grep(matchopt(val, value))).empty?
53
+
54
+ opts = opts.first(count) if count >= 0
55
+ opts.send(reverse ? :reverse_each : :each) { |key| target.delete(key) }
56
+ ret.concat(opts)
57
+ end
58
+ ret
59
+ end
60
+
48
61
  def strip(val)
49
62
  return [] unless val
50
63
 
51
64
  val = shell_split(val) if val.is_a?(String)
52
- val.map { |s| s.sub(/\A-([a-z\d])(.+)\z/i, '\1=\2').sub(/\A--?/, '') }.reject(&:empty?)
65
+ val.map { |s| s.sub(OPT_SINGLE, '\1=\2').sub(OPT_VALUE, '\1=\2') }.reject(&:empty?)
53
66
  end
54
67
 
55
68
  def select(list, bare: true, no: true, single: false, double: false)
@@ -63,16 +76,34 @@ module Squared
63
76
 
64
77
  def arg?(target, *args, value: false, **)
65
78
  r, s = args.partition { |val| val.is_a?(Regexp) }
66
- unless s.empty?
67
- s.map! { |val| Regexp.escape(val.start_with?('-') ? val : shell_option(val)) }
68
- r << /\A(?:#{s.join('|')})#{value ? '[ =].' : '(?: |=|\z)'}/
69
- end
79
+ r << matchopts(s, value: value) unless s.empty?
70
80
  Array(target).compact.any? { |val| r.any? { |pat| pat.match?(val.to_s) } }
71
81
  end
72
82
 
73
83
  def pattern?(val)
74
84
  val.match?(/(?:\A\^|\$\z)/) || val.match?(/(?:\.[*+]|\(\?:|\\[dsw]|\[.+\]|\{\d+,?\d*\})/)
75
85
  end
86
+
87
+ private
88
+
89
+ def matchopt(val, value = false)
90
+ /\A#{val.size == 1 ? shortopt(val) : longopt(val, value)}/
91
+ end
92
+
93
+ def matchopts(list, value = false)
94
+ a, b = list.partition { |val| val.size == 1 || val.match?(OPT_SINGLE) }
95
+ /\A(?:#{shortopt(*a)}|#{longopt(*b, value)})/
96
+ end
97
+
98
+ def shortopt(*group)
99
+ group.map! { |s| s.sub(/\A-/, '') }
100
+ "-(?:#{Regexp.escape(group.join('|'))})(?:\\z|[^ =]| +[^ -])"
101
+ end
102
+
103
+ def longopt(*group, value)
104
+ group.map! { |s| s.sub(/\A--/, '') }
105
+ "--(?:#{Regexp.escape(group.join('|'))})(?:#{value ? '=[^ ]| +[^ -]' : '[= ]|\z'})"
106
+ end
76
107
  end
77
108
 
78
109
  attr_reader :target, :extras, :found, :errors, :values, :project, :path
@@ -80,11 +111,14 @@ module Squared
80
111
  def_delegators :@target, :+, :-, :<<, :any?, :none?, :include?, :add, :add?, :find, :find_all, :find_index,
81
112
  :merge, :delete, :delete?, :delete_if, :grep, :grep_v, :inspect, :to_a, :to_s
82
113
  def_delegators :@extras, :empty?, :each, :each_with_index, :partition, :dup, :first, :last, :shift, :unshift,
83
- :pop, :push, :concat, :index, :delete_at, :join, :map, :map!, :select, :select!, :reject, :size
114
+ :pop, :push, :concat, :index, :join, :map, :map!, :detect, :select, :select!, :reject, :size,
115
+ :delete_at
84
116
 
85
117
  def_delegator :@extras, :delete, :remove
86
118
  def_delegator :@extras, :delete_at, :remove_at
87
119
  def_delegator :@extras, :delete_if, :remove_if
120
+ def_delegator :@extras, :find_all, :detect_all
121
+ def_delegator :@extras, :find_index, :detect_index
88
122
 
89
123
  def initialize(opts, list, target = Set.new, project: nil, path: nil, **kwargs, &blk)
90
124
  @target = target.is_a?(Set) ? target : target.to_set
@@ -95,7 +129,7 @@ module Squared
95
129
  parse(list, opts, **kwargs, &blk)
96
130
  end
97
131
 
98
- def parse(list, opts = extras, no: nil, single: nil, args: false, first: nil, &blk)
132
+ def parse(list, opts = extras, no: nil, single: nil, args: false, first: nil, underscore: nil, &blk)
99
133
  @extras = []
100
134
  @values = []
101
135
  bare = []
@@ -148,7 +182,7 @@ module Squared
148
182
  else
149
183
  next
150
184
  end
151
- m << flag if val[n + 2] == 'm'
185
+ m << flag if flag.size == 1 && val[n + 2] == 'm'
152
186
  bare << flag if val.end_with?('?')
153
187
  else
154
188
  bare << val
@@ -156,6 +190,22 @@ module Squared
156
190
  end
157
191
  no = (no || []).map { |val| (n = val.index('=')) ? val[0, n] : val }
158
192
  bare.concat(no)
193
+ if underscore
194
+ tr = ->(list) { list.map { |val| val.tr('-', '_') } }
195
+ @values.concat(tr.call(@values))
196
+ bare.concat(tr.call(bare))
197
+ e.concat(tr.call(e))
198
+ b.concat(tr.call(b))
199
+ m.concat(tr.call(m))
200
+ p.concat(tr.call(p))
201
+ q.concat(tr.call(q))
202
+ qq.concat(tr.call(qq))
203
+ i.concat(tr.call(i))
204
+ f.concat(tr.call(f))
205
+ si.concat(tr.call(si))
206
+ bl.concat(tr.call(bl))
207
+ no.concat(tr.call(no))
208
+ end
159
209
  numtype = [
160
210
  [i, /\A\d+\z/],
161
211
  [f, /\A\d*(?:\.\d+)?\z/],
@@ -171,7 +221,7 @@ module Squared
171
221
  add "-#{opt}"
172
222
  elsif bare.include?(opt)
173
223
  add(opt.size == 1 ? "-#{opt}" : "--#{opt}")
174
- elsif opt.start_with?('no-') && no.include?(name = opt[3..-1])
224
+ elsif opt.match?(/\Ano[-_]/) && no.include?(name = opt[3..-1])
175
225
  add "--no-#{name}"
176
226
  else
177
227
  if opt =~ OPT_VALUE
@@ -182,8 +232,14 @@ module Squared
182
232
  add shell_option(key, val, merge: merge)
183
233
  elsif q.include?(key)
184
234
  add quote_option(key, val, double: qq.include?(key), merge: merge)
185
- elsif p.include?(key) && path
186
- add quote_option(key, path + val, merge: merge)
235
+ elsif p.include?(key)
236
+ if val.match?(/\A(["']).+\1\z/)
237
+ add shell_option(key, val, escape: false, merge: merge, sep: sep)
238
+ elsif path
239
+ add quote_option(key, path + val, merge: merge, sep: sep)
240
+ else
241
+ push opt
242
+ end
187
243
  elsif b.include?(key) || (bl.include?(key) && %w[true false].include?(val)) || numcheck.call(key, val)
188
244
  add basic_option(key, val, merge: merge)
189
245
  elsif merge
@@ -219,57 +275,86 @@ module Squared
219
275
  self
220
276
  end
221
277
 
278
+ def append_any(*args, **kwargs)
279
+ (args.empty? ? extras : args.flatten).each do |val|
280
+ if exist?(val)
281
+ add_path(val, **kwargs)
282
+ else
283
+ add_quote(val, **kwargs)
284
+ end
285
+ end
286
+ self
287
+ end
288
+
222
289
  def uniq(list)
223
- items = map { |val| nameonly(val) }
290
+ ignore = map { |val| nameonly(val) }
224
291
  list.reject do |val|
225
- next true if items.include?(s = nameonly(val))
292
+ next true if ignore.include?(s = nameonly(val))
226
293
 
227
- pat = /\A#{s = fill_option(s)}(?:#{s.start_with?('--') ? '[= ]' : '.*'}|\z)/
294
+ pat = OptionPartition.send(:matchopt, s)
228
295
  any? { |opt| opt.match?(pat) }
229
296
  end
230
297
  end
231
298
 
232
- def uniq!(list)
233
- n = size
234
- concat uniq(list)
235
- extras if size > n
236
- end
237
-
238
299
  def clear(opts = nil, errors: false, **kwargs)
239
300
  styles = project.theme[:inline] if project
240
- if !opts
241
- opts = errors ? @errors : @extras
242
- elsif errors
243
- OptionPartition.clear(target, @errors, styles: styles, **kwargs)
244
- @errors.clear
301
+ if errors
302
+ OptionPartition.clear(target, self.errors, styles: styles, **kwargs)
303
+ self.errors.clear
304
+ return self unless opts
245
305
  end
246
- OptionPartition.clear(target, opts.reject { |val| found.include?(val) }, styles: styles, **kwargs)
306
+ opts ||= extras
307
+ OptionPartition.clear(target, if found.empty?
308
+ opts
309
+ else
310
+ opts.reject { |val| found.include?(val) }
311
+ end, styles: styles, **kwargs)
247
312
  opts.clear
248
313
  self
249
314
  end
250
315
 
251
- def adjoin(*args, start: false)
316
+ def adjoin(*args, with: nil, start: false)
252
317
  i = -1
253
- (items = to_a).each_with_index do |val, index|
254
- if i == 0
255
- next unless val.start_with?('-')
256
-
257
- i = index
258
- break
259
- elsif index > 0 && !val.start_with?('-')
260
- if start
318
+ temp = to_a
319
+ if with
320
+ pat = case with
321
+ when String, Symbol
322
+ /\A#{Regexp.escape(with)}\z/
323
+ when Array
324
+ OptionPartition.send(:matchopts, with)
325
+ else
326
+ with
327
+ end
328
+ temp.each_with_index do |val, index|
329
+ if val.to_s.match?(pat)
261
330
  i = index + (start.is_a?(Numeric) ? start : 1)
262
331
  break
263
332
  end
264
- i = 0
333
+ end
334
+ else
335
+ temp.each_with_index do |val, index|
336
+ if i == 0
337
+ next unless val.start_with?('-')
338
+
339
+ i = index
340
+ break
341
+ elsif index > 0 && !val.start_with?('-')
342
+ if start
343
+ i = index + (start.is_a?(Numeric) ? start : 1)
344
+ break
345
+ end
346
+ i = 0
347
+ end
265
348
  end
266
349
  end
267
350
  if i > 0
268
351
  if args.empty?
269
352
  args = dup
270
353
  reset
354
+ else
355
+ args.each { |val| remove val }
271
356
  end
272
- args = items[0...i] + args + items[i..-1]
357
+ args = temp[0...i] + args + temp[i..-1]
273
358
  target.clear
274
359
  end
275
360
  merge args
@@ -282,7 +367,7 @@ module Squared
282
367
  end
283
368
 
284
369
  def add_quote(*args, **kwargs)
285
- merge(args.map { |val| shell_quote(val, **kwargs) })
370
+ merge(args.map! { |val| shell_quote(val, **kwargs) })
286
371
  self
287
372
  end
288
373
 
@@ -305,7 +390,8 @@ module Squared
305
390
  if path
306
391
  found.each { |val| add_path(val) }
307
392
  else
308
- merge(quote ? found.map! { |val| shell_quote(val) } : found)
393
+ found.map! { |val| shell_quote(val) } if quote
394
+ merge found
309
395
  end
310
396
  end
311
397
  self
@@ -313,6 +399,7 @@ module Squared
313
399
 
314
400
  def reset(errors: false)
315
401
  extras.clear
402
+ found.clear
316
403
  clear(errors: true) if errors
317
404
  self
318
405
  end
@@ -339,6 +426,39 @@ module Squared
339
426
  OptionPartition.arg?(target, *args, **kwargs)
340
427
  end
341
428
 
429
+ def exist?(*args, add: false, first: false, last: false)
430
+ return false unless path
431
+ return path.join(*args).exist? unless args.empty?
432
+
433
+ if first || last
434
+ return false unless (val = first ? self.first : self.last).is_a?(String)
435
+
436
+ path.join(val).exist?.tap do |ret|
437
+ next unless add && ret
438
+
439
+ add_first(path: true, reverse: !first)
440
+ end
441
+ else
442
+ each_with_index do |val, index|
443
+ next unless val.is_a?(String) && path.join(val).exist?
444
+
445
+ if add
446
+ remove_at index
447
+ add_path val
448
+ end
449
+ return true
450
+ end
451
+ false
452
+ end
453
+ end
454
+
455
+ def uniq!(list)
456
+ unless (list = uniq(list)).empty?
457
+ concat list
458
+ self
459
+ end
460
+ end
461
+
342
462
  private
343
463
 
344
464
  def nameonly(val)
@@ -49,11 +49,7 @@ module Squared
49
49
 
50
50
  def base_set(obj)
51
51
  TASK_BASE.clear
52
- .concat((if TASK_KEYS.empty?
53
- obj.tasks
54
- else
55
- obj.tasks.reject { |val| TASK_KEYS.include?(val) }
56
- end).freeze)
52
+ TASK_BASE.concat(obj.tasks.reject { |val| TASK_KEYS.include?(val) })
57
53
  end
58
54
 
59
55
  private
@@ -210,27 +206,25 @@ module Squared
210
206
 
211
207
  def chain?(val)
212
208
  @chain.each_value do |tasks|
213
- tasks.flatten(1).each do |task|
214
- next unless Rake::Task[task].already_invoked
209
+ tasks.flatten(1).each do |name|
210
+ next unless (task = invoked_get(name))
215
211
 
216
- if val == task || Rake::Task[task].prerequisites.any? { |pr| pr == val && Rake::Task[val].already_invoked }
217
- return true
218
- end
212
+ return true if name == val || task.prerequisites.any? { |pr| pr == val && Rake::Task[pr].already_invoked }
219
213
  end
220
214
  end
221
215
  false
222
216
  end
223
217
 
224
218
  def multiple?(val = nil)
225
- already_invoked?(multiple, val)
219
+ already_invoked? multiple, val
226
220
  end
227
221
 
228
222
  def sync?(val = nil)
229
- already_invoked?(sync, val)
223
+ already_invoked? sync, val
230
224
  end
231
225
 
232
226
  def parallel?(val = nil)
233
- already_invoked?(parallel, val)
227
+ already_invoked? parallel, val
234
228
  end
235
229
 
236
230
  def exclude?(key, empty = false)
@@ -239,12 +233,16 @@ module Squared
239
233
 
240
234
  private
241
235
 
236
+ def invoked_get(name)
237
+ return unless Rake::Task.task_defined?(name) && (ret = Rake::Task[name]).already_invoked
238
+
239
+ ret
240
+ end
241
+
242
242
  def already_invoked?(list, val)
243
- if val
244
- list.include?(val) && Rake::Task[val].already_invoked
245
- else
246
- Rake::Task.tasks.any? { |obj| obj.already_invoked && list.include?(obj.name) }
247
- end
243
+ return Rake::Task.tasks.any? { |obj| obj.already_invoked && list.include?(obj.name) } unless val
244
+
245
+ list.include?(val) && !invoked_get(val).nil?
248
246
  end
249
247
  end
250
248
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: squared
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.20
4
+ version: 0.4.21
5
5
  platform: ruby
6
6
  authors:
7
7
  - An Pham