squared 0.5.3 → 0.5.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +159 -61
- data/README.md +662 -1273
- data/lib/squared/common/base.rb +1 -1
- data/lib/squared/common/format.rb +5 -3
- data/lib/squared/common/prompt.rb +1 -1
- data/lib/squared/common/shell.rb +13 -3
- data/lib/squared/common/system.rb +4 -4
- data/lib/squared/config.rb +8 -8
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +37 -14
- data/lib/squared/workspace/project/base.rb +143 -51
- data/lib/squared/workspace/project/docker.rb +68 -52
- data/lib/squared/workspace/project/git.rb +314 -208
- data/lib/squared/workspace/project/node.rb +42 -32
- data/lib/squared/workspace/project/python.rb +76 -30
- data/lib/squared/workspace/project/ruby.rb +121 -69
- data/lib/squared/workspace/project/support/class.rb +109 -15
- data/lib/squared/workspace/repo.rb +75 -48
- data/squared.gemspec +2 -2
- metadata +4 -5
- data/README.ruby.md +0 -724
@@ -19,10 +19,10 @@ module Squared
|
|
19
19
|
include ::Comparable
|
20
20
|
|
21
21
|
VAR_SET = %i[parent global script index envname desc dependfile dependindex theme archive env dev prod graph
|
22
|
-
pass only exclude].freeze
|
22
|
+
pass only exclude asdf].freeze
|
23
23
|
BLK_SET = %i[run depend doc lint test copy clean].freeze
|
24
|
-
SEM_VER = /\b(\d+)(?:(\.)(\d+))?(?:(\.)(\d+)(\S+)
|
25
|
-
URI_SCHEME = %r{
|
24
|
+
SEM_VER = /\b(\d+)(?:(\.)(\d+))?(?:(\.)(\d+))?[-.]?(\S+)?\b/.freeze
|
25
|
+
URI_SCHEME = %r{\A([a-z][a-z\d+-.]*)://[^@:\[\]\\^<>|\s]}i.freeze
|
26
26
|
TASK_METADATA = Rake::TaskManager.record_task_metadata
|
27
27
|
private_constant :VAR_SET, :BLK_SET, :SEM_VER, :URI_SCHEME, :TASK_METADATA
|
28
28
|
|
@@ -66,11 +66,17 @@ module Squared
|
|
66
66
|
|
67
67
|
@@tasks = {}
|
68
68
|
@@graph = { _: [] }
|
69
|
+
@@asdf = if File.exist?("#{Dir.home}/.asdf/asdf.sh")
|
70
|
+
[Pathname.new("#{Dir.home}/.asdf"), 15]
|
71
|
+
elsif ENV['ASDF_DATA_DIR']
|
72
|
+
[Pathname.new(ENV['ASDF_DATA_DIR']), 16]
|
73
|
+
end
|
69
74
|
@@print_order = 0
|
70
75
|
|
71
76
|
subtasks({
|
72
77
|
'graph' => %i[run print].freeze,
|
73
|
-
'unpack' => %i[zip tar gem ext].freeze
|
78
|
+
'unpack' => %i[zip tar gem ext].freeze,
|
79
|
+
'asdf' => %i[set exec current]
|
74
80
|
})
|
75
81
|
|
76
82
|
attr_reader :name, :project, :workspace, :path, :theme, :group, :parent, :dependfile,
|
@@ -114,6 +120,7 @@ module Squared
|
|
114
120
|
only_set kwargs[:only]
|
115
121
|
exclude_set kwargs[:exclude]
|
116
122
|
archive_set kwargs[:archive]
|
123
|
+
asdf_set kwargs[:asdf]
|
117
124
|
theme_set common
|
118
125
|
initialize_ref Base.ref
|
119
126
|
end
|
@@ -213,7 +220,7 @@ module Squared
|
|
213
220
|
def initialize_env(dev: nil, prod: nil, **)
|
214
221
|
@dev = env_match('BUILD', dev, suffix: 'DEV', strict: true)
|
215
222
|
@prod = env_match('BUILD', prod, suffix: 'PROD', strict: true)
|
216
|
-
|
223
|
+
unless @output[2] == false || !(val = env('BUILD', suffix: 'ENV'))
|
217
224
|
@output[2] = parse_json(val, hint: "BUILD_#{@envname}_ENV") || @output[2]
|
218
225
|
end
|
219
226
|
unless @output[0] == false || @output[0].is_a?(Array)
|
@@ -318,7 +325,7 @@ module Squared
|
|
318
325
|
flags.each do |flag|
|
319
326
|
case action
|
320
327
|
when 'graph'
|
321
|
-
|
328
|
+
break unless graph?
|
322
329
|
|
323
330
|
format_desc action, flag, '(-)project*'
|
324
331
|
task flag do |_, args|
|
@@ -369,6 +376,32 @@ module Squared
|
|
369
376
|
end
|
370
377
|
unpack(path + dir, uri: tag, digest: digest, ext: ext, force: force)
|
371
378
|
end
|
379
|
+
when 'asdf'
|
380
|
+
break unless @asdf
|
381
|
+
|
382
|
+
case flag
|
383
|
+
when :set
|
384
|
+
format_desc action, flag, 'version,opts*=u|home,p|parent'
|
385
|
+
task flag, [:version] do |_, args|
|
386
|
+
args = if (version = args.version)
|
387
|
+
args.extras
|
388
|
+
else
|
389
|
+
version, opts = choice_index('Select a version',
|
390
|
+
@asdf[1].children.map(&:basename).push('latest'),
|
391
|
+
force: true, accept: [['Confirm?', false, true]],
|
392
|
+
values: ['Options'])
|
393
|
+
OptionPartition.strip(opts)
|
394
|
+
end
|
395
|
+
asdf(flag, args, version: version)
|
396
|
+
end
|
397
|
+
else
|
398
|
+
format_desc(action, flag, flag == :exec ? 'command' : nil)
|
399
|
+
task flag do |_, args|
|
400
|
+
args = args.to_a
|
401
|
+
args << readline('Enter command', force: true) if args.empty? && flag == :exec
|
402
|
+
asdf flag, args
|
403
|
+
end
|
404
|
+
end
|
372
405
|
end
|
373
406
|
end
|
374
407
|
end
|
@@ -451,13 +484,13 @@ module Squared
|
|
451
484
|
if args.first.is_a?(Struct)
|
452
485
|
f, blk = args.first.to_a
|
453
486
|
args[0] = instance_eval(&blk) || f
|
454
|
-
return unless args
|
487
|
+
return unless args.first
|
455
488
|
end
|
456
489
|
if args.all? { |val| val.is_a?(Array) }
|
457
490
|
cmd = []
|
458
491
|
var = {}
|
459
492
|
args.each do |val|
|
460
|
-
next instance_exec(*val[1..-1], &val
|
493
|
+
next instance_exec(*val[1..-1], &val.first) if val.first.is_a?(Proc)
|
461
494
|
|
462
495
|
a, b, c, d, e = val
|
463
496
|
case b
|
@@ -658,7 +691,7 @@ module Squared
|
|
658
691
|
when 128, 'sha512'
|
659
692
|
Digest::SHA512
|
660
693
|
else
|
661
|
-
raise_error
|
694
|
+
raise_error "invalid checksum: #{digest}"
|
662
695
|
end
|
663
696
|
end
|
664
697
|
if (val = env('HEADERS')) && (val = parse_json(val, hint: "HEADERS_#{@envname}"))
|
@@ -761,6 +794,33 @@ module Squared
|
|
761
794
|
end
|
762
795
|
end
|
763
796
|
|
797
|
+
def asdf(flag, opts = [], version: nil)
|
798
|
+
return unless @asdf
|
799
|
+
|
800
|
+
cmd = session 'asdf', flag
|
801
|
+
name = @asdf.first
|
802
|
+
legacy = @@asdf[1] == 15
|
803
|
+
case flag
|
804
|
+
when :set
|
805
|
+
u = has_value?(opts, %w[u home])
|
806
|
+
cmd << if legacy
|
807
|
+
cmd.delete(flag)
|
808
|
+
u ? 'global' : 'local'
|
809
|
+
elsif has_value?(opts, %w[p parent])
|
810
|
+
'--parent'
|
811
|
+
elsif u
|
812
|
+
'--home'
|
813
|
+
end
|
814
|
+
cmd << name << version
|
815
|
+
when :exec
|
816
|
+
cmd.merge(opts)
|
817
|
+
when :current
|
818
|
+
cmd << '--no-header' unless legacy
|
819
|
+
cmd << name
|
820
|
+
end
|
821
|
+
print_success if success?(run(from: :"asdf:#{flag}")) && flag == :set
|
822
|
+
end
|
823
|
+
|
764
824
|
def first(key, *args, **kwargs, &blk)
|
765
825
|
event(:first, key, *args, **kwargs, &blk)
|
766
826
|
end
|
@@ -836,6 +896,8 @@ module Squared
|
|
836
896
|
parent_set val
|
837
897
|
when :archive
|
838
898
|
archive_set val
|
899
|
+
when :asdf
|
900
|
+
asdf_set val
|
839
901
|
when :run
|
840
902
|
run_set(*args, **kwargs)
|
841
903
|
when :script
|
@@ -945,7 +1007,7 @@ module Squared
|
|
945
1007
|
def log
|
946
1008
|
return @log unless @log.is_a?(Array)
|
947
1009
|
|
948
|
-
@log = Logger.new(enabled? ? @log
|
1010
|
+
@log = Logger.new(enabled? ? @log.first : nil, **@log.last)
|
949
1011
|
end
|
950
1012
|
|
951
1013
|
def allref
|
@@ -986,20 +1048,18 @@ module Squared
|
|
986
1048
|
|
987
1049
|
private
|
988
1050
|
|
989
|
-
def puts(*args)
|
990
|
-
|
1051
|
+
def puts(*args, **kwargs)
|
1052
|
+
log_console(*args, pipe: kwargs[:pipe] || pipe)
|
991
1053
|
end
|
992
1054
|
|
993
1055
|
def run(cmd = @session, var = nil, exception: self.exception, sync: true, from: nil, banner: true, chdir: path,
|
994
|
-
interactive: nil, **)
|
1056
|
+
interactive: nil, hint: nil, **)
|
995
1057
|
unless cmd
|
996
1058
|
warn log_message(Logger::WARN, 'no command given', subject: project, hint: from || 'unknown', pass: true)
|
997
1059
|
return
|
998
1060
|
end
|
999
|
-
i = interactive && !(@session && option('y'))
|
1000
1061
|
cmd = cmd.target if cmd.is_a?(OptionPartition)
|
1001
|
-
|
1002
|
-
if i
|
1062
|
+
if interactive && (!@session || !option('y'))
|
1003
1063
|
title, y = case interactive
|
1004
1064
|
when Array
|
1005
1065
|
interactive
|
@@ -1008,8 +1068,9 @@ module Squared
|
|
1008
1068
|
else
|
1009
1069
|
['Run', 'Y']
|
1010
1070
|
end
|
1011
|
-
exit 1 unless confirm("#{title}? [#{sub_style(cmd, styles: theme[:inline])}]", y)
|
1071
|
+
exit 1 unless confirm("#{title}? [#{sub_style(cmd.to_s, styles: theme[:inline])}]", y)
|
1012
1072
|
end
|
1073
|
+
cmd = session_done cmd
|
1013
1074
|
log&.info cmd
|
1014
1075
|
on :first, from
|
1015
1076
|
begin
|
@@ -1017,7 +1078,7 @@ module Squared
|
|
1017
1078
|
log&.warn "ENV discarded: #{var}" if var
|
1018
1079
|
task_invoke(cmd, exception: exception, warning: warning?)
|
1019
1080
|
else
|
1020
|
-
print_item format_banner(cmd, banner: banner) if sync
|
1081
|
+
print_item format_banner(hint ? "#{cmd} (#{hint})" : cmd, banner: banner) if sync
|
1021
1082
|
if var != false && (pre = runenv)
|
1022
1083
|
case pre
|
1023
1084
|
when Hash
|
@@ -1226,12 +1287,12 @@ module Squared
|
|
1226
1287
|
end
|
1227
1288
|
|
1228
1289
|
def session(*cmd, prefix: cmd.first, main: true, path: true, options: true)
|
1229
|
-
prefix = stripext
|
1230
|
-
if path && (val =
|
1290
|
+
prefix = stripext prefix.to_s
|
1291
|
+
if path && (val = shell_bin(prefix))
|
1231
1292
|
cmd[0] = shell_quote(val, force: false)
|
1232
1293
|
end
|
1233
1294
|
ret = JoinSet.new(cmd.flatten(1))
|
1234
|
-
if options && (val = env("#{prefix}_OPTIONS"))
|
1295
|
+
if options && (val = env("#{prefix.upcase}_OPTIONS"))
|
1235
1296
|
split_escape(val).each { |opt| ret.last(fill_option(opt), /\A(--?[^ =]+)[ =].+\z/m) }
|
1236
1297
|
end
|
1237
1298
|
main ? @session = ret : ret
|
@@ -1256,7 +1317,7 @@ module Squared
|
|
1256
1317
|
def session_done(cmd)
|
1257
1318
|
return cmd unless cmd.respond_to?(:done)
|
1258
1319
|
|
1259
|
-
raise_error('no args added', hint: cmd.first
|
1320
|
+
raise_error('no args added', hint: cmd.first) unless cmd.size > 1
|
1260
1321
|
@session = nil if cmd == @session
|
1261
1322
|
cmd.done
|
1262
1323
|
end
|
@@ -1410,9 +1471,9 @@ module Squared
|
|
1410
1471
|
unless items.empty?
|
1411
1472
|
pad = items.size.to_s.size
|
1412
1473
|
items.each_with_index do |val, i|
|
1413
|
-
next unless
|
1474
|
+
next unless matchany?(val.first, reg)
|
1414
1475
|
|
1415
|
-
out << ('%*d. %s' % [pad, i.succ, each ? each.call(val) : val
|
1476
|
+
out << ('%*d. %s' % [pad, i.succ, each ? each.call(val) : val.first])
|
1416
1477
|
end
|
1417
1478
|
end
|
1418
1479
|
sub = [headerstyle]
|
@@ -1513,11 +1574,11 @@ module Squared
|
|
1513
1574
|
list.flatten.each do |opt|
|
1514
1575
|
next unless (val = option(opt, **kwargs))
|
1515
1576
|
|
1516
|
-
return target <<
|
1517
|
-
|
1518
|
-
|
1519
|
-
|
1520
|
-
|
1577
|
+
return target << if flag
|
1578
|
+
shell_option(opt, equals ? val : nil, quote: quote, escape: escape, force: force)
|
1579
|
+
else
|
1580
|
+
shell_quote val
|
1581
|
+
end
|
1521
1582
|
end
|
1522
1583
|
nil
|
1523
1584
|
end
|
@@ -1726,6 +1787,17 @@ module Squared
|
|
1726
1787
|
files.map { |val| val == '.' ? '.' : shell_quote(path + val) }
|
1727
1788
|
end
|
1728
1789
|
|
1790
|
+
def matchmap(list, prefix = nil)
|
1791
|
+
list.map do |val|
|
1792
|
+
if val.is_a?(Regexp)
|
1793
|
+
val
|
1794
|
+
else
|
1795
|
+
val = ".*#{val}" if prefix && !val.sub!(/\A(\^|\\A)/, '')
|
1796
|
+
Regexp.new("#{prefix}#{val == '*' ? '.+' : val}")
|
1797
|
+
end
|
1798
|
+
end
|
1799
|
+
end
|
1800
|
+
|
1729
1801
|
def semver(val)
|
1730
1802
|
return val if val[3]
|
1731
1803
|
|
@@ -1743,12 +1815,20 @@ module Squared
|
|
1743
1815
|
end
|
1744
1816
|
|
1745
1817
|
def semcmp(val, other)
|
1746
|
-
|
1747
|
-
|
1748
|
-
|
1749
|
-
return
|
1818
|
+
return 0 if val == other
|
1819
|
+
|
1820
|
+
a, b = [val, other].map! { |ver| ver.scan(SEM_VER) }
|
1821
|
+
return -1 if b.empty?
|
1822
|
+
return 1 if a.empty?
|
1750
1823
|
|
1751
|
-
a, b = [a, b].map!
|
1824
|
+
a, b = [a.first, b.first].map! do |c|
|
1825
|
+
begin
|
1826
|
+
d = Integer(c[5]).to_s
|
1827
|
+
rescue StandardError
|
1828
|
+
d = c[5] ? '-1' : '0'
|
1829
|
+
end
|
1830
|
+
[c[0], c[2], c[4] || '0', d]
|
1831
|
+
end
|
1752
1832
|
a.each_with_index do |c, index|
|
1753
1833
|
next if c == (d = b[index])
|
1754
1834
|
|
@@ -1757,6 +1837,10 @@ module Squared
|
|
1757
1837
|
0
|
1758
1838
|
end
|
1759
1839
|
|
1840
|
+
def semgte?(val, other)
|
1841
|
+
semcmp(val, other) != 1
|
1842
|
+
end
|
1843
|
+
|
1760
1844
|
def indexitem(val)
|
1761
1845
|
[$1.to_i, $2 && $2[1..-1]] if val =~ /\A[=^#{indexchar}](\d+)(:.+)?\z/
|
1762
1846
|
end
|
@@ -1800,7 +1884,7 @@ module Squared
|
|
1800
1884
|
def on(event, from, *args, **kwargs)
|
1801
1885
|
return unless from && @events.key?(event)
|
1802
1886
|
|
1803
|
-
@events[event][from]
|
1887
|
+
Array(@events[event][from]).each do |obj|
|
1804
1888
|
target, opts = if obj.is_a?(Array) && obj[1].is_a?(Hash)
|
1805
1889
|
[obj[0], kwargs.empty? ? obj[1] : obj[1].merge(kwargs)]
|
1806
1890
|
else
|
@@ -1826,25 +1910,22 @@ module Squared
|
|
1826
1910
|
print_error(err, pass: pass) unless ret
|
1827
1911
|
end
|
1828
1912
|
|
1829
|
-
def pwd_set(pass: false, from: nil)
|
1830
|
-
pass = semscan(pass).join <= RUBY_VERSION if pass.is_a?(String)
|
1913
|
+
def pwd_set(pass: false, dryrun: false, from: nil)
|
1831
1914
|
pwd = Dir.pwd
|
1832
|
-
if (path.to_s == pwd || pass == true) && (workspace.mri? || !workspace.windows?)
|
1833
|
-
|
1834
|
-
|
1835
|
-
|
1836
|
-
|
1837
|
-
Dir.chdir(pwd)
|
1838
|
-
end
|
1915
|
+
return yield if (path.to_s == pwd || pass == true) && (workspace.mri? || !workspace.windows?)
|
1916
|
+
|
1917
|
+
Dir.chdir path
|
1918
|
+
ret = yield
|
1919
|
+
Dir.chdir pwd
|
1839
1920
|
rescue StandardError => e
|
1840
|
-
on_error
|
1921
|
+
on_error(e, from, dryrun: dryrun)
|
1841
1922
|
else
|
1842
1923
|
ret
|
1843
1924
|
end
|
1844
1925
|
|
1845
1926
|
def run_set(cmd, val = nil, opts: nil, **)
|
1846
|
-
|
1847
|
-
|
1927
|
+
noopt = @output[1] == false && !@output[0].nil?
|
1928
|
+
noenv = @output[2] == false
|
1848
1929
|
parse = lambda do |data|
|
1849
1930
|
ret = []
|
1850
1931
|
if data[:command]
|
@@ -1864,8 +1945,8 @@ module Squared
|
|
1864
1945
|
case cmd
|
1865
1946
|
when Array
|
1866
1947
|
@output = if cmd.all? { |data| data.is_a?(Hash) }
|
1867
|
-
|
1868
|
-
|
1948
|
+
noopt = false
|
1949
|
+
noenv = false
|
1869
1950
|
cmd.map { |data| parse.call(data) }
|
1870
1951
|
else
|
1871
1952
|
cmd.dup
|
@@ -1876,14 +1957,14 @@ module Squared
|
|
1876
1957
|
else
|
1877
1958
|
@output[0] = cmd
|
1878
1959
|
end
|
1879
|
-
unless
|
1960
|
+
unless noopt
|
1880
1961
|
if opts == false
|
1881
1962
|
@output[1] = false
|
1882
1963
|
elsif opts && opts != true
|
1883
1964
|
@output[1] = opts
|
1884
1965
|
end
|
1885
1966
|
end
|
1886
|
-
return if
|
1967
|
+
return if noenv
|
1887
1968
|
|
1888
1969
|
if val.is_a?(Hash)
|
1889
1970
|
@output[2] = val
|
@@ -1939,6 +2020,13 @@ module Squared
|
|
1939
2020
|
end
|
1940
2021
|
end
|
1941
2022
|
|
2023
|
+
def asdf_set(val)
|
2024
|
+
@asdf = if @@asdf && val
|
2025
|
+
dir = @@asdf[0].join('installs', val)
|
2026
|
+
[val, dir] if dir.exist? && !dir.empty?
|
2027
|
+
end
|
2028
|
+
end
|
2029
|
+
|
1942
2030
|
def theme_set(common)
|
1943
2031
|
@theme = if !verbose
|
1944
2032
|
{}
|
@@ -1986,6 +2074,10 @@ module Squared
|
|
1986
2074
|
@only ? !@only.include?(key) : @pass.include?(key)
|
1987
2075
|
end
|
1988
2076
|
|
2077
|
+
def matchany?(val, list, empty: true)
|
2078
|
+
list.empty? ? empty : list.any? { |pat| val.match?(pat) }
|
2079
|
+
end
|
2080
|
+
|
1989
2081
|
def projectpath?(val)
|
1990
2082
|
Pathname.new(val).cleanpath.yield_self do |file|
|
1991
2083
|
file.absolute? ? file.to_s.start_with?(File.join(path, '')) : !file.to_s.start_with?(File.join('..', ''))
|
@@ -55,15 +55,15 @@ module Squared
|
|
55
55
|
commit: %w[a|author=q c|change=q m|message=q pause=b?].freeze,
|
56
56
|
inspect: %w[s|size f|format=q].freeze,
|
57
57
|
start: %w[a|attach i|interactive detach-keys=q].freeze,
|
58
|
-
stop: %w[s|signal=b t|time=i].freeze,
|
59
|
-
restart: %w[s|signal=b t|time=i].freeze,
|
58
|
+
stop: %w[s|signal=b t|time=i t|timeout=i].freeze,
|
59
|
+
restart: %w[s|signal=b t|time=i t|timeout=i].freeze,
|
60
60
|
kill: %w[s|signal=b].freeze,
|
61
61
|
stats: %w[no-trunc format|q].freeze
|
62
62
|
}.freeze,
|
63
63
|
image: {
|
64
64
|
list: %w[a|all digests no-trunc f|filter=q format=q].freeze,
|
65
65
|
push: %w[a|all-tags disable-content-trust=b? platform=b q|quiet].freeze,
|
66
|
-
rm: %w[f|force no-prune].freeze,
|
66
|
+
rm: %w[f|force no-prune platform=b].freeze,
|
67
67
|
save: %w[o|output=p platform=b].freeze
|
68
68
|
}.freeze,
|
69
69
|
network: {
|
@@ -73,8 +73,11 @@ module Squared
|
|
73
73
|
}.freeze
|
74
74
|
VAL_DOCKER = {
|
75
75
|
run: {
|
76
|
-
|
77
|
-
|
76
|
+
common: %w[source src destination dst target readonly ro].freeze,
|
77
|
+
bind: %w[bind-propagation].freeze,
|
78
|
+
volume: %w[volume-subpath volume-nocopy volume-opt].freeze,
|
79
|
+
tmpfs: %w[tmpfs-size tmpfs-mode].freeze,
|
80
|
+
image: %w[image-path].freeze
|
78
81
|
}.freeze
|
79
82
|
}.freeze
|
80
83
|
private_constant :COMPOSEFILE, :BAKEFILE, :OPT_DOCKER, :VAL_DOCKER
|
@@ -92,7 +95,7 @@ module Squared
|
|
92
95
|
end
|
93
96
|
|
94
97
|
subtasks({
|
95
|
-
'build' => %i[tag context
|
98
|
+
'build' => %i[tag context].freeze,
|
96
99
|
'compose' => %i[build run exec up].freeze,
|
97
100
|
'bake' => %i[build check].freeze,
|
98
101
|
'image' => %i[list rm push tag save].freeze,
|
@@ -125,7 +128,7 @@ module Squared
|
|
125
128
|
|
126
129
|
def populate(*, **)
|
127
130
|
super
|
128
|
-
return unless ref?(Docker.ref)
|
131
|
+
return unless ref?(Docker.ref) || @only
|
129
132
|
|
130
133
|
namespace name do
|
131
134
|
Docker.subtasks do |action, flags|
|
@@ -134,7 +137,7 @@ module Squared
|
|
134
137
|
namespace action do
|
135
138
|
flags.each do |flag|
|
136
139
|
case action
|
137
|
-
when 'build'
|
140
|
+
when 'build'
|
138
141
|
case flag
|
139
142
|
when :tag, :context
|
140
143
|
format_desc(action, flag, 'opts*', before: flag == :tag ? 'name' : 'dir')
|
@@ -142,9 +145,12 @@ module Squared
|
|
142
145
|
param = param_guard(action, flag, args: args, key: flag)
|
143
146
|
buildx(:build, args.extras, "#{flag}": param)
|
144
147
|
end
|
145
|
-
|
146
|
-
|
148
|
+
end
|
149
|
+
when 'bake'
|
150
|
+
break unless bake?
|
147
151
|
|
152
|
+
case flag
|
153
|
+
when :build
|
148
154
|
format_desc action, flag, ':?,opts*,target*,context?'
|
149
155
|
task flag do |_, args|
|
150
156
|
args = args.to_a
|
@@ -155,8 +161,6 @@ module Squared
|
|
155
161
|
end
|
156
162
|
end
|
157
163
|
when :check
|
158
|
-
next unless bake?
|
159
|
-
|
160
164
|
format_desc action, flag, 'target'
|
161
165
|
task flag, [:target] do |_, args|
|
162
166
|
target = param_guard(action, flag, args: args, key: :target)
|
@@ -164,6 +168,8 @@ module Squared
|
|
164
168
|
end
|
165
169
|
end
|
166
170
|
when 'compose'
|
171
|
+
break unless compose?
|
172
|
+
|
167
173
|
case flag
|
168
174
|
when :build, :up
|
169
175
|
format_desc action, flag, 'opts*,service*'
|
@@ -348,7 +354,7 @@ module Squared
|
|
348
354
|
when :build, :up
|
349
355
|
op.append(escape: true)
|
350
356
|
when :exec, :run
|
351
|
-
append_command
|
357
|
+
append_command flag, service, op.extras
|
352
358
|
end
|
353
359
|
run(from: from)
|
354
360
|
end
|
@@ -365,44 +371,54 @@ module Squared
|
|
365
371
|
when :run, :create, :exec
|
366
372
|
if rc && !op.arg?('mount')
|
367
373
|
run = VAL_DOCKER[:run]
|
368
|
-
|
369
|
-
|
370
|
-
delim = Regexp.new(",\\s*(?=#{both.join('|')})")
|
374
|
+
all = collect_hash VAL_DOCKER[:run]
|
375
|
+
delim = Regexp.new(",\\s*(?=#{all.join('|')})")
|
371
376
|
Array(@mounts).each do |val|
|
372
377
|
args = []
|
373
|
-
|
378
|
+
type = nil
|
374
379
|
val.split(delim).each do |opt|
|
375
380
|
k, v, q = split_option opt
|
376
|
-
next unless both.include?(k)
|
377
|
-
|
378
381
|
if k == 'type'
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
382
|
+
case v
|
383
|
+
when 'bind', 'volume', 'image', 'tmpfs'
|
384
|
+
type = v
|
385
|
+
else
|
386
|
+
raise_error("unknown type: #{v}", hint: flag)
|
387
|
+
end
|
388
|
+
elsif all.include?(k)
|
389
|
+
unless type
|
390
|
+
run.each_pair do |key, val|
|
391
|
+
if val.include?(k)
|
392
|
+
type = key.to_s unless key == :common
|
393
|
+
break
|
394
|
+
end
|
395
|
+
end
|
396
|
+
end
|
397
|
+
case k
|
398
|
+
when 'readonly', 'ro'
|
399
|
+
args << k
|
400
|
+
next
|
401
|
+
when 'source', 'src', 'destination', 'dst', 'target', 'volume-subpath', 'image-path'
|
402
|
+
v = path + v
|
403
|
+
v = shell_quote(v, option: false, force: false) if q == ''
|
404
|
+
end
|
405
|
+
args << "#{k}=#{q + v + q}"
|
406
|
+
elsif verbose
|
407
|
+
log_message(Logger::INFO, 'unrecognized option', subject: from, hint: k)
|
392
408
|
end
|
393
|
-
args << "#{k}=#{q + v + q}"
|
394
409
|
end
|
395
|
-
|
410
|
+
raise_error('missing type', hint: flag) unless type
|
411
|
+
cmd << "--mount type=#{type},#{args.join(',')}"
|
396
412
|
end
|
397
413
|
end
|
398
|
-
append_command(flag, id || tagmain, op.extras
|
414
|
+
append_command(flag, id || tagmain, op.extras)
|
399
415
|
when :update
|
400
|
-
raise_error('missing container', hint:
|
416
|
+
raise_error('missing container', hint: flag) if op.empty?
|
401
417
|
op.append(escape: true)
|
402
418
|
when :commit
|
403
419
|
latest = op.shift || tagmain
|
404
420
|
cmd << id << latest
|
405
|
-
raise_error("unknown args: #{op.join(', ')}", hint:
|
421
|
+
raise_error("unknown args: #{op.join(', ')}", hint: flag) unless op.empty?
|
406
422
|
return unless confirm_command(cmd.to_s, title: from, target: id, as: latest)
|
407
423
|
|
408
424
|
registry = option('registry') || @registry
|
@@ -445,7 +461,7 @@ module Squared
|
|
445
461
|
when :rm
|
446
462
|
status = %w[created exited dead]
|
447
463
|
end
|
448
|
-
ps = docker_output('ps -a', *status.map { |s|
|
464
|
+
ps = docker_output('ps -a', *status.map { |s| quote_option('filter', "status=#{s}") })
|
449
465
|
list_image(flag, ps, no: no, hint: "status: #{status.join(', ')}", from: from) do |img|
|
450
466
|
run(cmd.temp(img), from: from)
|
451
467
|
end
|
@@ -509,8 +525,8 @@ module Squared
|
|
509
525
|
when :push
|
510
526
|
id ||= option('tag', ignore: false) || tagmain
|
511
527
|
registry ||= op.shift || option('registry') || @registry
|
512
|
-
raise_error(id ? "unknown args: #{op.join(', ')}" : 'no id/tag given', hint:
|
513
|
-
raise_error('username/registry not provided', hint:
|
528
|
+
raise_error(id ? "unknown args: #{op.join(', ')}" : 'no id/tag given', hint: flag) unless id && op.empty?
|
529
|
+
raise_error('username/registry not provided', hint: flag) unless registry
|
514
530
|
registry.chomp!('/')
|
515
531
|
uri = shell_quote "#{registry}/#{id}"
|
516
532
|
op << uri
|
@@ -544,6 +560,14 @@ module Squared
|
|
544
560
|
super || dockerfile.exist?
|
545
561
|
end
|
546
562
|
|
563
|
+
def compose?(file = dockerfile)
|
564
|
+
COMPOSEFILE.include?(File.basename(file))
|
565
|
+
end
|
566
|
+
|
567
|
+
def bake?(file = dockerfile)
|
568
|
+
BAKEFILE.include?(File.basename(file))
|
569
|
+
end
|
570
|
+
|
547
571
|
def dockerfile(val = nil)
|
548
572
|
if val == 'Dockerfile'
|
549
573
|
@file = false
|
@@ -573,7 +597,7 @@ module Squared
|
|
573
597
|
session('docker', *cmd, main: false, options: false, **kwargs)
|
574
598
|
end
|
575
599
|
|
576
|
-
def append_command(flag, val, list, target: @session
|
600
|
+
def append_command(flag, val, list, target: @session)
|
577
601
|
if list.delete(':')
|
578
602
|
list << readline('Enter command [args]', force: true)
|
579
603
|
elsif (args = env('DOCKER_ARGS'))
|
@@ -585,7 +609,7 @@ module Squared
|
|
585
609
|
target << basic_option('name', dnsname("#{name}_%s" % rand_s(6)))
|
586
610
|
end
|
587
611
|
when :exec
|
588
|
-
raise_error('no command args', hint:
|
612
|
+
raise_error('no command args', hint: flag) if list.empty?
|
589
613
|
end
|
590
614
|
target << val << list.shift
|
591
615
|
target << list.join(' && ') unless list.empty?
|
@@ -633,7 +657,7 @@ module Squared
|
|
633
657
|
index = 0
|
634
658
|
all = option('all', prefix: 'docker')
|
635
659
|
y = from == :'image:rm' && option('y', prefix: 'docker')
|
636
|
-
pat =
|
660
|
+
pat = /\b(?:#{dnsname(name)}|#{tagname(project)}|#{tagmain.split(':', 2).first})\b/
|
637
661
|
IO.popen(session_done(cmd << '--format=json')).each do |line|
|
638
662
|
data = JSON.parse(line)
|
639
663
|
id = data['ID']
|
@@ -681,7 +705,7 @@ module Squared
|
|
681
705
|
end
|
682
706
|
yield id
|
683
707
|
end
|
684
|
-
puts log_message(Logger::INFO, 'none detected', subject:
|
708
|
+
puts log_message(Logger::INFO, 'none detected', subject: name, hint: hint || from) if !found && !y
|
685
709
|
end
|
686
710
|
rescue StandardError => e
|
687
711
|
on_error e, from
|
@@ -801,14 +825,6 @@ module Squared
|
|
801
825
|
def tagmain
|
802
826
|
tag.is_a?(Array) ? tag.first : tag
|
803
827
|
end
|
804
|
-
|
805
|
-
def compose?(file = dockerfile)
|
806
|
-
COMPOSEFILE.include?(File.basename(file))
|
807
|
-
end
|
808
|
-
|
809
|
-
def bake?(file = dockerfile)
|
810
|
-
BAKEFILE.include?(File.basename(file))
|
811
|
-
end
|
812
828
|
end
|
813
829
|
|
814
830
|
Application.implement Docker
|