squared 0.5.7 → 0.5.9

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,15 +10,17 @@ 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
18
19
  include Shell
19
20
  include Prompt
20
21
 
21
- def append(target, *args, delim: false, escape: false, quote: true, strip: nil, **)
22
+ def append(target, *args, delim: false, escape: false, quote: true, strip: nil, force: true, double: false,
23
+ **)
22
24
  return if (ret = args.flatten).empty?
23
25
 
24
26
  target << '--' if delim && !target.include?('--')
@@ -26,7 +28,15 @@ module Squared
26
28
  pat, s = Array(strip)
27
29
  ret.map! { |val| val.gsub(pat, s || '') }
28
30
  end
29
- ret.map! { |val| escape ? shell_escape(val, quote: quote) : shell_quote(val) } if escape || quote
31
+ if escape || quote
32
+ ret.map! do |val|
33
+ if escape
34
+ shell_escape(val, quote: quote, double: double)
35
+ else
36
+ shell_quote(val, force: force, double: double)
37
+ end
38
+ end
39
+ end
30
40
  if target.is_a?(Set)
31
41
  target.merge(ret)
32
42
  else
@@ -45,11 +55,23 @@ module Squared
45
55
  exit 1 unless pass || confirm("Run? [#{sub_style(target, styles: styles)}]", 'N')
46
56
  end
47
57
 
58
+ def delete_key(target, *args, value: false, reverse: false, count: -1)
59
+ ret = []
60
+ args.each do |val|
61
+ next if (opts = target.grep(matchopt(val, value))).empty?
62
+
63
+ opts = opts.first(count) if count >= 0
64
+ opts.send(reverse ? :reverse_each : :each) { |key| target.delete(key) }
65
+ ret.concat(opts)
66
+ end
67
+ ret
68
+ end
69
+
48
70
  def strip(val)
49
71
  return [] unless val
50
72
 
51
73
  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?)
74
+ val.map { |s| s.sub(OPT_SINGLE, '\1=\2').sub(OPT_VALUE, '\1=\2') }.reject(&:empty?)
53
75
  end
54
76
 
55
77
  def select(list, bare: true, no: true, single: false, double: false)
@@ -63,10 +85,7 @@ module Squared
63
85
 
64
86
  def arg?(target, *args, value: false, **)
65
87
  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
88
+ r << matchopts(s, value) unless s.empty?
70
89
  s = target.to_a.compact
71
90
  r.any? { |pat| s.any?(pat) }
72
91
  end
@@ -74,6 +93,30 @@ module Squared
74
93
  def pattern?(val)
