squared 0.6.20 → 0.7.0

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.
@@ -27,12 +27,12 @@ module Squared
27
27
  def multiple=(val)
28
28
  case val
29
29
  when Enumerable
30
- @multiple.concat(val.to_a.map { |pat| pat.is_a?(Regexp) ? pat : pat.to_s })
30
+ @multiple.concat(val.to_a.map { |val| val.is_a?(Regexp) ? val : val.to_s })
31
31
  when String, Symbol, Pathname
32
32
  @multiple << val.to_s
33
33
  when Regexp
34
34
  @multiple << val
35
- when NilClass, FalseClass
35
+ when nil, false
36
36
  @multiple.clear
37
37
  end
38
38
  end
@@ -47,7 +47,9 @@ module Squared
47
47
 
48
48
  def slice!(*args)
49
49
  data = compact
50
- data.slice!(*args).tap { replace Set.new(data) }
50
+ ret = data.slice!(*args)
51
+ replace Set.new(data)
52
+ ret
51
53
  end
52
54
 
53
55
  def compact
@@ -109,7 +111,9 @@ module Squared
109
111
  end
110
112
 
111
113
  def done
112
- to_s.tap { clear }
114
+ ret = to_s
115
+ clear
116
+ ret
113
117
  end
114
118
 
115
119
  def merge(enum)
@@ -131,10 +135,12 @@ module Squared
131
135
  end
132
136
 
133
137
  def <<(obj)
134
- return super if extras.empty? && !extras?(obj)
138
+ unless obj.nil?
139
+ return super if extras.empty? && !extras?(obj)
135
140
 
136
- unless !extras.include?(@partition) && include?(obj) && @uniq.match?(s = obj.to_s) && !multiple?(s)
137
- extras << obj
141
+ unless !extras.include?(@partition) && include?(obj) && @uniq.match?(s = obj.to_s) && !multiple?(s)
142
+ extras << obj
143
+ end
138
144
  end
139
145
  self
140
146
  end
@@ -21,37 +21,38 @@ module Squared
21
21
  include Prompt
22
22
 
23
23
  def append(target, *args, delim: false, escape: false, quote: true, strip: nil, force: true, double: false,
24
- filter: nil, preserve: true, **)
25
- return if (ret = args.flatten).empty?
24
+ filter: nil, pass: nil, **)
25
+ return if (ret = args.flatten(1)).empty?
26
26
 
27
27
  target << '--' if delim && !target.include?('--')
28
28
  if strip
29
29
  pat, s = Array(strip)
30
30
  ret.map! { |val| val.is_a?(String) ? val.gsub(pat, s || '') : val }
31
31
  end
32
- ret, err = ret.partition { |val| filter.match?(val.to_s) } if filter
32
+ if filter
33
+ ret, err = ret.partition { |val| filter.match?(val.to_s) }
34
+ pass&.concat(err)
35
+ end
33
36
  if block_given?
34
- out = []
35
- err ||= []
36
- ret.each do |val|
37
- case (s = yield val)
37
+ ret = ret.each_with_object([]) do |val, out|
38
+ arg = yield val
39
+ case arg
38
40
  when String
39
- out << s
40
- when NilClass, FalseClass
41
- err << val
41
+ out << arg
42
+ when nil, false
43
+ pass&.push(val)
42
44
  else
43
45
  out << val
44
46
  end
45
47
  end
46
- ret = out
47
48
  end
48
49
  ret.map! do |val|
49
50
  next val if opt?(val)
50
51
 
51
- if !(pa = val.is_a?(Pathname)) && escape
52
+ if quote || val.is_a?(Pathname)
53
+ shell_quote(val, force: force, double: double)
54
+ elsif escape
52
55
  shell_escape(val, quote: quote, double: double)
53
- elsif quote || pa
54
- shell_quote(val, force: force, double: double, preserve: preserve)
55
56
  else
56
57
  val
57
58
  end
@@ -61,7 +62,7 @@ module Squared
61
62
  else
62
63
  target.concat(ret)
