squared 0.8.3 → 0.8.5

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,10 +10,11 @@ module Squared
10
10
  include Common::Shell
11
11
  extend Forwardable
12
12
 
13
- OPT_NAME = /\A(?:(--)|-)((?(1)[^=\s-][^=\s]*|[^=\s-]))\z/
14
- OPT_VALUE = /\A-{0,2}([^=\s-][^=\s]*)(?:=|\s+)(\S.*)\z/
15
- OPT_SINGLE = /\A-([^=\s-])(.+)\z/
16
- private_constant :OPT_NAME, :OPT_VALUE, :OPT_SINGLE
13
+ OPT_NAME = /\A(?:(--)|-)((?(1)[^=\s-][^=\s]*|[^=\s-]))\z/.freeze
14
+ OPT_VALUE = /\A-{0,2}([^=\s-][^=\s]*)(?:=|\s+)(\S.*)\z/.freeze
15
+ OPT_SINGLE = /\A-([^=\s-])(.+)\z/.freeze
16
+ QUOTE_VALUE = /\A(["'])(.+)\1\z/m.freeze
17
+ private_constant :OPT_NAME, :OPT_VALUE, :OPT_SINGLE, :QUOTE_VALUE
17
18
 
18
19
  class << self
19
20
  include Common::Format
@@ -22,7 +23,8 @@ module Squared
22
23
 
23
24
  def append(target, *args, delim: false, escape: false, quote: true, strip: nil, double: false, filter: nil,
24
25
  pass: nil, **kwargs)
25
- return if (ret = args.flatten(1)).empty?
26
+ ret = args.flatten(1)
27
+ return if ret.empty?
26
28
 
27
29
  target << '--' if delim && !target.include?('--')
28
30
  if strip
@@ -95,8 +97,26 @@ module Squared
95
97
 
96
98
  def strip(val)
97
99
  val = shell_split val if val.is_a?(String)
98
- Array(val).map { |s| s.sub(OPT_SINGLE, '\1=\2').sub(OPT_VALUE, '\1=\2').sub(OPT_NAME, '\2') }
99
- .reject(&:empty?)
100
+ ret = []
101
+ pass = -1
102
+ args = Array(val)
103
+ args.each_with_index do |s, i|
104
+ next if s.empty? || pass == i
105
+
106
+ if s == '--'
107
+ ret << s << args[i.succ..-1].join(' ')
108
+ break
109
+ end
110
+ next ret << s unless s.start_with?('-')
111
+
112
+ if !s.include?('=') && (j = args[i.succ]) && !j.start_with?('-')
113
+ ret << "#{s.sub(/^-{1,2}/, '')}=#{j}"
114
+ pass = i.succ
115
+ else
116
+ ret << s.sub(OPT_SINGLE, '\1=\2').sub(OPT_VALUE, '\1=\2').sub(OPT_NAME, '\2')
117
+ end
118
+ end
119
+ ret
100
120
  end
101
121
 
102
122
  def select(list, bare: true, no: true, single: false, double: false)
@@ -110,21 +130,17 @@ module Squared
110
130
 
111
131
  def union(list, other)
112
132
  base = list.map { |val| parse_option(val).first }
113
- other.each do |val|
114
- next if base.include?(parse_option(val).first)
115
-
116
- list << val
117
- end
118
- list
133
+ list + other.each_with_object([]) { |val, out| out << val unless base.include?(parse_option(val).first) }
119
134
  end
120
135
 
121
136
  def uniq!(list, pass: [])
122
- keys = {}
123
- list.each_with_index do |val, i|
124
- j = val =~ OPT_VALUE ? $1 : val
125
- (keys[j] ||= []) << i unless pass.include?(j)
126
- end
127
- data = keys.map { |item| item[1].size > 1 ? item[1][0..-2] : [] }.reject(&:empty?)
137
+ data = list.each_with_object({})
138
+ .with_index do |(val, out), i|
139
+ j = val =~ OPT_VALUE ? $1 : val
140
+ (out[j] ||= []) << i unless pass.include?(j)
141
+ end
142
+ .map { |item| item[1].size > 1 ? item[1][0..-2] : [] }
143
+ .reject(&:empty?)
128
144
  return if data.empty?
129
145
 
130
146
  data.each { |key| key.each { |i| list[i] = nil } }
@@ -229,7 +245,7 @@ module Squared
229
245
  end
230
246
 
231
247
  def parse(list, opts = extras, no: nil, single: nil, args: false, multiple: nil, first: nil, underscore: nil,
232
- stdin: false, &blk)
248
+ explicit: false, bool: %w[true false], stdin: false, &blk)
233
249
  @extras = []
234
250
  @values = []
235
251
  bare = []
@@ -243,7 +259,10 @@ module Squared
243
259
  f = []
244
260
  si = []
245
261
  bl = []
262
+ ex = []
246
263
  ml = []
264
+ re = {}
265
+ ar = {}
247
266
  sw = {}
248
267
  se = {}
249
268
  list.flat_map do |val|
@@ -272,13 +291,13 @@ module Squared
272
291
  else
273
292
  [flag]
274
293
  end
294
+ bare.concat(mod) if val.chomp!('?')
295
+ m.concat(mod) if val.chomp!('m')
275
296
  case val[n.succ]
276
297
  when 'e'
277
298
  e.concat(mod)
278
299
  when 'b'
279
300
  b.concat(mod)
280
- when 'm'
281
- m.concat(mod)
282
301
  when 'q'
283
302
  qq.concat(mod) if val[n + 2] == 'q'
284
303
  q.concat(mod)
@@ -297,13 +316,27 @@ module Squared
297
316
  when '+'
298
317
  ml.concat(mod)
299
318
  bare.concat(mod)
300
- else
301
- next
319
+ when '/'
320
+ begin
321
+ val = val[n.succ..-1]
322
+ pat = eval(val)
323
+ raise SyntaxError unless pat.is_a?(Regexp)
324
+
325
+ mod.each { |key| re[key] = pat }
326
+ rescue SyntaxError
327
+ warn "#{self.class}: invalid pattern (#{val})"
328
+ end
329
+ when '{'
330
+ group = val[(n + 2)..-1].chomp!('}')&.split(',')
331
+ if group
332
+ mod.each { |key| ar[key] = group }
333
+ else
334
+ warn "#{self.class}: invalid group (#{val})"
335
+ end
302
336
  end
303
- m.concat(mod) if val[n + 2] == 'm'
304
- bare.concat(mod) if val.end_with?('?')
305
337
  else
306
338
  bare << val
339
+ ex << val if explicit
307
340
  mod = [val]
308
341
  end
309
342
  mod.each do |key|
@@ -336,7 +369,7 @@ module Squared
336
369
  end
337
370
  numtype = [
338
371
  [i, /\A\d+\z/],
339
- [f, /\A\d*(\.\d+)?\z/],
372
+ [f, /\A(\d+(\.\d*)?|\d*\.\d+)\z/],
340
373
  [si, /\A-?\d+\z/]
341
374
  ].freeze
342
375
  numcheck = ->(k, v) { numtype.any? { |flag, pat| flag.include?(k) && v.match?(pat) } }
@@ -366,33 +399,63 @@ module Squared
366
399
  elsif opt.start_with?(/no[-_]/) && no.include?(s = opt[3..-1])
367
400
  add "--no-#{s}"
368
401
  else
402
+ has = lambda do |list, key|
403
+ return true if list.include?(key)
404
+ return false unless (pre = list.find { |s| s.end_with?(':*') })
405
+
406
+ key.start_with?(pre.chomp('*')) && !key.end_with?(':')
407
+ end
369
408
  if opt =~ OPT_VALUE
370
409
  key = $1
371
410
  val = $2
372
- has = lambda do |a|
373
- return true if a.include?(key)
374
- return false unless (k = a.find { |s| s.end_with?(':*') })
375
-
376
- key.start_with?(k.chomp('*')) && !key.end_with?(':')
411
+ if val =~ QUOTE_VALUE
412
+ val = $2
413
+ double = $1 == '"'
377
414
  end
378
- kwargs = { sep: se[key] || sep, merge: has.call(m), switch: sw[key] }
379
- if has.call(e) || (has.call(bl) && %w[true false].include?(val))
415
+ get = ->(h) { h[key] || h.find { |k,| k.end_with?(':*') }.last }
416
+ kwargs = { sep: se[key] || sep, merge: has.call(m, key), switch: sw[key] }
417
+ kwargs[:double] = double unless double.nil?
418
+ if has.call(e, key) || (has.call(bl, key) && bool.include?(val))
380
419
  add shell_option(key, val, **kwargs)
381
- elsif has.call(q)
382
- add quote_option(key, val, double: has.call(qq), **kwargs)
383
- elsif has.call(p)
384
- if val.match?(/\A(["']).+\1\z/)
420
+ elsif has.call(ex, key) && bool.include?(val)
421
+ add shell_option(key, val, explicit: explicit, **kwargs)
422
+ elsif has.call(q, key)
423
+ kwargs[:double] = true if has.call(qq, key)
424
+ add quote_option(key, val, **kwargs)
425
+ elsif has.call(p, key)
426
+ if !double.nil?
385
427
  add shell_option(key, val, escape: false, **kwargs)
386
428
  elsif path
387
429
  add quote_option(key, path + val, **kwargs)
388
430
  else
389
431
  push opt
390
432
  end
391
- elsif kwargs[:merge] || has.call(b) || numcheck.call(key, val) || se[key] || sw[key]
433
+ elsif !ar.empty? && has.call(ar.keys, key)
434
+ group = get.call(ar)
435
+ if group.include?(val)
436
+ add shell_option(key, val, force: false, **kwargs)
437
+ elsif @strict
438
+ clear([opt], hint: "include != {#{group.join(',')}}")
439
+ else
440
+ push opt
441
+ end
442
+ elsif !re.empty? && has.call(re.keys, key)
443
+ pat = get.call(re)
444
+ if val.match?(pat)
445
+ add quote_option(key, val, **kwargs)
446
+ elsif @strict
447
+ clear([opt], hint: "match != /#{pat.source}/")
448
+ else
449
+ push opt
450
+ end
451
+ elsif kwargs[:merge] || has.call(b, key) || numcheck.call(key, val) || se[key] || sw[key]
392
452
  add basic_option(key, val, **kwargs)
393
453
  else
394
454
  push opt
395
455
  end
456
+ opt = key unless opt == last
457
+ elsif has.call(m, key = opt[0]) && opt[1..-1] =~ QUOTE_VALUE
458
+ add basic_option(key, $2, double: $1 == '"' || has.call(qq, key), **kwargs, merge: true)
396
459
  opt = key
397
460
  else
398
461
  push opt
@@ -460,8 +523,8 @@ module Squared
460
523
 
461
524
  def values_of(*args, strict: true, first: false, last: false)
462
525
  eq, s = strict ? [sep, '[^ ]+'] : ['(?:=| +)', '[^-][^ ]*']
463
- g = ["\"((?:[^\"]|(?<=\\\\)\"(?!$#{'| ' if windows?}))*)\""]
464
- g << "'((?:[^']|'\\\\'')*)'" unless windows?
526
+ g = ["\"((?:[^\"]|(?<=\\\\)\"(?!$#{'| ' if Common::Host.windows?}))*)\""]
527
+ g << "'((?:[^']|'\\\\'')*)'" unless Common::Host.windows?
465
528
  g << "(#{s})"
466
529
  list = args.map do |opt|
467
530
  if opt.size == 1
@@ -737,16 +800,13 @@ module Squared
737
800
  end
738
801
 
739
802
  def exist?(*args, add: false, first: false, last: false, glob: false)
740
- return !args.first.nil? && with_glob?(File.join(*args), glob) unless args.empty?
803
+ return !args.include?(nil) && with_glob?(File.join(*args), glob) unless args.empty?
741
804
 
742
805
  if first || last
743
- return false unless (val = first ? self.first : self.last)
744
-
745
- with_glob?(val, glob).tap do |ret|
746
- next unless add && ret
806
+ val = first ? self.first : self.last
807
+ return false unless val
747
808
 
748
- add_first(path: true, reverse: !first)
749
- end
809
+ with_glob?(val, glob).tap { |ret| add_first(path: true, reverse: !first) if add && ret }
750
810
  else
751
811
  each_with_index do |val, i|
752
812
  next unless with_glob?(val, glob)
@@ -781,11 +841,6 @@ module Squared
781
841
 
782
842
  path.join(val).exist? || (glob && !path.glob(val).empty?)
783
843
  end
784
-
785
- def windows?
786
- require 'rake'
787
- Rake::Win32.windows?
788
- end
789
844
  end
790
845
  end
791
846
  end
@@ -126,7 +126,8 @@ module Squared
126
126
  stage = nil
127
127
  opts = %w[force rebase detach submodules fail no-update gc]
128
128
  desc = lambda do |val, alt = nil|
129
- if (ver = branch || alt)
129
+ ver = branch || alt
130
+ if ver
130
131
  val = val.sub('{0}', "opts*=#{opts.join(',')}")
131
132
  task_desc(path, val, ver)
132
133
  else
@@ -280,7 +281,7 @@ module Squared
280
281
  env('REPO_OPTIONS', **kwargs) { |val| cmd << val } if options
281
282
  cmd = cmd.join(' ')
282
283
  puts log_message(cmd, subject: main, hint: root) if verbose
283
- Common::System.shell(cmd, chdir: root, exception: exception)
284
+ Common::System.shell(cmd, chdir: root, exception: exception || env('REPO_FAIL', equals: %w[1 true]))
284
285
  end
285
286
 
286
287
  def repo_bin
@@ -23,8 +23,8 @@ module Squared
23
23
  @exclude = exclude.freeze
24
24
  @task = Struct::SeriesData.new(workspace.config_get(:rename))
25
25
  @data = {}
26
- project.each_with_index do |obj, index|
27
- if index == 0
26
+ project.each_with_index do |obj, i|
27
+ if i == 0
28
28
  target = @task.base
29
29
  obj.tasks.each do |key|
30
30
  target << key
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.8.3
4
+ version: 0.8.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - An Pham
@@ -80,6 +80,7 @@ files:
80
80
  - lib/squared/common.rb
81
81
  - lib/squared/common/base.rb
82
82
  - lib/squared/common/format.rb
83
+ - lib/squared/common/host.rb
83
84
  - lib/squared/common/prompt.rb
84
85
  - lib/squared/common/shell.rb
85
86
  - lib/squared/common/system.rb
@@ -125,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
126
  - !ruby/object:Gem::Version
126
127
  version: '0'
127
128
  requirements: []
128
- rubygems_version: 4.0.18
129
+ rubygems_version: 4.0.21
129
130
  specification_version: 4
130
131
  summary: Rake task generator for managing multi-language workspaces.
131
132
  test_files: []