75
94
  val.match?(/(?:\A\^|\$\z)/) || val.match?(/(?:\.[*+]|\(\?:|\\[dsw]|\[.+\]|\{\d+,?\d*\})/)
76
95
  end
96
+
97
+ private
98
+
99
+ def matchopt(val, value = false)
100
+ /\A#{val.size == 1 ? shortopt(val) : longopt(val, value)}/
101
+ end
102
+
103
+ def matchopts(list, value = false)
104
+ a, b = Array(list).partition { |val| val.size == 1 || val.match?(OPT_SINGLE) }
105
+ return /\A#{shortopt(*a)}}/ if b.empty?
106
+ return /\A#{longopt(*b, value)}/ if a.empty?
107
+
108
+ /\A(?:#{shortopt(*a)}|#{longopt(*b, value)})/
109
+ end
110
+
111
+ def shortopt(*group)
112
+ group.map! { |s| s.delete_prefix('-') }
113
+ "-(?:#{Regexp.escape(group.join('|'))})(?:\\z|[^ =]| +[^ -])"
114
+ end
115
+
116
+ def longopt(*group, value)
117
+ group.map! { |s| s.delete_prefix('--') }
118
+ "--(?:#{Regexp.escape(group.join('|'))})(?:#{value ? '=[^ ]| +[^ -]' : '[= ]|\z'})"
119
+ end
77
120
  end
78
121
 
79
122
  attr_reader :target, :extras, :found, :errors, :values, :project, :path
@@ -81,11 +124,14 @@ module Squared
81
124
  def_delegators :@target, :+, :-, :<<, :any?, :none?, :include?, :add, :add?, :find, :find_all, :find_index,
82
125
  :merge, :delete, :delete?, :delete_if, :grep, :grep_v, :inspect, :to_a, :to_s
83
126
  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
127
+ :pop, :push, :concat, :index, :join, :map, :map!, :detect, :select, :select!, :reject, :size,
128
+ :delete_at
85
129
 
86
130
  def_delegator :@extras, :delete, :remove
87
131
  def_delegator :@extras, :delete_at, :remove_at
88
132
  def_delegator :@extras, :delete_if, :remove_if
133
+ def_delegator :@extras, :find_all, :detect_all
134
+ def_delegator :@extras, :find_index, :detect_index
89
135
 
90
136
  def initialize(opts, list, target = Set.new, project: nil, path: nil, **kwargs, &blk)
91
137
  @target = target.is_a?(Set) ? target : target.to_set
@@ -96,7 +142,7 @@ module Squared
96
142
  parse(list, opts, **kwargs, &blk)
97
143
  end
98
144
 
99
- def parse(list, opts = extras, no: nil, single: nil, args: false, first: nil, &blk)
145
+ def parse(list, opts = extras, no: nil, single: nil, args: false, first: nil, underscore: nil, &blk)
100
146
  @extras = []
101
147
  @values = []
102
148
  bare = []
@@ -149,7 +195,7 @@ module Squared
149
195
  else
150
196
  next
151
197
  end
152
- m << flag if val[n + 2] == 'm'
198
+ m << flag if flag.size == 1 && val[n + 2] == 'm'
153
199
  bare << flag if val.end_with?('?')
154
200
  else
155
201
  bare << val
@@ -157,6 +203,22 @@ module Squared
157
203
  end
158
204
  no = (no || []).map { |val| (n = val.index('=')) ? val[0, n] : val }
159
205
  bare.concat(no)
206
+ if underscore
207
+ tr = ->(list) { list.map { |val| val.tr('-', '_') } }
208
+ @values.concat(tr.call(@values))
209
+ bare.concat(tr.call(bare))
210
+ e.concat(tr.call(e))
211
+ b.concat(tr.call(b))
212
+ m.concat(tr.call(m))
213
+ p.concat(tr.call(p))
214
+ q.concat(tr.call(q))
215
+ qq.concat(tr.call(qq))
216
+ i.concat(tr.call(i))
217
+ f.concat(tr.call(f))
218
+ si.concat(tr.call(si))
219
+ bl.concat(tr.call(bl))
220
+ no.concat(tr.call(no))
221
+ end
160
222
  numtype = [
161
223
  [i, /\A\d+\z/],
162
224
  [f, /\A\d*(?:\.\d+)?\z/],
@@ -172,7 +234,7 @@ module Squared
172
234
  add "-#{opt}"
173
235
  elsif bare.include?(opt)
174
236
  add(opt.size == 1 ? "-#{opt}" : "--#{opt}")
175
- elsif opt.start_with?('no-') && no.include?(name = opt[3..-1])
237
+ elsif opt.start_with?(/no[-_]/) && no.include?(name = opt[3..-1])
176
238
  add "--no-#{name}"
177
239
  else
178
240
  if opt =~ OPT_VALUE
@@ -183,8 +245,14 @@ module Squared
183
245
  add shell_option(key, val, merge: merge)
184
246
  elsif q.include?(key)
185
247
  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)
248
+ elsif p.include?(key)
249
+ if val.match?(/\A(["']).+\1\z/)
250
+ add shell_option(key, val, escape: false, merge: merge, sep: sep)
251
+ elsif path
252
+ add quote_option(key, path + val, merge: merge, sep: sep)
253
+ else
254
+ push opt
255
+ end
188
256
  elsif b.include?(key) || (bl.include?(key) && %w[true false].include?(val)) || numcheck.call(key, val)
189
257
  add basic_option(key, val, merge: merge)
190
258
  elsif merge
@@ -220,16 +288,34 @@ module Squared
220
288
  self
221
289
  end
222
290
 
291
+ def append_any(*args, quote: true, **kwargs)
292
+ (args.empty? ? extras : args.flatten).each do |val|
293
+ if exist?(val)
294
+ add_path(val, **kwargs)
295
+ elsif quote
296
+ add_quote(val, **kwargs)
297
+ else
298
+ add val
299
+ end
300
+ end
301
+ self
302
+ end
303
+
304
+ def delete_key(*args, **kwargs)
305
+ OptionPartition.delete_key(target, *args, **kwargs)
306
+ self
307
+ end
308
+
223
309
  def values_of(*args, strict: true, first: false, last: false)
224
310
  eq, s = strict ? ['=', '[^ ]+'] : ['(?:=| +)', '[^-][^ ]*']
225
- grp = ["\"((?:[^\"]|(?<=\\\\)\"(?!$#{Rake::Win32.windows? ? '| ' : ''}))*)\""]
226
- grp << "'((?:[^']|'\\\\'')*)'" unless Rake::Win32.windows?
227
- grp << "(#{s})"
311
+ g = ["\"((?:[^\"]|(?<=\\\\)\"(?!$#{windows? ? '| ' : ''}))*)\""]
312
+ g << "'((?:[^']|'\\\\'')*)'" unless windows?
313
+ g << "(#{s})"
228
314
  args.map! do |opt|
229
315
  if opt.size == 1
230
316
  /(?:\A| )-#{opt} ?([^ ]+)/
231
317
  else
232
- /(?:\A| )--#{opt + eq}(?:#{grp.join('|')})/
318
+ /(?:\A| )--#{opt + eq}(?:#{g.join('|')})/
233
319
  end
234
320
  end
235
321
  ret = []
@@ -243,64 +329,79 @@ module Squared
243
329
  end
244
330
  return ret unless first || last
245
331
 
246
- if last
247
- last.is_a?(Numeric) ? ret.last(last) : ret.last
332
+ if last.is_a?(Numeric)
333
+ ret.last(last)
334
+ elsif last
335
+ ret.last
248
336
  else
249
337
  first.is_a?(Numeric) ? ret.first(first) : ret.first
250
338
  end
251
339
  end
252
340
 
253
341
  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
342
+ ignore = map { |val| nameonly(val) }
343
+ list.reject { |val| ignore.include?(s = nameonly(val)) || any?(OptionPartition.send(:matchopt, s)) }
267
344
  end
268
345
 
269
346
  def clear(opts = nil, errors: false, **kwargs)
270
347
  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
348
+ if errors
349
+ OptionPartition.clear(target, self.errors, styles: styles, **kwargs)
350
+ self.errors.clear
351
+ return self unless opts
276
352
  end
277
- OptionPartition.clear(target, opts.reject { |val| found.include?(val) }, styles: styles, **kwargs)
353
+ opts ||= extras
354
+ OptionPartition.clear(target, if found.empty?
355
+ opts
356
+ else
357
+ opts.reject { |val| found.include?(val) }
358
+ end, styles: styles, **kwargs)
278
359
  opts.clear
279
360
  self
280
361
  end
281
362
 
282
- def adjoin(*args, start: false)
363
+ def adjoin(*args, with: nil, start: false)
283
364
  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
365
+ temp = to_a
366
+ if with
367
+ pat = case with
368
+ when String, Symbol
369
+ /\A#{Regexp.escape(with)}\z/
370
+ when Array
371
+ OptionPartition.send(:matchopts, with)
372
+ else
373
+ with
374
+ end
375
+ temp.each_with_index do |val, index|
376
+ if val.to_s.match?(pat)
292
377
  i = index + (start.is_a?(Numeric) ? start : 1)
293
378
  break
294
379
  end
295
- i = 0
380
+ end
381
+ else
382
+ temp.each_with_index do |val, index|
383
+ if i == 0
384
+ next unless val.start_with?('-')
385
+
386
+ i = index
387
+ break
388
+ elsif index > 0 && !val.start_with?('-')
389
+ if start
390
+ i = index + (start.is_a?(Numeric) ? start : 1)
391
+ break
392
+ end
393
+ i = 0
394
+ end
296
395
  end
297
396
  end
298
397
  if i > 0
299
398
  if args.empty?
300
399
  args = dup
301
400
  reset
401
+ else
402
+ args.each { |val| remove val }
302
403
  end
303
- args = items[0...i] + args + items[i..-1]
404
+ args = temp[0...i] + args + temp[i..-1]
304
405
  target.clear
305
406
  end
306
407
  merge args
@@ -308,12 +409,12 @@ module Squared
308
409
  end
309
410
 
310
411
  def add_path(*args, **kwargs)
311
- add shell_quote(path ? path.join(*args) : File.join(*args), **kwargs)
412
+ add shell_quote(path ? path.join(*args) : File.join(*args), option: false, **kwargs)
312
413
  self
313
414
  end
314
415
 
315
416
  def add_quote(*args, **kwargs)
316
- merge(args.map { |val| shell_quote(val, **kwargs) })
417
+ merge(args.map! { |val| shell_quote(val, **kwargs) })
317
418
  self
318
419
  end
319
420
 
@@ -336,7 +437,8 @@ module Squared
336
437
  if path
337
438
  found.each { |val| add_path(val) }
338
439
  else
339
- merge(quote ? found.map! { |val| shell_quote(val) } : found)
440
+ found.map! { |val| shell_quote(val) } if quote
441
+ merge found
340
442
  end
341
443
  end
342
444
  self
@@ -344,6 +446,7 @@ module Squared
344
446
 
345
447
  def reset(errors: false)
346
448
  extras.clear
449
+ found.clear
347
450
  clear(errors: true) if errors
348
451
  self
349
452
  end
@@ -370,11 +473,48 @@ module Squared
370
473
  OptionPartition.arg?(target, *args, **kwargs)
371
474
  end
372
475
 
476
+ def exist?(*args, add: false, first: false, last: false)
477
+ return false unless path
478
+ return path.join(*args).exist? unless args.empty?
479
+
480
+ if first || last
481
+ return false unless (val = first ? self.first : self.last).is_a?(String)
482
+
483
+ path.join(val).exist?.tap do |ret|
484
+ next unless add && ret
485
+
486
+ add_path(first ? shift : pop)
487
+ end
488
+ else
489
+ each_with_index do |val, index|
490
+ next unless val.is_a?(String) && path.join(val).exist?
491
+
492
+ if add
493
+ remove_at index
494
+ add_path val
495
+ end
496
+ return true
497
+ end
498
+ false
499
+ end
500
+ end
501
+
502
+ def uniq!(list)
503
+ unless (list = uniq(list)).empty?
504
+ concat list
505
+ self
506
+ end
507
+ end
508
+
373
509
  private
374
510
 
375
511
  def nameonly(val)
376
512
  val[OPT_VALUE, 1] || val
377
513
  end
514
+
515
+ def windows?
516
+ Rake::Win32.windows?
517
+ end
378
518
  end
379
519
 
380
520
  class JoinSet < Set
@@ -416,7 +556,9 @@ module Squared
416
556
  end
417
557
  ret[i.last] = val
418
558
  end
419
- block_given? ? ret.reject(&blk) : ret
559
+ return ret unless block_given?
560
+
561
+ ret.reject(&blk)
420
562
  end
421
563
 
422
564
  def and(*args)
@@ -441,9 +583,7 @@ module Squared
441
583
  end
442
584
 
443
585
  def done
444
- ret = to_s
445
- clear
446
- ret
586
+ to_s.tap { clear }
447
587
  end
448
588
 
449
589
  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.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - An Pham
@@ -124,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
126
  requirements: []
127
- rubygems_version: 3.6.9
127
+ rubygems_version: 3.7.2
128
128
  specification_version: 4
129
129
  summary: Rake task generator for managing multi-language workspaces.
130
130
  test_files: []