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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +64 -0
- data/README.md +16 -12
- data/lib/squared/common/format.rb +3 -7
- data/lib/squared/common/utils.rb +5 -2
- data/lib/squared/config.rb +3 -3
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +3 -1
- data/lib/squared/workspace/project/base.rb +83 -89
- data/lib/squared/workspace/project/docker.rb +20 -19
- data/lib/squared/workspace/project/git.rb +20 -19
- data/lib/squared/workspace/project/node.rb +60 -52
- data/lib/squared/workspace/project/python.rb +20 -28
- data/lib/squared/workspace/project/ruby.rb +111 -111
- data/lib/squared/workspace/project/support/class.rb +198 -58
- data/lib/squared/workspace/series.rb +16 -18
- metadata +2 -2
@@ -10,15 +10,17 @@ module Squared
|
|
10
10
|
include Common::Shell
|
11
11
|
extend Forwardable
|
12
12
|
|
13
|
-
OPT_VALUE = /\A([^=]+)
|
14
|
-
|
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
|
-
|
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(
|
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, :
|
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?(
|
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)
|
187
|
-
|
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
|
-
|
226
|
-
|
227
|
-
|
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}(?:#{
|
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
|
-
|
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
|
-
|
255
|
-
list.reject
|
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
|
272
|
-
|
273
|
-
|
274
|
-
|
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
|
-
|
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
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
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
|
-
|
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 =
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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 |
|
214
|
-
next unless
|
209
|
+
tasks.flatten(1).each do |name|
|
210
|
+
next unless (task = invoked_get(name))
|
215
211
|
|
216
|
-
if
|
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?
|
219
|
+
already_invoked? multiple, val
|
226
220
|
end
|
227
221
|
|
228
222
|
def sync?(val = nil)
|
229
|
-
already_invoked?
|
223
|
+
already_invoked? sync, val
|
230
224
|
end
|
231
225
|
|
232
226
|
def parallel?(val = nil)
|
233
|
-
already_invoked?
|
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
|
-
|
244
|
-
|
245
|
-
|
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.
|
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.
|
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: []
|