63
64
  end
64
- err || ret
65
+ ret
65
66
  end
66
67
 
67
68
  def clear(target, opts, pass: true, styles: nil, **kwargs)
@@ -75,42 +76,23 @@ module Squared
75
76
  end
76
77
 
77
78
  def delete_key(target, *args, value: false, reverse: false, count: -1)
78
- ret = []
79
- args.each do |val|
79
+ args.each_with_object([]) do |val, out|
80
80
  next if (opts = target.grep(matchopt(val, value))).empty?
81
81
 
82
82
  opts = opts.first(count) if count >= 0
83
83
  opts.send(reverse ? :reverse_each : :each) { |key| target.delete(key) }
84
- ret.concat(opts)
84
+ out.concat(opts)
85
85
  end
86
- ret
87
86
  end
88
87
 
89
88
  def strip(val)
90
89
  val = shell_split val if val.is_a?(String)
91
- ret = []
92
- pass = -1
93
- (args = Array(val)).each_with_index do |s, i|
94
- next if s.empty? || pass == i
95
-
96
- if s == '--'
97
- ret << s << args[i.succ..-1].join(' ')
98
- break
99
- end
100
- next ret << s unless s.start_with?('-')
101
-
102
- if !s.include?('=') && (j = args[i.succ]) && !j.start_with?('-')
103
- ret << "#{s.sub(/^-{1,2}/, '')}=#{j}"
104
- pass = i.succ
105
- else
106
- ret << s.sub(OPT_SINGLE, '\1=\2').sub(OPT_VALUE, '\1=\2').sub(OPT_NAME, '\2')
107
- end
108
- end
109
- ret
90
+ Array(val).map { |s| s.sub(OPT_SINGLE, '\1=\2').sub(OPT_VALUE, '\1=\2').sub(OPT_NAME, '\2') }
91
+ .reject(&:empty?)
110
92
  end
111
93
 
112
94
  def select(list, bare: true, no: true, single: false, double: false)
113
- ret = bare ? list.grep_v(/=/) : list.grep(/=/).map! { |val| val.split('=', 2).first }
95
+ ret = bare ? list.grep_v(/=/) : list.grep(/=/).map { |val| val.split('=', 2).first }
114
96
  ret.map! { |val| val.split('|', 2).last }
115
97
  ret = ret.grep_v(/\Ano-/) unless no
116
98
  return ret if single == double
@@ -132,6 +114,18 @@ module Squared
132
114
  list
133
115
  end
134
116
 
