squared 0.4.12 → 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 +56 -0
- data/README.md +4 -4
- data/README.ruby.md +19 -12
- data/lib/squared/common/base.rb +5 -3
- data/lib/squared/common/format.rb +1 -1
- data/lib/squared/common/prompt.rb +35 -39
- data/lib/squared/common/shell.rb +27 -22
- data/lib/squared/common/system.rb +36 -32
- data/lib/squared/common/utils.rb +0 -12
- data/lib/squared/common.rb +2 -1
- data/lib/squared/config.rb +12 -11
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +17 -21
- data/lib/squared/workspace/project/base.rb +363 -220
- data/lib/squared/workspace/project/docker.rb +110 -68
- data/lib/squared/workspace/project/git.rb +82 -74
- data/lib/squared/workspace/project/node.rb +63 -21
- data/lib/squared/workspace/project/python.rb +138 -103
- data/lib/squared/workspace/project/ruby.rb +60 -43
- data/lib/squared/workspace/project/support/class.rb +81 -6
- data/lib/squared/workspace/project.rb +0 -10
- data/lib/squared/workspace/repo.rb +5 -5
- data/lib/squared/workspace/series.rb +8 -8
- data/lib/squared/workspace/support/data.rb +1 -0
- data/lib/squared/workspace.rb +1 -1
- data/squared.gemspec +1 -1
- metadata +2 -3
- data/lib/squared/common/class.rb +0 -110
@@ -32,22 +32,24 @@ module Squared
|
|
32
32
|
no-attach=b pull=b scale=i t|timeout=i wait-timeout=i].freeze
|
33
33
|
}.freeze,
|
34
34
|
container: {
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
35
|
+
create: %w[init i|interactive no-healthcheck oom-kill-disable privileged P|publish-all q|quiet read-only
|
36
|
+
rm runtime t|tty use-api-socket io-maxbandwidth=b io-maxiops=b add-host=q annotation=q
|
37
|
+
a|attach=b blkio-weight=i blkio-weight-device=i cap-add=b cap-drop=b cgroup-parent=b cgroupns=b
|
38
|
+
cidfile=p device=q device-cgroup-rule=q device-read-bps=q device-read-iops=q device-write-bps=q
|
39
|
+
device-write-iops=q disable-content-trust=b? dns=e dns-option=e dns-search=e domainname=b
|
40
|
+
entrypoint=q e|env=qq env-file=p expose=e gpus=q group-add=b health-cmd=q health-interval=b
|
41
|
+
health-retries=i health-start-interval=b health-start-period=b health-timeout=b h|hostname=e ip=b
|
42
|
+
ip6=e ipc=b isolation=b kernel-memory=b l|label=q label-file=p link=b link-local-ip=b
|
43
|
+
log-driver=b log-opt=q mac-address=e m|memory=b memory-reservation=b memory-swap=n
|
44
|
+
memory-swappiness=n mount=qq name=b network=b network-alias=b oom-score-adj=b pid=b pids-limit=n
|
45
|
+
platform=b p|publish=e pull=b restart=b runtime=b security-opt=q shm-size=b stop-signal=b
|
46
|
+
stop-timeout=i storage-opt=q sysctl=q tmpfs=q ulimit=q u|user=b userns=b uts=b v|volume=q
|
47
|
+
volume-driver=b volumes-from=b w|workdir=q].freeze,
|
48
|
+
run: %w[d|detach detach-keys=q sig-proxy=b?].freeze,
|
47
49
|
exec: %w[d|detach i|interactive privileged t|tty detach-keys=q e|env=qq env-file=p user=e
|
48
50
|
w|workdir=q].freeze,
|
49
51
|
update: %w[blkio-weight=i cpu-period=i cpu-quota=i cpu-rt-period=i cpu-rt-runtime=i c|cpu-shares=i cpus=f
|
50
|
-
cpuset-cpus=b cpuset-mems=b m|memory=b memory-reservation=b memory-swap=b pids-limit=
|
52
|
+
cpuset-cpus=b cpuset-mems=b m|memory=b memory-reservation=b memory-swap=b pids-limit=n
|
51
53
|
restart=q].freeze,
|
52
54
|
commit: %w[a|author=q c|change=q m|message=q pause=b?].freeze,
|
53
55
|
inspect: %w[s|size f|format=q].freeze,
|
@@ -60,7 +62,8 @@ module Squared
|
|
60
62
|
image: {
|
61
63
|
list: %w[a|all digests no-trunc f|filter=q format=q].freeze,
|
62
64
|
push: %w[a|all-tags disable-content-trust=b? platform=b q|quiet].freeze,
|
63
|
-
rm: %w[f|force no-prune].freeze
|
65
|
+
rm: %w[f|force no-prune].freeze,
|
66
|
+
save: %w[o|output=p platform=b].freeze
|
64
67
|
}.freeze,
|
65
68
|
network: {
|
66
69
|
connect: %w[alias=b driver-opt=q gw-priority=n ip=b ip6=b link=b link-local-ip=b].freeze,
|
@@ -90,8 +93,8 @@ module Squared
|
|
90
93
|
subtasks({
|
91
94
|
'build' => %i[tag context bake].freeze,
|
92
95
|
'compose' => %i[build run exec up].freeze,
|
93
|
-
'image' => %i[list rm push].freeze,
|
94
|
-
'container' => %i[run exec update commit inspect diff start stop restart pause unpause top stats kill
|
96
|
+
'image' => %i[list rm push tag save].freeze,
|
97
|
+
'container' => %i[run create exec update commit inspect diff start stop restart pause unpause top stats kill
|
95
98
|
rm].freeze,
|
96
99
|
'network' => %i[connect disconnect].freeze
|
97
100
|
})
|
@@ -107,7 +110,8 @@ module Squared
|
|
107
110
|
@tag = tag || tagname("#{@project}:#{@version || 'latest'}")
|
108
111
|
@mounts = mounts
|
109
112
|
@secrets = secrets
|
110
|
-
@registry =
|
113
|
+
@registry = tagjoin registry, kwargs[:username]
|
114
|
+
@file = nil
|
111
115
|
initialize_ref Docker.ref
|
112
116
|
initialize_logger(**kwargs)
|
113
117
|
initialize_env(**kwargs)
|
@@ -174,7 +178,7 @@ module Squared
|
|
174
178
|
container(flag, args.extras, id: id)
|
175
179
|
end
|
176
180
|
end
|
177
|
-
when :run
|
181
|
+
when :run, :create
|
178
182
|
format_desc action, flag, 'image,opts*,args*'
|
179
183
|
task flag, [:image] do |_, args|
|
180
184
|
if args.image
|
@@ -194,15 +198,18 @@ module Squared
|
|
194
198
|
when :push
|
195
199
|
format_desc action, flag, 'tag,registry/username?,opts*'
|
196
200
|
task flag, [:tag] do |_, args|
|
197
|
-
|
198
|
-
image(flag, args.extras, id:
|
201
|
+
id = param_guard(action, flag, args: args, key: :tag)
|
202
|
+
image(flag, args.extras, id: id)
|
199
203
|
end
|
200
|
-
|
201
|
-
format_desc(action, flag, flag
|
204
|
+
else
|
205
|
+
format_desc(action, flag, case flag
|
206
|
+
when :rm, :save then 'id*,opts*'
|
207
|
+
when :tag then 'version?'
|
208
|
+
else 'opts*,args*' end)
|
202
209
|
task flag do |_, args|
|
203
210
|
args = args.to_a
|
204
|
-
if flag
|
205
|
-
choice_command
|
211
|
+
if args.empty? && flag != :list
|
212
|
+
choice_command flag
|
206
213
|
else
|
207
214
|
image flag, args
|
208
215
|
end
|
@@ -260,10 +267,8 @@ module Squared
|
|
260
267
|
end
|
261
268
|
|
262
269
|
[args, flags].each_with_index do |target, index|
|
263
|
-
if target
|
264
|
-
ret
|
265
|
-
elsif (target = append_any(target, target: []))
|
266
|
-
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) })
|
267
272
|
end
|
268
273
|
end
|
269
274
|
case from
|
@@ -287,8 +292,8 @@ module Squared
|
|
287
292
|
end
|
288
293
|
append_context
|
289
294
|
when :bake, :compose
|
290
|
-
|
291
|
-
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) })
|
292
297
|
end
|
293
298
|
end
|
294
299
|
ret
|
@@ -340,13 +345,15 @@ module Squared
|
|
340
345
|
|
341
346
|
def container(flag, opts = [], id: nil)
|
342
347
|
cmd, opts = docker_session('container', flag, opts: opts)
|
348
|
+
rc = flag == :run || flag == :create
|
343
349
|
list = OPT_DOCKER[:container].fetch(flag, [])
|
344
|
-
list += OPT_DOCKER[:container][:
|
345
|
-
|
350
|
+
list += OPT_DOCKER[:container][:create] if flag == :run
|
351
|
+
list += OPT_DOCKER[:container][:update] if rc
|
352
|
+
op = OptionPartition.new(opts, list, cmd, project: self, args: rc || flag == :exec)
|
346
353
|
from = :"container:#{flag}"
|
347
354
|
case flag
|
348
|
-
when :run, :exec
|
349
|
-
if
|
355
|
+
when :run, :create, :exec
|
356
|
+
if rc && !op.arg?('mount')
|
350
357
|
run = VAL_DOCKER[:run]
|
351
358
|
both = run[:bind] + run[:tmpfs]
|
352
359
|
diff = run[:bind].reject { |val| run[:tmpfs].include?(val) }
|
@@ -355,7 +362,7 @@ module Squared
|
|
355
362
|
args = []
|
356
363
|
tmpfs = true
|
357
364
|
val.split(delim).each do |opt|
|
358
|
-
k, v, q = split_option
|
365
|
+
k, v, q = split_option opt
|
359
366
|
next unless both.include?(k)
|
360
367
|
|
361
368
|
if k == 'type'
|
@@ -378,7 +385,7 @@ module Squared
|
|
378
385
|
cmd << "--mount type=#{tmpfs ? 'tmpfs' : 'bind'},#{args.join(',')}"
|
379
386
|
end
|
380
387
|
end
|
381
|
-
append_command(flag, id
|
388
|
+
append_command(flag, id || tagmain, op.extras, from: from)
|
382
389
|
when :update
|
383
390
|
raise_error('missing container', hint: from) if op.empty?
|
384
391
|
op.append(escape: true)
|
@@ -442,7 +449,7 @@ module Squared
|
|
442
449
|
|
443
450
|
def image(flag, opts = [], sync: true, id: nil, registry: nil)
|
444
451
|
cmd, opts = docker_session('image', flag, opts: opts)
|
445
|
-
op = OptionPartition.new(opts, OPT_DOCKER[:image][
|
452
|
+
op = OptionPartition.new(opts, OPT_DOCKER[:image].fetch(flag, []), cmd, project: self)
|
446
453
|
exception = @exception
|
447
454
|
banner = true
|
448
455
|
from = :"image:#{flag}"
|
@@ -473,7 +480,7 @@ module Squared
|
|
473
480
|
end
|
474
481
|
else
|
475
482
|
if op.empty?
|
476
|
-
list_image(
|
483
|
+
list_image(:rm, docker_output('image ls -a'), from: from) do |val|
|
477
484
|
image(:rm, opts, sync: sync, id: val)
|
478
485
|
end
|
479
486
|
else
|
@@ -481,13 +488,21 @@ module Squared
|
|
481
488
|
end
|
482
489
|
return
|
483
490
|
end
|
491
|
+
when :tag, :save
|
492
|
+
list_image(flag, docker_output('image ls -a'), from: from) do |val|
|
493
|
+
op << val
|
494
|
+
if flag == :tag
|
495
|
+
op << tagname("#{@project}:#{op.extras.first}")
|
496
|
+
break
|
497
|
+
end
|
498
|
+
end
|
484
499
|
when :push
|
485
500
|
id ||= option('tag', ignore: false) || tagmain
|
486
501
|
registry ||= op.shift || option('registry') || @registry
|
487
502
|
raise_error(id ? "unknown args: #{op.join(', ')}" : 'no id/tag given', hint: from) unless id && op.empty?
|
488
503
|
raise_error('username/registry not provided', hint: from) unless registry
|
489
504
|
registry.chomp!('/')
|
490
|
-
uri = shell_quote
|
505
|
+
uri = shell_quote "#{registry}/#{id}"
|
491
506
|
op << uri
|
492
507
|
img = docker_output 'image', 'tag', id, uri
|
493
508
|
return unless confirm_command(img.to_s, cmd.to_s, target: id, as: registry, title: from)
|
@@ -497,7 +512,8 @@ module Squared
|
|
497
512
|
exception = true
|
498
513
|
banner = false
|
499
514
|
end
|
500
|
-
run(cmd, sync: sync, exception: exception, banner: banner, from: from)
|
515
|
+
ret = run(cmd, sync: sync, exception: exception, banner: banner, from: from)
|
516
|
+
print_success if success?(ret) && (flag == :tag || flag == :save)
|
501
517
|
end
|
502
518
|
|
503
519
|
def network(flag, opts = [], target: nil)
|
@@ -587,18 +603,20 @@ module Squared
|
|
587
603
|
end
|
588
604
|
|
589
605
|
def append_tag(val, target: @session)
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
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
|
602
620
|
end
|
603
621
|
end
|
604
622
|
|
@@ -685,14 +703,14 @@ module Squared
|
|
685
703
|
|
686
704
|
def choice_command(flag)
|
687
705
|
msg, cmd, index = case flag
|
688
|
-
when :run, :rm
|
689
|
-
['Choose an image', 'images -a', 2]
|
690
706
|
when :exec
|
691
707
|
['Choose a container', 'ps -a', 0]
|
692
708
|
when :bake
|
693
709
|
['Choose a target', 'buildx bake --list=type=targets', 0]
|
694
|
-
|
710
|
+
when :connect, :disconnect
|
695
711
|
['Choose a network', 'network ls', 0]
|
712
|
+
else
|
713
|
+
['Choose an image', 'images -a', 2]
|
696
714
|
end
|
697
715
|
lines = `#{docker_output(cmd)}`.lines
|
698
716
|
header = lines.shift
|
@@ -702,25 +720,43 @@ module Squared
|
|
702
720
|
puts " # #{header}"
|
703
721
|
multiple = false
|
704
722
|
parse = ->(val) { val.split(/\s+/)[index] }
|
723
|
+
ctx = flag.to_s
|
705
724
|
case flag
|
706
725
|
when :run, :exec
|
707
726
|
values = [['Options', flag == :run], ['Arguments', flag == :exec]]
|
708
|
-
cmd = flag.to_s
|
709
727
|
when :rm, :bake
|
710
728
|
values = ['Options']
|
711
729
|
multiple = true
|
712
|
-
|
713
|
-
|
730
|
+
ctx = flag == :rm ? 'image rm' : "buildx bake -f #{shell_quote(dockerfile)}"
|
731
|
+
when :save
|
732
|
+
values = [['Output', true], 'Platform']
|
733
|
+
multiple = true
|
734
|
+
when :connect, :disconnect
|
714
735
|
values = ['Options', ['Container', true]]
|
715
|
-
|
736
|
+
ctx = "network #{flag}"
|
716
737
|
end
|
717
738
|
out, opts, args = choice_index(msg, lines, multiple: multiple, values: values)
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
739
|
+
cmd = docker_output ctx
|
740
|
+
case flag
|
741
|
+
when :tag
|
742
|
+
args = tagjoin @registry, @tag
|
743
|
+
when :save
|
744
|
+
opts = "#{opts}.tar" unless opts.end_with?('.tar')
|
745
|
+
cmd << quote_option('output', File.expand_path(opts))
|
746
|
+
if args
|
747
|
+
cmd << basic_option('platform', args)
|
748
|
+
args = nil
|
749
|
+
end
|
750
|
+
else
|
751
|
+
cmd << opts << '--'
|
752
|
+
end
|
753
|
+
cmd.merge(if out.is_a?(Array)
|
754
|
+
out.map! { |val| parse.call(val) }
|
755
|
+
else
|
756
|
+
[parse.call(out)]
|
757
|
+
end)
|
758
|
+
cmd << args
|
759
|
+
print_success if success?(run(cmd)) && ctx.start_with?(/(?:network|tag|save)/)
|
724
760
|
end
|
725
761
|
end
|
726
762
|
|
@@ -743,11 +779,17 @@ module Squared
|
|
743
779
|
val && projectpath?(val) ? shell_quote(path + val) : '.'
|
744
780
|
end
|
745
781
|
|
782
|
+
def tagjoin(*args, char: '/')
|
783
|
+
args.compact!
|
784
|
+
args.join(char) unless args.empty?
|
785
|
+
end
|
786
|
+
|
746
787
|
def tagname(val)
|
747
788
|
val = val.split(':').map! { |s| charname(s.sub(/^\W+/, '')) }
|
748
|
-
|
749
|
-
|
750
|
-
|
789
|
+
val.join(':').yield_self do |s|
|
790
|
+
s = val.first if val.size > 1 && s.size > 128
|
791
|
+
s[0..127]
|
792
|
+
end
|
751
793
|
end
|
752
794
|
|
753
795
|
def dnsname(val)
|