squared 0.4.7 → 0.4.8
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 +30 -0
- data/README.ruby.md +16 -0
- data/lib/squared/common/base.rb +1 -0
- data/lib/squared/common/class.rb +19 -1
- data/lib/squared/common/format.rb +25 -21
- data/lib/squared/common/prompt.rb +39 -1
- data/lib/squared/common/shell.rb +12 -8
- data/lib/squared/common/system.rb +1 -1
- data/lib/squared/common/utils.rb +11 -10
- data/lib/squared/config.rb +1 -2
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +36 -20
- data/lib/squared/workspace/project/base.rb +125 -48
- data/lib/squared/workspace/project/docker.rb +64 -23
- data/lib/squared/workspace/project/git.rb +111 -65
- data/lib/squared/workspace/project/node.rb +22 -37
- data/lib/squared/workspace/project/python.rb +7 -7
- data/lib/squared/workspace/project/ruby.rb +227 -39
- data/lib/squared/workspace/project/support/class.rb +11 -9
- data/lib/squared/workspace/repo.rb +6 -8
- data/lib/squared/workspace/series.rb +6 -5
- data/lib/squared/workspace.rb +1 -8
- metadata +2 -2
@@ -4,7 +4,6 @@ require 'json'
|
|
4
4
|
require 'date'
|
5
5
|
require 'time'
|
6
6
|
require 'logger'
|
7
|
-
require 'digest'
|
8
7
|
|
9
8
|
module Squared
|
10
9
|
module Workspace
|
@@ -22,7 +21,8 @@ module Squared
|
|
22
21
|
BLK_SET = %i[run depend doc lint test copy clean].freeze
|
23
22
|
SEM_VER = /\b(\d+)(?:(\.)(\d+))?(?:(\.)(\d+)(\S+)?)?\b/.freeze
|
24
23
|
URI_SCHEME = %r{^([a-z][a-z\d+-.]*)://[^@:\[\]\\^<>|\s]}i.freeze
|
25
|
-
|
24
|
+
TASK_METADATA = Rake::TaskManager.record_task_metadata
|
25
|
+
private_constant :VAR_SET, :BLK_SET, :SEM_VER, :URI_SCHEME, :TASK_METADATA
|
26
26
|
|
27
27
|
class << self
|
28
28
|
def populate(*); end
|
@@ -47,7 +47,9 @@ module Squared
|
|
47
47
|
@ref ||= to_s.downcase.to_sym
|
48
48
|
end
|
49
49
|
|
50
|
-
def subtasks(val)
|
50
|
+
def subtasks(val = nil, &blk)
|
51
|
+
return @@tasks[val || ref].each(&blk) if block_given?
|
52
|
+
|
51
53
|
@@tasks[ref] = val.freeze
|
52
54
|
end
|
53
55
|
|
@@ -61,12 +63,11 @@ module Squared
|
|
61
63
|
end
|
62
64
|
|
63
65
|
@@tasks = {}
|
64
|
-
@@task_desc = Rake::TaskManager.record_task_metadata
|
65
66
|
@@print_order = 0
|
66
67
|
|
67
68
|
subtasks({
|
68
69
|
'graph' => %i[run print].freeze,
|
69
|
-
'unpack' => %i[zip tar ext].freeze
|
70
|
+
'unpack' => %i[zip tar gem ext].freeze
|
70
71
|
})
|
71
72
|
|
72
73
|
attr_reader :name, :project, :workspace, :path, :theme, :exception, :pipe, :verbose,
|
@@ -97,7 +98,7 @@ module Squared
|
|
97
98
|
@exception = env_bool(kwargs[:exception], workspace.exception, strict: true)
|
98
99
|
@pipe = env_pipe(kwargs[:pipe], workspace.pipe, strict: true)
|
99
100
|
@verbose = case verbose
|
100
|
-
when
|
101
|
+
when NilClass
|
101
102
|
workspace.verbose
|
102
103
|
when String
|
103
104
|
env_bool(verbose, workspace.verbose, strict: true, index: true)
|
@@ -267,7 +268,7 @@ module Squared
|
|
267
268
|
return unless ref?(Base.ref)
|
268
269
|
|
269
270
|
namespace name do
|
270
|
-
|
271
|
+
Base.subtasks do |action, flags|
|
271
272
|
next if @pass.include?(action)
|
272
273
|
|
273
274
|
namespace action do
|
@@ -300,17 +301,21 @@ module Squared
|
|
300
301
|
end
|
301
302
|
end
|
302
303
|
when 'unpack'
|
303
|
-
format_desc(action, flag, 'tag/url,dir,digest?,f
|
304
|
+
format_desc(action, flag, 'tag/url,dir,digest?,f|force?', before: flag == :ext ? 'ext' : nil)
|
304
305
|
params = %i[tag dir digest force]
|
305
306
|
params.unshift(:ext) if flag == :ext
|
306
307
|
task flag, params do |_, args|
|
307
|
-
ext = param_guard(action, flag, args: args, key: :ext)
|
308
|
+
ext = flag == :ext ? param_guard(action, flag, args: args, key: :ext) : flag.to_s
|
308
309
|
tag = param_guard(action, flag, args: args, key: :tag)
|
309
310
|
dir = param_guard(action, flag, args: args, key: :dir)
|
310
311
|
unless tag.match?(URI_SCHEME)
|
311
|
-
|
312
|
-
|
313
|
-
|
312
|
+
if flag == :gem
|
313
|
+
tag = "https://rubygems.org/downloads/#{File.basename(tag, '.gem')}.gem"
|
314
|
+
elsif @release
|
315
|
+
tag = "%s.#{ext}" % [@release.include?('??') ? @release.sub('??', tag) : @release + tag]
|
316
|
+
else
|
317
|
+
raise_error("no base uri: #{tag}", hint: ext)
|
318
|
+
end
|
314
319
|
end
|
315
320
|
case (digest = args.digest)
|
316
321
|
when 'f', 'force'
|
@@ -319,7 +324,7 @@ module Squared
|
|
319
324
|
else
|
320
325
|
force = args.fetch(:force, false)
|
321
326
|
end
|
322
|
-
unpack(basepath(dir), uri: tag, digest: digest, ext: ext
|
327
|
+
unpack(basepath(dir), uri: tag, digest: digest, ext: ext, force: force)
|
323
328
|
end
|
324
329
|
end
|
325
330
|
end
|
@@ -351,15 +356,15 @@ module Squared
|
|
351
356
|
end
|
352
357
|
end
|
353
358
|
if path.is_a?(String) && (seg = path[%r{^(.+)[\\/]\*+$}, 1])
|
354
|
-
return self unless checkdir.(path = basepath(seg))
|
359
|
+
return self unless checkdir.call(path = basepath(seg))
|
355
360
|
|
356
|
-
path = path.children.select { |val| checkdir.(val) }
|
361
|
+
path = path.children.select { |val| checkdir.call(val) }
|
357
362
|
end
|
358
363
|
if path.is_a?(Array)
|
359
364
|
name = @name if name == true
|
360
365
|
path.each { |val| add(val, name && task_join(name, File.basename(val)), **kwargs, &blk) }
|
361
366
|
return self
|
362
|
-
elsif !projectpath?(path = basepath(path)) || !checkdir.(path)
|
367
|
+
elsif !projectpath?(path = basepath(path)) || !checkdir.call(path)
|
363
368
|
return self
|
364
369
|
elsif name.is_a?(Symbol)
|
365
370
|
name = name.to_s
|
@@ -405,10 +410,17 @@ module Squared
|
|
405
410
|
args = @output
|
406
411
|
banner = verbosetype > 1 if task_invoked?('build', 'build:sync', 'default')
|
407
412
|
end
|
413
|
+
if args.first.is_a?(Struct)
|
414
|
+
f, blk = args.first.to_a
|
415
|
+
args[0] = instance_eval(&blk) || f
|
416
|
+
return unless args[0]
|
417
|
+
end
|
408
418
|
if args.all? { |val| val.is_a?(Array) }
|
409
419
|
cmd = []
|
410
420
|
var = {}
|
411
421
|
args.each do |val|
|
422
|
+
next instance_exec(*val[1..-1], &val[0]) if val.first.is_a?(Proc)
|
423
|
+
|
412
424
|
a, b, c, d, e = val
|
413
425
|
case b
|
414
426
|
when Hash
|
@@ -479,11 +491,18 @@ module Squared
|
|
479
491
|
run_b(@copy, sync: sync, from: :copy)
|
480
492
|
end
|
481
493
|
|
482
|
-
def clean(
|
494
|
+
def clean(*args, sync: invoked_sync?('clean'), pass: false, **kwargs)
|
483
495
|
return unless @clean
|
484
496
|
|
485
|
-
on :first, :clean
|
497
|
+
on :first, :clean unless pass
|
486
498
|
case @clean
|
499
|
+
when Struct
|
500
|
+
if (any = instance_eval(&@clean.block) || @clean.run)
|
501
|
+
temp = @clean
|
502
|
+
@clean = any
|
503
|
+
clean(*args, sync: sync, pass: true, **kwargs)
|
504
|
+
@clean = temp
|
505
|
+
end
|
487
506
|
when String
|
488
507
|
run_s(@clean, sync: sync)
|
489
508
|
when Hash
|
@@ -518,7 +537,7 @@ module Squared
|
|
518
537
|
run_b(@clean, sync: sync)
|
519
538
|
end
|
520
539
|
end
|
521
|
-
on :last, :clean
|
540
|
+
on :last, :clean unless pass
|
522
541
|
end
|
523
542
|
|
524
543
|
def graph(start = [], tasks = nil, sync: invoked_sync?('graph'), pass: [], out: nil)
|
@@ -561,8 +580,11 @@ module Squared
|
|
561
580
|
elsif !target.empty?
|
562
581
|
raise_error('directory not empty', hint: target) unless force || env('UNPACK_FORCE')
|
563
582
|
create = true
|
583
|
+
elsif !uri
|
584
|
+
raise_error('no download uri', hint: target)
|
564
585
|
end
|
565
586
|
if digest
|
587
|
+
require 'digest'
|
566
588
|
if (n = digest.index(':').to_i) > 0
|
567
589
|
size = digest[0, n].downcase
|
568
590
|
digest = digest[n + 1..-1]
|
@@ -616,13 +638,19 @@ module Squared
|
|
616
638
|
raise_error('no content', hint: url)
|
617
639
|
end
|
618
640
|
end
|
619
|
-
ext ||= URI.parse(uri).path[/\.(\w+)(\?|$)/i, 1]
|
620
|
-
|
621
|
-
|
641
|
+
raise_error('no content type', hint: uri) unless ext ||= URI.parse(uri).path[/\.(\w+)(\?|$)/i, 1]
|
642
|
+
ext = ext.downcase
|
643
|
+
if (val = env("#{%w[zip 7z gem].include?(ext) ? ext.upcase : 'TAR'}_DEPTH", ignore: false))
|
644
|
+
depth = val.to_i
|
622
645
|
end
|
623
646
|
begin
|
624
|
-
|
625
|
-
|
647
|
+
if ext == 'gem'
|
648
|
+
dir = Dir.mktmpdir
|
649
|
+
file = File.new(File.join(dir, File.basename(uri)), 'w')
|
650
|
+
else
|
651
|
+
require 'tempfile'
|
652
|
+
file = Tempfile.new("#{name}-")
|
653
|
+
end
|
626
654
|
file.write(data)
|
627
655
|
file.close
|
628
656
|
if create
|
@@ -630,7 +658,7 @@ module Squared
|
|
630
658
|
target.rmtree
|
631
659
|
target.mkpath
|
632
660
|
end
|
633
|
-
case ext
|
661
|
+
case ext
|
634
662
|
when 'zip', 'aar'
|
635
663
|
session 'unzip', shell_quote(file.path), quote_option('d', target)
|
636
664
|
when 'tar', 'tgz', 'tar.gz', 'tar.xz', 'gz', 'xz'
|
@@ -645,6 +673,9 @@ module Squared
|
|
645
673
|
depth = 0
|
646
674
|
when '7z'
|
647
675
|
session '7z', 'x', shell_quote(file.path), "-o#{shell_quote(target)}"
|
676
|
+
when 'gem'
|
677
|
+
session 'gem', 'unpack', shell_quote(file.path), quote_option('target', target)
|
678
|
+
depth = 0 unless val
|
648
679
|
else
|
649
680
|
raise_error("unsupported format: #{ext}", hint: uri)
|
650
681
|
end
|
@@ -653,15 +684,22 @@ module Squared
|
|
653
684
|
entry = target.children.first
|
654
685
|
break unless entry.directory?
|
655
686
|
|
656
|
-
|
657
|
-
|
658
|
-
|
687
|
+
i = 0
|
688
|
+
while (dest = target.join("#{File.basename(file.path)}-#{i}")).exist?
|
689
|
+
i += 1
|
690
|
+
end
|
691
|
+
FileUtils.mv(entry, dest)
|
692
|
+
dest.children.each { |child| FileUtils.mv(child, target) }
|
659
693
|
dest.rmdir
|
660
694
|
target = entry
|
661
695
|
depth -= 1
|
662
696
|
end
|
663
697
|
ensure
|
664
|
-
|
698
|
+
if dir
|
699
|
+
remove_entry dir
|
700
|
+
elsif file
|
701
|
+
file.unlink
|
702
|
+
end
|
665
703
|
end
|
666
704
|
end
|
667
705
|
|
@@ -721,7 +759,7 @@ module Squared
|
|
721
759
|
@parent = val if (val = val.first).is_a?(Project::Base)
|
722
760
|
when :graph
|
723
761
|
@graph = case val.first
|
724
|
-
when
|
762
|
+
when NilClass, FalseClass
|
725
763
|
nil
|
726
764
|
else
|
727
765
|
val.flatten.map!(&:to_s).freeze
|
@@ -924,7 +962,13 @@ module Squared
|
|
924
962
|
|
925
963
|
def run_b(obj, from: nil, sync: true)
|
926
964
|
case obj
|
927
|
-
when
|
965
|
+
when Struct
|
966
|
+
if (any = instance_eval(&obj.block) || obj.run)
|
967
|
+
run_b(any, from: from, sync: sync)
|
968
|
+
end
|
969
|
+
when Proc
|
970
|
+
instance_eval(&obj)
|
971
|
+
when Method
|
928
972
|
obj.call
|
929
973
|
else
|
930
974
|
if series?(obj)
|
@@ -953,14 +997,14 @@ module Squared
|
|
953
997
|
end
|
954
998
|
start = target.name
|
955
999
|
if depth == 0
|
956
|
-
items = check.(dedupe.(start))
|
1000
|
+
items = check.call(dedupe.call(start))
|
957
1001
|
single = items.size == 1
|
958
1002
|
else
|
959
|
-
items = check.(data[start])
|
1003
|
+
items = check.call(data[start])
|
960
1004
|
end
|
961
1005
|
if out
|
962
1006
|
a, b, c, d, e = ARG[:GRAPH]
|
963
|
-
f = tag.(target)
|
1007
|
+
f = tag.call(target)
|
964
1008
|
out << case depth
|
965
1009
|
when 0
|
966
1010
|
f
|
@@ -977,15 +1021,15 @@ module Squared
|
|
977
1021
|
items.each_with_index do |proj, i|
|
978
1022
|
next if done.include?(proj)
|
979
1023
|
|
980
|
-
t = dedupe.(proj.name)
|
1024
|
+
t = dedupe.call(proj.name)
|
981
1025
|
j = if out
|
982
|
-
if i == items.size - 1 || check.(post = items[i + 1..-1]).empty?
|
1026
|
+
if i == items.size - 1 || check.call(post = items[i + 1..-1]).empty?
|
983
1027
|
true
|
984
1028
|
elsif !t.empty? && depth > 0
|
985
1029
|
post.reject { |pr| t.include?(pr) }.empty?
|
986
1030
|
end
|
987
1031
|
end
|
988
|
-
unless start == proj.name || (none = check.(t).empty?)
|
1032
|
+
unless start == proj.name || (none = check.call(t).empty?)
|
989
1033
|
graph_branch(proj, data, tasks, out, sync: sync, pass: pass, done: done, depth: depth.succ,
|
990
1034
|
single: single, last: j == true, context: target)
|
991
1035
|
end
|
@@ -1011,7 +1055,7 @@ module Squared
|
|
1011
1055
|
elsif none
|
1012
1056
|
a, b, c, d = ARG[:GRAPH]
|
1013
1057
|
out << if depth == 0
|
1014
|
-
"#{i == items.size - 1 ? d : c}#{b * 4} #{tag.(proj)}"
|
1058
|
+
"#{i == items.size - 1 ? d : c}#{b * 4} #{tag.call(proj)}"
|
1015
1059
|
else
|
1016
1060
|
s = ''.dup
|
1017
1061
|
k = 0
|
@@ -1021,7 +1065,7 @@ module Squared
|
|
1021
1065
|
s += "#{indent || (last && data[final].last == context) ? ' ' : a} "
|
1022
1066
|
k += 1
|
1023
1067
|
end
|
1024
|
-
s + "#{j ? d : c}#{b * 3} #{tag.(proj)}"
|
1068
|
+
s + "#{j ? d : c}#{b * 3} #{tag.call(proj)}"
|
1025
1069
|
end
|
1026
1070
|
end
|
1027
1071
|
done << proj
|
@@ -1172,7 +1216,7 @@ module Squared
|
|
1172
1216
|
end
|
1173
1217
|
|
1174
1218
|
def format_desc(action, flag, opts = nil, **kwargs)
|
1175
|
-
return unless
|
1219
|
+
return unless TASK_METADATA
|
1176
1220
|
|
1177
1221
|
ret = [@desc, action]
|
1178
1222
|
ret << flag if flag
|
@@ -1232,7 +1276,7 @@ module Squared
|
|
1232
1276
|
items.each_with_index do |val, i|
|
1233
1277
|
next unless reg.empty? || reg.any? { |pat| val[0].match?(pat) }
|
1234
1278
|
|
1235
|
-
out << "#{i.succ.to_s.rjust(pad)}. #{each ? each.(val) : val[0]}"
|
1279
|
+
out << "#{i.succ.to_s.rjust(pad)}. #{each ? each.call(val) : val[0]}"
|
1236
1280
|
end
|
1237
1281
|
end
|
1238
1282
|
sub = [headerstyle]
|
@@ -1287,7 +1331,7 @@ module Squared
|
|
1287
1331
|
append_repeat(key, val, target: target)
|
1288
1332
|
when Numeric
|
1289
1333
|
target << basic_option(key, val)
|
1290
|
-
when
|
1334
|
+
when FalseClass
|
1291
1335
|
target << shell_option(key).sub(/^--(?!no-)/, '--no-')
|
1292
1336
|
else
|
1293
1337
|
target << shell_option(key, val.is_a?(String) ? val : nil)
|
@@ -1441,6 +1485,39 @@ module Squared
|
|
1441
1485
|
args
|
1442
1486
|
end
|
1443
1487
|
|
1488
|
+
def confirm_outdated(pkg, ver, rev, lock: false)
|
1489
|
+
a = sub_style(case rev
|
1490
|
+
when 1
|
1491
|
+
'MAJOR'
|
1492
|
+
when 2
|
1493
|
+
'MINOR'
|
1494
|
+
else
|
1495
|
+
'PATCH'
|
1496
|
+
end, styles: theme[:header])
|
1497
|
+
b = sub_style("#{pkg} #{ver}", styles: theme[:inline])
|
1498
|
+
c, d = rev == 1 || lock ? ['y/N', 'N'] : ['Y/n', 'Y']
|
1499
|
+
e = lock ? " #{sub_style('(locked)', styles: color(:red))}" : ''
|
1500
|
+
confirm("Upgrade to #{a}? #{b + e} [#{c}] ", d, timeout: 60)
|
1501
|
+
end
|
1502
|
+
|
1503
|
+
def choice_index(msg, list, values: nil, multiple: false, accept: nil, trim: nil)
|
1504
|
+
puts if @@print_order > 0
|
1505
|
+
raise_error 'user cancelled' unless (ret = choice(msg, list, multiple: multiple))
|
1506
|
+
ret = multiple ? ret.map! { |val| val.sub(trim, '') } : ret.sub(trim, '') if trim
|
1507
|
+
exit 1 if accept && !confirm("#{accept} [#{ret.join(', ')}] [y/N] ", 'N', timeout: 60)
|
1508
|
+
if values
|
1509
|
+
ret = [ret]
|
1510
|
+
values.each do |val|
|
1511
|
+
val, req = val if val.is_a?(Array)
|
1512
|
+
val = Readline.readline("#{val} (#{req ? 'required' : 'optional'}): ", true).strip
|
1513
|
+
raise_error 'user cancelled' if req && val.empty?
|
1514
|
+
ret << (val.empty? ? nil : val)
|
1515
|
+
end
|
1516
|
+
end
|
1517
|
+
@@print_order += 1
|
1518
|
+
ret
|
1519
|
+
end
|
1520
|
+
|
1444
1521
|
def runenv
|
1445
1522
|
nil
|
1446
1523
|
end
|
@@ -1515,7 +1592,7 @@ module Squared
|
|
1515
1592
|
|
1516
1593
|
def verbosetype
|
1517
1594
|
case verbose
|
1518
|
-
when
|
1595
|
+
when TrueClasss
|
1519
1596
|
1
|
1520
1597
|
when Numeric
|
1521
1598
|
verbose.succ
|
@@ -1546,15 +1623,15 @@ module Squared
|
|
1546
1623
|
end
|
1547
1624
|
end
|
1548
1625
|
|
1549
|
-
def pwd_set(done = nil, pass: false, from: nil, dryrun: false
|
1626
|
+
def pwd_set(done = nil, pass: false, from: nil, dryrun: false)
|
1550
1627
|
pwd = Pathname.pwd
|
1551
1628
|
if block_given?
|
1552
1629
|
begin
|
1553
1630
|
if path == pwd || pass == true || (pass.is_a?(String) && semscan(pass).join >= RUBY_VERSION)
|
1554
|
-
ret =
|
1631
|
+
ret = yield
|
1555
1632
|
else
|
1556
1633
|
Dir.chdir(path)
|
1557
|
-
ret =
|
1634
|
+
ret = yield
|
1558
1635
|
Dir.chdir(pwd)
|
1559
1636
|
end
|
1560
1637
|
rescue StandardError => e
|
@@ -1605,13 +1682,13 @@ module Squared
|
|
1605
1682
|
@output = if cmd.all? { |data| data.is_a?(Hash) }
|
1606
1683
|
diso = false
|
1607
1684
|
dise = false
|
1608
|
-
cmd.map { |data| parse.(data) }
|
1685
|
+
cmd.map { |data| parse.call(data) }
|
1609
1686
|
else
|
1610
1687
|
cmd.dup
|
1611
1688
|
end
|
1612
1689
|
return
|
1613
1690
|
when Hash
|
1614
|
-
@output = parse.(data)
|
1691
|
+
@output = parse.call(data)
|
1615
1692
|
else
|
1616
1693
|
@output[0] = cmd
|
1617
1694
|
end
|
@@ -125,7 +125,7 @@ module Squared
|
|
125
125
|
return unless ref?(Docker.ref)
|
126
126
|
|
127
127
|
namespace name do
|
128
|
-
|
128
|
+
Docker.subtasks do |action, flags|
|
129
129
|
next if @pass.include?(action)
|
130
130
|
|
131
131
|
namespace action do
|
@@ -151,31 +151,38 @@ module Squared
|
|
151
151
|
when :build, :up
|
152
152
|
format_desc action, flag, 'opts*,service*'
|
153
153
|
task flag do |_, args|
|
154
|
-
|
154
|
+
compose! flag, args.to_a
|
155
155
|
end
|
156
156
|
when :exec, :run
|
157
157
|
format_desc action, flag, "service,command#{flag == :exec ? '' : '?'},args*,opts*"
|
158
158
|
task flag, [:service] do |_, args|
|
159
159
|
service = param_guard(action, flag, args: args, key: :service)
|
160
|
-
|
160
|
+
compose!(flag, args.extras, service: service)
|
161
161
|
end
|
162
162
|
end
|
163
163
|
when 'container'
|
164
164
|
case flag
|
165
165
|
when :exec, :commit
|
166
|
-
format_desc(action, flag,
|
166
|
+
format_desc(action, flag, flag == :exec ? 'id/name?,opts*,args+' : 'id/name,tag?,opts*')
|
167
167
|
task flag, [:id] do |_, args|
|
168
|
-
|
169
|
-
|
168
|
+
if flag == :exec && !args.id
|
169
|
+
choice_command flag
|
170
|
+
else
|
171
|
+
id = param_guard(action, flag, args: args, key: :id)
|
172
|
+
container(flag, args.extras, id: id)
|
173
|
+
end
|
170
174
|
end
|
171
175
|
when :run
|
172
|
-
format_desc action, flag, 'image
|
176
|
+
format_desc action, flag, 'image?,opts*,args*'
|
173
177
|
task flag, [:image] do |_, args|
|
174
|
-
|
175
|
-
|
178
|
+
if args.image
|
179
|
+
container(flag, args.extras, id: args.image)
|
180
|
+
else
|
181
|
+
choice_command flag
|
182
|
+
end
|
176
183
|
end
|
177
184
|
else
|
178
|
-
format_desc(action, flag, 'opts
|
185
|
+
format_desc(action, flag, 'opts*,id/name', after: flag == :update ? '+' : '*')
|
179
186
|
task flag do |_, args|
|
180
187
|
container flag, args.to_a
|
181
188
|
end
|
@@ -188,7 +195,7 @@ module Squared
|
|
188
195
|
tag = param_guard(action, flag, args: args, key: :tag)
|
189
196
|
image(flag, args.extras, id: tag)
|
190
197
|
end
|
191
|
-
|
198
|
+
when :list, :rm
|
192
199
|
format_desc(action, flag, flag == :rm ? 'id*,opts*' : 'opts*,args*')
|
193
200
|
task flag do |_, args|
|
194
201
|
image flag, args.to_a
|
@@ -197,8 +204,11 @@ module Squared
|
|
197
204
|
when 'network'
|
198
205
|
format_desc action, flag, 'target,opts*'
|
199
206
|
task flag, [:target] do |_, args|
|
200
|
-
target =
|
201
|
-
|
207
|
+
if (target = args.target)
|
208
|
+
network(flag, args.extras, target: target)
|
209
|
+
else
|
210
|
+
choice_command flag
|
211
|
+
end
|
202
212
|
end
|
203
213
|
end
|
204
214
|
end
|
@@ -251,13 +261,13 @@ module Squared
|
|
251
261
|
when :build
|
252
262
|
case @secrets
|
253
263
|
when String
|
254
|
-
quote_option('secret', @secrets, double: true)
|
264
|
+
ret << quote_option('secret', @secrets, double: true)
|
255
265
|
when Hash
|
256
266
|
append = lambda do |type|
|
257
267
|
as_a(@secrets[type]).each { |arg| ret << quote_option('secret', "type=#{type},#{arg}", double: true) }
|
258
268
|
end
|
259
|
-
append.(:file)
|
260
|
-
append.(:env)
|
269
|
+
append.call(:file)
|
270
|
+
append.call(:env)
|
261
271
|
else
|
262
272
|
as_a(@secrets).each { |arg| ret << quote_option('secret', arg) }
|
263
273
|
end
|
@@ -304,7 +314,7 @@ module Squared
|
|
304
314
|
run(from: :"buildx:#{flag}")
|
305
315
|
end
|
306
316
|
|
307
|
-
def
|
317
|
+
def compose!(flag, opts = [], service: nil)
|
308
318
|
cmd, opts = docker_session('compose', opts: opts)
|
309
319
|
op = OptionPartition.new(opts, OPT_DOCKER[:compose][:common], cmd, project: self)
|
310
320
|
append_file filetype unless op.arg?('f', 'file')
|
@@ -449,8 +459,7 @@ module Squared
|
|
449
459
|
op << id
|
450
460
|
else
|
451
461
|
if op.empty?
|
452
|
-
list_image(flag, docker_output('image
|
453
|
-
puts val
|
462
|
+
list_image(flag, docker_output('image ls -a'), from: from) do |val|
|
454
463
|
image(:rm, opts, sync: sync, id: val)
|
455
464
|
end
|
456
465
|
else
|
@@ -522,6 +531,9 @@ module Squared
|
|
522
531
|
end
|
523
532
|
|
524
533
|
def append_command(flag, val, list, target: @session, from: nil)
|
534
|
+
if (args = env('DOCKER_ARGS'))
|
535
|
+
list << args
|
536
|
+
end
|
525
537
|
case flag
|
526
538
|
when :run
|
527
539
|
unless session_arg?('name', target: target)
|
@@ -532,7 +544,7 @@ module Squared
|
|
532
544
|
raise_error('no command args', hint: from) if list.empty?
|
533
545
|
end
|
534
546
|
target << val << list.shift
|
535
|
-
target <<
|
547
|
+
target << list.join(' && ') unless list.empty?
|
536
548
|
end
|
537
549
|
|
538
550
|
def append_file(type, target: @session)
|
@@ -569,7 +581,7 @@ module Squared
|
|
569
581
|
end
|
570
582
|
end
|
571
583
|
|
572
|
-
def list_image(flag, cmd, hint: nil, from: nil, no: true
|
584
|
+
def list_image(flag, cmd, hint: nil, from: nil, no: true)
|
573
585
|
pwd_set do
|
574
586
|
found = false
|
575
587
|
index = 0
|
@@ -586,7 +598,7 @@ module Squared
|
|
586
598
|
id
|
587
599
|
end)
|
588
600
|
ee = data['Image'] || rt || aa
|
589
|
-
next unless ee.match?(pat) || aa.match?(pat)
|
601
|
+
next unless option('all') || ee.match?(pat) || aa.match?(pat)
|
590
602
|
|
591
603
|
bb = index.succ.to_s
|
592
604
|
cc = bb.size + 1
|
@@ -618,7 +630,7 @@ module Squared
|
|
618
630
|
next unless confirm("#{h + b}? [#{c}] ", d, timeout: 60)
|
619
631
|
|
620
632
|
puts if @@print_order == 0
|
621
|
-
|
633
|
+
yield id
|
622
634
|
end
|
623
635
|
puts log_message(Logger::INFO, 'none detected', subject: "#{name}:#{from}", hint: hint) unless found
|
624
636
|
end
|
@@ -646,6 +658,35 @@ module Squared
|
|
646
658
|
confirm("#{a} #{b}#{c ? " as #{c}" : ''}? [y/N] ", 'N', timeout: 60)
|
647
659
|
end
|
648
660
|
|
661
|
+
def choice_command(flag)
|
662
|
+
msg, cmd, index = case flag
|
663
|
+
when :run
|
664
|
+
['Choose an image', 'images -a', 2]
|
665
|
+
when :exec
|
666
|
+
['Choose a container', 'ps -a', 0]
|
667
|
+
else
|
668
|
+
['Choose a network', 'network ls', 0]
|
669
|
+
end
|
670
|
+
lines = `#{docker_output(cmd)}`.lines
|
671
|
+
header = lines.shift
|
672
|
+
if lines.empty?
|
673
|
+
puts log_message(Logger::INFO, 'none found', subject: name, hint: "docker #{cmd}")
|
674
|
+
else
|
675
|
+
puts " # #{header}"
|
676
|
+
case flag
|
677
|
+
when :run, :exec
|
678
|
+
values = [['Options', flag == :run], ['Command arguments', flag == :exec]]
|
679
|
+
cmd = flag.to_s
|
680
|
+
else
|
681
|
+
values = [['Options', false], ['Container', true]]
|
682
|
+
cmd = "network #{flag}"
|
683
|
+
end
|
684
|
+
out, opts, args = choice_index(msg, lines, values: values)
|
685
|
+
ret = run docker_output(cmd, opts, '--', out.split(/\s+/)[index], args)
|
686
|
+
puts 'Success' if ret && cmd.start_with?('network')
|
687
|
+
end
|
688
|
+
end
|
689
|
+
|
649
690
|
def filetype(val = dockerfile)
|
650
691
|
case File.extname(val)
|
651
692
|
when '.hcl', '.json'
|