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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +70 -249
- data/README.md +242 -205
- data/lib/squared/common/base.rb +0 -8
- data/lib/squared/common/format.rb +7 -10
- data/lib/squared/common/prompt.rb +25 -30
- data/lib/squared/common/shell.rb +27 -35
- data/lib/squared/common/system.rb +29 -21
- data/lib/squared/common/utils.rb +45 -64
- data/lib/squared/config.rb +17 -16
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +292 -186
- data/lib/squared/workspace/project/base.rb +569 -500
- data/lib/squared/workspace/project/docker.rb +198 -219
- data/lib/squared/workspace/project/git.rb +244 -215
- data/lib/squared/workspace/project/node.rb +125 -161
- data/lib/squared/workspace/project/python.rb +250 -163
- data/lib/squared/workspace/project/ruby.rb +408 -298
- data/lib/squared/workspace/project/support/class.rb +13 -7
- data/lib/squared/workspace/project/support/optionpartition.rb +80 -90
- data/lib/squared/workspace/project/support/utils.rb +68 -0
- data/lib/squared/workspace/project.rb +0 -7
- data/lib/squared/workspace/repo.rb +235 -170
- data/lib/squared/workspace/series.rb +93 -89
- data/lib/squared/workspace/support/base.rb +15 -1
- metadata +3 -2
|
@@ -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 { |
|
|
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
|
|
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)
|
|
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
|
-
|
|
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
|
-
|
|
138
|
+
unless obj.nil?
|
|
139
|
+
return super if extras.empty? && !extras?(obj)
|
|
135
140
|
|
|
136
|
-
|
|
137
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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 <<
|
|
40
|
-
when
|
|
41
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
92
|
-
|
|
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
|
|
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?(/[.)][*+?]|\(
|
|
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
|
|
184
|
-
"-(?:#{
|
|
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
|
|
189
|
-
"--(?:#{
|
|
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
|
|
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,
|
|
328
|
+
add shell_option(key, val, merge: merge, sep: sep)
|
|
342
329
|
elsif q.include?(key)
|
|
343
|
-
add quote_option(key, val, double:
|
|
330
|
+
add quote_option(key, val, double: qq.include?(key), merge: merge, sep: sep)
|
|
344
331
|
elsif p.include?(key)
|
|
345
|
-
if
|
|
346
|
-
add shell_option(key, val,
|
|
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,
|
|
340
|
+
add basic_option(key, val, merge: merge, sep: sep)
|
|
354
341
|
elsif merge
|
|
355
|
-
add basic_option(key, val,
|
|
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? { |
|
|
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,
|
|
383
|
-
args =
|
|
384
|
-
|
|
385
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
524
|
-
found.concat(
|
|
525
|
-
|
|
526
|
-
append(
|
|
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
|
-
|
|
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,
|
|
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
|
|
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
|
|
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
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
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
|