117
+ def parse_option(val)
118
+ val = val.strip
119
+ return [val, nil, ''] unless (i = val.index('='))
120
+
121
+ last = val[i.succ..-1].strip
122
+ if last =~ /\A(["'])(.*)\1\z/m
123
+ last = $2
124
+ quote = $1
125
+ end
126
+ [val[0..i.pred], last, quote || '']
127
+ end
128
+
135
129
  def parse_arg!(name, val)
136
130
  return unless val.is_a?(String)
137
131
 
@@ -158,11 +152,8 @@ module Squared
158
152
  end
159
153
 
160
154
  def pattern?(val)
161
- Regexp.new(val)
162
155
  val.start_with?('\A', '^') || val.end_with?('\z', '$') ||
163
- val.match?(/[.)][*+?]|\(\?[:=!><]|\\[dsw\d]|\[.+\]|\{\d+,?\d*\}/i)
164
- rescue RegexpError
165
- false
156
+ val.match?(/[.)][*+?]|\(\?:|\\[dsw\d]|\[.+\]|\{\d+,?\d*\}/i)
166
157
  end
167
158
 
168
159
  private
@@ -180,13 +171,13 @@ module Squared
180
171
  end
181
172
 
182
173
  def shortopt(*group)
183
- group.map! { |s| Regexp.escape(s.delete_prefix('-')) }
184
- "-(?:#{group.join('|')})(?:\\z|[^ =]| +[^ -])"
174
+ g = group.map { |s| Regexp.escape(s.delete_prefix('-')) }
175
+ "-(?:#{g.join('|')})(?:\\z|[^ =]| +[^ -])"
185
176
  end
186
177
 
187
178
  def longopt(*group, value)
188
- group.map! { |s| Regexp.escape(s.delete_prefix('--')) }
189
- "--(?:#{group.join('|')})(?:#{value ? '=[^ ]| +[^ -]' : '[= ]|\z'})"
179
+ g = group.map { |s| Regexp.escape(s.delete_prefix('--')) }
180
+ "--(?:#{g.join('|')})(?:#{value ? '=[^ ]| +[^ -]' : '[= ]|\z'})"
190
181
  end
191
182
  end
192
183
 
@@ -303,7 +294,7 @@ module Squared
303
294
  end
304
295
  numtype = [
305
296
  [i, /\A\d+\z/],
306
- [f, /\A(\d+(\.\d*)?|\d*\.\d+)\z/],
297
+ [f, /\A\d*(?:\.\d+)?\z/],
307
298
  [si, /\A-?\d+\z/]
308
299
  ].freeze
309
300
  numcheck = ->(k, v) { numtype.any? { |flag, pat| flag.include?(k) && v.match?(pat) } }
@@ -332,27 +323,23 @@ module Squared
332
323
  if opt =~ OPT_VALUE
333
324
  key = $1
334
325
  val = $2
335
- if val =~ /\A(["'])(.+)\1\z/
336
- val = $2
337
- double = $1 == '"'
338
- end
339
326
  merge = m.include?(key)
340
327
  if e.include?(key)
341
- add shell_option(key, val, double: double, merge: merge, sep: sep)
328
+ add shell_option(key, val, merge: merge, sep: sep)
342
329
  elsif q.include?(key)
343
- add quote_option(key, val, double: double || qq.include?(key), merge: merge, sep: sep)
330
+ add quote_option(key, val, double: qq.include?(key), merge: merge, sep: sep)
344
331
  elsif p.include?(key)
345
- if !double.nil?
346
- add shell_option(key, val, double: double, merge: merge, sep: sep, escape: false)
332
+ if val.match?(/\A(["']).+\1\z/)
333
+ add shell_option(key, val, escape: false, merge: merge, sep: sep)
347
334
  elsif path
348
335
  add quote_option(key, path + val, merge: merge, sep: sep)
349
336
  else
350
337
  push opt
351
338
  end
352
339
  elsif b.include?(key) || (bl.include?(key) && %w[true false].include?(val)) || numcheck.call(key, val)
353
- add basic_option(key, val, double: double, merge: merge, sep: sep)
340
+ add basic_option(key, val, merge: merge, sep: sep)
354
341
  elsif merge
355
- add basic_option(key, val, double: double, merge: true, sep: sep)
342
+ add basic_option(key, val, merge: true, sep: sep)
356
343
  else
357
344
  push opt
358
345
  end
@@ -361,7 +348,7 @@ module Squared
361
348
  push opt
362
349
  skip = true if args
363
350
  end
364
- skip = true if first&.any? { |pat| pat.is_a?(Regexp) ? opt.match?(pat) : !opt.include?(pat) }
351
+ skip = true if first&.any? { |s| s.is_a?(Regexp) ? opt.match?(s) : !opt.include?(s) }
365
352
  end
366
353
  end
367
354
  @values = @values.empty? ? /\A\s+\z/ : /\A(#{@values.join('|')})#{sep}(.+)\z/m
@@ -379,23 +366,23 @@ module Squared
379
366
  self
380
367
  end
381
368
 
382
- def append(*args, clear: false, preserve: '"', **kwargs, &blk)
383
- args = clear ? extras.dup.tap { extras.clear } : extras if args.empty?
384
- out = OptionPartition.append(target, *args, preserve: preserve, **kwargs, &blk)
385
- errors.concat(out) if out && (block_given? || kwargs[:filter])
369
+ def append(*args, **kwargs, &blk)
370
+ args = extras if args.empty?
371
+ pass = kwargs[:pass] ||= []
372
+ OptionPartition.append(target, *args, **kwargs, &blk)
373
+ errors.concat(pass)
386
374
  self
387
375
  end
388
376
 
389
- def append_any(*args, escape: false, **kwargs)
390
- quote = kwargs.fetch(:quote, true)
391
- (args.empty? ? extras : args.flatten).each do |val|
377
+ def append_any(*args, escape: false, quote: true, **kwargs)
378
+ (args.empty? ? extras : args.flatten(1)).each do |val|
392
379
  if block_given?
393
380
  temp = val
394
381
  val = yield val
395
382
  if val.is_a?(Array)
396
383
  found << temp
397
384
  k, v, q = val
398
- add_option(k, v, escape: escape, double: q == '"', merge: q == true, **kwargs)
385
+ add_option(k, v, escape: escape, quote: quote, double: q == '"', merge: q == true, **kwargs)
399
386
  next
400
387
  end
401
388
  end
@@ -403,10 +390,10 @@ module Squared
403
390
 
404
391
  if exist?(val)
405
392
  add_path(val, **kwargs)
406
- elsif escape
407
- add shell_escape(val, **kwargs)
408
393
  elsif quote
409
394
  add_quote(val, **kwargs)
395
+ elsif escape
396
+ add shell_escape(val, **kwargs)
410
397
  else
411
398
  add val
412
399
  end
@@ -425,7 +412,7 @@ module Squared
425
412
  g = ["\"((?:[^\"]|(?<=\\\\)\"(?!$#{'| ' if windows?}))*)\""]
426
413
  g << "'((?:[^']|'\\\\'')*)'" unless windows?
427
414
  g << "(#{s})"
428
- args.map! do |opt|
415
+ list = args.map do |opt|
429
416
  if opt.size == 1
430
417
  /(?:\A| )-#{opt} ?([^ ]+)/
431
418
  else
@@ -434,7 +421,7 @@ module Squared
434
421
  end
435
422
  ret = []
436
423
  target.each do |opt|
437
- args.each do |pat|
424
+ list.each do |pat|
438
425
  next unless opt =~ pat
439
426
 
440
427
  ret << ($1 || $2 || $3)
@@ -520,10 +507,10 @@ module Squared
520
507
 
521
508
  def add_path(*args, option: nil, force: true, double: false, **kwargs)
522
509
  if args.empty?
523
- args = grep(String)
524
- found.concat(args)
525
- args.map! { |val| path + val } if path
526
- append(args, force: force, **kwargs)
510
+ list = select { |val| val.is_a?(String) }
511
+ found.concat(list)
512
+ list.map! { |val| path + val } if path
513
+ append(list, force: force, **kwargs)
527
514
  else
528
515
  val = path ? path.join(*args) : File.join(*args)
529
516
  if option
@@ -536,9 +523,7 @@ module Squared
536
523
  end
537
524
 
538
525
  def add_quote(*args, **kwargs)
539
- kwargs.delete(:quote)
540
- merge(args.compact
541
- .map! { |val| val == '--' || OptionPartition.opt?(val) ? val : shell_quote(val, **kwargs) })
526
+ merge(args.compact.map { |s| s == '--' || OptionPartition.opt?(s) ? s : shell_quote(s, **kwargs) })
542
527
  self
543
528
  end
544
529
 
@@ -547,8 +532,8 @@ module Squared
547
532
  self
548
533
  end
549
534
 
550
- def add_first(fallback = nil, prefix: nil, path: false, escape: false, reverse: false, expect: false,
551
- **kwargs)
535
+ def add_first(fallback = nil, prefix: nil, path: false, escape: false, quote: false, reverse: false,
536
+ expect: false, **kwargs)
552
537
  val = (reverse ? pop : shift) || fallback
553
538
  if val
554
539
  temp = val
@@ -556,10 +541,10 @@ module Squared
556
541
  unless block_given? && !(val = yield val).is_a?(String)
557
542
  if path
558
543
  add_path(val, **kwargs)
544
+ elsif quote
545
+ add_quote(val, **kwargs)
559
546
  elsif escape
560
547
  add shell_escape(val, **kwargs)
561
- elsif kwargs[:quote]
562
- add_quote(val, **kwargs)
563
548
  else
564
549
  add val
565
550
  end
@@ -571,6 +556,12 @@ module Squared
571
556
  self
572
557
  end
573
558
 
559
+ def detach
560
+ ret = extras
561
+ @extras = []
562
+ ret
563
+ end
564
+
574
565
  def delim
575
566
  add '--'
576
567
  self
@@ -579,7 +570,7 @@ module Squared
579
570
  def last(val = nil, &blk)
580
571
  unless block_given?
581
572
  case val
582
- when NilClass
573
+ when nil
583
574
  return extras.last
584
575
  when Numeric
585
576
  return extras.last(val)
@@ -593,7 +584,7 @@ module Squared
593
584
  ret = find_all(&blk)
594
585
  unless ret.empty?
595
586
  ret = case val
596
- when NilClass
587
+ when nil
597
588
  ret.first(1)
598
589
  when Numeric
599
590
  ret.first(val)
@@ -611,8 +602,6 @@ module Squared
611
602
  def splice(*exclude, quote: true, delim: true, path: false, pattern: false, &blk)
612
603
  temp, other = if block_given?
613
604
  partition(&blk)
614
- elsif exclude.first.is_a?(Symbol)
615
- partition(&exclude.first)
616
605
  else
617
606
  exclude.map! { |pat| Regexp.new(pat) }
618
607
  partition do |val|
@@ -691,10 +680,11 @@ module Squared
691
680
  end
692
681
 
693
682
  def uniq!(list)
694
- unless (list = uniq(list)).empty?
695
- concat list
696
- self
697
- end
683
+ list = uniq list
684
+ return if list.empty?
685
+
686
+ concat list
687
+ self
698
688
  end
699
689
 
700
690
  private
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Squared
4
+ module Workspace
5
+ module Project
6
+ module Support
7
+ module Utils
8
+ private
9
+
10
+ def rand_s(size)
11
+ if RUBY_VERSION >= '3.1'
12
+ require 'random/formatter'
13
+ Random.new.alphanumeric(size)
14
+ else
15
+ (0...size).map { rand(97..122).chr }.join
16
+ end
17
+ end
18
+
19
+ def merge_list(target, list)
20
+ list = Array(list)
21
+ case target
22
+ when Array
23
+ target.concat(list)
24
+ when Set
25
+ target.merge(list)
26
+ else
27
+ Array(target).concat(list)
28
+ end
29
+ end
30
+
31
+ def matchmap(list, prefix = nil)
32
+ list.map do |val|
33
+ next val if val.is_a?(Regexp)
34
+
35
+ val = ".*#{val}" if prefix && !val.sub!(/\A(\^|\\A)/, '')
36
+ Regexp.new("#{prefix}#{val == '*' ? '.+' : val}")
37
+ end
38
+ end
39
+
40
+ def matchany?(list, *args, empty: true)
41
+ return empty if list.empty?
42
+
43
+ list.any? { |pat| args.any?(pat) }
44
+ end
45
+
46
+ def has_value?(target, *args)
47
+ args.any? { |obj,| target.include?(obj) }
48
+ end
49
+
50
+ def has_value!(target, *args, first: false)
51
+ ret = nil
52
+ args.each do |val|
53
+ if target.respond_to?(:delete?)
54
+ ret = target if target.delete?(val)
55
+ elsif target.respond_to?(:delete)
56
+ ret = target if target.delete(val)
57
+ elsif target.include?(val)
58
+ ret = target
59
+ end
60
+ break if ret && first
61
+ end
62
+ ret
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -1,11 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Squared
4
- module Workspace
5
- module Project
6
- end
7
- end
8
- end
9
-
10
3
  require_relative 'project/base'
11
4
  require_relative 'project/git'