squared 0.6.9 → 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 +74 -2
- data/README.md +239 -200
- data/lib/squared/common/format.rb +7 -10
- data/lib/squared/common/prompt.rb +23 -24
- data/lib/squared/common/shell.rb +16 -17
- data/lib/squared/common/system.rb +29 -20
- data/lib/squared/common/utils.rb +43 -54
- data/lib/squared/config.rb +17 -16
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +290 -175
- data/lib/squared/workspace/project/base.rb +542 -442
- data/lib/squared/workspace/project/docker.rb +151 -131
- data/lib/squared/workspace/project/git.rb +178 -144
- data/lib/squared/workspace/project/node.rb +89 -87
- data/lib/squared/workspace/project/python.rb +236 -139
- data/lib/squared/workspace/project/ruby.rb +395 -281
- data/lib/squared/workspace/project/support/class.rb +12 -6
- data/lib/squared/workspace/project/support/optionpartition.rb +58 -41
- data/lib/squared/workspace/project/support/utils.rb +68 -0
- data/lib/squared/workspace/project.rb +0 -7
- data/lib/squared/workspace/repo.rb +234 -169
- data/lib/squared/workspace/series.rb +91 -86
- data/lib/squared/workspace/support/base.rb +15 -1
- metadata +2 -1
|
@@ -33,7 +33,8 @@ module Squared
|
|
|
33
33
|
d|detach force-recreate menu no-build no-color no-deps no-log-prefix no-recreate no-start quiet-build
|
|
34
34
|
quiet-pull remove-orphans V|renew-anon-volumes timestamps wait w|watch y|yes attach=b
|
|
35
35
|
exit-code-from=b no-attach=b pull=b scale=i t|timeout=i wait-timeout=i].freeze,
|
|
36
|
-
down: %w[remove-orphans v|volumes rmi=b t|timeout=i].freeze
|
|
36
|
+
down: %w[remove-orphans v|volumes rmi=b t|timeout=i].freeze,
|
|
37
|
+
publish: %w[app resolve-image-digests with-env y|yes oci-version=b].freeze
|
|
37
38
|
}.freeze,
|
|
38
39
|
container: {
|
|
39
40
|
create: %w[init i|interactive no-healthcheck oom-kill-disable privileged P|publish-all q|quiet read-only
|
|
@@ -64,6 +65,7 @@ module Squared
|
|
|
64
65
|
}.freeze,
|
|
65
66
|
image: {
|
|
66
67
|
ls: %w[a|all digests no-trunc q|quiet tree f|filter=q format=q].freeze,
|
|
68
|
+
pull: %w[a|all-tags platform=q q|quiet].freeze,
|
|
67
69
|
push: %w[a|all-tags platform=q q|quiet].freeze,
|
|
68
70
|
rm: %w[f|force no-prune platform=q].freeze,
|
|
69
71
|
save: %w[o|output=p platform=q].freeze
|
|
@@ -107,9 +109,9 @@ module Squared
|
|
|
107
109
|
|
|
108
110
|
subtasks({
|
|
109
111
|
'build' => %i[tag context].freeze,
|
|
110
|
-
'compose' => %i[build create run exec up down service].freeze,
|
|
111
|
-
'bake' => %i[build check].freeze,
|
|
112
|
-
'image' => %i[ls rm push tag save].freeze,
|
|
112
|
+
'compose' => %i[build create publish run exec up down service].freeze,
|
|
113
|
+
'bake' => %i[build compose check].freeze,
|
|
114
|
+
'image' => %i[ls rm pull push tag save].freeze,
|
|
113
115
|
'container' => %i[run create exec update commit inspect diff start stop restart pause unpause top stats kill
|
|
114
116
|
rm].freeze,
|
|
115
117
|
'network' => %i[connect disconnect].freeze,
|
|
@@ -119,17 +121,19 @@ module Squared
|
|
|
119
121
|
attr_reader :context
|
|
120
122
|
attr_accessor :tag
|
|
121
123
|
|
|
122
|
-
def initialize(*,
|
|
124
|
+
def initialize(*, mounts: [], **kwargs)
|
|
123
125
|
super
|
|
124
|
-
|
|
126
|
+
self.global = nil
|
|
127
|
+
return unless dockerfile(kwargs[:file]).exist?
|
|
125
128
|
|
|
126
|
-
|
|
127
|
-
|
|
129
|
+
self.tag = kwargs[:tag] || tagname("#{@project}:#{@version || 'latest'}")
|
|
130
|
+
@context = kwargs[:context]
|
|
128
131
|
@mounts = mounts
|
|
129
|
-
@secrets = secrets
|
|
130
|
-
@registry = tagjoin registry, kwargs[:username]
|
|
132
|
+
@secrets = kwargs[:secrets]
|
|
133
|
+
@registry = tagjoin kwargs[:registry], kwargs[:username]
|
|
134
|
+
@oci = tagjoin kwargs[:oci], kwargs[:username]
|
|
131
135
|
initialize_ref Docker.ref
|
|
132
|
-
initialize_logger
|
|
136
|
+
initialize_logger kwargs[:log]
|
|
133
137
|
initialize_env(**kwargs)
|
|
134
138
|
@output[4] = merge_opts(kwargs[:args], @output[4]) if kwargs[:args]
|
|
135
139
|
end
|
|
@@ -163,25 +167,21 @@ module Squared
|
|
|
163
167
|
end
|
|
164
168
|
cmd << '-a' if has_value!(args, 'a', 'all') && command != 'network'
|
|
165
169
|
data = VAL_DOCKER[:ls][command.to_sym]
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
out.replace(choice_index('Select a column', data, multiple: true, attempts: 1))
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
cmd << quote_option('format', "table #{cols.map! { |val| "{{.#{val}}}" }.join("\t")}")
|
|
170
|
+
if has_value!(args, 's', 'standard')
|
|
171
|
+
cols = data.first(data.index('CreatedAt'))
|
|
172
|
+
else
|
|
173
|
+
cols = args.each_with_object([]) do |val, out|
|
|
174
|
+
if val =~ /^(\d+)$/
|
|
175
|
+
out << data[$1.to_i.pred]
|
|
176
|
+
elsif val =~ /^(\d+)(-|\.{2,3})(\d+)$/
|
|
177
|
+
j = $1.to_i.pred
|
|
178
|
+
k = $3.to_i - ($2 == '..' ? 2 : 1)
|
|
179
|
+
out.concat(data[j..k]) if k > j
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
cols = choice_index('Select a column', data, multiple: true, attempts: 1) if cols.empty?
|
|
183
|
+
end
|
|
184
|
+
cmd << quote_option('format', "table #{cols.map { |val| "{{.#{val}}}" }.join("\t")}")
|
|
185
185
|
run(cmd, banner: false, from: :ls)
|
|
186
186
|
end
|
|
187
187
|
end
|
|
@@ -199,14 +199,14 @@ module Squared
|
|
|
199
199
|
break unless bake?
|
|
200
200
|
|
|
201
201
|
case flag
|
|
202
|
-
when :build
|
|
203
|
-
format_desc action, flag, 'opts*,target*,context
|
|
202
|
+
when :build, :compose
|
|
203
|
+
format_desc action, flag, 'opts*,target*,context?|:'
|
|
204
204
|
task flag do |_, args|
|
|
205
205
|
args = args.to_a
|
|
206
206
|
if args.first == ':'
|
|
207
207
|
choice_command :bake
|
|
208
208
|
else
|
|
209
|
-
buildx
|
|
209
|
+
buildx(:bake, args, from: (:'buildx:bake' if flag == :compose))
|
|
210
210
|
end
|
|
211
211
|
end
|
|
212
212
|
when :check
|
|
@@ -239,6 +239,13 @@ module Squared
|
|
|
239
239
|
compose!(flag, [command], service: service.empty? || service)
|
|
240
240
|
end
|
|
241
241
|
end
|
|
242
|
+
when :publish
|
|
243
|
+
next unless @oci
|
|
244
|
+
|
|
245
|
+
format_desc action, flag, 'tag?,repository?,opts*'
|
|
246
|
+
task flag, [:tag] do |_, args|
|
|
247
|
+
compose! flag, args.to_a
|
|
248
|
+
end
|
|
242
249
|
else
|
|
243
250
|
format_desc action, flag, 'opts*,service*|:'
|
|
244
251
|
task flag do |_, args|
|
|
@@ -275,6 +282,13 @@ module Squared
|
|
|
275
282
|
when 'image'
|
|
276
283
|
case flag
|
|
277
284
|
when :push
|
|
285
|
+
next unless @registry
|
|
286
|
+
|
|
287
|
+
format_desc action, flag, 'tag?,registry/username?,opts*'
|
|
288
|
+
task flag, [:tag] do |_, args|
|
|
289
|
+
image flag, args.to_a
|
|
290
|
+
end
|
|
291
|
+
when :pull
|
|
278
292
|
format_desc action, flag, 'tag,registry/username?,opts*'
|
|
279
293
|
task flag, [:tag] do |_, args|
|
|
280
294
|
id = param_guard(action, flag, args: args, key: :tag)
|
|
@@ -349,7 +363,7 @@ module Squared
|
|
|
349
363
|
[args, flags].each_with_index do |item, i|
|
|
350
364
|
next unless item && (data = append_any(item, target: []))
|
|
351
365
|
|
|
352
|
-
ret.merge(data.map
|
|
366
|
+
ret.merge(data.map { |arg| i == 0 ? fill_option(arg) : quote_option('build-arg', arg) })
|
|
353
367
|
end
|
|
354
368
|
case from
|
|
355
369
|
when :run
|
|
@@ -357,13 +371,13 @@ module Squared
|
|
|
357
371
|
when String
|
|
358
372
|
ret << quote_option('secret', @secrets, double: true)
|
|
359
373
|
when Hash
|
|
360
|
-
append = lambda do |
|
|
361
|
-
Array(@secrets[
|
|
374
|
+
append = lambda do |key|
|
|
375
|
+
ret.merge(Array(@secrets[key]).map { |arg| quote_option('secret', "type=#{key},#{arg}", double: true) })
|
|
362
376
|
end
|
|
363
377
|
append.call(:file)
|
|
364
378
|
append.call(:env)
|
|
365
379
|
else
|
|
366
|
-
Array(@secrets).
|
|
380
|
+
ret.merge(Array(@secrets).map { |arg| quote_option('secret', arg) })
|
|
367
381
|
end
|
|
368
382
|
if (val = option('tag', ignore: false))
|
|
369
383
|
append_tag val
|
|
@@ -377,18 +391,18 @@ module Squared
|
|
|
377
391
|
ret
|
|
378
392
|
end
|
|
379
393
|
|
|
380
|
-
def buildx(flag, opts = [], tag: nil, context: nil)
|
|
394
|
+
def buildx(flag, opts = [], tag: nil, context: nil, from: nil)
|
|
381
395
|
cmd, opts = docker_session('buildx', opts: opts)
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
end
|
|
396
|
+
data = OPT_DOCKER[:buildx]
|
|
397
|
+
op = OptionPartition.new(opts, data[:common], cmd, project: self)
|
|
398
|
+
op.append(flag, quote: false)
|
|
399
|
+
.parse(data[flag == :bake ? :bake : :build] + data[:shared])
|
|
387
400
|
case flag
|
|
388
401
|
when :build, :context
|
|
389
402
|
append_tag(tag || option('tag', ignore: false) || self.tag)
|
|
390
403
|
append_context context
|
|
391
404
|
when :bake
|
|
405
|
+
append_file(0, index: 3) unless from || op.arg?('f', 'file') || !anypath?(*COMPOSEFILE)
|
|
392
406
|
unless op.empty?
|
|
393
407
|
args = op.dup
|
|
394
408
|
op.reset
|
|
@@ -404,11 +418,11 @@ module Squared
|
|
|
404
418
|
end
|
|
405
419
|
end
|
|
406
420
|
op.clear(pass: false)
|
|
407
|
-
run(from:
|
|
421
|
+
run(from: from || symjoin('buildx', flag))
|
|
408
422
|
end
|
|
409
423
|
|
|
410
|
-
def compose!(flag, opts = [], service: nil, multiple: false)
|
|
411
|
-
from =
|
|
424
|
+
def compose!(flag, opts = [], id: nil, service: nil, multiple: false)
|
|
425
|
+
from = symjoin 'compose', flag
|
|
412
426
|
if flag == :service
|
|
413
427
|
command = opts.first
|
|
414
428
|
if service == true
|
|
@@ -422,23 +436,31 @@ module Squared
|
|
|
422
436
|
else
|
|
423
437
|
cmd, opts = docker_session('compose', opts: opts)
|
|
424
438
|
op = OptionPartition.new(opts, OPT_DOCKER[:compose][:common], cmd, project: self)
|
|
425
|
-
append_file
|
|
439
|
+
append_file(filetype, force: flag == :publish) unless op.arg?('f', 'file')
|
|
426
440
|
op << flag
|
|
427
441
|
op.parse(OPT_DOCKER[:compose].fetch(flag, []))
|
|
428
|
-
if
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
end
|
|
435
|
-
end
|
|
436
|
-
if multiple
|
|
437
|
-
op.concat(service) if service
|
|
438
|
-
op.append(delim: true, escape: true, strip: /^:/)
|
|
442
|
+
if flag == :publish
|
|
443
|
+
id ||= option('tag', ignore: false) || op.shift || tagmain
|
|
444
|
+
registry ||= option('registry') || op.shift || @oci
|
|
445
|
+
emptyargs op, flag
|
|
446
|
+
op << shell_quote(tagjoin(registry, id))
|
|
447
|
+
return unless confirm_command(op.to_s, title: from, target: id)
|
|
439
448
|
else
|
|
440
|
-
|
|
441
|
-
|
|
449
|
+
if op.remove(':') || service == ':'
|
|
450
|
+
keys = Set.new
|
|
451
|
+
read_composefile('services', target: op.values_of('f', 'file')) { |data| keys.merge(data.keys) }
|
|
452
|
+
service = unless keys.empty?
|
|
453
|
+
choice_index('Add services', keys, multiple: multiple, force: !multiple,
|
|
454
|
+
attempts: multiple ? 1 : 3)
|
|
455
|
+
end
|
|
456
|
+
end
|
|
457
|
+
if multiple
|
|
458
|
+
op.concat(service) if service
|
|
459
|
+
op.append(delim: true, escape: true, strip: /^:/)
|
|
460
|
+
else
|
|
461
|
+
raise_error ArgumentError, 'no service was selected', hint: flag unless service
|
|
462
|
+
append_command(flag, service, op.extras, prompt: '::')
|
|
463
|
+
end
|
|
442
464
|
end
|
|
443
465
|
end
|
|
444
466
|
run(from: from)
|
|
@@ -446,35 +468,32 @@ module Squared
|
|
|
446
468
|
|
|
447
469
|
def container(flag, opts = [], id: nil)
|
|
448
470
|
cmd, opts = docker_session('container', flag, opts: opts)
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
end
|
|
456
|
-
from = :"container:#{flag}"
|
|
471
|
+
data = OPT_DOCKER[:container]
|
|
472
|
+
list = data.fetch(flag, [])
|
|
473
|
+
list += data[:create] if (rc = flag == :run)
|
|
474
|
+
list += data[:update] if rc ||= flag == :create
|
|
475
|
+
op = OptionPartition.new(opts, list, cmd, project: self, args: rc || flag == :exec)
|
|
476
|
+
from = symjoin 'container', flag
|
|
457
477
|
case flag
|
|
458
478
|
when :run, :create, :exec
|
|
459
479
|
if rc && !op.arg?('mount')
|
|
460
480
|
all = collect_hash VAL_DOCKER[:run]
|
|
461
481
|
delim = Regexp.new(",\\s*(?=#{all.join('|')})")
|
|
462
482
|
Array(@mounts).each do |val|
|
|
463
|
-
args = []
|
|
464
483
|
type = nil
|
|
465
|
-
val.split(delim).
|
|
466
|
-
k, v, q =
|
|
484
|
+
args = val.split(delim).each_with_object([]) do |opt, out|
|
|
485
|
+
k, v, q = OptionPartition.parse_option(opt)
|
|
467
486
|
if k == 'type'
|
|
468
487
|
case v
|
|
469
488
|
when 'bind', 'volume', 'image', 'tmpfs'
|
|
470
489
|
type = v
|
|
471
490
|
else
|
|
472
|
-
raise_error TypeError, "unknown: #{v}", hint: flag
|
|
491
|
+
raise_error TypeError, "unknown: #{v || "''"}", hint: flag
|
|
473
492
|
end
|
|
474
493
|
elsif all.include?(k)
|
|
475
494
|
unless type
|
|
476
|
-
VAL_DOCKER[:run].each_pair do |key,
|
|
477
|
-
next unless
|
|
495
|
+
VAL_DOCKER[:run].each_pair do |key, items|
|
|
496
|
+
next unless items.include?(k)
|
|
478
497
|
|
|
479
498
|
type = key.to_s unless key == :common
|
|
480
499
|
break
|
|
@@ -482,13 +501,14 @@ module Squared
|
|
|
482
501
|
end
|
|
483
502
|
case k
|
|
484
503
|
when 'readonly', 'ro'
|
|
485
|
-
|
|
504
|
+
out << k
|
|
486
505
|
next
|
|
487
506
|
when 'source', 'src', 'destination', 'dst', 'target', 'volume-subpath', 'image-path'
|
|
507
|
+
raise_error ArgumentError, "#{k}: no path value", hint: flag unless v
|
|
488
508
|
v = basepath v
|
|
489
509
|
v = shell_quote(v, option: false, force: false) if q == ''
|
|
490
510
|
end
|
|
491
|
-
|
|
511
|
+
out << "#{k}=#{q}#{v}#{q}"
|
|
492
512
|
elsif !silent?
|
|
493
513
|
log_message('unrecognized option', subject: from, hint: k)
|
|
494
514
|
end
|
|
@@ -514,7 +534,7 @@ module Squared
|
|
|
514
534
|
opts = []
|
|
515
535
|
append_option('platform', target: opts, equals: true)
|
|
516
536
|
opts << case option('disable-content-trust', ignore: false)
|
|
517
|
-
when '
|
|
537
|
+
when '0', 'false'
|
|
518
538
|
'--disable-content-trust=false'
|
|
519
539
|
else
|
|
520
540
|
'--disable-content-trust'
|
|
@@ -536,9 +556,9 @@ module Squared
|
|
|
536
556
|
def image(flag, opts = [], sync: true, id: nil, registry: nil)
|
|
537
557
|
cmd, opts = docker_session('image', flag, opts: opts)
|
|
538
558
|
op = OptionPartition.new(opts, OPT_DOCKER[:image].fetch(flag, []), cmd, project: self)
|
|
539
|
-
exception =
|
|
559
|
+
exception = exception?
|
|
540
560
|
banner = true
|
|
541
|
-
from =
|
|
561
|
+
from = symjoin 'image', flag
|
|
542
562
|
case flag
|
|
543
563
|
when :ls
|
|
544
564
|
if opts.size == op.size
|
|
@@ -565,9 +585,7 @@ module Squared
|
|
|
565
585
|
when :rm
|
|
566
586
|
unless id
|
|
567
587
|
if op.empty?
|
|
568
|
-
list_image(:rm, from: from)
|
|
569
|
-
image(:rm, opts, sync: sync, id: val)
|
|
570
|
-
end
|
|
588
|
+
list_image(:rm, from: from) { |val| image(:rm, opts, sync: sync, id: val) }
|
|
571
589
|
else
|
|
572
590
|
op.each { |val| run(cmd.temp(val), sync: sync, from: from) }
|
|
573
591
|
end
|
|
@@ -581,46 +599,46 @@ module Squared
|
|
|
581
599
|
when :tag, :save
|
|
582
600
|
list_image(flag, from: from) do |val|
|
|
583
601
|
op << val
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
602
|
+
next unless flag == :tag
|
|
603
|
+
|
|
604
|
+
op << tagname("#{project}:#{op.first}")
|
|
605
|
+
break
|
|
588
606
|
end
|
|
589
|
-
when :
|
|
590
|
-
id
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
607
|
+
when :pull
|
|
608
|
+
if !id
|
|
609
|
+
id = tagmain
|
|
610
|
+
elsif !op.arg?('a', 'all-tags') && !id.include?(':')
|
|
611
|
+
id = "#{project}:#{id}"
|
|
612
|
+
end
|
|
613
|
+
unless registry
|
|
614
|
+
registry = op.shift
|
|
615
|
+
registry ||= option('registry') || @registry unless id.include?('/')
|
|
598
616
|
end
|
|
617
|
+
cmd << shell_quote(tagjoin(registry, id))
|
|
618
|
+
when :push
|
|
619
|
+
id ||= option('tag', ignore: false) || op.shift || tagmain
|
|
620
|
+
registry ||= option('registry') || op.shift || @registry
|
|
621
|
+
emptyargs op, flag
|
|
599
622
|
raise_error ArgumentError, 'username/registry not specified', hint: flag unless registry
|
|
600
|
-
registry
|
|
601
|
-
uri = shell_quote "#{registry}/#{id}"
|
|
623
|
+
uri = shell_quote tagjoin(registry, id)
|
|
602
624
|
op << uri
|
|
603
625
|
img = docker_output 'image', 'tag', id, uri
|
|
604
626
|
return unless confirm_command(img.to_s, cmd.to_s, target: id, as: registry, title: from)
|
|
605
627
|
|
|
606
|
-
|
|
628
|
+
@session = img
|
|
607
629
|
sync = false
|
|
608
|
-
exception
|
|
630
|
+
exception ||= true
|
|
609
631
|
banner = false
|
|
610
632
|
end
|
|
611
|
-
run(
|
|
612
|
-
success?(ret, flag == :tag || flag == :save)
|
|
613
|
-
end
|
|
633
|
+
success?(run(sync: sync, exception: exception, banner: banner, from: from), flag == :tag || flag == :save)
|
|
614
634
|
end
|
|
615
635
|
|
|
616
636
|
def network(flag, opts = [], target: nil)
|
|
617
637
|
cmd, opts = docker_session('network', flag, opts: opts)
|
|
618
638
|
OptionPartition.new(opts, OPT_DOCKER[:network].fetch(flag, []), cmd, project: self)
|
|
619
639
|
.clear
|
|
620
|
-
from =
|
|
621
|
-
list_image(flag, docker_output('ps -a'), from: from)
|
|
622
|
-
success?(run(cmd.temp(target, img), from: from))
|
|
623
|
-
end
|
|
640
|
+
from = symjoin 'network', flag
|
|
641
|
+
list_image(flag, docker_output('ps -a'), from: from) { |id| success?(run(cmd.temp(target, id), from: from)) }
|
|
624
642
|
end
|
|
625
643
|
|
|
626
644
|
def build?
|
|
@@ -669,7 +687,7 @@ module Squared
|
|
|
669
687
|
elsif (data = doc.dig(*keys))
|
|
670
688
|
yield data
|
|
671
689
|
end
|
|
672
|
-
rescue
|
|
690
|
+
rescue => e
|
|
673
691
|
log.debug e
|
|
674
692
|
end
|
|
675
693
|
end
|
|
@@ -686,11 +704,11 @@ module Squared
|
|
|
686
704
|
end
|
|
687
705
|
|
|
688
706
|
def append_command(flag, val, list, target: @session, prompt: ':')
|
|
689
|
-
if list.delete(prompt)
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
707
|
+
list << if list.delete(prompt)
|
|
708
|
+
readline('Enter command [args]', force: flag == :exec)
|
|
709
|
+
else
|
|
710
|
+
env('DOCKER_ARGS')
|
|
711
|
+
end
|
|
694
712
|
case flag
|
|
695
713
|
when :run
|
|
696
714
|
unless session_arg?('name', target: target)
|
|
@@ -703,10 +721,10 @@ module Squared
|
|
|
703
721
|
target << list.join(' && ') unless list.empty?
|
|
704
722
|
end
|
|
705
723
|
|
|
706
|
-
def append_file(type, target: @session, index: 2)
|
|
707
|
-
return
|
|
724
|
+
def append_file(type, target: @session, index: 2, force: false)
|
|
725
|
+
return unless @file && !(ENV['COMPOSE_FILE'] && compose?(type))
|
|
708
726
|
|
|
709
|
-
unless @file.is_a?(Array)
|
|
727
|
+
unless @file.is_a?(Array) || force
|
|
710
728
|
case type
|
|
711
729
|
when 2, 4
|
|
712
730
|
return
|
|
@@ -714,14 +732,7 @@ module Squared
|
|
|
714
732
|
return unless COMPOSEFILE.select { |val| basepath!(val) }.size > 1
|
|
715
733
|
end
|
|
716
734
|
end
|
|
717
|
-
|
|
718
|
-
if target.is_a?(Set)
|
|
719
|
-
opts = target.to_a.insert(index, *files)
|
|
720
|
-
target.clear
|
|
721
|
-
.merge(opts)
|
|
722
|
-
else
|
|
723
|
-
target.insert(index, *files)
|
|
724
|
-
end
|
|
735
|
+
target.insert(index, *Array(@file).map { |val| quote_option('file', basepath(val)) })
|
|
725
736
|
end
|
|
726
737
|
|
|
727
738
|
def append_context(ctx = nil, target: @session)
|
|
@@ -735,7 +746,7 @@ module Squared
|
|
|
735
746
|
ver = option('version', target: target, ignore: false)
|
|
736
747
|
case val
|
|
737
748
|
when String
|
|
738
|
-
|
|
749
|
+
val.split(',')
|
|
739
750
|
else
|
|
740
751
|
Array(val)
|
|
741
752
|
end.each do |s|
|
|
@@ -828,7 +839,7 @@ module Squared
|
|
|
828
839
|
end
|
|
829
840
|
list_empty(hint: hint || from) if index == 1 && !y
|
|
830
841
|
end
|
|
831
|
-
rescue
|
|
842
|
+
rescue => e
|
|
832
843
|
on_error e, from
|
|
833
844
|
end
|
|
834
845
|
|
|
@@ -900,18 +911,18 @@ module Squared
|
|
|
900
911
|
when :tag
|
|
901
912
|
args = tagjoin @registry, tag
|
|
902
913
|
when :save
|
|
903
|
-
opts =
|
|
914
|
+
opts = opts.sub_ext('.tar')
|
|
904
915
|
cmd << quote_option('output', File.expand_path(opts))
|
|
905
916
|
if args
|
|
906
|
-
cmd <<
|
|
917
|
+
cmd << quote_option('platform', args)
|
|
907
918
|
args = nil
|
|
908
919
|
end
|
|
909
920
|
else
|
|
910
921
|
cmd << opts << '--'
|
|
911
922
|
end
|
|
912
|
-
cmd.merge(Array(out).map
|
|
923
|
+
cmd.merge(Array(out).map { |val| val.split(/\s+/, 2).first })
|
|
913
924
|
cmd << args
|
|
914
|
-
success?(run(cmd), ctx.start_with?(
|
|
925
|
+
success?(run(cmd), ctx.start_with?('network', 'tag', 'save'))
|
|
915
926
|
end
|
|
916
927
|
|
|
917
928
|
def filetype(val = dockerfile)
|
|
@@ -934,11 +945,12 @@ module Squared
|
|
|
934
945
|
end
|
|
935
946
|
|
|
936
947
|
def tagjoin(*args, char: '/')
|
|
937
|
-
args.
|
|
948
|
+
args.compact!
|
|
949
|
+
args.map { |val| val.chomp(char) }.join(char) unless args.empty?
|
|
938
950
|
end
|
|
939
951
|
|
|
940
952
|
def tagname(val)
|
|
941
|
-
val = val.split(':').map
|
|
953
|
+
val = val.split(':').map { |s| charname(s.sub(/^\W+/, '')) }
|
|
942
954
|
ret = val.join(':')
|
|
943
955
|
ret = val.first if val.size > 1 && ret.size > 128
|
|
944
956
|
ret[0..127]
|
|
@@ -955,6 +967,14 @@ module Squared
|
|
|
955
967
|
def tagmain
|
|
956
968
|
tag.is_a?(Array) ? tag.first : tag
|
|
957
969
|
end
|
|
970
|
+
|
|
971
|
+
def emptyargs(list, hint = nil)
|
|
972
|
+
raise_error ArgumentError, "unrecognized args: #{list.join(', ')}", hint: hint unless list.empty?
|
|
973
|
+
end
|
|
974
|
+
|
|
975
|
+
def anypath?(*args)
|
|
976
|
+
args.any? { |val| basepath!(val) }
|
|
977
|
+
end
|
|
958
978
|
end
|
|
959
979
|
|
|
960
980
|
Application.implement Docker
|