squared 0.8.1 → 0.8.3
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 +99 -0
- data/README.md +33 -30
- data/lib/squared/common/base.rb +7 -0
- data/lib/squared/common/prompt.rb +8 -4
- data/lib/squared/common/utils.rb +9 -1
- data/lib/squared/config.rb +1 -2
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +7 -1
- data/lib/squared/workspace/project/base.rb +43 -11
- data/lib/squared/workspace/project/docker.rb +85 -28
- data/lib/squared/workspace/project/git.rb +296 -122
- data/lib/squared/workspace/project/node.rb +31 -12
- data/lib/squared/workspace/project/python.rb +41 -28
- data/lib/squared/workspace/project/ruby.rb +30 -25
- data/lib/squared/workspace/project/support/optionpartition.rb +35 -4
- data/lib/squared/workspace/project/support/utils.rb +22 -6
- data/lib/squared/workspace/repo.rb +3 -8
- data/lib/squared/workspace/series.rb +2 -2
- metadata +2 -2
|
@@ -13,11 +13,11 @@ module Squared
|
|
|
13
13
|
buildx: {
|
|
14
14
|
common: %w[builder=b D|debug],
|
|
15
15
|
build: %w[add-host=q annotation=q attest=q build-arg=qq build-context=qq cache-from=q cache-to=q
|
|
16
|
-
cgroup-parent=b iidfile=p label=q network=b no-cache-filter=b o|output=q platform=q
|
|
17
|
-
q
|
|
18
|
-
bake: %w[print list=q set=
|
|
19
|
-
shared: %w[check load no-cache pull push allow=q call=b? f|file=p metadata-file=p progress=b
|
|
20
|
-
sbom=q].freeze
|
|
16
|
+
cgroup-parent=b iidfile=p label=q network=b no-cache-filter=b o|output=q platform=q q|quiet
|
|
17
|
+
resource=q secret=qq shm-size=b ssh=qq t|tag=b target=b ulimit=q].freeze,
|
|
18
|
+
bake: %w[print list=q set=qq var=qq].freeze,
|
|
19
|
+
shared: %w[check load no-cache pull push allow=q call=b? f|file=p metadata-file=p policy=q progress=b
|
|
20
|
+
provenance=q sbom=q].freeze
|
|
21
21
|
}.freeze,
|
|
22
22
|
compose: {
|
|
23
23
|
common: %w[all-resources ansi=b compatibility dry-run env-file=p f|file=p parallel=n profile=b progress=b
|
|
@@ -34,7 +34,8 @@ module Squared
|
|
|
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
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
|
+
publish: %w[app resolve-image-digests with-env y|yes oci-version=b].freeze,
|
|
38
|
+
logs: %w[dry-run f|follow no-color no-log-prefix t|timestamps index=i since=q n|tail=b until=q].freeze
|
|
38
39
|
}.freeze,
|
|
39
40
|
container: {
|
|
40
41
|
create: %w[init i|interactive no-healthcheck oom-kill-disable privileged P|publish-all q|quiet read-only
|
|
@@ -55,8 +56,9 @@ module Squared
|
|
|
55
56
|
restart=q].freeze,
|
|
56
57
|
exec: %w[d|detach i|interactive privileged t|tty detach-keys=q e|env=qq env-file=p u|user=e
|
|
57
58
|
w|workdir=q].freeze,
|
|
58
|
-
commit: %w[no-pause a|author=q c|change=q m|message=q
|
|
59
|
-
|
|
59
|
+
commit: %w[no-pause a|author=q c|change=q m|message=q].freeze,
|
|
60
|
+
logs: %w[details f|follow t|timestamps since=q n|tail=b until=q].freeze,
|
|
61
|
+
inspect: %w[s|size f|format=q].freeze,
|
|
60
62
|
start: %w[a|attach i|interactive detach-keys=q].freeze,
|
|
61
63
|
stop: %w[s|signal=b t|timeout=i].freeze,
|
|
62
64
|
restart: %w[s|signal=b t|timeout=i].freeze,
|
|
@@ -65,11 +67,14 @@ module Squared
|
|
|
65
67
|
attach: %w[no-stdin detach-keys=q sig-proxy=!?].freeze
|
|
66
68
|
}.freeze,
|
|
67
69
|
image: {
|
|
70
|
+
common: %w[platform=q].freeze,
|
|
71
|
+
inspect: %w[f|format].freeze,
|
|
72
|
+
history: %w[f|format no-trunc q|quiet H|human=!?].freeze,
|
|
68
73
|
ls: %w[a|all digests no-trunc q|quiet tree f|filter=q format=q].freeze,
|
|
69
|
-
pull: %w[a|all-tags
|
|
70
|
-
push: %w[a|all-tags
|
|
71
|
-
rm: %w[f|force no-prune
|
|
72
|
-
save: %w[o|output=p
|
|
74
|
+
pull: %w[a|all-tags q|quiet].freeze,
|
|
75
|
+
push: %w[a|all-tags q|quiet].freeze,
|
|
76
|
+
rm: %w[f|force no-prune].freeze,
|
|
77
|
+
save: %w[o|output=p].freeze
|
|
73
78
|
}.freeze,
|
|
74
79
|
network: {
|
|
75
80
|
connect: %w[alias=b driver-opt=q gw-priority=n ip=b ip6=q link=b link-local-ip=q].freeze,
|
|
@@ -112,10 +117,10 @@ module Squared
|
|
|
112
117
|
|
|
113
118
|
subtasks({
|
|
114
119
|
'build' => %i[tag context].freeze,
|
|
115
|
-
'compose' => %i[build create publish run exec up down service].freeze,
|
|
120
|
+
'compose' => %i[build create publish run exec up down logs service].freeze,
|
|
116
121
|
'bake' => %i[build compose check].freeze,
|
|
117
|
-
'image' => %i[ls rm pull push tag save].freeze,
|
|
118
|
-
'container' => %i[attach commit create diff exec inspect kill pause restart rm run start stats stop
|
|
122
|
+
'image' => %i[ls rm pull push tag save inspect history].freeze,
|
|
123
|
+
'container' => %i[attach commit create diff exec logs top inspect kill pause restart rm run start stats stop
|
|
119
124
|
unpause update].freeze,
|
|
120
125
|
'network' => %i[connect disconnect create].freeze,
|
|
121
126
|
'ls' => nil
|
|
@@ -124,13 +129,31 @@ module Squared
|
|
|
124
129
|
attr_reader :context
|
|
125
130
|
attr_accessor :tag
|
|
126
131
|
|
|
127
|
-
def initialize(*, mounts: [], **kwargs)
|
|
132
|
+
def initialize(*, client: nil, mounts: [], **kwargs)
|
|
128
133
|
super
|
|
129
134
|
self.global = nil
|
|
130
135
|
return unless dockerfile(kwargs[:file]).exist?
|
|
131
136
|
|
|
132
137
|
@tag = kwargs[:tag] || tagname("#{@project}:#{@version || 'latest'}")
|
|
133
138
|
@context = kwargs[:context]
|
|
139
|
+
@client = if client
|
|
140
|
+
opts = []
|
|
141
|
+
client.each do |key, val|
|
|
142
|
+
val = case (key = key.to_s)
|
|
143
|
+
when 'config'
|
|
144
|
+
basepath!(val, type: 'd')
|
|
145
|
+
when 'tlscacert', 'tlscert', 'tlskey'
|
|
146
|
+
basepath!(val, type: 'f')
|
|
147
|
+
when 'context', 'host', 'log-level'
|
|
148
|
+
quote_option(key, val)
|
|
149
|
+
when 'debug', 'tls', 'tlsverify'
|
|
150
|
+
opts << key
|
|
151
|
+
next
|
|
152
|
+
end
|
|
153
|
+
opts << quote_option(key, val) if val
|
|
154
|
+
end
|
|
155
|
+
opts unless opts.empty?
|
|
156
|
+
end
|
|
134
157
|
@mounts = mounts
|
|
135
158
|
@secrets = kwargs[:secrets]
|
|
136
159
|
@registry = tagjoin kwargs[:registry], kwargs[:username]
|
|
@@ -278,7 +301,11 @@ module Squared
|
|
|
278
301
|
end
|
|
279
302
|
end
|
|
280
303
|
else
|
|
281
|
-
format_desc action, flag, "opts*,id/name#{flag
|
|
304
|
+
format_desc action, flag, "opts*,id/name#{case flag
|
|
305
|
+
when :stats then '*'
|
|
306
|
+
when :logs, :diff, :attach, :top then nil
|
|
307
|
+
else '+'
|
|
308
|
+
end}"
|
|
282
309
|
task flag do |_, args|
|
|
283
310
|
container flag, args.to_a
|
|
284
311
|
end
|
|
@@ -289,7 +316,7 @@ module Squared
|
|
|
289
316
|
next unless @registry
|
|
290
317
|
|
|
291
318
|
format_desc action, flag, 'tag?,registry/username?,opts*'
|
|
292
|
-
task flag
|
|
319
|
+
task flag do |_, args|
|
|
293
320
|
image flag, args.to_a
|
|
294
321
|
end
|
|
295
322
|
when :pull
|
|
@@ -298,6 +325,16 @@ module Squared
|
|
|
298
325
|
id = param_guard(action, flag, args: args, key: :tag)
|
|
299
326
|
image(flag, args.extras, id: id)
|
|
300
327
|
end
|
|
328
|
+
when :inspect, :history
|
|
329
|
+
format_desc action, flag, "opts*,id#{'+' if flag == :inspect}"
|
|
330
|
+
task flag do |_, args|
|
|
331
|
+
args = args.to_a
|
|
332
|
+
if args.empty?
|
|
333
|
+
choice_command :image, flag
|
|
334
|
+
else
|
|
335
|
+
image flag, args.to_a
|
|
336
|
+
end
|
|
337
|
+
end
|
|
301
338
|
else
|
|
302
339
|
format_desc(action, flag, case flag
|
|
303
340
|
when :rm, :save then 'id,opts*'
|
|
@@ -380,11 +417,9 @@ module Squared
|
|
|
380
417
|
when String
|
|
381
418
|
ret << quote_option('secret', @secrets, double: true)
|
|
382
419
|
when Hash
|
|
383
|
-
|
|
420
|
+
%i[file env].each do |key|
|
|
384
421
|
ret.merge(Array(@secrets[key]).map { |arg| quote_option('secret', "type=#{key},#{arg}", double: true) })
|
|
385
422
|
end
|
|
386
|
-
append.call(:file)
|
|
387
|
-
append.call(:env)
|
|
388
423
|
else
|
|
389
424
|
ret.merge(Array(@secrets).map { |arg| quote_option('secret', arg) })
|
|
390
425
|
end
|
|
@@ -412,7 +447,7 @@ module Squared
|
|
|
412
447
|
.parse(data[flag == :bake ? :bake : :build] + (shared || data[:shared]))
|
|
413
448
|
case flag
|
|
414
449
|
when :build, :context
|
|
415
|
-
append_tag
|
|
450
|
+
append_tag tag || option('tag', ignore: false) || self.tag
|
|
416
451
|
if shared
|
|
417
452
|
op.add_quote(context, preserve: false)
|
|
418
453
|
else
|
|
@@ -429,7 +464,7 @@ module Squared
|
|
|
429
464
|
context = basepath context
|
|
430
465
|
op.each { |name| op.add_option('set', "#{name}.context=#{context}", escape: false) }
|
|
431
466
|
end
|
|
432
|
-
op.append(escape: true, strip:
|
|
467
|
+
op.append(escape: true, strip: ':', clear: true)
|
|
433
468
|
end
|
|
434
469
|
end
|
|
435
470
|
op.clear(pass: false)
|
|
@@ -471,7 +506,7 @@ module Squared
|
|
|
471
506
|
end
|
|
472
507
|
if multiple
|
|
473
508
|
op.concat(service) if service
|
|
474
|
-
op.append(delim: true, escape: true, strip:
|
|
509
|
+
op.append(delim: true, escape: true, strip: ':')
|
|
475
510
|
else
|
|
476
511
|
raise ArgumentError, message('no service was selected', hint: flag) unless service
|
|
477
512
|
|
|
@@ -536,10 +571,10 @@ module Squared
|
|
|
536
571
|
end
|
|
537
572
|
end
|
|
538
573
|
append_command(flag, id || tagmain, op.extras)
|
|
539
|
-
when :update
|
|
574
|
+
when :update, :inspect
|
|
540
575
|
raise ArgumentError, message('missing container', hint: flag) if op.empty?
|
|
541
576
|
|
|
542
|
-
op.append(escape: true, strip:
|
|
577
|
+
op.append(escape: true, strip: ':')
|
|
543
578
|
when :commit
|
|
544
579
|
latest = op.shift || tagmain
|
|
545
580
|
cmd << id << latest
|
|
@@ -569,14 +604,26 @@ module Squared
|
|
|
569
604
|
end
|
|
570
605
|
return
|
|
571
606
|
end
|
|
572
|
-
|
|
607
|
+
case flag
|
|
608
|
+
when :logs, :diff, :attach, :top
|
|
609
|
+
op.add_first(escape: true, strip: ':')
|
|
610
|
+
if flag == :top
|
|
611
|
+
op.append(delim: true)
|
|
612
|
+
else
|
|
613
|
+
op.clear
|
|
614
|
+
end
|
|
615
|
+
else
|
|
616
|
+
op.append(escape: true, strip: ':')
|
|
617
|
+
end
|
|
573
618
|
end
|
|
574
619
|
run(from: from)
|
|
575
620
|
end
|
|
576
621
|
|
|
577
622
|
def image(flag, opts = [], sync: true, id: nil, registry: nil, filter: nil)
|
|
578
623
|
cmd, opts = docker_session('image', flag, opts: opts)
|
|
579
|
-
|
|
624
|
+
list = OPT_DOCKER[:image].fetch(flag, [])
|
|
625
|
+
list += OPT_DOCKER[:image][:common] unless flag == :ls || flag == :tag
|
|
626
|
+
op = OptionPartition.new(opts, list, cmd, project: self, strict: strict?)
|
|
580
627
|
exception = exception?
|
|
581
628
|
banner = true
|
|
582
629
|
from = symjoin 'image', flag
|
|
@@ -654,6 +701,15 @@ module Squared
|
|
|
654
701
|
sync = false
|
|
655
702
|
exception ||= true
|
|
656
703
|
banner = false
|
|
704
|
+
when :inspect, :history
|
|
705
|
+
raise ArgumentError, message('missing image', hint: flag) if op.empty?
|
|
706
|
+
|
|
707
|
+
if flag == :history
|
|
708
|
+
op.add_first(escape: true, strip: ':')
|
|
709
|
+
.clear
|
|
710
|
+
else
|
|
711
|
+
op.append(escape: true, strip: ':')
|
|
712
|
+
end
|
|
657
713
|
end
|
|
658
714
|
success?(run(sync: sync, exception: exception, banner: banner, from: from), flag == :tag || flag == :save)
|
|
659
715
|
end
|
|
@@ -725,6 +781,7 @@ module Squared
|
|
|
725
781
|
end
|
|
726
782
|
|
|
727
783
|
def docker_session(*cmd, opts: nil)
|
|
784
|
+
opts = OptionPartition.union(Array(opts), @client) if @client
|
|
728
785
|
return session('docker', *cmd) unless opts
|
|
729
786
|
|
|
730
787
|
op = OptionPartition.new(opts, OPT_DOCKER[:common], project: self, strict: strict?)
|