squared 0.5.2 → 0.5.4
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 -0
- data/README.ruby.md +21 -15
- data/lib/squared/common/format.rb +6 -4
- data/lib/squared/common/prompt.rb +3 -3
- data/lib/squared/common/shell.rb +9 -5
- data/lib/squared/common/system.rb +3 -3
- data/lib/squared/common/utils.rb +9 -0
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +25 -16
- data/lib/squared/workspace/project/base.rb +201 -140
- data/lib/squared/workspace/project/docker.rb +83 -70
- data/lib/squared/workspace/project/git.rb +234 -152
- data/lib/squared/workspace/project/node.rb +87 -34
- data/lib/squared/workspace/project/python.rb +55 -22
- data/lib/squared/workspace/project/ruby.rb +101 -58
- data/lib/squared/workspace/project/support/class.rb +66 -17
- data/lib/squared/workspace/repo.rb +47 -43
- data/lib/squared/workspace/series.rb +4 -4
- data/lib/squared/workspace/support/base.rb +17 -0
- data/lib/squared/workspace/support.rb +1 -0
- data/lib/squared/workspace.rb +0 -8
- data/squared.gemspec +2 -2
- metadata +2 -1
@@ -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,8 +95,9 @@ 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,
|
100
|
+
'bake' => %i[build check].freeze,
|
97
101
|
'image' => %i[list rm push tag save].freeze,
|
98
102
|
'container' => %i[run create exec update commit inspect diff start stop restart pause unpause top stats kill
|
99
103
|
rm].freeze,
|
@@ -112,7 +116,6 @@ module Squared
|
|
112
116
|
@mounts = mounts
|
113
117
|
@secrets = secrets
|
114
118
|
@registry = tagjoin registry, kwargs[:username]
|
115
|
-
@file = nil
|
116
119
|
initialize_ref Docker.ref
|
117
120
|
initialize_logger(**kwargs)
|
118
121
|
initialize_env(**kwargs)
|
@@ -125,11 +128,11 @@ 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|
|
132
|
-
next if
|
135
|
+
next if task_pass?(action)
|
133
136
|
|
134
137
|
namespace action do
|
135
138
|
flags.each do |flag|
|
@@ -142,18 +145,31 @@ 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
|
-
|
148
|
+
end
|
149
|
+
when 'bake'
|
150
|
+
next unless bake?
|
151
|
+
|
152
|
+
case flag
|
153
|
+
when :build
|
146
154
|
format_desc action, flag, ':?,opts*,target*,context?'
|
147
155
|
task flag do |_, args|
|
148
156
|
args = args.to_a
|
149
157
|
if args.first == ':'
|
150
158
|
choice_command :bake
|
151
159
|
else
|
152
|
-
buildx
|
160
|
+
buildx :bake, args
|
153
161
|
end
|
154
162
|
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
|
155
169
|
end
|
156
170
|
when 'compose'
|
171
|
+
next unless compose?
|
172
|
+
|
157
173
|
case flag
|
158
174
|
when :build, :up
|
159
175
|
format_desc action, flag, 'opts*,service*'
|
@@ -306,7 +322,7 @@ module Squared
|
|
306
322
|
op.parse(OPT_DOCKER[:buildx][flag == :bake ? :bake : :build] + OPT_DOCKER[:buildx][:shared])
|
307
323
|
case flag
|
308
324
|
when :build, :context
|
309
|
-
append_tag(tag || option('tag', ignore: false) ||
|
325
|
+
append_tag(tag || option('tag', ignore: false) || self.tag)
|
310
326
|
append_context context
|
311
327
|
when :bake
|
312
328
|
unless op.empty?
|
@@ -316,7 +332,7 @@ module Squared
|
|
316
332
|
if projectpath?(val = args.pop)
|
317
333
|
context = val
|
318
334
|
else
|
319
|
-
op.
|
335
|
+
op.push(val)
|
320
336
|
end
|
321
337
|
end
|
322
338
|
op.append(args, escape: true)
|
@@ -338,7 +354,7 @@ module Squared
|
|
338
354
|
when :build, :up
|
339
355
|
op.append(escape: true)
|
340
356
|
when :exec, :run
|
341
|
-
append_command
|
357
|
+
append_command flag, service, op.extras
|
342
358
|
end
|
343
359
|
run(from: from)
|
344
360
|
end
|
@@ -355,44 +371,54 @@ module Squared
|
|
355
371
|
when :run, :create, :exec
|
356
372
|
if rc && !op.arg?('mount')
|
357
373
|
run = VAL_DOCKER[:run]
|
358
|
-
|
359
|
-
|
360
|
-
delim = Regexp.new(",\\s*(?=#{both.join('|')})")
|
374
|
+
all = collect_hash VAL_DOCKER[:run]
|
375
|
+
delim = Regexp.new(",\\s*(?=#{all.join('|')})")
|
361
376
|
Array(@mounts).each do |val|
|
362
377
|
args = []
|
363
|
-
|
378
|
+
type = nil
|
364
379
|
val.split(delim).each do |opt|
|
365
380
|
k, v, q = split_option opt
|
366
|
-
next unless both.include?(k)
|
367
|
-
|
368
381
|
if k == 'type'
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
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)
|
382
408
|
end
|
383
|
-
args << "#{k}=#{q + v + q}"
|
384
409
|
end
|
385
|
-
|
410
|
+
raise_error('missing type', hint: flag) unless type
|
411
|
+
cmd << "--mount type=#{type},#{args.join(',')}"
|
386
412
|
end
|
387
413
|
end
|
388
|
-
append_command(flag, id || tagmain, op.extras
|
414
|
+
append_command(flag, id || tagmain, op.extras)
|
389
415
|
when :update
|
390
|
-
raise_error('missing container', hint:
|
416
|
+
raise_error('missing container', hint: flag) if op.empty?
|
391
417
|
op.append(escape: true)
|
392
418
|
when :commit
|
393
419
|
latest = op.shift || tagmain
|
394
420
|
cmd << id << latest
|
395
|
-
raise_error("unknown args: #{op.join(', ')}", hint:
|
421
|
+
raise_error("unknown args: #{op.join(', ')}", hint: flag) unless op.empty?
|
396
422
|
return unless confirm_command(cmd.to_s, title: from, target: id, as: latest)
|
397
423
|
|
398
424
|
registry = option('registry') || @registry
|
@@ -435,7 +461,7 @@ module Squared
|
|
435
461
|
when :rm
|
436
462
|
status = %w[created exited dead]
|
437
463
|
end
|
438
|
-
ps = docker_output('ps -a', *status.map { |s|
|
464
|
+
ps = docker_output('ps -a', *status.map { |s| quote_option('filter', "status=#{s}") })
|
439
465
|
list_image(flag, ps, no: no, hint: "status: #{status.join(', ')}", from: from) do |img|
|
440
466
|
run(cmd.temp(img), from: from)
|
441
467
|
end
|
@@ -499,8 +525,8 @@ module Squared
|
|
499
525
|
when :push
|
500
526
|
id ||= option('tag', ignore: false) || tagmain
|
501
527
|
registry ||= op.shift || option('registry') || @registry
|
502
|
-
raise_error(id ? "unknown args: #{op.join(', ')}" : 'no id/tag given', hint:
|
503
|
-
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
|
504
530
|
registry.chomp!('/')
|
505
531
|
uri = shell_quote "#{registry}/#{id}"
|
506
532
|
op << uri
|
@@ -534,6 +560,14 @@ module Squared
|
|
534
560
|
super || dockerfile.exist?
|
535
561
|
end
|
536
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
|
+
|
537
571
|
def dockerfile(val = nil)
|
538
572
|
if val == 'Dockerfile'
|
539
573
|
@file = false
|
@@ -563,7 +597,7 @@ module Squared
|
|
563
597
|
session('docker', *cmd, main: false, options: false, **kwargs)
|
564
598
|
end
|
565
599
|
|
566
|
-
def append_command(flag, val, list, target: @session
|
600
|
+
def append_command(flag, val, list, target: @session)
|
567
601
|
if list.delete(':')
|
568
602
|
list << readline('Enter command [args]', force: true)
|
569
603
|
elsif (args = env('DOCKER_ARGS'))
|
@@ -572,15 +606,10 @@ module Squared
|
|
572
606
|
case flag
|
573
607
|
when :run
|
574
608
|
unless session_arg?('name', target: target)
|
575
|
-
target << basic_option('name', dnsname("#{name}_%s" %
|
576
|
-
require 'random/formatter'
|
577
|
-
Random.new.alphanumeric(6)
|
578
|
-
else
|
579
|
-
(0...6).map { rand(97..122).chr }.join
|
580
|
-
end))
|
609
|
+
target << basic_option('name', dnsname("#{name}_%s" % rand_s(6)))
|
581
610
|
end
|
582
611
|
when :exec
|
583
|
-
raise_error('no command args', hint:
|
612
|
+
raise_error('no command args', hint: flag) if list.empty?
|
584
613
|
end
|
585
614
|
target << val << list.shift
|
586
615
|
target << list.join(' && ') unless list.empty?
|
@@ -628,7 +657,7 @@ module Squared
|
|
628
657
|
index = 0
|
629
658
|
all = option('all', prefix: 'docker')
|
630
659
|
y = from == :'image:rm' && option('y', prefix: 'docker')
|
631
|
-
pat =
|
660
|
+
pat = /\b(?:#{dnsname(name)}|#{tagname(project)}|#{tagmain.split(':', 2).first})\b/
|
632
661
|
IO.popen(session_done(cmd << '--format=json')).each do |line|
|
633
662
|
data = JSON.parse(line)
|
634
663
|
id = data['ID']
|
@@ -676,14 +705,10 @@ module Squared
|
|
676
705
|
end
|
677
706
|
yield id
|
678
707
|
end
|
679
|
-
puts log_message(Logger::INFO, 'none detected', subject:
|
708
|
+
puts log_message(Logger::INFO, 'none detected', subject: name, hint: hint || from) if !found && !y
|
680
709
|
end
|
681
710
|
rescue StandardError => e
|
682
|
-
|
683
|
-
ret = on :error, from, e
|
684
|
-
raise if exception && ret != true
|
685
|
-
|
686
|
-
warn log_message(Logger::WARN, e, pass: true) if warning?
|
711
|
+
on_error e, from
|
687
712
|
end
|
688
713
|
|
689
714
|
def confirm_command(*args, title: nil, target: nil, as: nil)
|
@@ -740,7 +765,7 @@ module Squared
|
|
740
765
|
cmd = docker_output ctx
|
741
766
|
case flag
|
742
767
|
when :tag
|
743
|
-
args = tagjoin @registry,
|
768
|
+
args = tagjoin @registry, tag
|
744
769
|
when :save
|
745
770
|
opts = "#{opts}.tar" unless opts.end_with?('.tar')
|
746
771
|
cmd << quote_option('output', File.expand_path(opts))
|
@@ -751,11 +776,7 @@ module Squared
|
|
751
776
|
else
|
752
777
|
cmd << opts << '--'
|
753
778
|
end
|
754
|
-
cmd.merge(
|
755
|
-
out.map! { |val| parse.call(val) }
|
756
|
-
else
|
757
|
-
[parse.call(out)]
|
758
|
-
end)
|
779
|
+
cmd.merge(Array(out).map! { |val| parse.call(val) })
|
759
780
|
cmd << args
|
760
781
|
print_success if success?(run(cmd)) && ctx.start_with?(/(?:network|tag|save)/)
|
761
782
|
end
|
@@ -804,14 +825,6 @@ module Squared
|
|
804
825
|
def tagmain
|
805
826
|
tag.is_a?(Array) ? tag.first : tag
|
806
827
|
end
|
807
|
-
|
808
|
-
def compose?(file = dockerfile)
|
809
|
-
COMPOSEFILE.include?(File.basename(file))
|
810
|
-
end
|
811
|
-
|
812
|
-
def bake?(file = dockerfile)
|
813
|
-
BAKEFILE.include?(File.basename(file))
|
814
|
-
end
|
815
828
|
end
|
816
829
|
|
817
830
|
Application.implement Docker
|