squared 0.5.7 → 0.5.8

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)}]", '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,10 +76,7 @@ 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) unless s.empty?
70
80
  s = target.to_a.compact
71
81
  r.any? { |pat| s.any?(pat) }
72
82
  end
@@ -74,6 +84,27 @@ module Squared
74
84
  def pattern?(val)
75
85
  val.match?(/(?:\A\^|\$\z)/) || val.match?(/(?:\.[*+]|\(\?:|\\[dsw]|\[.+\]|\{\d+,?\d*\})/)
76
86
  end
87
+
88
+ private
89
+
90
+ def matchopt(val, value = false)
91
+ /\A#{val.size == 1 ? shortopt(val) : longopt(val, value)}/
92
+ end
93
+
94
+ def matchopts(list, value = false)
95
+ a, b = list.partition { |val| val.size == 1 || val.match?(OPT_SINGLE) }
96
+ /\A(?:#{shortopt(*a)}|#{longopt(*b, value)})/
97
+ end
98
+
99
+ def shortopt(*group)
100
+ group.map! { |s| s.delete_prefix('-') }
101
+ "-(?:#{Regexp.escape(group.join('|'))})(?:\\z|[^ =]| +[^ -])"
102
+ end
103
+
104
+ def longopt(*group, value)
105
+ group.map! { |s| s.delete_prefix('--') }
106
+ "--(?:#{Regexp.escape(group.join('|'))})(?:#{value ? '=[^ ]| +[^ -]' : '[= ]|\z'})"
107
+ end
77
108
  end
78
109
 
79
110
  attr_reader :target, :extras, :found, :errors, :values, :project, :path
@@ -81,11 +112,14 @@ module Squared
81
112
  def_delegators :@target, :+, :-, :<<, :any?, :none?, :include?, :add, :add?, :find, :find_all, :find_index,
82
113
  :merge, :delete, :delete?, :delete_if, :grep, :grep_v, :inspect, :to_a, :to_s
83
114
  def_delegators :@extras, :empty?, :each, :each_with_index, :partition, :dup, :first, :last, :shift, :unshift,
84
- :pop, :push, :concat, :index, :delete_at, :join, :map, :map!, :select, :select!, :reject, :size
115
+ :pop, :push, :concat, :index, :join, :map, :map!, :detect, :select, :select!, :reject, :size,
116
+ :delete_at
85
117
 
86
118
  def_delegator :@extras, :delete, :remove
87
119
  def_delegator :@extras, :delete_at, :remove_at
88
120
  def_delegator :@extras, :delete_if, :remove_if
121
+ def_delegator :@extras, :find_all, :detect_all
122
+ def_delegator :@extras, :find_index, :detect_index
89
123
 
90
124
  def initialize(opts, list, target = Set.new, project: nil, path: nil, **kwargs, &blk)
91
125
  @target = target.is_a?(Set) ? target : target.to_set
@@ -96,7 +130,7 @@ module Squared
96
130
  parse(list, opts, **kwargs, &blk)
97
131
  end
98
132
 
99
- def parse(list, opts = extras, no: nil, single: nil, args: false, first: nil, &blk)
133
+ def parse(list, opts = extras, no: nil, single: nil, args: false, first: nil, underscore: nil, &blk)
100
134
  @extras = []
101
135
  @values = []
102
136
  bare = []
@@ -149,7 +183,7 @@ module Squared
149
183
  else
150
184
  next
151
185
  end
152
- m << flag if val[n + 2] == 'm'
186
+ m << flag if flag.size == 1 && val[n + 2] == 'm'
153
187
  bare << flag if val.end_with?('?')
154
188
  else
155
189
  bare << val
@@ -157,6 +191,22 @@ module Squared
157
191
  end
158
192
  no = (no || []).map { |val| (n = val.index('=')) ? val[0, n] : val }
159
193
  bare.concat(no)
194
+ if underscore
195
+ tr = ->(list) { list.map { |val| val.tr('-', '_') } }
196
+ @values.concat(tr.call(@values))
197
+ bare.concat(tr.call(bare))
198
+ e.concat(tr.call(e))
199
+ b.concat(tr.call(b))
200
+ m.concat(tr.call(m))
201
+ p.concat(tr.call(p))
202
+ q.concat(tr.call(q))
203
+ qq.concat(tr.call(qq))
204
+ i.concat(tr.call(i))
205
+ f.concat(tr.call(f))
206
+ si.concat(tr.call(si))
207
+ bl.concat(tr.call(bl))
208
+ no.concat(tr.call(no))
209
+ end
160
210
  numtype = [
161
211
  [i, /\A\d+\z/],
162
212
  [f, /\A\d*(?:\.\d+)?\z/],
@@ -172,7 +222,7 @@ module Squared
172
222
  add "-#{opt}"
173
223
  elsif bare.include?(opt)
174
224
  add(opt.size == 1 ? "-#{opt}" : "--#{opt}")
175
- elsif opt.start_with?('no-') && no.include?(name = opt[3..-1])
225
+ elsif opt.start_with?(/no[-_]/) && no.include?(name = opt[3..-1])
176
226
  add "--no-#{name}"
177
227
  else
178
228
  if opt =~ OPT_VALUE
@@ -183,8 +233,14 @@ module Squared
183
233
  add shell_option(key, val, merge: merge)
184
234
  elsif q.include?(key)
185
235
  add quote_option(key, val, double: qq.include?(key), merge: merge)
186
- elsif p.include?(key) && path
187
- add quote_option(key, path + val, merge: merge)
236
+ elsif p.include?(key)
237
+ if val.match?(/\A(["']).+\1\z/)
238
+ add shell_option(key, val, escape: false, merge: merge, sep: sep)
239
+ elsif path
240
+ add quote_option(key, path + val, merge: merge, sep: sep)
241
+ else
242
+ push opt
243
+ end
188
244
  elsif b.include?(key) || (bl.include?(key) && %w[true false].include?(val)) || numcheck.call(key, val)
189
245
  add basic_option(key, val, merge: merge)
190
246
  elsif merge
@@ -220,16 +276,34 @@ module Squared
220
276
  self
221
277
  end
222
278
 
279
+ def append_any(*args, quote: true, **kwargs)
280
+ (args.empty? ? extras : args.flatten).each do |val|
281
+ if exist?(val)
282
+ add_path(val, **kwargs)
283
+ elsif quote
284
+ add_quote(val, **kwargs)
285
+ else
286
+ add val
287
+ end
288
+ end
289
+ self
290
+ end
291
+
292
+ def delete_key(*args, **kwargs)
293
+ OptionPartition.delete_key(target, *args, **kwargs)
294
+ self
295
+ end
296
+
223
297
  def values_of(*args, strict: true, first: false, last: false)
224
298
  eq, s = strict ? ['=', '[^ ]+'] : ['(?:=| +)', '[^-][^ ]*']
225
- grp = ["\"((?:[^\"]|(?<=\\\\)\"(?!$#{Rake::Win32.windows? ? '| ' : ''}))*)\""]
226
- grp << "'((?:[^']|'\\\\'')*)'" unless Rake::Win32.windows?
227
- grp << "(#{s})"
299
+ g = ["\"((?:[^\"]|(?<=\\\\)\"(?!$#{windows? ? '| ' : ''}))*)\""]
300
+ g << "'((?:[^']|'\\\\'')*)'" unless windows?
301
+ g << "(#{s})"
228
302
  args.map! do |opt|
229
303
  if opt.size == 1
230
304
  /(?:\A| )-#{opt} ?([^ ]+)/
231
305
  else
232
- /(?:\A| )--#{opt + eq}(?:#{grp.join('|')})/
306
+ /(?:\A| )--#{opt + eq}(?:#{g.join('|')})/
233
307
  end
234
308
  end
235
309
  ret = []
@@ -243,64 +317,79 @@ module Squared
243
317
  end
244
318
  return ret unless first || last
245
319
 
246
- if last
247
- last.is_a?(Numeric) ? ret.last(last) : ret.last
320
+ if last.is_a?(Numeric)
321
+ ret.last(last)
322
+ elsif last
323
+ ret.last
248
324
  else
249
325
  first.is_a?(Numeric) ? ret.first(first) : ret.first
250
326
  end
251
327
  end
252
328
 
253
329
  def uniq(list)
254
- items = map { |val| nameonly(val) }
255
- list.reject do |val|
256
- next true if items.include?(s = nameonly(val))
257
-
258
- pat = /\A#{s = fill_option(s)}(?:#{s.start_with?('--') ? '[= ]' : '.*'}|\z)/
259
- any? { |opt| opt.match?(pat) }
260
- end
261
- end
262
-
263
- def uniq!(list)
264
- n = size
265
- concat uniq(list)
266
- extras if size > n
330
+ ignore = map { |val| nameonly(val) }
331
+ list.reject { |val| ignore.include?(s = nameonly(val)) || any?(OptionPartition.send(:matchopt, s)) }
267
332
  end
268
333
 
269
334
  def clear(opts = nil, errors: false, **kwargs)
270
335
  styles = project.theme[:inline] if project
271
- if !opts
272
- opts = errors ? @errors : @extras
273
- elsif errors
274
- OptionPartition.clear(target, @errors, styles: styles, **kwargs)
275
- @errors.clear
336
+ if errors
337
+ OptionPartition.clear(target, self.errors, styles: styles, **kwargs)
338
+ self.errors.clear
339
+ return self unless opts
276
340
  end
277
- OptionPartition.clear(target, opts.reject { |val| found.include?(val) }, styles: styles, **kwargs)
341
+ opts ||= extras
342
+ OptionPartition.clear(target, if found.empty?
343
+ opts
344
+ else
345
+ opts.reject { |val| found.include?(val) }
346
+ end, styles: styles, **kwargs)
278
347
  opts.clear
279
348
  self
280
349
  end
281
350
 
282
- def adjoin(*args, start: false)
351
+ def adjoin(*args, with: nil, start: false)
283
352
  i = -1
284
- (items = to_a).each_with_index do |val, index|
285
- if i == 0
286
- next unless val.start_with?('-')
287
-
288
- i = index
289
- break
290
- elsif index > 0 && !val.start_with?('-')
291
- if start
353
+ temp = to_a
354
+ if with
355
+ pat = case with
356
+ when String, Symbol
357
+ /\A#{Regexp.escape(with)}\z/
358
+ when Array
359
+ OptionPartition.send(:matchopts, with)
360
+ else
361
+ with
362
+ end
363
+ temp.each_with_index do |val, index|
364
+ if val.to_s.match?(pat)
292
365
  i = index + (start.is_a?(Numeric) ? start : 1)
293
366
  break
294
367
  end
295
- i = 0
368
+ end
369
+ else
370
+ temp.each_with_index do |val, index|
371
+ if i == 0
372
+ next unless val.start_with?('-')
373
+
374
+ i = index
375
+ break
376
+ elsif index > 0 && !val.start_with?('-')
377
+ if start
378
+ i = index + (start.is_a?(Numeric) ? start : 1)
379
+ break
380
+ end
381
+ i = 0
382
+ end
296
383
  end
297
384
  end
298
385
  if i > 0
299
386
  if args.empty?
300
387
  args = dup
301
388
  reset
389
+ else
390
+ args.each { |val| remove val }
302
391
  end
303
- args = items[0...i] + args + items[i..-1]
392
+ args = temp[0...i] + args + temp[i..-1]
304
393
  target.clear
305
394
  end
306
395
  merge args
@@ -308,12 +397,12 @@ module Squared
308
397
  end
309
398
 
310
399
  def add_path(*args, **kwargs)
311
- add shell_quote(path ? path.join(*args) : File.join(*args), **kwargs)
400
+ add shell_quote(path ? path.join(*args) : File.join(*args), option: false, **kwargs)
312
401
  self
313
402
  end
314
403
 
315
404
  def add_quote(*args, **kwargs)
316
- merge(args.map { |val| shell_quote(val, **kwargs) })
405
+ merge(args.map! { |val| shell_quote(val, **kwargs) })
317
406
  self
318
407
  end
319
408
 
@@ -336,7 +425,8 @@ module Squared
336
425
  if path
337
426
  found.each { |val| add_path(val) }
338
427
  else
339
- merge(quote ? found.map! { |val| shell_quote(val) } : found)
428
+ found.map! { |val| shell_quote(val) } if quote
429
+ merge found
340
430
  end
341
431
  end
342
432
  self
@@ -344,6 +434,7 @@ module Squared
344
434
 
345
435
  def reset(errors: false)
346
436
  extras.clear
437
+ found.clear
347
438
  clear(errors: true) if errors
348
439
  self
349
440
  end
@@ -370,11 +461,48 @@ module Squared
370
461
  OptionPartition.arg?(target, *args, **kwargs)
371
462
  end
372
463
 
464
+ def exist?(*args, add: false, first: false, last: false)
465
+ return false unless path
466
+ return path.join(*args).exist? unless args.empty?
467
+
468
+ if first || last
469
+ return false unless (val = first ? self.first : self.last).is_a?(String)
470
+
471
+ path.join(val).exist?.tap do |ret|
472
+ next unless add && ret
473
+
474
+ add_first(path: true, reverse: !first)
475
+ end
476
+ else
477
+ each_with_index do |val, index|
478
+ next unless val.is_a?(String) && path.join(val).exist?
479
+
480
+ if add
481
+ remove_at index
482
+ add_path val
483
+ end
484
+ return true
485
+ end
486
+ false
487
+ end
488
+ end
489
+
490
+ def uniq!(list)
491
+ unless (list = uniq(list)).empty?
492
+ concat list
493
+ self
494
+ end
495
+ end
496
+
373
497
  private
374
498
 
375
499
  def nameonly(val)
376
500
  val[OPT_VALUE, 1] || val
377
501
  end
502
+
503
+ def windows?
504
+ Rake::Win32.windows?
505
+ end
378
506
  end
379
507
 
380
508
  class JoinSet < Set
@@ -416,7 +544,9 @@ module Squared
416
544
  end
417
545
  ret[i.last] = val
418
546
  end
419
- block_given? ? ret.reject(&blk) : ret
547
+ return ret unless block_given?
548
+
549
+ ret.reject(&blk)
420
550
  end
421
551
 
422
552
  def and(*args)
@@ -441,9 +571,7 @@ module Squared
441
571
  end
442
572
 
443
573
  def done
444
- ret = to_s
445
- clear
446
- ret
574
+ to_s.tap { clear }
447
575
  end
448
576
 
449
577
  def to_s
@@ -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.5.7
4
+ version: 0.5.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - An Pham