squared 0.4.18 → 0.5.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 +62 -242
- data/README.md +1280 -647
- data/README.ruby.md +722 -0
- data/lib/squared/common/base.rb +8 -9
- data/lib/squared/common/format.rb +6 -14
- data/lib/squared/common/prompt.rb +38 -42
- data/lib/squared/common/shell.rb +10 -10
- data/lib/squared/common/system.rb +31 -35
- data/lib/squared/common/utils.rb +3 -28
- data/lib/squared/common.rb +2 -1
- data/lib/squared/config.rb +19 -19
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +55 -89
- data/lib/squared/workspace/project/base.rb +258 -399
- data/lib/squared/workspace/project/docker.rb +106 -120
- data/lib/squared/workspace/project/git.rb +330 -467
- data/lib/squared/workspace/project/node.rb +96 -141
- data/lib/squared/workspace/project/python.rb +73 -299
- data/lib/squared/workspace/project/ruby.rb +158 -237
- data/lib/squared/workspace/project/support/class.rb +81 -134
- data/lib/squared/workspace/project.rb +0 -10
- data/lib/squared/workspace/repo.rb +51 -79
- data/lib/squared/workspace/series.rb +16 -16
- data/lib/squared/workspace/support/data.rb +3 -2
- data/lib/squared/workspace/support.rb +0 -1
- data/lib/squared/workspace.rb +1 -1
- data/squared.gemspec +5 -5
- metadata +7 -8
- data/lib/squared/common/class.rb +0 -110
- data/lib/squared/workspace/support/base.rb +0 -17
@@ -21,8 +21,7 @@ module Squared
|
|
21
21
|
compose: {
|
22
22
|
common: %w[all-resources compatibility dry-run ansi|b env-file=p f|file=p parallel=b profile=b progress=b
|
23
23
|
project-directory=p p|project-name=e].freeze,
|
24
|
-
build: %w[
|
25
|
-
ssh=qq].freeze,
|
24
|
+
build: %w[no-cache pull push with-dependencies q|quiet build-arg=qq builder=b m|memory=b ssh=qq].freeze,
|
26
25
|
exec: %w[dry-run privileged d|detach e|env=qq index=i T|no-TTY=b? user=e w|workdir=q].freeze,
|
27
26
|
run: %w[build dry-run no-deps quiet-pull remove-orphans rm P|service-ports use-aliases cap-add=b cap-drop=b
|
28
27
|
d|detach entrypoint=q e|env=qq i|interactive=b? l|label=q name=b T|no-TTY=b? p|publish=e pull=b
|
@@ -55,15 +54,15 @@ module Squared
|
|
55
54
|
commit: %w[a|author=q c|change=q m|message=q pause=b?].freeze,
|
56
55
|
inspect: %w[s|size f|format=q].freeze,
|
57
56
|
start: %w[a|attach i|interactive detach-keys=q].freeze,
|
58
|
-
stop: %w[s|signal=b t|time=i
|
59
|
-
restart: %w[s|signal=b t|time=i
|
57
|
+
stop: %w[s|signal=b t|time=i].freeze,
|
58
|
+
restart: %w[s|signal=b t|time=i].freeze,
|
60
59
|
kill: %w[s|signal=b].freeze,
|
61
60
|
stats: %w[no-trunc format|q].freeze
|
62
61
|
}.freeze,
|
63
62
|
image: {
|
64
63
|
list: %w[a|all digests no-trunc f|filter=q format=q].freeze,
|
65
64
|
push: %w[a|all-tags disable-content-trust=b? platform=b q|quiet].freeze,
|
66
|
-
rm: %w[f|force no-prune
|
65
|
+
rm: %w[f|force no-prune].freeze,
|
67
66
|
save: %w[o|output=p platform=b].freeze
|
68
67
|
}.freeze,
|
69
68
|
network: {
|
@@ -73,11 +72,8 @@ module Squared
|
|
73
72
|
}.freeze
|
74
73
|
VAL_DOCKER = {
|
75
74
|
run: {
|
76
|
-
|
77
|
-
|
78
|
-
volume: %w[volume-subpath volume-nocopy volume-opt].freeze,
|
79
|
-
tmpfs: %w[tmpfs-size tmpfs-mode].freeze,
|
80
|
-
image: %w[image-path].freeze
|
75
|
+
bind: %w[type source src destination dst target readonly ro bind-propagation].freeze,
|
76
|
+
tmpfs: %w[type destination dst target tmpfs-size tmpfs-mode].freeze
|
81
77
|
}.freeze
|
82
78
|
}.freeze
|
83
79
|
private_constant :COMPOSEFILE, :BAKEFILE, :OPT_DOCKER, :VAL_DOCKER
|
@@ -95,9 +91,8 @@ module Squared
|
|
95
91
|
end
|
96
92
|
|
97
93
|
subtasks({
|
98
|
-
'build' => %i[tag context].freeze,
|
94
|
+
'build' => %i[tag context bake].freeze,
|
99
95
|
'compose' => %i[build run exec up].freeze,
|
100
|
-
'bake' => %i[build check].freeze,
|
101
96
|
'image' => %i[list rm push tag save].freeze,
|
102
97
|
'container' => %i[run create exec update commit inspect diff start stop restart pause unpause top stats kill
|
103
98
|
rm].freeze,
|
@@ -116,6 +111,7 @@ module Squared
|
|
116
111
|
@mounts = mounts
|
117
112
|
@secrets = secrets
|
118
113
|
@registry = tagjoin registry, kwargs[:username]
|
114
|
+
@file = nil
|
119
115
|
initialize_ref Docker.ref
|
120
116
|
initialize_logger(**kwargs)
|
121
117
|
initialize_env(**kwargs)
|
@@ -128,11 +124,11 @@ module Squared
|
|
128
124
|
|
129
125
|
def populate(*, **)
|
130
126
|
super
|
131
|
-
return unless ref?(Docker.ref)
|
127
|
+
return unless ref?(Docker.ref)
|
132
128
|
|
133
129
|
namespace name do
|
134
130
|
Docker.subtasks do |action, flags|
|
135
|
-
next if
|
131
|
+
next if @pass.include?(action)
|
136
132
|
|
137
133
|
namespace action do
|
138
134
|
flags.each do |flag|
|
@@ -145,31 +141,18 @@ module Squared
|
|
145
141
|
param = param_guard(action, flag, args: args, key: flag)
|
146
142
|
buildx(:build, args.extras, "#{flag}": param)
|
147
143
|
end
|
148
|
-
|
149
|
-
when 'bake'
|
150
|
-
break unless bake?
|
151
|
-
|
152
|
-
case flag
|
153
|
-
when :build
|
144
|
+
when :bake
|
154
145
|
format_desc action, flag, ':?,opts*,target*,context?'
|
155
146
|
task flag do |_, args|
|
156
147
|
args = args.to_a
|
157
148
|
if args.first == ':'
|
158
149
|
choice_command :bake
|
159
150
|
else
|
160
|
-
buildx
|
151
|
+
buildx flag, args
|
161
152
|
end
|
162
153
|
end
|
163
|
-
when :check
|
164
|
-
format_desc action, flag, 'target'
|
165
|
-
task flag, [:target] do |_, args|
|
166
|
-
target = param_guard(action, flag, args: args, key: :target)
|
167
|
-
buildx :bake, ['allow=fs.read=*', 'call=check', target]
|
168
|
-
end
|
169
154
|
end
|
170
155
|
when 'compose'
|
171
|
-
break unless compose?
|
172
|
-
|
173
156
|
case flag
|
174
157
|
when :build, :up
|
175
158
|
format_desc action, flag, 'opts*,service*'
|
@@ -177,7 +160,7 @@ module Squared
|
|
177
160
|
compose! flag, args.to_a
|
178
161
|
end
|
179
162
|
when :exec, :run
|
180
|
-
format_desc action, flag, "service,command#{flag == :exec ? '' : '?'}
|
163
|
+
format_desc action, flag, "service,command#{flag == :exec ? '' : '?'},args*,opts*"
|
181
164
|
task flag, [:service] do |_, args|
|
182
165
|
service = param_guard(action, flag, args: args, key: :service)
|
183
166
|
compose!(flag, args.extras, service: service)
|
@@ -215,8 +198,8 @@ module Squared
|
|
215
198
|
when :push
|
216
199
|
format_desc action, flag, 'tag,registry/username?,opts*'
|
217
200
|
task flag, [:tag] do |_, args|
|
218
|
-
|
219
|
-
image(flag, args.extras, id:
|
201
|
+
id = param_guard(action, flag, args: args, key: :tag)
|
202
|
+
image(flag, args.extras, id: id)
|
220
203
|
end
|
221
204
|
else
|
222
205
|
format_desc(action, flag, case flag
|
@@ -282,11 +265,10 @@ module Squared
|
|
282
265
|
when Enumerable
|
283
266
|
ret.merge(opts.to_a)
|
284
267
|
end
|
268
|
+
|
285
269
|
[args, flags].each_with_index do |target, index|
|
286
|
-
if target
|
287
|
-
ret
|
288
|
-
elsif (target = append_any(target, target: []))
|
289
|
-
ret.merge(target.map { |arg| index == 0 ? fill_option(arg) : quote_option('build-arg', arg) })
|
270
|
+
if (data = append_any(target, target: []))
|
271
|
+
ret.merge(data.map { |arg| index == 0 ? fill_option(arg) : quote_option('build-arg', arg) })
|
290
272
|
end
|
291
273
|
end
|
292
274
|
case from
|
@@ -296,12 +278,12 @@ module Squared
|
|
296
278
|
ret << quote_option('secret', @secrets, double: true)
|
297
279
|
when Hash
|
298
280
|
append = lambda do |type|
|
299
|
-
|
281
|
+
as_a(@secrets[type]).each { |arg| ret << quote_option('secret', "type=#{type},#{arg}", double: true) }
|
300
282
|
end
|
301
283
|
append.call(:file)
|
302
284
|
append.call(:env)
|
303
285
|
else
|
304
|
-
|
286
|
+
as_a(@secrets).each { |arg| ret << quote_option('secret', arg) }
|
305
287
|
end
|
306
288
|
if (val = option('tag', ignore: false))
|
307
289
|
append_tag val
|
@@ -310,8 +292,8 @@ module Squared
|
|
310
292
|
end
|
311
293
|
append_context
|
312
294
|
when :bake, :compose
|
313
|
-
|
314
|
-
ret.merge(split_escape(
|
295
|
+
option(from == :bake ? 'target' : 'service', ignore: false) do |a|
|
296
|
+
ret.merge(split_escape(a).map! { |b| shell_escape(b) })
|
315
297
|
end
|
316
298
|
end
|
317
299
|
ret
|
@@ -324,17 +306,17 @@ module Squared
|
|
324
306
|
op.parse(OPT_DOCKER[:buildx][flag == :bake ? :bake : :build] + OPT_DOCKER[:buildx][:shared])
|
325
307
|
case flag
|
326
308
|
when :build, :context
|
327
|
-
append_tag(tag || option('tag', ignore: false) ||
|
309
|
+
append_tag(tag || option('tag', ignore: false) || @tag)
|
328
310
|
append_context context
|
329
311
|
when :bake
|
330
312
|
unless op.empty?
|
331
313
|
args = op.dup
|
332
|
-
op.
|
314
|
+
op.extras.clear
|
333
315
|
if Dir.exist?(args.last)
|
334
316
|
if projectpath?(val = args.pop)
|
335
317
|
context = val
|
336
318
|
else
|
337
|
-
op.
|
319
|
+
op.extras << val
|
338
320
|
end
|
339
321
|
end
|
340
322
|
op.append(args, escape: true)
|
@@ -356,7 +338,7 @@ module Squared
|
|
356
338
|
when :build, :up
|
357
339
|
op.append(escape: true)
|
358
340
|
when :exec, :run
|
359
|
-
append_command
|
341
|
+
append_command(flag, service, op.extras, from: from)
|
360
342
|
end
|
361
343
|
run(from: from)
|
362
344
|
end
|
@@ -373,54 +355,44 @@ module Squared
|
|
373
355
|
when :run, :create, :exec
|
374
356
|
if rc && !op.arg?('mount')
|
375
357
|
run = VAL_DOCKER[:run]
|
376
|
-
|
377
|
-
|
378
|
-
|
358
|
+
both = run[:bind] + run[:tmpfs]
|
359
|
+
diff = run[:bind].reject { |val| run[:tmpfs].include?(val) }
|
360
|
+
delim = Regexp.new(",\\s*(?=#{both.join('|')})")
|
361
|
+
as_a(@mounts).each do |val|
|
379
362
|
args = []
|
380
|
-
|
363
|
+
tmpfs = true
|
381
364
|
val.split(delim).each do |opt|
|
382
365
|
k, v, q = split_option opt
|
366
|
+
next unless both.include?(k)
|
367
|
+
|
383
368
|
if k == 'type'
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
end
|
398
|
-
end
|
399
|
-
case k
|
400
|
-
when 'readonly', 'ro'
|
401
|
-
args << k
|
402
|
-
next
|
403
|
-
when 'source', 'src', 'destination', 'dst', 'target', 'volume-subpath', 'image-path'
|
404
|
-
v = path + v
|
405
|
-
v = shell_quote(v, option: false, force: false) if q == ''
|
406
|
-
end
|
407
|
-
args << "#{k}=#{q + v + q}"
|
408
|
-
elsif verbose
|
409
|
-
log_message(Logger::INFO, 'unrecognized option', subject: from, hint: k)
|
369
|
+
tmpfs = false if v == 'bind'
|
370
|
+
next
|
371
|
+
elsif diff.include?(k)
|
372
|
+
tmpfs = false
|
373
|
+
end
|
374
|
+
case k
|
375
|
+
when 'readonly', 'ro'
|
376
|
+
args << k
|
377
|
+
next
|
378
|
+
when 'source', 'src', 'destination', 'dst', 'target'
|
379
|
+
v = path + v
|
380
|
+
v = shell_quote(v, option: false, force: false) if q == ''
|
381
|
+
tmpfs = false if k[0] == 's'
|
410
382
|
end
|
383
|
+
args << "#{k}=#{q + v + q}"
|
411
384
|
end
|
412
|
-
|
413
|
-
cmd << "--mount type=#{type},#{args.join(',')}"
|
385
|
+
cmd << "--mount type=#{tmpfs ? 'tmpfs' : 'bind'},#{args.join(',')}"
|
414
386
|
end
|
415
387
|
end
|
416
|
-
append_command(flag, id || tagmain, op.extras)
|
388
|
+
append_command(flag, id || tagmain, op.extras, from: from)
|
417
389
|
when :update
|
418
|
-
raise_error('missing container', hint:
|
390
|
+
raise_error('missing container', hint: from) if op.empty?
|
419
391
|
op.append(escape: true)
|
420
392
|
when :commit
|
421
393
|
latest = op.shift || tagmain
|
422
394
|
cmd << id << latest
|
423
|
-
raise_error("unknown args: #{op.join(', ')}", hint:
|
395
|
+
raise_error("unknown args: #{op.join(', ')}", hint: from) unless op.empty?
|
424
396
|
return unless confirm_command(cmd.to_s, title: from, target: id, as: latest)
|
425
397
|
|
426
398
|
registry = option('registry') || @registry
|
@@ -463,7 +435,7 @@ module Squared
|
|
463
435
|
when :rm
|
464
436
|
status = %w[created exited dead]
|
465
437
|
end
|
466
|
-
ps = docker_output('ps -a', *status.map { |s|
|
438
|
+
ps = docker_output('ps -a', *status.map { |s| "--filter=\"status=#{s}\"" })
|
467
439
|
list_image(flag, ps, no: no, hint: "status: #{status.join(', ')}", from: from) do |img|
|
468
440
|
run(cmd.temp(img), from: from)
|
469
441
|
end
|
@@ -527,10 +499,10 @@ module Squared
|
|
527
499
|
when :push
|
528
500
|
id ||= option('tag', ignore: false) || tagmain
|
529
501
|
registry ||= op.shift || option('registry') || @registry
|
530
|
-
raise_error(id ? "unknown args: #{op.join(', ')}" : 'no id/tag given', hint:
|
531
|
-
raise_error('username/registry not provided', hint:
|
502
|
+
raise_error(id ? "unknown args: #{op.join(', ')}" : 'no id/tag given', hint: from) unless id && op.empty?
|
503
|
+
raise_error('username/registry not provided', hint: from) unless registry
|
532
504
|
registry.chomp!('/')
|
533
|
-
uri = shell_quote
|
505
|
+
uri = shell_quote "#{registry}/#{id}"
|
534
506
|
op << uri
|
535
507
|
img = docker_output 'image', 'tag', id, uri
|
536
508
|
return unless confirm_command(img.to_s, cmd.to_s, target: id, as: registry, title: from)
|
@@ -562,14 +534,6 @@ module Squared
|
|
562
534
|
super || dockerfile.exist?
|
563
535
|
end
|
564
536
|
|
565
|
-
def compose?(file = dockerfile)
|
566
|
-
COMPOSEFILE.include?(File.basename(file))
|
567
|
-
end
|
568
|
-
|
569
|
-
def bake?(file = dockerfile)
|
570
|
-
BAKEFILE.include?(File.basename(file))
|
571
|
-
end
|
572
|
-
|
573
537
|
def dockerfile(val = nil)
|
574
538
|
if val == 'Dockerfile'
|
575
539
|
@file = false
|
@@ -599,19 +563,22 @@ module Squared
|
|
599
563
|
session('docker', *cmd, main: false, options: false, **kwargs)
|
600
564
|
end
|
601
565
|
|
602
|
-
def append_command(flag, val, list, target: @session)
|
603
|
-
if
|
604
|
-
list << readline('Enter command [args]', force: true)
|
605
|
-
elsif (args = env('DOCKER_ARGS'))
|
566
|
+
def append_command(flag, val, list, target: @session, from: nil)
|
567
|
+
if (args = env('DOCKER_ARGS'))
|
606
568
|
list << args
|
607
569
|
end
|
608
570
|
case flag
|
609
571
|
when :run
|
610
572
|
unless session_arg?('name', target: target)
|
611
|
-
target << basic_option('name', dnsname("#{name}_%s" %
|
573
|
+
target << basic_option('name', dnsname("#{name}_%s" % if RUBY_VERSION >= '3.1'
|
574
|
+
require 'random/formatter'
|
575
|
+
Random.new.alphanumeric(6)
|
576
|
+
else
|
577
|
+
(0...6).map { rand(97..122).chr }.join
|
578
|
+
end))
|
612
579
|
end
|
613
580
|
when :exec
|
614
|
-
raise_error('no command args', hint:
|
581
|
+
raise_error('no command args', hint: from) if list.empty?
|
615
582
|
end
|
616
583
|
target << val << list.shift
|
617
584
|
target << list.join(' && ') unless list.empty?
|
@@ -620,7 +587,7 @@ module Squared
|
|
620
587
|
def append_file(type, target: @session)
|
621
588
|
return unless type == 2 || type == 4 || @file.is_a?(Array)
|
622
589
|
|
623
|
-
files =
|
590
|
+
files = as_a(@file).map { |val| quote_option('file', path + val) }
|
624
591
|
if target.is_a?(Set)
|
625
592
|
target.merge(files)
|
626
593
|
else
|
@@ -636,18 +603,20 @@ module Squared
|
|
636
603
|
end
|
637
604
|
|
638
605
|
def append_tag(val, target: @session)
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
606
|
+
case val
|
607
|
+
when String
|
608
|
+
val.split(',')
|
609
|
+
when Array
|
610
|
+
val
|
611
|
+
else
|
612
|
+
[]
|
613
|
+
end.yield_self do |list|
|
614
|
+
ver = option('version', target: target, ignore: false)
|
615
|
+
list.each do |s|
|
616
|
+
s = "#{s}:#{ver}" if ver && (!s.include?(':') || s.delete_suffix!(':latest'))
|
617
|
+
target << basic_option('tag', tagname(s))
|
618
|
+
end
|
619
|
+
target
|
651
620
|
end
|
652
621
|
end
|
653
622
|
|
@@ -657,7 +626,7 @@ module Squared
|
|
657
626
|
index = 0
|
658
627
|
all = option('all', prefix: 'docker')
|
659
628
|
y = from == :'image:rm' && option('y', prefix: 'docker')
|
660
|
-
pat =
|
629
|
+
pat = /^(?:#{dnsname(name)}|#{tagname(project)}|#{tagmain.split(':', 2).first})(?:[_.,:-]|$)/
|
661
630
|
IO.popen(session_done(cmd << '--format=json')).each do |line|
|
662
631
|
data = JSON.parse(line)
|
663
632
|
id = data['ID']
|
@@ -694,7 +663,7 @@ module Squared
|
|
694
663
|
cols.each do |key|
|
695
664
|
next if (key == 'Tag' && !dd) || (key == 'Size' && data[key] == '0B')
|
696
665
|
|
697
|
-
puts "#{g + f} #{key}: #{
|
666
|
+
puts "#{g + f} #{key}: #{as_a(data[key]).join(', ')}" unless data[key].to_s.empty?
|
698
667
|
end
|
699
668
|
w = 9 + flag.to_s.size + 4 + ee.size
|
700
669
|
puts g + sub_style(ARG[:BORDER][6] + (ARG[:BORDER][1] * w), styles: theme[:inline])
|
@@ -706,10 +675,14 @@ module Squared
|
|
706
675
|
end
|
707
676
|
yield id
|
708
677
|
end
|
709
|
-
puts log_message(Logger::INFO, 'none detected', subject: name, hint: hint
|
678
|
+
puts log_message(Logger::INFO, 'none detected', subject: "#{name}:#{from}", hint: hint) if found || y
|
710
679
|
end
|
711
680
|
rescue StandardError => e
|
712
|
-
|
681
|
+
log.error e
|
682
|
+
ret = on(:error, from, e)
|
683
|
+
raise if exception && ret != true
|
684
|
+
|
685
|
+
warn log_message(Logger::WARN, e, pass: true) if warning?
|
713
686
|
end
|
714
687
|
|
715
688
|
def confirm_command(*args, title: nil, target: nil, as: nil)
|
@@ -766,7 +739,7 @@ module Squared
|
|
766
739
|
cmd = docker_output ctx
|
767
740
|
case flag
|
768
741
|
when :tag
|
769
|
-
args = tagjoin @registry, tag
|
742
|
+
args = tagjoin @registry, @tag
|
770
743
|
when :save
|
771
744
|
opts = "#{opts}.tar" unless opts.end_with?('.tar')
|
772
745
|
cmd << quote_option('output', File.expand_path(opts))
|
@@ -777,9 +750,13 @@ module Squared
|
|
777
750
|
else
|
778
751
|
cmd << opts << '--'
|
779
752
|
end
|
780
|
-
cmd.merge(
|
753
|
+
cmd.merge(if out.is_a?(Array)
|
754
|
+
out.map! { |val| parse.call(val) }
|
755
|
+
else
|
756
|
+
[parse.call(out)]
|
757
|
+
end)
|
781
758
|
cmd << args
|
782
|
-
print_success if success?(run(cmd)) && ctx.
|
759
|
+
print_success if success?(run(cmd)) && ctx.start_with?(/(?:network|tag|save)/)
|
783
760
|
end
|
784
761
|
end
|
785
762
|
|
@@ -809,9 +786,10 @@ module Squared
|
|
809
786
|
|
810
787
|
def tagname(val)
|
811
788
|
val = val.split(':').map! { |s| charname(s.sub(/^\W+/, '')) }
|
812
|
-
|
813
|
-
|
814
|
-
|
789
|
+
val.join(':').yield_self do |s|
|
790
|
+
s = val.first if val.size > 1 && s.size > 128
|
791
|
+
s[0..127]
|
792
|
+
end
|
815
793
|
end
|
816
794
|
|
817
795
|
def dnsname(val)
|
@@ -825,6 +803,14 @@ module Squared
|
|
825
803
|
def tagmain
|
826
804
|
tag.is_a?(Array) ? tag.first : tag
|
827
805
|
end
|
806
|
+
|
807
|
+
def compose?(file = dockerfile)
|
808
|
+
COMPOSEFILE.include?(File.basename(file))
|
809
|
+
end
|
810
|
+
|
811
|
+
def bake?(file = dockerfile)
|
812
|
+
BAKEFILE.include?(File.basename(file))
|
813
|
+
end
|
828
814
|
end
|
829
815
|
|
830
816
|
Application.implement Docker
|